准备写接口,了解了nuxt请求的生命周期,不要尝试在中间件中等请求体返回后处理数据

This commit is contained in:
expressgy 2025-04-24 18:15:06 +08:00
parent bed2d0c643
commit cc5c1c7212
25 changed files with 953 additions and 38 deletions

4
.gitignore vendored
View File

@ -22,3 +22,7 @@ logs
.env
.env.*
!.env.example
# drizzle schema
drizzle/meta
drizzle/relations.ts

View File

@ -0,0 +1,28 @@
# 博客设计思路
## 目录结构
- 可建立多级子目录
## 目录属性
- 目录名称: name
- 上级目录: pid
- 目录图标: icon
- 目录标签: label
- 排序: sort
- 阅读量: read
- 点赞量: like
- 是否公开: public
- 是否删除: deleted
- 创建时间: createtime
- 修改时间: updatetime
- 创建人: createuser
## 目录接口
- 获取用户目录 blog/blogMenu.get
- 删除目录-》存在子集要提示 blog/blogMenu.[blogId].delete
- 创建目录 blog/blogMenu.post
- 修改目录名称或图标 blog/blogMenu.[blogId].update
- 修改目录顺序 blog/blogMenu.[blogId].patch

22
drizzle.config.js Normal file
View File

@ -0,0 +1,22 @@
import dotenv from 'dotenv';
dotenv.config({ path: '.env' });
export default {
schema: './drizzle/schema.ts',
out: './drizzle',
dialect: 'mysql',
dbCredentials: {
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT),
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
},
verbose: true,
strict: true,
introspect: {
// 启用驼峰命名
casing: 'camel',
},
};

View File

@ -0,0 +1,23 @@
CREATE TABLE `blog_menu` (
`id` bigint NOT NULL,
`pid` bigint NOT NULL,
`name` varchar(255) NOT NULL,
`desc` varchar(255),
`icon` varchar(255) NOT NULL DEFAULT '',
`label` varchar(255),
`background` varchar(255),
`sort` int NOT NULL DEFAULT 0,
`read` int NOT NULL DEFAULT 0,
`like` int NOT NULL DEFAULT 0,
`public` tinyint NOT NULL DEFAULT 1,
`deleted` tinyint NOT NULL DEFAULT 0,
`created_at` datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
`updated_at` datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
`deleted_at` varchar(255),
`created_by` bigint NOT NULL,
CONSTRAINT `blog_menu_id` PRIMARY KEY(`id`),
CONSTRAINT `unique_checkname` UNIQUE(`pid`,`name`,`deleted_at`)
);
--> statement-breakpoint
CREATE INDEX `create_at` ON `blog_menu` (`created_at`);--> statement-breakpoint
CREATE INDEX `name` ON `blog_menu` (`name`);

27
drizzle/customType.js Normal file
View File

@ -0,0 +1,27 @@
// | ------------------------------------------------------------
// | @版本: version 0.1
// | @创建人: 【Nie-x7129】
// | @E-mail: x71291@outlook.com
// | @所在项目: pac-auth
// | @文件描述: customType.ts -
// | @创建时间: 2024-06-04 16:27
// | @更新时间: 2024-06-04 16:27
// | @修改记录:
// | -*-*-*- (时间--修改人--修改说明) -*-*-*-
// | =
// | ------------------------------------------------------------
// 定义自定义类型
import { customType } from 'drizzle-orm/mysql-core';
// 写入读取是将bigint转化为string
export const bigintString = customType({
dataType() {
return 'bigint';
},
fromDriver(value) { // 数据库 -> JS
return value?.toString(); // 处理 null 值
},
toDriver(value) { // JS -> 数据库
return BigInt(value); // 确保写入时为数字类型
}
});

28
drizzle/schema.ts Normal file
View File

