From ba18d5dfbe33e062e48b0b48a9866faf59015b70 Mon Sep 17 00:00:00 2001 From: npmrun Date: Wed, 17 May 2023 17:13:09 +0800 Subject: [PATCH] add --- data/data.db | Bin 28672 -> 28672 bytes public/style/views/color.css | 119 ++++++++++++++++++---------------- route.txt | 15 +++-- source/plugins/index.ts | 1 - source/plugins/router-plugin/index.ts | 23 ++++--- source/route/views/index.ts | 26 ++++++-- source/route/views/user.ts | 71 ++++++++++---------- source/run.ts | 13 +++- template/helper/helper.pug | 2 +- template/htmx/path/color.pug | 53 +++++++++++++++ template/ui/header.pug | 2 + template/views/color.pug | 53 +-------------- 12 files changed, 216 insertions(+), 162 deletions(-) create mode 100644 template/htmx/path/color.pug diff --git a/data/data.db b/data/data.db index ec1a18cbac563d9a20dfce2f7c33598a7450ae90..5bf9e51e1bf53d53e0fccac97b42a6fb17c6cd56 100644 GIT binary patch delta 127 zcmZp8z}WDBae_2s_Cy(H#_Wv=%j~%pG4NaSb@47@VA?Dw(7`MAl|j6bRaC!GR=F{i znHS1op1jsKQ=5Z0~2r YXQp6iVr6V*Wo)8nWMsCv*{@a+0PwpXi2wiq diff --git a/public/style/views/color.css b/public/style/views/color.css index bd816b5..1a2a66f 100644 --- a/public/style/views/color.css +++ b/public/style/views/color.css @@ -2,17 +2,22 @@ min-height: 100%; padding-top: 20px; position: relative; - } - - .color_list { +} + +h1{ + font-size: 25px; + margin-bottom: 12px; +} + +.color_list { display: -webkit-box; display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; - flex-wrap: wrap; - } - - .color_list .color_item { + flex-wrap: wrap; +} + +.color_list .color_item { position: relative; display: inline-block; border-radius: 5px; @@ -20,71 +25,75 @@ padding: 5px 10px; cursor: pointer; width: 100px; - height: 125px; - } - - .color_list .color_item:hover .color_add { +} + +.color_list .color_item:hover .color_add { -webkit-transform: translate(-50%, -50%) scale(1.3); - transform: translate(-50%, -50%) scale(1.3); - } - - .color_list .color_item .color_add { + transform: translate(-50%, -50%) scale(1.3); +} + +.color_list .color_item .color_add { width: 50px; height: 50px; position: absolute; top: 50%; left: 50%; - -webkit-transition: -webkit-transform .3s linear; - transition: -webkit-transform .3s linear; - transition: transform .3s linear; - transition: transform .3s linear, -webkit-transform .3s linear; + -webkit-transition: -webkit-transform 0.3s linear; + transition: -webkit-transform 0.3s linear; + transition: transform 0.3s linear; + transition: transform 0.3s linear, -webkit-transform 0.3s linear; -webkit-transform: translate(-50%, -50%); - transform: translate(-50%, -50%); - } - - .color_list .color_item:hover { + transform: translate(-50%, -50%); +} + +.color_list .color_item:hover { background-color: rgba(0, 0, 0, 0.041); - } - - .color_list .color_item:hover .color_toggle_list { - max-height: 99px; - } - - .color_list .color_item .color_toggle_list { +} + +.color_list .color_item:hover .color_toggle_list { + top: 0; +} + +.color_list .color_item .color_toggle_list { overflow: hidden; position: absolute; - bottom: 0; + top: 100%; left: 0; right: 0; width: 100%; - max-height: 0; - -webkit-transition: max-height .5s linear; - transition: max-height .5s linear; - background-color: rgba(180, 180, 180, 0.274); - } - - .color_list .color_item .color_toggle_list .color_toggle_item { - display: inline-block; - height: 25px; + height: 100%; + -webkit-transition: top 0.3s ease; + transition: top 0.3s ease; + color: white; + background-color: rgba(0, 0, 0, 0.2); + /* filter: brightness(.7); */ + display: flex; + flex-direction: column; +} + +.color_list .color_item .color_toggle_list .color_toggle_item { + flex: 1; + height: 0; + box-sizing: border-box; padding: 2px 6px; - } - - .color_list .color_item .color_toggle_list .color_toggle_item:hover { +} + +.color_list .color_item .color_toggle_list .color_toggle_item:hover { background-color: rgba(0, 0, 0, 0.185); - } - - .color_list .color_item .color_item_bg { +} + +.color_list .color_item .color_item_bg { height: 50px; - background-color: red; position: relative; - } - - .color_list .color_item .color_item_content .color_item_title { + overflow: hidden; +} + +.color_list .color_item .color_item_content .color_item_title { font-size: 1.2em; font-weight: bold; - } - - .color_list .color_item .color_item_content .color_item_desc { +} + +.color_list .color_item .color_item_content .color_item_desc { color: #a7a6a6; display: -webkit-box; -webkit-box-orient: vertical; @@ -92,5 +101,5 @@ overflow: hidden; text-overflow: ellipsis; word-break: break-all; - } - /*# sourceMappingURL=color.css.map */ \ No newline at end of file +} +/*# sourceMappingURL=color.css.map */ diff --git a/route.txt b/route.txt index b9ffa42..017f45b 100644 --- a/route.txt +++ b/route.txt @@ -1,16 +1,17 @@ -/home/topuser/Code/@project/hapi-demo/source/route/htmx对应路径: - 不需权限 : GET /htmx/path/{path*} -/home/topuser/Code/@project/hapi-demo/source/route/views对应路径: +D:\1XYX\pro\hapi-demo\source\route\htmx对应路径: + 不需权限(提供无需验证): GET /htmx/path/{path*} +D:\1XYX\pro\hapi-demo\source\route\views对应路径: 不需权限(提供无需验证): GET /404 不需权限(提供无需验证): GET / 不需权限(提供无需验证): GET /about + 不需权限(提供无需验证): GET /color 需要权限 : GET /docs/{path*} - 不需权限 : GET /{path*} + 不需权限(提供无需验证): GET /{path*} 不需权限(提供无需验证): GET /login - 不需权限 : POST /login - 不需权限 : GET /nav + 不需权限(提供无需验证): POST /login + 不需权限(提供无需验证): GET /nav 不需权限(提供无需验证): GET /register - 不需权限 : POST /register + 不需权限(提供无需验证): POST /register 需要权限 : POST /user 需要权限 : GET /user 需要权限 : GET /user/logout diff --git a/source/plugins/index.ts b/source/plugins/index.ts index 1cfca57..8e025af 100644 --- a/source/plugins/index.ts +++ b/source/plugins/index.ts @@ -95,7 +95,6 @@ export default [ const isLogin = request.auth.isAuthenticated // const { id } = request.auth.credentials; // loggerSite.debug(`${isLogin?'当前登录ID:'+id:'未登录用户'}, 请求路径:${request.path}, 请求方法:${request.method}`) - // @ts-ignore // console.log(isLogin, request.path, request.response.variety); // let user; diff --git a/source/plugins/router-plugin/index.ts b/source/plugins/router-plugin/index.ts index 5bf986a..82540b3 100755 --- a/source/plugins/router-plugin/index.ts +++ b/source/plugins/router-plugin/index.ts @@ -71,16 +71,23 @@ class routePlugin { if (auth && auth.length && auth.filter(v => route.startsWith(v)).length) { options.auth = type } else { - options.auth = false + // 默认是try + options.auth = { + strategy: type, + mode: "try", + } } } else if (ff.$auth) { - options.auth = - typeof ff.$auth === "boolean" - ? type - : { - strategy: type, - mode: ff.$auth, - } + if(typeof ff.$auth === "boolean" && ff.$auth){ + options.auth = type + }else if(typeof ff.$auth === "boolean"){ + options.auth = false + }else { + options.auth = { + strategy: type, + mode: ff.$auth, + } + } } else { options.auth = false } diff --git a/source/route/views/index.ts b/source/route/views/index.ts index d8eb13b..c1ec9e7 100644 --- a/source/route/views/index.ts +++ b/source/route/views/index.ts @@ -28,11 +28,11 @@ export default class Index { return h.redirect(`/login?next=${encodeURIComponent(request.path)}`).takeover() } const md = new MarkdownIt() - console.log(path.resolve(baseDir, "./docs/a.md")); - + console.log(path.resolve(baseDir, "./docs/a.md")) + var result = md.render(fs.readFileSync(path.resolve(baseDir, "./docs/a.md"), "utf-8")) const data = { - md: result + md: result, } if (isRenderHtmx) { return h.view("htmx/path/about.pug", data) @@ -40,6 +40,18 @@ export default class Index { return h.view("views/about.pug", data) } + @route("/color") + async color(request: Req, h: Res) { + const filePath = path.resolve(baseDir, "template/views", "color.pug") + if (fs.existsSync(filePath)) { + const isRenderHtmx = Reflect.has(request.query, "htmx") + if (isRenderHtmx) { + return h.view(`htmx/path/color.pug`) + } + return h.view(`views/color.pug`) + } + } + @route("/docs/{path*}") @auth() async docs(req: Req, h: Res): ReturnValue { @@ -72,8 +84,12 @@ export default class Index { @route("/{path*}") async any(req: Req, h: Res): ReturnValue { if (req.path) { - const filePath = path.resolve(baseDir, "template/views", "."+req.path+".pug") - if(fs.existsSync(filePath)){ + const filePath = path.resolve(baseDir, "template/views", "." + req.path + ".pug") + if (fs.existsSync(filePath)) { + const isRenderHtmx = Reflect.has(req.query, "htmx") + if (isRenderHtmx) { + return h.view(`htmx/path${req.path}.pug`) + } return h.view(`views${req.path}.pug`) } } diff --git a/source/route/views/user.ts b/source/route/views/user.ts index bc75833..8dc8903 100644 --- a/source/route/views/user.ts +++ b/source/route/views/user.ts @@ -111,41 +111,46 @@ export default class { @auth() @route_path("/user") async index_post(request: Req, h: Res): ReturnValue { - const { id, username, nickname, email, tel } = request.auth.credentials - const { filelist, fields } = await Save(request.payload, request) - const result = {} - if (fields["username"] && fields["username"][0] && username !== fields["username"][0]) { - result["username"] = fields["username"][0] - } - if (fields["tel"] && fields["tel"][0] && tel !== fields["tel"][0]) { - result["tel"] = fields["tel"][0] - } - if (fields["nickname"] && fields["nickname"][0] && nickname !== fields["nickname"][0]) { - result["nickname"] = fields["nickname"][0] - } - if (fields["email"] && fields["email"][0] && email !== fields["email"][0]) { - result["email"] = fields["email"][0] - } - if (fields["password"] && fields["password"][0]) { - const pwd = fields["password"][0] - let salt = bcrypt.genSaltSync(10) - let pwdLock = bcrypt.hashSync(pwd, salt) - result["password"] = pwdLock - } - if (filelist && filelist[0]) { - result["avatar"] = filelist[0] - } - if (JSON.stringify(result) !== "{}") { - const UserModel = request.getModel("user") - const user = await UserModel.findOne({ where: { username: fields["username"] } }) - if (!!user && user.id !== id) { - request.yar.flash("error", "用户名已被他人占用") + try { + const { id, username, nickname, email, tel } = request.auth.credentials + const { filelist, fields } = await Save(request.payload, request) + const result = {} + if (fields["username"] && fields["username"][0] && username !== fields["username"][0]) { + result["username"] = fields["username"][0] } - if (!!user && user.id === id) { - await UserModel.update(result, { where: { id } }) - // @ts-ignore - request.auth.credentials = await UserModel.findOne({ where: { id } }) + if (fields["tel"] && fields["tel"][0] && tel !== fields["tel"][0]) { + result["tel"] = fields["tel"][0] } + if (fields["nickname"] && fields["nickname"][0] && nickname !== fields["nickname"][0]) { + result["nickname"] = fields["nickname"][0] + } + if (fields["email"] && fields["email"][0] && email !== fields["email"][0]) { + result["email"] = fields["email"][0] + } + if (fields["password"] && fields["password"][0]) { + const pwd = fields["password"][0] + let salt = bcrypt.genSaltSync(10) + let pwdLock = bcrypt.hashSync(pwd, salt) + result["password"] = pwdLock + } + if (filelist && filelist[0]) { + result["avatar"] = filelist[0] + } + if (JSON.stringify(result) !== "{}") { + const UserModel = request.getModel("user") + const user = await UserModel.findOne({ where: { username: fields["username"] } }) + if (!!user && user.id !== id) { + request.yar.flash("error", "用户名已被他人占用") + } + if (!!user && user.id === id) { + await UserModel.update(result, { where: { id } }) + // @ts-ignore + request.auth.credentials = await UserModel.findOne({ where: { id } }) + } + } + } catch (error) { + loggerSite.error(error.message) + request.yar.flash("error", error.message) } return h.redirect("/user") } diff --git a/source/run.ts b/source/run.ts index 34feb48..dda706f 100644 --- a/source/run.ts +++ b/source/run.ts @@ -1,12 +1,13 @@ "use strict" import plugins from "@/plugins" import path from "path" -import { baseDir, isDev, sourceDir, templateDir } from "@/util" +import { baseDir, isDev, publicDir, sourceDir, templateDir } from "@/util" import { validateJwt, validateSession } from "./auth" import Hapi, { Server } from "@hapi/hapi" import { Sequelize } from "sequelize" import { Req } from "#/global" import { sequelize } from "./plugins/sequelize" +import fs from "fs-extra" // const Hapi = require("@hapi/hapi"); // const HapiSwagger = require("hapi-swagger"); // const HapiSwagger = require("hapi-swaggered-ui"); // swagger v2版本 @@ -89,10 +90,18 @@ const run = async (): Promise => { */ // https://hapi.dev/module/vision/api/?v=6.1.0 await server.register(require("@hapi/vision")) + const Pug = require("pug") + Pug.filters.public = function (text, options) { + const p = path.resolve(publicDir, text) + if(fs.pathExistsSync(p)) { + return fs.readFileSync(p, "utf-8") + } + return "" + }; server.views({ engines: { ejs: require("ejs"), - pug: require("pug"), + pug: Pug, }, isCached: process.env.NODE_ENV === "development" ? false : true, compileMode: "sync", // ejs diff --git a/template/helper/helper.pug b/template/helper/helper.pug index e25c111..61718b4 100644 --- a/template/helper/helper.pug +++ b/template/helper/helper.pug @@ -4,4 +4,4 @@ mixin script(src) script(src="/public/"+src) mixin security - include ./form_security.pug + include ./form_security.pug \ No newline at end of file diff --git a/template/htmx/path/color.pug b/template/htmx/path/color.pug new file mode 100644 index 0000000..f350f84 --- /dev/null +++ b/template/htmx/path/color.pug @@ -0,0 +1,53 @@ +include @/helper/flush.pug +include @/helper/helper.pug + +block var + -title="颜色" // 网页标题 +title 颜色 + +div(class="container page") + style + :public style/views/color.css + h1 颜色表 + div(class="color_list") + - + var list=[ + { color:"#00ffff",title: "青色",describe:""}, + { color:"#222222",title: "辅助色",describe:""}, + { color:"#8f8f8f",title: "辅助色",describe:""}, + { color:"#00d1b2",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + { color:"#999999",title: "辅助色",describe:""}, + ] + each item in list + div(class="color_item") + div(class="color_item_bg" style=`background: ${item.color}`) + div(class="color_toggle_list") + div(class="color_toggle_item") hex + div(class="color_toggle_item") rgba + div(class="color_item_name") #{item.color} + div(class="color_item_content") + div(class="color_item_title") #{item.title} + div(class="color_item_desc") #{item.describe || "暂无描述"} + //- div(class="color_item") + //- img(src="/public/image/add.png", alt="添加" title="添加" class="color_add") + if isLogin + div + form(action="POST" method="post") + div(class=".wrapper_input"): input(type="text" tabindex="1" value="sadsa" name="a") + div(class=".wrapper_input"): input(type="text" tabindex="3" value="sadsa" name="b") + button(type="submit" tabindex="2") 提交 \ No newline at end of file diff --git a/template/ui/header.pug b/template/ui/header.pug index da9f114..f831a3b 100644 --- a/template/ui/header.pug +++ b/template/ui/header.pug @@ -12,6 +12,8 @@ nav.is-fixed-top.navbar(role='navigation', aria-label='main navigation', style=" .navbar-start a.navbar-item(hx-get="/?htmx" hx-push-url="/" hx-trigger="click" hx-target="#single-page" hx-swap="innerHTML") | 首页 + a.navbar-item(hx-get="/color?htmx" hx-push-url="/color" hx-trigger="click" hx-target="#single-page" hx-swap="innerHTML") + | 颜色 .navbar-item.has-dropdown.is-hoverable a.navbar-link | 更多 diff --git a/template/views/color.pug b/template/views/color.pug index 60fadd1..85df5d2 100644 --- a/template/views/color.pug +++ b/template/views/color.pug @@ -1,51 +1,4 @@ -extends /layout/layout +extends @/layout/single-page -block var - -title="颜色表" // 网页标题 - -block head - link(rel="stylesheet", href="/public/style/views/color.css") - -block content - div(class="container page") - div(class="color_list") - - - var list=[ - { color:"#999999",title: "辅助色",describe:"灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色"}, - { color:"#999999",title: "辅助色",describe:"灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色"}, - { color:"#999999",title: "辅助色",describe:"灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色灰色"}, - { color:"#000000",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - { color:"#999999",title: "辅助色",describe:""}, - ] - each item in list - div(class="color_item") - div(class="color_item_bg" style=`background: ${item.color}`) - div(class="color_toggle_list") - div(class="color_toggle_item") hex - div(class="color_toggle_item") rgba - div(class="color_item_name") #{item.color} - div(class="color_item_content") - div(class="color_item_title") #{item.title} - div(class="color_item_desc") #{item.describe || "暂无描述"} - div(class="color_item") - //- img(src="/public/image/add.png", alt="添加" title="添加" class="color_add") - div - form(action="POST" method="post") - div(class=".wrapper_input"): input(type="text" tabindex="1" value="sadsa" name="a") - div(class=".wrapper_input"): input(type="text" tabindex="3" value="sadsa" name="b") - button(type="submit" tabindex="2") 提交 +block page + include @hxpath/color.pug