From 201028f527a58f934127be28b8431bafbaf75cab Mon Sep 17 00:00:00 2001 From: npmrun Date: Thu, 18 May 2023 16:45:29 +0800 Subject: [PATCH] add --- data/data.db | Bin 28672 -> 32768 bytes docs/a.md | 1 - docs/index.md | 8 +++ public/js/common/flush.js | 2 +- public/style/common/style.css | 11 ++- public/style/views/index.css | 124 ++++++++++++++++++++++++++++++++++ public/style/views/test.css | 26 +++++++ route.txt | 26 +++---- source/models/color.ts | 5 +- source/models/color_cate.ts | 56 +++++++++++++++ source/plugins/index.ts | 1 - source/plugins/router-plugin/index.ts | 4 +- source/route/views/index.ts | 24 +++++-- source/run.ts | 7 +- template/404.pug | 1 + template/helper/flush.pug | 121 ++++++++++++++++----------------- template/htmx/path/index.pug | 38 +++++++++-- template/layout/layout.pug | 2 - template/views/login.pug | 1 + template/views/register.pug | 1 + template/views/resume.pug | 3 + template/views/test.pug | 31 +++++++++ types/global.d.ts | 2 + 23 files changed, 400 insertions(+), 95 deletions(-) delete mode 100644 docs/a.md create mode 100644 docs/index.md create mode 100644 public/style/views/index.css create mode 100644 public/style/views/test.css create mode 100644 source/models/color_cate.ts create mode 100644 template/views/test.pug diff --git a/data/data.db b/data/data.db index 41acff1e5c0e4aef9338b84fbfbc105a61e02482..c7a5199bc2078f5d7c2ec6dc3607d09cdd3e2bf5 100644 GIT binary patch delta 848 zcmZp8z}V2hG(lRhoq>UY1BhXOZ=#N|bUTAy+Dl&Eat3yGDF%Li9#-B{TpKu>II7vD zHa0F`vulduW*1jhW^83HNleN~P0r8BFN#l2EJ-a!VsbbKxjKfpDug&X`M4@1AY>*V z;MARbokNZ_F()&zc(Mnd`eb?DaCRMtn#lz`QY;|FlY4pe88tUob9k^aa&JDuYs)0f z^NoRvYYPK^3-2aAb-w$&uH1b*)!e_i6}h%-Ruq`QRiDkx!5}Ow?CI%Ql$ruTMg~U4 zx(24Yh87A2=2nIlR))rU24-do+6D$z1_q?cTIv}Yn?v+7nu2Vek(H65m8r3w zxv4Q0+wjYpSs9yJnOXpCGlkj44zq2NtZO~0JqE^BhGu#u<}hE?adI%I3#$TyA+b0G zgi?xAih)ETkd+8T5D{cEfDSdaGBVRMHh`IdSGFD{;2@eU^~^0TppLEN;9$@d76myV zuQI7LGbcr%pfo8bvp56lAPm!i?zb?)X*arTGCWGbb{ksi8CqCE?dDs^;15m%43wpT t&33ZOgn%jUss3(RMuy1?eXsDsl8~{9p1I-XCciqxNe(QVSq%R00|2{G%!L2| delta 161 zcmZo@U}|{4I6+#lnt_3V9f)CoccPB5WHp0c+Dl&Eat1bzY6gCO9#-B{TpKu>II1@* z3NUkQuIBJyW#rm?gx8iym~SBi8_zce{ubU%eCmAnd0lzFZ5C8`#KYyw&cProEbQsY zFxg*LYVrkXvB~wa96*|Pv#acUAx8GiPxW`pGRjU~=zE3NT*1)L%GBJ-$VAV~a&wbk Gogx5xA1H?a diff --git a/docs/a.md b/docs/a.md deleted file mode 100644 index 4529c59..0000000 --- a/docs/a.md +++ /dev/null @@ -1 +0,0 @@ -## Hello World \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..4e959be --- /dev/null +++ b/docs/index.md @@ -0,0 +1,8 @@ +# 欢迎做客前端作坊 + +> 作者:YSir +> 站点:[个人单页](https://xieyaxin.top) + +## 前言 + +又是一个新项目,工作这些年,也不知做了多少项目,大多数是难产而亡,本项目是第一个比较完整的后端项目,开发此站的目的仅是学习学习hapijs,最后写着写着就不想再搞其他的框架了,折腾累了,对于繁杂的网络信息,我感到神经有些疲劳,因此就先开发着这个项目,把完整的开源项目流程走一遍。 \ No newline at end of file diff --git a/public/js/common/flush.js b/public/js/common/flush.js index bb1863a..72fb1d3 100644 --- a/public/js/common/flush.js +++ b/public/js/common/flush.js @@ -1,4 +1,4 @@ -var $messages = Array.prototype.slice.call(document.querySelectorAll(".message-container .message button.delete"), 0) +var $messages = Array.prototype.slice.call(document.querySelectorAll(".message button.delete"), 0) $messages.forEach((el, index) => { let timeID function click() { diff --git a/public/style/common/style.css b/public/style/common/style.css index e3091b2..f49c028 100644 --- a/public/style/common/style.css +++ b/public/style/common/style.css @@ -2,7 +2,7 @@ html { overflow-y: auto; } -.message-container { +/* .message-container { position: fixed; right: 0; top: 0; @@ -12,8 +12,13 @@ html { } .message-container::-webkit-scrollbar { display: none; -} -.message-container .message { +} */ +.message { + position: fixed; + right: 0; + top: 0; + z-index: 999; + overflow: auto; min-width: 250px; max-width: 250px; margin: 25px; diff --git a/public/style/views/index.css b/public/style/views/index.css new file mode 100644 index 0000000..6dd2d35 --- /dev/null +++ b/public/style/views/index.css @@ -0,0 +1,124 @@ +.tree{ + flex: 1; + direction: rtl; + overflow: auto; + padding: 4px 0; + position: relative; + width: 300px; + font-size: .875em; + font-weight: 400; + color: rgba(25, 23, 17, 0.6); + fill: rgba(25, 23, 17, 0.6); + z-index: 0; + user-select: none; + /* @include media-pc(sm){ + width: 100%; + } */ +} + +/*去掉前面默认的小黑三角*/ +.tree details summary::-webkit-details-marker{ + display:none; +} + +.tree summary{ + outline: 0; + padding-left: 17px; + list-style: none; + list-style-type: none; + display: flex; + align-items: center; + display: -webkit-flex; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.tree .tree-md-file:before{ + content: ''; + background: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNjczNDAyMTUyMTkwIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEyODAgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjYyMzIiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjUwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTExODcuNiAxMTguMkg5Mi40QzQxLjQgMTE4LjIgMCAxNTkuNiAwIDIxMC40djYwM2MwIDUxIDQxLjQgOTIuNCA5Mi40IDkyLjRoMTA5NS40YzUxIDAgOTIuNC00MS40IDkyLjItOTIuMlYyMTAuNGMwLTUwLjgtNDEuNC05Mi4yLTkyLjQtOTIuMnpNNjc3IDcyMS4ySDU1NHYtMjQwbC0xMjMgMTUzLjgtMTIzLTE1My44djI0MEgxODQuNlYzMDIuOGgxMjNsMTIzIDE1My44IDEyMy0xNTMuOGgxMjN2NDE4LjR6IG0yNzAuNiA2LjJMNzYzIDUxMkg4ODZWMzAyLjhoMTIzVjUxMkgxMTMyeiIgcC1pZD0iNjIzMyIgZmlsbD0iIzhjOGM4YyI+PC9wYXRoPjwvc3ZnPg==") center no-repeat !important; + background-size: contain !important; +} + + +.tree .tree-md-file.mdx-file:before{ + content: ''; + background: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNjczNDAyMTUyMTkwIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEyODAgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjYyMzIiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjUwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTExODcuNiAxMTguMkg5Mi40QzQxLjQgMTE4LjIgMCAxNTkuNiAwIDIxMC40djYwM2MwIDUxIDQxLjQgOTIuNCA5Mi40IDkyLjRoMTA5NS40YzUxIDAgOTIuNC00MS40IDkyLjItOTIuMlYyMTAuNGMwLTUwLjgtNDEuNC05Mi4yLTkyLjQtOTIuMnpNNjc3IDcyMS4ySDU1NHYtMjQwbC0xMjMgMTUzLjgtMTIzLTE1My44djI0MEgxODQuNlYzMDIuOGgxMjNsMTIzIDE1My44IDEyMy0xNTMuOGgxMjN2NDE4LjR6IG0yNzAuNiA2LjJMNzYzIDUxMkg4ODZWMzAyLjhoMTIzVjUxMkgxMTMyeiIgcC1pZD0iNjIzMyIgZmlsbD0iIzhjOGM4YyI+PC9wYXRoPjwvc3ZnPg==") center no-repeat !important; + background-size: contain !important; +} + + +.tree summary:not(:only-child){ + background: url("data:image/svg+xml,%3Csvg width='12' height='12' viewBox='0 0 12 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.354 2.646A.5.5 0 0 0 4.5 3v6a.5.5 0 0 0 .854.354l3-3a.5.5 0 0 0 0-.708l-3-3z' fill='%23000' fill-opacity='.45'/%3E%3C/svg%3E") 4px center no-repeat; +} +.tree details[open]>summary:not(:only-child){ + background-image: url("data:image/svg+xml,%3Csvg width='12' height='12' viewBox='0 0 12 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9.354 5.354A.5.5 0 0 0 9 4.5H3a.5.5 0 0 0-.354.854l3 3a.5.5 0 0 0 .708 0l3-3z' fill='%23000' fill-opacity='.45'/%3E%3C/svg%3E"); +} +.tree details{ + padding-left: 15px +} +.tree>details{ + padding-left: 10px +} +summary.active{ + background-color: #1abc9c1a !important; +} +.op{ + display: none; + font-size: .8em; + margin-left: 1em; + margin-right: 1em; +} +summary:hover .op{ + display: block; +} + +.tree-item{ + flex: 1; + width: 0; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + display: inline-flex; + align-items: center; + line-height: 1; + padding: 5px 0; + cursor: default; +} +.tree details summary a{ + border: 0; + color: inherit; + cursor: pointer; +} + .tree-item:hover{ + text-decoration: none; +} + +.tree-item::after{ + content: ''; + position: absolute; + left: 0; + right: 0; + height: 28px; + z-index: -1; + transition: .2s; +} +.tree-item:hover::after{ + background: #1abc9c1a; +} +.tree-item.active::after{ + background: #1abc9c48; + border-right: 4px solid #1abc9c; +} + +.tree-item::before{ + content: ''; + width: 20px; + height: 20px; + flex-shrink: 0; + margin-right: 5px; + background: url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M.833 3.75c0-.92.746-1.667 1.667-1.667h5.417c.247 0 .481.11.64.3l1.833 2.2h7.11c.92 0 1.667.747 1.667 1.667v10c0 .92-.747 1.667-1.667 1.667h-15c-.92 0-1.667-.746-1.667-1.667V3.75zm6.693 0H2.5v4.584h15V6.25H10a.833.833 0 0 1-.64-.3l-1.834-2.2zM17.5 10h-15v6.25h15V10z' fill='%23000' fill-opacity='.45'/%3E%3C/svg%3E") center no-repeat; +} +.tree details[open]>summary:not(:only-child)>.tree-item::before{ + background-image: url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M7.917 2.083c.247 0 .481.11.64.3l1.833 2.2h5.443c.92 0 1.667.747 1.667 1.667v1.667h.833a.833.833 0 0 1 .817.997l-1.666 8.333a.833.833 0 0 1-.817.67H1.677a.814.814 0 0 1-.157-.013.83.83 0 0 1-.687-.82V3.75c0-.92.746-1.667 1.667-1.667h5.417zM10 6.25a.833.833 0 0 1-.64-.3l-1.834-2.2H2.5v6.564l.441-1.766a.833.833 0 0 1 .809-.631h12.083V6.25H10zm-7.266 10L4.4 9.584h12.916l-1.334 6.666H2.733z' fill='%23000' fill-opacity='.45'/%3E%3C/svg%3E"); +} \ No newline at end of file diff --git a/public/style/views/test.css b/public/style/views/test.css new file mode 100644 index 0000000..d4e8887 --- /dev/null +++ b/public/style/views/test.css @@ -0,0 +1,26 @@ +html,body{ + height: 100%; +} + +body{ + display: flex; + flex-direction: column; +} + +.section{ + height: 0; + flex-grow: 1; +} + +.container{ + height: 100%; +} + +#root{ + height: 100%; +} + +.bytemd { + height: 100%; + z-index: 99; +} \ No newline at end of file diff --git a/route.txt b/route.txt index 2c8d9ad..207fde4 100644 --- a/route.txt +++ b/route.txt @@ -1,19 +1,19 @@ -/home/topuser/Code/@project/hapi-demo/source/route/htmx对应路径: - 不需权限(提供无需验证): GET /htmx/path/{path*} -/home/topuser/Code/@project/hapi-demo/source/route/views对应路径: - 不需权限(提供无需验证): GET /404 - 不需权限(提供无需验证): GET / - 不需权限(提供无需验证): GET /about +D:\1XYX\pro\hapi-demo\source\route\htmx对应路径: + 不需权限(提供无需验证try): GET /htmx/path/{path*} +D:\1XYX\pro\hapi-demo\source\route\views对应路径: + 不需权限(提供无需验证try): GET /404 + 不需权限(提供即需验证optional): GET / + 不需权限(提供无需验证try): GET /about 需要权限 : POST /color/del 需要权限 : POST /color - 不需权限(提供无需验证): GET /color + 不需权限(提供无需验证try): GET /color 需要权限 : GET /docs/{path*} - 不需权限(提供无需验证): GET /{path*} - 不需权限(提供无需验证): GET /login - 不需权限(提供无需验证): POST /login - 不需权限(提供无需验证): GET /nav - 不需权限(提供无需验证): GET /register - 不需权限(提供无需验证): POST /register + 不需权限(提供无需验证try): GET /{path*} + 不需权限(提供无需验证try): GET /login + 不需权限(提供无需验证try): POST /login + 不需权限(提供无需验证try): GET /nav + 不需权限(提供无需验证try): GET /register + 不需权限(提供无需验证try): POST /register 需要权限 : POST /user 需要权限 : GET /user 需要权限 : GET /user/logout diff --git a/source/models/color.ts b/source/models/color.ts index b7a23f7..c627732 100644 --- a/source/models/color.ts +++ b/source/models/color.ts @@ -47,6 +47,9 @@ export default function ColorModel(sequelize: Sequelize) { delete values.deletedAt return values } - Color.associate = function (models) { } + Color.associate = function (models) { + models["color"].hasMany(models["color_cate"]) + models["color_cate"].belongsTo(models["color"]) + } return Color } diff --git a/source/models/color_cate.ts b/source/models/color_cate.ts new file mode 100644 index 0000000..8f741c5 --- /dev/null +++ b/source/models/color_cate.ts @@ -0,0 +1,56 @@ +import { Sequelize, DataTypes, Optional, Model } from "sequelize" + +interface ColorCateAttributes { + id: number + name: string + alias: string + describe: string + + createdAt?: Date + updatedAt?: Date + deletedAt?: Date +} + +export interface ColorCateInput extends Optional {} +export interface ColorCateOutput extends Required {} +export type TColorCateModel = ReturnType + +export default function ColorCateModel(sequelize: Sequelize) { + interface ColorCateInstance extends Model, ColorCateAttributes {} + const ColorCate = sequelize.define( + "color_cate", + { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + name: { + type: DataTypes.STRING, + allowNull: false, + }, + alias: { + type: DataTypes.STRING, + }, + describe: { + type: DataTypes.STRING, + }, + }, + { + underscored: true, + deletedAt: true, + paranoid: true, + timestamps: true, + }, + ) + // 覆盖Color的toJSON方法 + ColorCate.prototype.toJSON = function () { + const values = Object.assign({}, this.get()) as ColorCateAttributes + delete values.deletedAt + return values + } + ColorCate.associate = function (models) { + + } + return ColorCate +} diff --git a/source/plugins/index.ts b/source/plugins/index.ts index 8e3bbd1..f9cfa60 100644 --- a/source/plugins/index.ts +++ b/source/plugins/index.ts @@ -117,7 +117,6 @@ export default [ } }, {}) } - console.log(temp) request.yar.set("_flash", {}) // @ts-ignore request.response.source.context = Hoek.applyToDefaults( diff --git a/source/plugins/router-plugin/index.ts b/source/plugins/router-plugin/index.ts index 82540b3..ce57176 100755 --- a/source/plugins/router-plugin/index.ts +++ b/source/plugins/router-plugin/index.ts @@ -161,9 +161,9 @@ class routePlugin { ) { str = " 需要权限 : " + " " + full(method) + " " + str } else if (typeof options.auth === "object" && options.auth.mode === "optional") { - str = " 不需权限(提供即需验证): " + " " + full(method) + " " + str + str = " 不需权限(提供即需验证optional): " + " " + full(method) + " " + str } else if (typeof options.auth === "object" && options.auth.mode === "try") { - str = " 不需权限(提供无需验证): " + " " + full(method) + " " + str + str = " 不需权限(提供无需验证try): " + " " + full(method) + " " + str } else { str = " 不需权限 : " + " " + full(method) + " " + str } diff --git a/source/route/views/index.ts b/source/route/views/index.ts index c51b211..9308bd3 100644 --- a/source/route/views/index.ts +++ b/source/route/views/index.ts @@ -6,13 +6,17 @@ import { baseDir, gFail, sourceDir } from "@/util" import MarkdownIt from "markdown-it" export default class Index { - @auth("try") + @auth("optional") async index(request: Req, h: Res): ReturnValue { + + const md = new MarkdownIt() + var result = md.render(fs.readFileSync(path.resolve(baseDir, "./docs/index.md"), "utf-8")) + const isRenderHtmx = Reflect.has(request.query, "htmx") if (isRenderHtmx) { - return h.view("htmx/path/index.pug", { isLogin: request.auth.isAuthenticated }) + return h.view("htmx/path/index.pug", { isLogin: request.auth.isAuthenticated, md: result }) } - return h.view("views/index.pug", { isLogin: request.auth.isAuthenticated }) + return h.view("views/index.pug", { isLogin: request.auth.isAuthenticated, md: result }) } @route("/about") @@ -86,7 +90,19 @@ export default class Index { @route("/color") async color_get(request: Req, h: Res) { const ColorModel = request.getModel("color") - const colorList = await ColorModel.findAll() + const colorList = await ColorModel.findAll({}) + // const colorList = await ColorModel.findAll({ + // include: [ + // { model: request.getModel("color_cate"), attributes: ['name'] } + // ] + // }) + // console.log(colorList); + + // const ColorCateModel = request.getModel("color_cate") + // console.log(await ColorCateModel.findAll({ + // include: [request.getModel("color")] + // })) + const isRenderHtmx = Reflect.has(request.query, "htmx") if (isRenderHtmx) { return h.view(`htmx/path/color.pug`, { list: colorList }) diff --git a/source/run.ts b/source/run.ts index dda706f..77e4516 100644 --- a/source/run.ts +++ b/source/run.ts @@ -24,9 +24,9 @@ const run = async (): Promise => { }) server.events.on('request', (request, event, tags) => { if (tags.error) { - loggerSite.error(event); + loggerSite.error(request.path, "\n", event); } else { - loggerSite.info(event); + loggerSite.info(request.path, "\n", event); } }); server.events.on('log', (event, tags) => { @@ -70,6 +70,9 @@ const run = async (): Promise => { name: "sid", //cookie的名字 password: process.env.KEY, isSecure: false, // false: 允许 Cookie 通过不安全的连接传输,这会使其受到攻击 + isHttpOnly: true, + clearInvalid: false, + strictHeader: true }, redirectTo(request: Req) { if (request.path.startsWith("/api")) { diff --git a/template/404.pug b/template/404.pug index 01de240..2318a13 100644 --- a/template/404.pug +++ b/template/404.pug @@ -1,4 +1,5 @@ extends layout/layout +include @/helper/flush.pug block head link(rel="stylesheet", href="/public/css/views/404.css") diff --git a/template/helper/flush.pug b/template/helper/flush.pug index 888b14d..0bab670 100644 --- a/template/helper/flush.pug +++ b/template/helper/flush.pug @@ -1,64 +1,63 @@ //- 服务器反馈UI include @/helper/helper.pug if flash - .message-container - - index = 0 - if flash.error - each item in flash.error - - index++ - .message.is-danger.animate__animated.animate__slideInRight(id="message"+index) - .message-header - p 错误 - button.delete.messagec(aria-label='delete' data-target="message"+index) - .message-body - | #{item} - if flash.success - each item in flash.success - - index++ - .message.is-success.animate__animated.animate__slideInRight(id="message"+index) - .message-header - p 成功 - button.delete.messagec(aria-label='delete' data-target="message"+index) - .message-body - | #{item} - if flash.info - each item in flash.info - - index++ - .message.is-info.animate__animated.animate__slideInRight(id="message"+index) - .message-header - p 信息 - button.delete.messagec(aria-label='delete' data-target="message"+index) - .message-body - | #{item} - if flash.warning - each item in flash.warning - - index++ - .message.is-warning.animate__animated.animate__slideInRight(id="message"+index) - .message-header - p 警告 - button.delete.messagec(aria-label='delete' data-target="message"+index) - .message-body - | #{item} - //- .toast-container.top-0.end-0.p-3 - //- each item in flash.error - //- .toast.show(role='alert', aria-live='assertive', aria-atomic='true') - //- .toast-header - //- img.rounded.me-2(src='/public/image/icons/error.svg', alt='错误' style="width:20px;height: 20px;") - //- strong.me-auto 提示 - //- //- small.text-muted just now - //- button.btn-close(type='button', data-bs-dismiss='toast', aria-label='Close') - //- .toast-body. - //- #{item} - //- .toast-container.position-fixed.bottom-0.end-0.p-3 - //- #liveToast.toast(role='alert', aria-live='assertive', aria-atomic='true') - //- .toast-header - //- img.rounded.me-2(src='...', alt='...') - //- strong.me-auto Bootstrap - //- small 11 mins ago - //- button.btn-close(type='button', data-bs-dismiss='toast', aria-label='Close') - //- .toast-body. - //- Hello, world! This is a toast message. - //- ul - //- each item in flash.error - //- li #{item} - +script("js/common/flush.js") + - index = 0 + if flash.error + each item in flash.error + - index++ + .message.is-danger.animate__animated.animate__slideInRight(id="message"+index) + .message-header + p 错误 + button.delete.messagec(aria-label='delete' data-target="message"+index) + .message-body + | #{item} + if flash.success + each item in flash.success + - index++ + .message.is-success.animate__animated.animate__slideInRight(id="message"+index) + .message-header + p 成功 + button.delete.messagec(aria-label='delete' data-target="message"+index) + .message-body + | #{item} + if flash.info + each item in flash.info + - index++ + .message.is-info.animate__animated.animate__slideInRight(id="message"+index) + .message-header + p 信息 + button.delete.messagec(aria-label='delete' data-target="message"+index) + .message-body + | #{item} + if flash.warning + each item in flash.warning + - index++ + .message.is-warning.animate__animated.animate__slideInRight(id="message"+index) + .message-header + p 警告 + button.delete.messagec(aria-label='delete' data-target="message"+index) + .message-body + | #{item} + //- .toast-container.top-0.end-0.p-3 + //- each item in flash.error + //- .toast.show(role='alert', aria-live='assertive', aria-atomic='true') + //- .toast-header + //- img.rounded.me-2(src='/public/image/icons/error.svg', alt='错误' style="width:20px;height: 20px;") + //- strong.me-auto 提示 + //- //- small.text-muted just now + //- button.btn-close(type='button', data-bs-dismiss='toast', aria-label='Close') + //- .toast-body. + //- #{item} + //- .toast-container.position-fixed.bottom-0.end-0.p-3 + //- #liveToast.toast(role='alert', aria-live='assertive', aria-atomic='true') + //- .toast-header + //- img.rounded.me-2(src='...', alt='...') + //- strong.me-auto Bootstrap + //- small 11 mins ago + //- button.btn-close(type='button', data-bs-dismiss='toast', aria-label='Close') + //- .toast-body. + //- Hello, world! This is a toast message. + //- ul + //- each item in flash.error + //- li #{item} + +script("js/common/flush.js") diff --git a/template/htmx/path/index.pug b/template/htmx/path/index.pug index cae0d4a..35ac44c 100644 --- a/template/htmx/path/index.pug +++ b/template/htmx/path/index.pug @@ -1,10 +1,40 @@ include @/helper/flush.pug include @/helper/helper.pug +title 首页 block var -title="首页" // 网页标题 -title 首页 -div sad -if isLogin - button(hx-target="#single-page" hx-get="/about?htmx" hx-push-url="/about" hx-trigger="click" hx-swap="innerHTML") Click Me! \ No newline at end of file +block page + div + style + :public style/views/index.css + .content!= md + //- if isLogin + //- button(hx-target="#single-page" hx-get="/about?htmx" hx-push-url="/about" hx-trigger="click" hx-swap="innerHTML") Click Me! + + .tree#tree + details(open="true" style="direction: ltr;") + summary + span.tree-item sad + a.op(href="") 新建 + details(open="true") + summary + span.tree-item sad + a.op(href="") 新建 + details + summary + span.tree-item.tree-md-file + div(style="flex: 1;width: 0;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;") asda + a.op(href="") 新建 + details + summary + span.tree-item.tree-md-file + div(style="flex: 1;width: 0;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;") asda + a.op(href="") 新建 + details + summary + span.tree-item.tree-md-file.active + div(style="flex: 1;width: 0;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;") asda + a.op(href="") 新建 + diff --git a/template/layout/layout.pug b/template/layout/layout.pug index 56dc3e7..9441af6 100644 --- a/template/layout/layout.pug +++ b/template/layout/layout.pug @@ -1,6 +1,5 @@ doctype html include @/helper/helper.pug -//- include @/helper/flush.pug block var html(lang="zh-cn" class=hideHeader?"":"has-navbar-fixed-top") @@ -18,7 +17,6 @@ html(lang="zh-cn" class=hideHeader?"":"has-navbar-fixed-top") script!= "window.STATIC_USER = "+JSON.stringify(user) //- window.STATIC_DATA = #{JSON.stringify(user)} body - //- include @/helper/flush.pug if !hideHeader include @/ui/header.pug block content diff --git a/template/views/login.pug b/template/views/login.pug index dc35ff9..a7f8d10 100644 --- a/template/views/login.pug +++ b/template/views/login.pug @@ -8,6 +8,7 @@ block head +css("style/views/login.css") block content + include @/helper/flush.pug .login h1.title.is-1 登录 form(action='/login' method='post') diff --git a/template/views/register.pug b/template/views/register.pug index ef3a334..c49e38f 100644 --- a/template/views/register.pug +++ b/template/views/register.pug @@ -1,4 +1,5 @@ extends @/layout/layout +include @/helper/flush.pug block var -title="注册" // 网页标题 diff --git a/template/views/resume.pug b/template/views/resume.pug index b4f567e..b611c11 100644 --- a/template/views/resume.pug +++ b/template/views/resume.pug @@ -1,3 +1,6 @@ +include @/helper/helper.pug +include @/helper/flush.pug + doctype html html(lang='zh') head diff --git a/template/views/test.pug b/template/views/test.pug new file mode 100644 index 0000000..ab646e9 --- /dev/null +++ b/template/views/test.pug @@ -0,0 +1,31 @@ +extends @/layout/single-page + +block head + link(rel="stylesheet", href="https://unpkg.com/bytemd/dist/index.css") + link(rel="stylesheet", href="https://unpkg.com/github-markdown-css") + script. + let process = {} + process.env = {} + process.env.NODE_ENV = 'production' + script(src="https://unpkg.com/bytemd") + script(src="https://unpkg.com/@bytemd/plugin-gfm") + +block page + include @/helper/flush.pug + style + :public style/views/test.css + #root + script. + const plugins = [bytemdPluginGfm()] + + const editor = new bytemd.Editor({ + target: document.getElementById('root'), + props: { + value: '# heading\n\nparagraph\n\n> blockquote', + plugins, + }, + }) + + editor.$on('change', (e) => { + editor.$set({ value: e.detail.value }) + }) diff --git a/types/global.d.ts b/types/global.d.ts index fe2e402..4b008a5 100644 --- a/types/global.d.ts +++ b/types/global.d.ts @@ -3,6 +3,7 @@ import { Server } from "@hapi/hapi" import { Request, ResponseToolkit, Lifecycle } from "@hapi/hapi" import { TUserModel } from "@/models/user" import { TColorModel } from "@/models/color" +import { TColorCateModel } from "@/models/color_cate" import yar from "@hapi/yar" import { TAttachmentModel } from "@/models/Attachment" @@ -16,6 +17,7 @@ declare global { interface Models { user: TUserModel color: TColorModel + color_cate: TColorCateModel attachment: TAttachmentModel }