@ -0,0 +1,28 @@
import { mysqlTable, index, primaryKey, unique, varchar, int, tinyint, datetime } from "drizzle-orm/mysql-core"
import { sql } from "drizzle-orm"
import { bigintString } from './customType.js';
const bigint = bigintString;
export const blogMenu = mysqlTable("blog_menu", {
id: bigint({ mode: "number" }).notNull(),
pid: bigint({ mode: "number" }).notNull(),
name: varchar({ length: 255 }).notNull(),
desc: varchar({ length: 255 }),
icon: varchar({ length: 255 }).default("").notNull(),
label: varchar({ length: 255 }),
background: varchar({ length: 255 }),
sort: int().default(0).notNull(),
read: int().default(0).notNull(),
like: int().default(0).notNull(),
public: tinyint().default(1).notNull(),
deleted: tinyint().default(0).notNull(),
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`),
deletedAt: varchar("deleted_at", { length: 255 }),
createdBy: bigint("created_by", { mode: "number" }).notNull(),
},
(table) => [
index("create_at").on(table.createdAt),
index("name").on(table.name),
primaryKey({ columns: [table.id], name: "blog_menu_id"}),
unique("unique_checkname").on(table.pid, table.name, table.deletedAt),
]);

51
drizzle/starwrit.sql Normal file
View File

@ -0,0 +1,51 @@
/*
Navicat Premium Data Transfer
Source Server : 172root
Source Server Type : MySQL
Source Server Version : 80403 (8.4.3)
Source Host : 172.16.1.10:3306
Source Schema : starwrit
Target Server Type : MySQL
Target Server Version : 80403 (8.4.3)
File Encoding : 65001
Date: 24/04/2025 18:13:26
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for blog_menu
-- ----------------------------
DROP TABLE IF EXISTS `blog_menu`;
CREATE TABLE `blog_menu` (
`id` bigint NOT NULL COMMENT 'menuId',
`pid` bigint NOT NULL DEFAULT 0 COMMENT '上级ID',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '目录名',
`desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述',
`icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '图标',
`label` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '标签',
`background` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '背景',
`sort` int NOT NULL DEFAULT 0 COMMENT '排序',
`read` int NOT NULL DEFAULT 0 COMMENT '阅读量',
`like` int NOT NULL DEFAULT 0 COMMENT '喜欢',
`public` tinyint NOT NULL DEFAULT 1 COMMENT '公开',
`deleted` tinyint NOT NULL DEFAULT 0 COMMENT '删除',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建者',
`updated_at` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
`deleted_at` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '删除时间',
`created_by` bigint NOT NULL COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `unique_checkname`(`pid` ASC, `name` ASC, `deleted_at` ASC) USING BTREE COMMENT '重名',
INDEX `name`(`name` ASC) USING BTREE COMMENT '名称搜索优化',
INDEX `create_at`(`created_at` ASC) USING BTREE COMMENT '创建人搜索优化'
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of blog_menu
-- ----------------------------
SET FOREIGN_KEY_CHECKS = 1;

View File

@ -11,6 +11,7 @@ export default defineNuxtConfig({
modules: ['@nuxt/eslint', '@nuxtjs/tailwindcss'],
devServer: {
host: '0.0.0.0',
port: 3000,
},
css: [
'~/assets/css/style.css',
@ -55,7 +56,6 @@ export default defineNuxtConfig({
},
},
runtimeConfig: {
server: {
redis: {
host: process.env.REDIS_HOST || '127.0.0.1',
port: Number(process.env.REDIS_PORT) || 6379,
@ -66,19 +66,32 @@ export default defineNuxtConfig({
},
mysql:{
host: process.env.DB_HOST || '127.0.0.1',
port: process.env.DB_PORT || 3306,
port: Number(process.env.DB_PORT) || 3306,
user: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME || 'yuheng',
ssl:
process.env.NODE_ENV === 'production'
? {
rejectUnauthorized: false,
servername: '', // 明确置空servername参数
}
: null,
}
}
// ssl:
// process.env.NODE_ENV === 'production'
// ? {
// rejectUnauthorized: false,
// servername: '', // 明确置空servername参数
// }
// : null,
},
jwt: {
secret: process.env.JWT_SECRET || 'Hxl1314521',
accessExpiresIn: process.env.JWT_ACCESS_EXPIRES || '20m',
refreshExpiresIn: process.env.JWT_REFRESH_EXPIRES || '14d',
whitelist: [
'/user/login',
'/user/register',
'/user/refreshToken',
'/',
// '/module',
'/docs*',
'/docs/json'
],
},
},
})

606
package-lock.json generated
View File

@ -9,8 +9,10 @@
"dependencies": {
"@nuxt/eslint": "^1.3.0",
"consola": "^3.4.2",
"dayjs": "^1.11.13",
"drizzle-orm": "^0.42.0",
"eslint": "^9.25.0",
"jsonwebtoken": "^9.0.2",
"mysql2": "^3.14.0",
"nuxt": "^3.16.2",
"redis": "^4.7.0",
@ -19,7 +21,9 @@
},
"devDependencies": {
"@nuxtjs/tailwindcss": "^6.13.2",
"@types/jsonwebtoken": "^9.0.9",
"autoprefixer": "^10.4.21",
"drizzle-kit": "^0.31.0",
"open": "^10.1.1",
"postcss": "^8.5.3",
"sass": "^1.86.3",
@ -609,6 +613,13 @@
"node": ">=14"
}
},
"node_modules/@drizzle-team/brocli": {
"version": "0.10.2",
"resolved": "https://registry.npmmirror.com/@drizzle-team/brocli/-/brocli-0.10.2.tgz",
"integrity": "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/@emnapi/core": {
"version": "1.4.3",
"resolved": "https://registry.npmmirror.com/@emnapi/core/-/core-1.4.3.tgz",
@ -654,6 +665,442 @@
"node": ">=16"
}
},
"node_modules/@esbuild-kit/core-utils": {
"version": "3.3.2",
"resolved": "https://registry.npmmirror.com/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz",
"integrity": "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==",
"deprecated": "Merged into tsx: https://tsx.is",
"dev": true,
"license": "MIT",
"dependencies": {
"esbuild": "~0.18.20",
"source-map-support": "^0.5.21"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
"integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
"integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
"integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
"integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
"integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
"integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
"integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
"integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
"integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ia32": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
"integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-loong64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
"integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-mips64el": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
"integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ppc64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
"integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-riscv64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
"integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-s390x": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
"integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
"integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/netbsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
"integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/openbsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
"integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/sunos-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
"integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
"integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-ia32": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
"integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
"integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild-kit/core-utils/node_modules/esbuild": {
"version": "0.18.20",
"resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.18.20.tgz",
"integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=12"
},
"optionalDependencies": {
"@esbuild/android-arm": "0.18.20",
"@esbuild/android-arm64": "0.18.20",
"@esbuild/android-x64": "0.18.20",
"@esbuild/darwin-arm64": "0.18.20",
"@esbuild/darwin-x64": "0.18.20",
"@esbuild/freebsd-arm64": "0.18.20",
"@esbuild/freebsd-x64": "0.18.20",
"@esbuild/linux-arm": "0.18.20",
"@esbuild/linux-arm64": "0.18.20",
"@esbuild/linux-ia32": "0.18.20",
"@esbuild/linux-loong64": "0.18.20",
"@esbuild/linux-mips64el": "0.18.20",
"@esbuild/linux-ppc64": "0.18.20",
"@esbuild/linux-riscv64": "0.18.20",
"@esbuild/linux-s390x": "0.18.20",
"@esbuild/linux-x64": "0.18.20",
"@esbuild/netbsd-x64": "0.18.20",
"@esbuild/openbsd-x64": "0.18.20",
"@esbuild/sunos-x64": "0.18.20",
"@esbuild/win32-arm64": "0.18.20",
"@esbuild/win32-ia32": "0.18.20",
"@esbuild/win32-x64": "0.18.20"
}
},
"node_modules/@esbuild-kit/esm-loader": {
"version": "2.6.5",
"resolved": "https://registry.npmmirror.com/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz",
"integrity": "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==",
"deprecated": "Merged into tsx: https://tsx.is",
"dev": true,
"license": "MIT",
"dependencies": {
"@esbuild-kit/core-utils": "^3.3.2",
"get-tsconfig": "^4.7.0"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.25.2",
"resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz",
@ -4103,12 +4550,30 @@
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"license": "MIT"
},
"node_modules/@types/jsonwebtoken": {
"version": "9.0.9",
"resolved": "https://registry.npmmirror.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz",
"integrity": "sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/ms": "*",
"@types/node": "*"
}
},
"node_modules/@types/ms": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/@types/ms/-/ms-2.1.0.tgz",
"integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.14.1",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-22.14.1.tgz",
"integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"undici-types": "~6.21.0"
}
@ -5867,6 +6332,12 @@
"node": ">=8.0.0"
}
},
"node_modules/buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
"license": "BSD-3-Clause"
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
@ -6791,6 +7262,12 @@
"node": ">= 12"
}
},
"node_modules/dayjs": {
"version": "1.11.13",
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
"license": "MIT"
},
"node_modules/db0": {
"version": "0.3.2",
"resolved": "https://registry.npmmirror.com/db0/-/db0-0.3.2.tgz",
@ -7223,6 +7700,22 @@
"url": "https://dotenvx.com"
}
},
"node_modules/drizzle-kit": {
"version": "0.31.0",
"resolved": "https://registry.npmmirror.com/drizzle-kit/-/drizzle-kit-0.31.0.tgz",
"integrity": "sha512-pcKVT+GbfPA+bUovPIilgVOoq+onNBo/YQBG86sf3/GFHkN6lRJPm1l7dKN0IMAk57RQoIm4GUllRrasLlcaSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@drizzle-team/brocli": "^0.10.2",
"@esbuild-kit/esm-loader": "^2.5.5",
"esbuild": "^0.25.2",
"esbuild-register": "^3.5.0"
},
"bin": {
"drizzle-kit": "bin.cjs"
}
},
"node_modules/drizzle-orm": {
"version": "0.42.0",
"resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.42.0.tgz",
@ -7370,6 +7863,15 @@
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"license": "MIT"
},
"node_modules/ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmmirror.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
"license": "Apache-2.0",
"dependencies": {
"safe-buffer": "^5.0.1"
}
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz",
@ -7540,6 +8042,19 @@
"@esbuild/win32-x64": "0.25.2"
}
},
"node_modules/esbuild-register": {
"version": "3.6.0",
"resolved": "https://registry.npmmirror.com/esbuild-register/-/esbuild-register-3.6.0.tgz",
"integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.3.4"
},
"peerDependencies": {
"esbuild": ">=0.12 <1"
}
},
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz",
@ -9864,6 +10379,28 @@
"graceful-fs": "^4.1.6"
}
},
"node_modules/jsonwebtoken": {
"version": "9.0.2",
"resolved": "https://registry.npmmirror.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
"integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
"license": "MIT",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^7.5.4"
},
"engines": {
"node": ">=12",
"npm": ">=6"
}
},
"node_modules/junk": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/junk/-/junk-4.0.1.tgz",
@ -9876,6 +10413,27 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmmirror.com/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"license": "MIT",
"dependencies": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"node_modules/jws": {
"version": "3.2.2",
"resolved": "https://registry.npmmirror.com/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"license": "MIT",
"dependencies": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"node_modules/jwt-decode": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/jwt-decode/-/jwt-decode-4.0.0.tgz",
@ -10328,12 +10886,48 @@
"integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==",
"license": "MIT"
},
"node_modules/lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmmirror.com/lodash.includes/-/lodash.includes-4.3.0.tgz",
"integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
"license": "MIT"
},
"node_modules/lodash.isarguments": {
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
"integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==",
"license": "MIT"
},
"node_modules/lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmmirror.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
"license": "MIT"
},
"node_modules/lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmmirror.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
"integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
"license": "MIT"
},
"node_modules/lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmmirror.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
"integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
"license": "MIT"
},
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmmirror.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
"license": "MIT"
},
"node_modules/lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
"integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
"license": "MIT"
},
"node_modules/lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmmirror.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@ -10346,6 +10940,12 @@
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"license": "MIT"
},
"node_modules/lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmmirror.com/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
"license": "MIT"
},
"node_modules/lodash.uniq": {
"version": "4.5.0",
"resolved": "https://registry.npmmirror.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
@ -14863,8 +15463,8 @@
"version": "6.21.0",
"resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"license": "MIT",
"optional": true
"devOptional": true,
"license": "MIT"
},
"node_modules/unenv": {
"version": "2.0.0-rc.15",

View File

@ -7,13 +7,19 @@
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview --port 4000",
"postinstall": "nuxt prepare"
"postinstall": "nuxt prepare",
"makeSQL": "drizzle-kit generate",
"makeEntity": "drizzle-kit introspect",
"syncDB": "drizzle-kit migrate",
"sqlV": "drizzle-kit studio"
},
"dependencies": {
"@nuxt/eslint": "^1.3.0",
"consola": "^3.4.2",
"dayjs": "^1.11.13",
"drizzle-orm": "^0.42.0",
"eslint": "^9.25.0",
"jsonwebtoken": "^9.0.2",
"mysql2": "^3.14.0",
"nuxt": "^3.16.2",
"redis": "^4.7.0",
@ -22,7 +28,9 @@
},
"devDependencies": {
"@nuxtjs/tailwindcss": "^6.13.2",
"@types/jsonwebtoken": "^9.0.9",
"autoprefixer": "^10.4.21",
"drizzle-kit": "^0.31.0",
"open": "^10.1.1",
"postcss": "^8.5.3",
"sass": "^1.86.3",

View File

@ -0,0 +1,3 @@
export default defineEventHandler(event => {
return 'Hello blog/blogMenu.[blogId].delete' + event.context.params.blogId;
})

View File

@ -0,0 +1,3 @@
export default defineEventHandler(event => {
return 'Hello blog/blogMenu.[blogId].patch' + event.context.params.blogId;
})

View File

@ -0,0 +1,3 @@
export default defineEventHandler(event => {
return 'Hello blog/blogMenu.[blogId].update' + event.context.params.blogId;
})

View File

@ -0,0 +1,3 @@
export default defineEventHandler(event => {
return 'Hello blog/blogMenu.get'
})

View File

@ -0,0 +1,3 @@
export default defineEventHandler(event => {
return 'Hello blog/blogMenu.post'
})

View File

@ -1,6 +1,12 @@
import consola from "consola";
export default defineEventHandler(async event => {
// console.log(await event.context.redis.get('SI HI'))
consola.info('API')
await new Promise(resolve => setTimeout(resolve, 1000));
consola.info('API TimeOut')
const result = await event.context.redis.get('SI HI');
return {
'SI HI': await event.context.redis.get('SI HI')
'SI HI': result
}
})

12
server/api/home.ts Normal file
View File

@ -0,0 +1,12 @@
import consola from "consola";
export default defineEventHandler(async event => {
// console.log(await event.context.redis.get('SI HI'))
consola.info('API')
await new Promise(resolve => setTimeout(resolve, 1000));
consola.info('API TimeOut')
const result = await event.context.redis.get('SI HI');
return {
'HOME': result
}
})

View File

@ -1,4 +1,5 @@
export default defineEventHandler(event => {
import consola from "consola";
import dayjs from "dayjs";
export default defineEventHandler(async event => {
consola.info(dayjs().format('YYYY-MM-DD HH:mm:ss'), event.node.req.method, event.node.req.url);
})

View File

@ -0,0 +1,29 @@
import consola from "consola";
export default defineEventHandler(event => {
// 跳过无需验证的路由
if (event.path?.startsWith('/api/auth')) return
const token = getHeader(event, 'Authorization')?.split('Bearer ')[1];
const t = generateAccessToken({
name: event.path,
})
consola.info(`Token ${t}`);
if (!t) {
throw createError({
statusCode: 401,
statusMessage: '未提供认证Token'
})
}
try {
// 验证JWT示例使用jsonwebtoken
const verified = verifyToken(t) // 你的验证逻辑
event.context.auth = verified // 将用户信息挂载到上下文
} catch (e) {
throw createError({
statusCode: 401,
statusMessage: '无效Token'
})
}
})

View File

@ -5,7 +5,7 @@ import type { PoolOptions, Pool} from 'mysql2/promise';
import consola from "consola";
export default defineNitroPlugin(async nitroApp => {
const {server: {mysql: config}} = useRuntimeConfig()
const {mysql: config} = useRuntimeConfig()
consola.info('MySQL ...');
// 配置数据库
const poolOptions: PoolOptions = {
@ -48,14 +48,14 @@ export default defineNitroPlugin(async nitroApp => {
}
}
});
const [result] = await db.execute(sql`SHOW TABLES`);
const result = await db.execute(sql`SHOW TABLES`);
const tableList = result.map(row => Object.values(row)[0]);
consola.info('TableList', tableList)
consola.info('TableList', tableList.length)
// 将连接池添加到 Nitro 应用上下文
nitroApp.hooks.hook('request', async (event) => {
event.context.mysql = db
})
nitroApp.hooks.hook('error', async () => {
db.close();
pool.end();
})
})

View File

@ -2,7 +2,7 @@ import { createClient } from 'redis';
import consola from 'consola'
export default defineNitroPlugin(async (nitroApp) => {
const {server: {redis: config}} = useRuntimeConfig()
const {redis: config} = useRuntimeConfig()
consola.info('Redis ...');
const redisConnect = createClient({
name: config.connectName,

12
server/routes/home.ts Normal file
View File

@ -0,0 +1,12 @@
import consola from "consola";
export default defineEventHandler(async event => {
// console.log(await event.context.redis.get('SI HI'))
consola.info('API')
await new Promise(resolve => setTimeout(resolve, 1000));
consola.info('API TimeOut')
const result = await event.context.redis.get('SI HI');
return {
'HOME': result
}
})

4
server/utils/entity.ts Normal file
View File

@ -0,0 +1,4 @@
import * as schema from "../../drizzle/schema";
export function entity() {
return schema
}

21
server/utils/jwt.ts Normal file
View File

@ -0,0 +1,21 @@
import jwt from 'jsonwebtoken'
import type {StringValue} from "ms";
const {sign, verify} = jwt
console.log(jwt)
// export function jwt() {}
export const generateAccessToken = (payload: object) => {
const {jwt: config} = useRuntimeConfig()
return sign(payload, config.secret, { expiresIn: config.accessExpiresIn as StringValue })
}
export const generateRefreshToken = (payload: object) => {
const {jwt: config} = useRuntimeConfig()
return sign(payload, config.secret, { expiresIn: config.refreshExpiresIn as StringValue })
}
export const verifyToken = (token: string) => {
const {jwt: config} = useRuntimeConfig()
return verify(token, config.secret) // 返回解码后的payload
}

11
types/nuxt.config.d.ts vendored Normal file
View File

@ -0,0 +1,11 @@
// declare module 'nuxt/schema' {
// interface RuntimeConfig {
// // 私有配置(仅服务端)
// jwt: {
// secret: string,
// accessExpiresIn: string,
// refreshExpiresIn: string,
// whitelist: string[]
// },
// }
// }