import { Req, Res, ReturnValue } from "#/global" import { auth, config, method, route, route_path, swagger, validate } from "@noderun/hapi-router" import path, { resolve } from "path" import { gFail, uploadDir } from "@/util" import { dateTimeFormat } from "@/util/util" import fs from "fs-extra" import * as bcrypt from "bcrypt" const multiparty = require("multiparty") function saveFile(file) { return new Promise(async (resolve, reject) => { const filename = file.originalFilename const uploadedPath = file.path const filetype = await (await import("file-type")).fileTypeFromFile(uploadedPath) const _file = path.parse(filename) if (filetype && (filetype.ext == "jpg" || filetype.ext == "png")) { let _name = _file.name + "_" + dateTimeFormat(new Date(), "yyyy_MM_dd") + "_" + new Date().getTime() + _file.ext const dstPath = path.resolve(uploadDir, _name) fs.rename(uploadedPath, dstPath, function (err) { if (err) { console.log("rename error: " + err) reject() } else { resolve("/public/upload/" + _name) } }) } else { fs.unlinkSync(uploadedPath) reject(new Error(filename + "文件不是图片")) } }) } function Save(payload, req: Req) { const AttachmentModel = req.getModel("attachment") const form = new multiparty.Form({ uploadDir: uploadDir, //路径需要对应自己的项目更改 /*设置文件保存路径 */ encoding: "utf-8", /*编码设置 */ maxFilesSize: 20000 * 1024 * 1024, /*设置文件最大值 20MB */ keepExtensions: true, /*保留后缀*/ }) return new Promise(async (resolve, reject) => { form.on("part", function (part) { console.log(1111) console.log(part.filename) }) form.on("progress", function (bytesReceived, bytesExpected) { if (bytesExpected === null) { return } // var percentComplete = (bytesReceived / bytesExpected) * 100 // console.log("the form is " + Math.floor(percentComplete) + "%" + " complete") }) form.parse(payload, async function (err, fields, files) { // console.log(err, fields, files); if (err) { reject(err.message) return } const errList = [] const fileList = [] if (files && files.file && files.file.length) { for (let i = 0; i < files.file.length; i++) { const file = files.file[i] if (file.originalFilename === "" && file.size === 0) { const uploadedPath = file.path fs.unlinkSync(uploadedPath) continue } try { const dstPath = await saveFile(file) fileList.push(dstPath) } catch (error) { errList.push(error.message) } } } if (errList.length) { reject(gFail(null, errList.join("\n"))) return } resolve({ fields, filelist: [...new Set(fileList)], }) }) }) } /** * 登录界面 */ export default class { @config({ payload: { maxBytes: 20000 * 1024 * 1024, output: "stream", parse: false, multipart: true, timeout: false, allow: ["multipart/form-data", "application/x-www-form-urlencoded"], }, }) @method("POST") @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", "用户名已被他人占用") } if (!!user && user.id === id) { await UserModel.update(result, { where: { id } }) // @ts-ignore request.auth.credentials = await UserModel.findOne({ where: { id } }) } } return h.redirect("/user") } @method("GET") @auth() @route_path("/user") async index_get(request: Req, h: Res): ReturnValue { const isRenderHtmx = Reflect.has(request.query, "htmx") if (isRenderHtmx) { return h.view("htmx/path/user.pug") } return h.view("views/user.pug") } @method("GET") @auth() async logout(request: Req, h: Res): ReturnValue { request.yar.flash("success", "用户已退出") request.cookieAuth.clear() return h.redirect("/") } @method("POST") @auth() async del(request: Req, h: Res): ReturnValue { const { id } = request.auth.credentials try { const UserModel = request.getModel("user") await UserModel.destroy({ where: { id: id } }) request.yar.flash("success", "用户已删除") request.cookieAuth.clear() } catch (error) { loggerSite.error(`用户删除错误`, error.message) request.yar.flash("error", "用户删除错误") } return h.redirect("/") } }