feat: 添加Redis支持、雪花ID生成器及集群模式
- 新增Redis插件,支持分布式锁及缓存功能 - 引入雪花ID生成器,用于生成唯一用户ID - 实现集群模式,支持多线程运行 - 优化用户注册逻辑,增加分布式锁机制 - 更新配置文件,添加Redis及雪花ID相关配置 - 修复部分代码格式及数据库字段类型
This commit is contained in:
parent
3d4af91569
commit
fdc4d67092
14
.env
14
.env
@ -1,5 +1,5 @@
|
|||||||
# 服务器配置
|
# 服务器配置
|
||||||
PORT=9000
|
PORT=19000
|
||||||
HOST=0.0.0.0
|
HOST=0.0.0.0
|
||||||
BACKLOG=511
|
BACKLOG=511
|
||||||
|
|
||||||
@ -17,3 +17,15 @@ DB_USER=nie
|
|||||||
DB_PASSWORD=Hxl1314521
|
DB_PASSWORD=Hxl1314521
|
||||||
DB_NAME=yuheng
|
DB_NAME=yuheng
|
||||||
DB_PORT=3306
|
DB_PORT=3306
|
||||||
|
|
||||||
|
# redis
|
||||||
|
REDIS_HOST=172.16.1.10
|
||||||
|
REDIS_PORT=16379
|
||||||
|
REDIS_PASSWORD=Hxl1314521
|
||||||
|
REDIS_DB=9
|
||||||
|
|
||||||
|
# 数据中心ID
|
||||||
|
DATACENTER_ID=1
|
||||||
|
|
||||||
|
# 机器ID
|
||||||
|
MACHINE_ID=1
|
||||||
|
@ -106,9 +106,7 @@
|
|||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"sys_dict_id": {
|
"sys_dict_id": {
|
||||||
"name": "sys_dict_id",
|
"name": "sys_dict_id",
|
||||||
"columns": [
|
"columns": ["id"]
|
||||||
"id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -116,10 +114,7 @@
|
|||||||
"uniqueConstraints": {
|
"uniqueConstraints": {
|
||||||
"uniq_dict_key": {
|
"uniq_dict_key": {
|
||||||
"name": "uniq_dict_key",
|
"name": "uniq_dict_key",
|
||||||
"columns": [
|
"columns": ["dict_key", "pid"]
|
||||||
"dict_key",
|
|
||||||
"pid"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"checkConstraint": {}
|
"checkConstraint": {}
|
||||||
@ -219,9 +214,7 @@
|
|||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"sys_organization_org_id": {
|
"sys_organization_org_id": {
|
||||||
"name": "sys_organization_org_id",
|
"name": "sys_organization_org_id",
|
||||||
"columns": [
|
"columns": ["org_id"]
|
||||||
"org_id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -229,17 +222,11 @@
|
|||||||
"uniqueConstraints": {
|
"uniqueConstraints": {
|
||||||
"uniq_org_code": {
|
"uniq_org_code": {
|
||||||
"name": "uniq_org_code",
|
"name": "uniq_org_code",
|
||||||
"columns": [
|
"columns": ["org_code", "pid"]
|
||||||
"org_code",
|
|
||||||
"pid"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"uniq_org_name": {
|
"uniq_org_name": {
|
||||||
"name": "uniq_org_name",
|
"name": "uniq_org_name",
|
||||||
"columns": [
|
"columns": ["org_name", "pid"]
|
||||||
"org_name",
|
|
||||||
"pid"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"checkConstraint": {}
|
"checkConstraint": {}
|
||||||
@ -324,9 +311,7 @@
|
|||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"sys_organization_manager_id": {
|
"sys_organization_manager_id": {
|
||||||
"name": "sys_organization_manager_id",
|
"name": "sys_organization_manager_id",
|
||||||
"columns": [
|
"columns": ["id"]
|
||||||
"id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -334,10 +319,7 @@
|
|||||||
"uniqueConstraints": {
|
"uniqueConstraints": {
|
||||||
"uniq_org_user": {
|
"uniq_org_user": {
|
||||||
"name": "uniq_org_user",
|
"name": "uniq_org_user",
|
||||||
"columns": [
|
"columns": ["org_id", "user_id"]
|
||||||
"org_id",
|
|
||||||
"user_id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"checkConstraint": {}
|
"checkConstraint": {}
|
||||||
@ -467,9 +449,7 @@
|
|||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"sys_permission_perm_id": {
|
"sys_permission_perm_id": {
|
||||||
"name": "sys_permission_perm_id",
|
"name": "sys_permission_perm_id",
|
||||||
"columns": [
|
"columns": ["perm_id"]
|
||||||
"perm_id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -477,16 +457,11 @@
|
|||||||
"uniqueConstraints": {
|
"uniqueConstraints": {
|
||||||
"uniq_pid_name": {
|
"uniq_pid_name": {
|
||||||
"name": "uniq_pid_name",
|
"name": "uniq_pid_name",
|
||||||
"columns": [
|
"columns": ["perm_name", "pid"]
|
||||||
"perm_name",
|
|
||||||
"pid"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"uniq_perm_key": {
|
"uniq_perm_key": {
|
||||||
"name": "uniq_perm_key",
|
"name": "uniq_perm_key",
|
||||||
"columns": [
|
"columns": ["perm_key"]
|
||||||
"perm_key"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"checkConstraint": {}
|
"checkConstraint": {}
|
||||||
@ -549,9 +524,7 @@
|
|||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"sys_re_role_permission_id": {
|
"sys_re_role_permission_id": {
|
||||||
"name": "sys_re_role_permission_id",
|
"name": "sys_re_role_permission_id",
|
||||||
"columns": [
|
"columns": ["id"]
|
||||||
"id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -559,10 +532,7 @@
|
|||||||
"uniqueConstraints": {
|
"uniqueConstraints": {
|
||||||
"uniq_perm_role": {
|
"uniq_perm_role": {
|
||||||
"name": "uniq_perm_role",
|
"name": "uniq_perm_role",
|
||||||
"columns": [
|
"columns": ["role_id", "perm_id"]
|
||||||
"role_id",
|
|
||||||
"perm_id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"checkConstraint": {}
|
"checkConstraint": {}
|
||||||
@ -633,9 +603,7 @@
|
|||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"sys_re_user_organization_id": {
|
"sys_re_user_organization_id": {
|
||||||
"name": "sys_re_user_organization_id",
|
"name": "sys_re_user_organization_id",
|
||||||
"columns": [
|
"columns": ["id"]
|
||||||
"id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -643,10 +611,7 @@
|
|||||||
"uniqueConstraints": {
|
"uniqueConstraints": {
|
||||||
"uniq_user_org": {
|
"uniq_user_org": {
|
||||||
"name": "uniq_user_org",
|
"name": "uniq_user_org",
|
||||||
"columns": [
|
"columns": ["user_id", "org_id"]
|
||||||
"user_id",
|
|
||||||
"org_id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"checkConstraint": {}
|
"checkConstraint": {}
|
||||||
@ -717,9 +682,7 @@
|
|||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"sys_re_user_role_id": {
|
"sys_re_user_role_id": {
|
||||||
"name": "sys_re_user_role_id",
|
"name": "sys_re_user_role_id",
|
||||||
"columns": [
|
"columns": ["id"]
|
||||||
"id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -727,10 +690,7 @@
|
|||||||
"uniqueConstraints": {
|
"uniqueConstraints": {
|
||||||
"uniq_user_role": {
|
"uniq_user_role": {
|
||||||
"name": "uniq_user_role",
|
"name": "uniq_user_role",
|
||||||
"columns": [
|
"columns": ["user_id", "role_id"]
|
||||||
"user_id",
|
|
||||||
"role_id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"checkConstraint": {}
|
"checkConstraint": {}
|
||||||
@ -814,9 +774,7 @@
|
|||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"sys_role_role_id": {
|
"sys_role_role_id": {
|
||||||
"name": "sys_role_role_id",
|
"name": "sys_role_role_id",
|
||||||
"columns": [
|
"columns": ["role_id"]
|
||||||
"role_id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -824,10 +782,7 @@
|
|||||||
"uniqueConstraints": {
|
"uniqueConstraints": {
|
||||||
"uniq_role_pid": {
|
"uniq_role_pid": {
|
||||||
"name": "uniq_role_pid",
|
"name": "uniq_role_pid",
|
||||||
"columns": [
|
"columns": ["role_name", "pid"]
|
||||||
"role_name",
|
|
||||||
"pid"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"checkConstraint": {}
|
"checkConstraint": {}
|
||||||
@ -926,9 +881,7 @@
|
|||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"sys_user_user_id": {
|
"sys_user_user_id": {
|
||||||
"name": "sys_user_user_id",
|
"name": "sys_user_user_id",
|
||||||
"columns": [
|
"columns": ["user_id"]
|
||||||
"user_id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -936,15 +889,11 @@
|
|||||||
"uniqueConstraints": {
|
"uniqueConstraints": {
|
||||||
"uniq_username": {
|
"uniq_username": {
|
||||||
"name": "uniq_username",
|
"name": "uniq_username",
|
||||||
"columns": [
|
"columns": ["username"]
|
||||||
"username"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"uniq_email": {
|
"uniq_email": {
|
||||||
"name": "uniq_email",
|
"name": "uniq_email",
|
||||||
"columns": [
|
"columns": ["email"]
|
||||||
"email"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"checkConstraint": {}
|
"checkConstraint": {}
|
||||||
@ -984,9 +933,7 @@
|
|||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"sys_user_auth_user_id": {
|
"sys_user_auth_user_id": {
|
||||||
"name": "sys_user_auth_user_id",
|
"name": "sys_user_auth_user_id",
|
||||||
"columns": [
|
"columns": ["user_id"]
|
||||||
"user_id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -1029,9 +976,7 @@
|
|||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"sys_user_auth_history_id": {
|
"sys_user_auth_history_id": {
|
||||||
"name": "sys_user_auth_history_id",
|
"name": "sys_user_auth_history_id",
|
||||||
"columns": [
|
"columns": ["id"]
|
||||||
"id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -1170,9 +1115,7 @@
|
|||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"sys_user_field_definition_field_id": {
|
"sys_user_field_definition_field_id": {
|
||||||
"name": "sys_user_field_definition_field_id",
|
"name": "sys_user_field_definition_field_id",
|
||||||
"columns": [
|
"columns": ["field_id"]
|
||||||
"field_id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -1180,15 +1123,11 @@
|
|||||||
"uniqueConstraints": {
|
"uniqueConstraints": {
|
||||||
"uniq_field_name": {
|
"uniq_field_name": {
|
||||||
"name": "uniq_field_name",
|
"name": "uniq_field_name",
|
||||||
"columns": [
|
"columns": ["field_name"]
|
||||||
"field_name"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"uniq_field_key": {
|
"uniq_field_key": {
|
||||||
"name": "uniq_field_key",
|
"name": "uniq_field_key",
|
||||||
"columns": [
|
"columns": ["field_key"]
|
||||||
"field_key"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"checkConstraint": {}
|
"checkConstraint": {}
|
||||||
@ -1258,9 +1197,7 @@
|
|||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"sys_user_field_value_id": {
|
"sys_user_field_value_id": {
|
||||||
"name": "sys_user_field_value_id",
|
"name": "sys_user_field_value_id",
|
||||||
"columns": [
|
"columns": ["id"]
|
||||||
"id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -1268,10 +1205,7 @@
|
|||||||
"uniqueConstraints": {
|
"uniqueConstraints": {
|
||||||
"uniq_user_field": {
|
"uniq_user_field": {
|
||||||
"name": "uniq_user_field",
|
"name": "uniq_user_field",
|
||||||
"columns": [
|
"columns": ["user_id", "field_id"]
|
||||||
"user_id",
|
|
||||||
"field_id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"checkConstraint": {}
|
"checkConstraint": {}
|
||||||
@ -1356,9 +1290,7 @@
|
|||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"sys_user_profile_id": {
|
"sys_user_profile_id": {
|
||||||
"name": "sys_user_profile_id",
|
"name": "sys_user_profile_id",
|
||||||
"columns": [
|
"columns": ["id"]
|
||||||
"id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -1366,15 +1298,11 @@
|
|||||||
"uniqueConstraints": {
|
"uniqueConstraints": {
|
||||||
"uniq_name": {
|
"uniq_name": {
|
||||||
"name": "uniq_name",
|
"name": "uniq_name",
|
||||||
"columns": [
|
"columns": ["name"]
|
||||||
"name"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"uniq_profile_key": {
|
"uniq_profile_key": {
|
||||||
"name": "uniq_profile_key",
|
"name": "uniq_profile_key",
|
||||||
"columns": [
|
"columns": ["profile_key"]
|
||||||
"profile_key"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"checkConstraint": {}
|
"checkConstraint": {}
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
import { relations } from "drizzle-orm/relations";
|
import { relations } from 'drizzle-orm/relations';
|
||||||
import { } from "./schema";
|
import {} from './schema';
|
||||||
|
|
||||||
|
455
SQL/schema.ts
455
SQL/schema.ts
@ -1,242 +1,339 @@
|
|||||||
import { mysqlTable, mysqlSchema, AnyMySqlColumn, primaryKey, unique, bigint, int, tinyint, varchar, datetime } from "drizzle-orm/mysql-core"
|
import {
|
||||||
import { sql } from "drizzle-orm"
|
mysqlTable,
|
||||||
|
mysqlSchema,
|
||||||
|
AnyMySqlColumn,
|
||||||
|
primaryKey,
|
||||||
|
unique,
|
||||||
|
bigint,
|
||||||
|
int,
|
||||||
|
tinyint,
|
||||||
|
varchar,
|
||||||
|
datetime,
|
||||||
|
} from 'drizzle-orm/mysql-core';
|
||||||
|
import { sql } from 'drizzle-orm';
|
||||||
|
|
||||||
export const sysDict = mysqlTable("sys_dict", {
|
export const sysDict = mysqlTable(
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
'sys_dict',
|
||||||
|
{
|
||||||
|
id: bigint({ mode: 'number' }).autoincrement().notNull(),
|
||||||
version: int().default(0).notNull(),
|
version: int().default(0).notNull(),
|
||||||
pid: bigint({ mode: "number" }).notNull(),
|
pid: bigint({ mode: 'number' }).notNull(),
|
||||||
module: tinyint(),
|
module: tinyint(),
|
||||||
dictKey: varchar("dict_key", { length: 255 }),
|
dictKey: varchar('dict_key', { length: 255 }),
|
||||||
value: varchar({ length: 255 }),
|
value: varchar({ length: 255 }),
|
||||||
description: varchar({ length: 255 }),
|
description: varchar({ length: 255 }),
|
||||||
sort: int().default(0).notNull(),
|
sort: int().default(0).notNull(),
|
||||||
status: int().notNull(),
|
status: int().notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.id], name: "sys_dict_id"}),
|
primaryKey({ columns: [table.id], name: 'sys_dict_id' }),
|
||||||
unique("uniq_dict_key").on(table.dictKey, table.pid),
|
unique('uniq_dict_key').on(table.dictKey, table.pid),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysOrganization = mysqlTable("sys_organization", {
|
export const sysOrganization = mysqlTable(
|
||||||
orgId: bigint("org_id", { mode: "number" }).autoincrement().notNull(),
|
'sys_organization',
|
||||||
pid: bigint({ mode: "number" }).notNull(),
|
{
|
||||||
orgName: varchar("org_name", { length: 255 }),
|
orgId: bigint('org_id', { mode: 'number' }).autoincrement().notNull(),
|
||||||
orgCode: varchar("org_code", { length: 128 }),
|
pid: bigint({ mode: 'number' }).notNull(),
|
||||||
orgType: int("org_type").notNull(),
|
orgName: varchar('org_name', { length: 255 }),
|
||||||
|
orgCode: varchar('org_code', { length: 128 }),
|
||||||
|
orgType: int('org_type').notNull(),
|
||||||
description: varchar({ length: 255 }),
|
description: varchar({ length: 255 }),
|
||||||
sort: int().default(0).notNull(),
|
sort: int().default(0).notNull(),
|
||||||
status: int().notNull(),
|
status: int().notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.orgId], name: "sys_organization_org_id"}),
|
primaryKey({ columns: [table.orgId], name: 'sys_organization_org_id' }),
|
||||||
unique("uniq_org_code").on(table.orgCode, table.pid),
|
unique('uniq_org_code').on(table.orgCode, table.pid),
|
||||||
unique("uniq_org_name").on(table.orgName, table.pid),
|
unique('uniq_org_name').on(table.orgName, table.pid),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysOrganizationManager = mysqlTable("sys_organization_manager", {
|
export const sysOrganizationManager = mysqlTable(
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
'sys_organization_manager',
|
||||||
|
{
|
||||||
|
id: bigint({ mode: 'number' }).autoincrement().notNull(),
|
||||||
version: int().default(0).notNull(),
|
version: int().default(0).notNull(),
|
||||||
orgId: bigint("org_id", { mode: "number" }).notNull(),
|
orgId: bigint('org_id', { mode: 'number' }).notNull(),
|
||||||
userId: bigint("user_id", { mode: "number" }).notNull(),
|
userId: bigint('user_id', { mode: 'number' }).notNull(),
|
||||||
rank: int().notNull(),
|
rank: int().notNull(),
|
||||||
description: varchar({ length: 255 }),
|
description: varchar({ length: 255 }),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.id], name: "sys_organization_manager_id"}),
|
primaryKey({ columns: [table.id], name: 'sys_organization_manager_id' }),
|
||||||
unique("uniq_org_user").on(table.orgId, table.userId),
|
unique('uniq_org_user').on(table.orgId, table.userId),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysPermission = mysqlTable("sys_permission", {
|
export const sysPermission = mysqlTable(
|
||||||
permId: bigint("perm_id", { mode: "number" }).autoincrement().notNull(),
|
'sys_permission',
|
||||||
pid: bigint({ mode: "number" }).notNull(),
|
{
|
||||||
permName: varchar("perm_name", { length: 255 }).notNull(),
|
permId: bigint('perm_id', { mode: 'number' }).autoincrement().notNull(),
|
||||||
permKey: varchar("perm_key", { length: 255 }).notNull(),
|
pid: bigint({ mode: 'number' }).notNull(),
|
||||||
|
permName: varchar('perm_name', { length: 255 }).notNull(),
|
||||||
|
permKey: varchar('perm_key', { length: 255 }).notNull(),
|
||||||
url: varchar({ length: 255 }),
|
url: varchar({ length: 255 }),
|
||||||
avatarUrl: varchar("avatar_url", { length: 255 }),
|
avatarUrl: varchar('avatar_url', { length: 255 }),
|
||||||
description: varchar({ length: 255 }),
|
description: varchar({ length: 255 }),
|
||||||
permType: int("perm_type").notNull(),
|
permType: int('perm_type').notNull(),
|
||||||
isVisible: int("is_visible").default(0).notNull(),
|
isVisible: int('is_visible').default(0).notNull(),
|
||||||
version: int().default(0).notNull(),
|
version: int().default(0).notNull(),
|
||||||
sort: int().default(0).notNull(),
|
sort: int().default(0).notNull(),
|
||||||
status: int().notNull(),
|
status: int().notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.permId], name: "sys_permission_perm_id"}),
|
primaryKey({ columns: [table.permId], name: 'sys_permission_perm_id' }),
|
||||||
unique("uniq_pid_name").on(table.permName, table.pid),
|
unique('uniq_pid_name').on(table.permName, table.pid),
|
||||||
unique("uniq_perm_key").on(table.permKey),
|
unique('uniq_perm_key').on(table.permKey),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysReRolePermission = mysqlTable("sys_re_role_permission", {
|
export const sysReRolePermission = mysqlTable(
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
'sys_re_role_permission',
|
||||||
roleId: bigint("role_id", { mode: "number" }).notNull(),
|
{
|
||||||
permId: bigint("perm_id", { mode: "number" }).notNull(),
|
id: bigint({ mode: 'number' }).autoincrement().notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
roleId: bigint('role_id', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
permId: bigint('perm_id', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.id], name: "sys_re_role_permission_id"}),
|
primaryKey({ columns: [table.id], name: 'sys_re_role_permission_id' }),
|
||||||
unique("uniq_perm_role").on(table.roleId, table.permId),
|
unique('uniq_perm_role').on(table.roleId, table.permId),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysReUserOrganization = mysqlTable("sys_re_user_organization", {
|
export const sysReUserOrganization = mysqlTable(
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
'sys_re_user_organization',
|
||||||
userId: bigint("user_id", { mode: "number" }).notNull(),
|
{
|
||||||
orgId: bigint("org_id", { mode: "number" }).notNull(),
|
id: bigint({ mode: 'number' }).autoincrement().notNull(),
|
||||||
|
userId: bigint('user_id', { mode: 'number' }).notNull(),
|
||||||
|
orgId: bigint('org_id', { mode: 'number' }).notNull(),
|
||||||
version: int().default(0).notNull(),
|
version: int().default(0).notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.id], name: "sys_re_user_organization_id"}),
|
primaryKey({ columns: [table.id], name: 'sys_re_user_organization_id' }),
|
||||||
unique("uniq_user_org").on(table.userId, table.orgId),
|
unique('uniq_user_org').on(table.userId, table.orgId),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysReUserRole = mysqlTable("sys_re_user_role", {
|
export const sysReUserRole = mysqlTable(
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
'sys_re_user_role',
|
||||||
userId: bigint("user_id", { mode: "number" }).notNull(),
|
{
|
||||||
roleId: bigint("role_id", { mode: "number" }).notNull(),
|
id: bigint({ mode: 'number' }).autoincrement().notNull(),
|
||||||
|
userId: bigint('user_id', { mode: 'number' }).notNull(),
|
||||||
|
roleId: bigint('role_id', { mode: 'number' }).notNull(),
|
||||||
version: int().default(0).notNull(),
|
version: int().default(0).notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.id], name: "sys_re_user_role_id"}),
|
primaryKey({ columns: [table.id], name: 'sys_re_user_role_id' }),
|
||||||
unique("uniq_user_role").on(table.userId, table.roleId),
|
unique('uniq_user_role').on(table.userId, table.roleId),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysRole = mysqlTable("sys_role", {
|
export const sysRole = mysqlTable(
|
||||||
roleId: bigint("role_id", { mode: "number" }).autoincrement().notNull(),
|
'sys_role',
|
||||||
pid: bigint({ mode: "number" }).notNull(),
|
{
|
||||||
roleName: varchar("role_name", { length: 255 }).notNull(),
|
roleId: bigint('role_id', { mode: 'number' }).autoincrement().notNull(),
|
||||||
roleKey: varchar("role_key", { length: 255 }).notNull(),
|
pid: bigint({ mode: 'number' }).notNull(),
|
||||||
|
roleName: varchar('role_name', { length: 255 }).notNull(),
|
||||||
|
roleKey: varchar('role_key', { length: 255 }).notNull(),
|
||||||
description: varchar({ length: 255 }),
|
description: varchar({ length: 255 }),
|
||||||
status: int().notNull(),
|
status: int().notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.roleId], name: "sys_role_role_id"}),
|
primaryKey({ columns: [table.roleId], name: 'sys_role_role_id' }),
|
||||||
unique("uniq_role_pid").on(table.roleName, table.pid),
|
unique('uniq_role_pid').on(table.roleName, table.pid),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysUser = mysqlTable("sys_user", {
|
export const sysUser = mysqlTable(
|
||||||
userId: bigint("user_id", { mode: "number" }).notNull(),
|
'sys_user',
|
||||||
pid: bigint({ mode: "number" }).notNull(),
|
{
|
||||||
|
userId: bigint('user_id', { mode: 'number' }).notNull(),
|
||||||
|
pid: bigint({ mode: 'number' }).notNull(),
|
||||||
username: varchar({ length: 255 }).notNull(),
|
username: varchar({ length: 255 }).notNull(),
|
||||||
email: varchar({ length: 255 }).notNull(),
|
email: varchar({ length: 255 }).notNull(),
|
||||||
phone: varchar({ length: 255 }),
|
phone: varchar({ length: 255 }),
|
||||||
avatarUrl: varchar("avatar_url", { length: 255 }),
|
avatarUrl: varchar('avatar_url', { length: 255 }),
|
||||||
userType: tinyint("user_type"),
|
userType: tinyint('user_type'),
|
||||||
status: tinyint().default(0).notNull(),
|
status: tinyint().default(0).notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.userId], name: "sys_user_user_id"}),
|
primaryKey({ columns: [table.userId], name: 'sys_user_user_id' }),
|
||||||
unique("uniq_username").on(table.username),
|
unique('uniq_username').on(table.username),
|
||||||
unique("uniq_email").on(table.email),
|
unique('uniq_email').on(table.email),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysUserAuth = mysqlTable("sys_user_auth", {
|
export const sysUserAuth = mysqlTable(
|
||||||
userId: bigint("user_id", { mode: "number" }).notNull(),
|
'sys_user_auth',
|
||||||
passwordHash: varchar("password_hash", { length: 255 }).notNull(),
|
{
|
||||||
passwordModified: datetime("password_modified", { mode: 'string'}).notNull(),
|
userId: bigint('user_id', { mode: 'number' }).notNull(),
|
||||||
passwordExpire: datetime("password_expire", { mode: 'string'}),
|
passwordHash: varchar('password_hash', { length: 255 }).notNull(),
|
||||||
|
passwordModified: datetime('password_modified', { mode: 'string' }).notNull(),
|
||||||
|
passwordExpire: datetime('password_expire', { mode: 'string' }),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [primaryKey({ columns: [table.userId], name: 'sys_user_auth_user_id' })],
|
||||||
primaryKey({ columns: [table.userId], name: "sys_user_auth_user_id"}),
|
);
|
||||||
]);
|
|
||||||
|
|
||||||
export const sysUserAuthHistory = mysqlTable("sys_user_auth_history", {
|
export const sysUserAuthHistory = mysqlTable(
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
'sys_user_auth_history',
|
||||||
userId: bigint("user_id", { mode: "number" }).notNull(),
|
{
|
||||||
passwordHash: varchar("password_hash", { length: 255 }).notNull(),
|
id: bigint({ mode: 'number' }).autoincrement().notNull(),
|
||||||
modifiedAt: varchar("modified_at", { length: 255 }).notNull(),
|
userId: bigint('user_id', { mode: 'number' }).notNull(),
|
||||||
|
passwordHash: varchar('password_hash', { length: 255 }).notNull(),
|
||||||
|
modifiedAt: varchar('modified_at', { length: 255 }).notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [primaryKey({ columns: [table.id], name: 'sys_user_auth_history_id' })],
|
||||||
primaryKey({ columns: [table.id], name: "sys_user_auth_history_id"}),
|
);
|
||||||
]);
|
|
||||||
|
|
||||||
export const sysUserFieldDefinition = mysqlTable("sys_user_field_definition", {
|
export const sysUserFieldDefinition = mysqlTable(
|
||||||
fieldId: bigint("field_id", { mode: "number" }).autoincrement().notNull(),
|
'sys_user_field_definition',
|
||||||
|
{
|
||||||
|
fieldId: bigint('field_id', { mode: 'number' }).autoincrement().notNull(),
|
||||||
version: int().default(0).notNull(),
|
version: int().default(0).notNull(),
|
||||||
fieldName: varchar("field_name", { length: 255 }).notNull(),
|
fieldName: varchar('field_name', { length: 255 }).notNull(),
|
||||||
fieldKey: varchar("field_key", { length: 255 }).notNull(),
|
fieldKey: varchar('field_key', { length: 255 }).notNull(),
|
||||||
fieldType: tinyint("field_type").notNull(),
|
fieldType: tinyint('field_type').notNull(),
|
||||||
dictModule: int("dict_module"),
|
dictModule: int('dict_module'),
|
||||||
isRequired: tinyint("is_required").default(0).notNull(),
|
isRequired: tinyint('is_required').default(0).notNull(),
|
||||||
limit: int(),
|
limit: int(),
|
||||||
description: varchar({ length: 255 }),
|
description: varchar({ length: 255 }),
|
||||||
defaultValue: varchar("default_value", { length: 255 }),
|
defaultValue: varchar('default_value', { length: 255 }),
|
||||||
defaultOptions: varchar("default_options", { length: 255 }),
|
defaultOptions: varchar('default_options', { length: 255 }),
|
||||||
sort: int().default(0).notNull(),
|
sort: int().default(0).notNull(),
|
||||||
status: int().notNull(),
|
status: int().notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.fieldId], name: "sys_user_field_definition_field_id"}),
|
primaryKey({ columns: [table.fieldId], name: 'sys_user_field_definition_field_id' }),
|
||||||
unique("uniq_field_name").on(table.fieldName),
|
unique('uniq_field_name').on(table.fieldName),
|
||||||
unique("uniq_field_key").on(table.fieldKey),
|
unique('uniq_field_key').on(table.fieldKey),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysUserFieldValue = mysqlTable("sys_user_field_value", {
|
export const sysUserFieldValue = mysqlTable(
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
'sys_user_field_value',
|
||||||
userId: bigint("user_id", { mode: "number" }).notNull(),
|
{
|
||||||
fieldId: int("field_id").notNull(),
|
id: bigint({ mode: 'number' }).autoincrement().notNull(),
|
||||||
|
userId: bigint('user_id', { mode: 'number' }).notNull(),
|
||||||
|
fieldId: int('field_id').notNull(),
|
||||||
value: varchar({ length: 4096 }),
|
value: varchar({ length: 4096 }),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.id], name: "sys_user_field_value_id"}),
|
primaryKey({ columns: [table.id], name: 'sys_user_field_value_id' }),
|
||||||
unique("uniq_user_field").on(table.userId, table.fieldId),
|
unique('uniq_user_field').on(table.userId, table.fieldId),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysUserProfile = mysqlTable("sys_user_profile", {
|
export const sysUserProfile = mysqlTable(
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
'sys_user_profile',
|
||||||
|
{
|
||||||
|
id: bigint({ mode: 'number' }).autoincrement().notNull(),
|
||||||
version: int().default(0).notNull(),
|
version: int().default(0).notNull(),
|
||||||
name: varchar({ length: 32 }).notNull(),
|
name: varchar({ length: 32 }).notNull(),
|
||||||
profileKey: varchar("profile_key", { length: 255 }).notNull(),
|
profileKey: varchar('profile_key', { length: 255 }).notNull(),
|
||||||
description: varchar({ length: 255 }),
|
description: varchar({ length: 255 }),
|
||||||
content: varchar({ length: 255 }),
|
content: varchar({ length: 255 }),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.id], name: "sys_user_profile_id"}),
|
primaryKey({ columns: [table.id], name: 'sys_user_profile_id' }),
|
||||||
unique("uniq_name").on(table.name),
|
unique('uniq_name').on(table.name),
|
||||||
unique("uniq_profile_key").on(table.profileKey),
|
unique('uniq_profile_key').on(table.profileKey),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
@ -4,7 +4,7 @@ import path from 'path';
|
|||||||
|
|
||||||
// 加载环境变量
|
// 加载环境变量
|
||||||
config({ path: path.resolve(process.cwd(), '.env') });
|
config({ path: path.resolve(process.cwd(), '.env') });
|
||||||
console.log('[NODE_ENV]:', process.env.NODE_ENV);
|
// console.log('[NODE_ENV]:', process.env.NODE_ENV);
|
||||||
|
|
||||||
// 基础配置
|
// 基础配置
|
||||||
const baseConfig = {
|
const baseConfig = {
|
||||||
@ -13,6 +13,11 @@ const baseConfig = {
|
|||||||
serviceName: 'YuHeng',
|
serviceName: 'YuHeng',
|
||||||
description: 'User System',
|
description: 'User System',
|
||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
|
deviceInfo: {
|
||||||
|
dataCenterId: process.env.DATACENTER_ID,
|
||||||
|
machineId: process.env.MACHINE_ID,
|
||||||
|
pid: process.pid,
|
||||||
|
},
|
||||||
server: {
|
server: {
|
||||||
port: process.env.PORT || 9000,
|
port: process.env.PORT || 9000,
|
||||||
host: process.env.HOST || 'localhost',
|
host: process.env.HOST || 'localhost',
|
||||||
@ -21,7 +26,7 @@ const baseConfig = {
|
|||||||
profile: {
|
profile: {
|
||||||
swagger: {
|
swagger: {
|
||||||
basePath: '/swagger',
|
basePath: '/swagger',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
logger: {
|
logger: {
|
||||||
level: process.env.LOG_LEVEL || 'trace',
|
level: process.env.LOG_LEVEL || 'trace',
|
||||||
@ -38,11 +43,22 @@ const baseConfig = {
|
|||||||
user: process.env.DB_USER || 'root',
|
user: process.env.DB_USER || 'root',
|
||||||
password: process.env.DB_PASSWORD,
|
password: process.env.DB_PASSWORD,
|
||||||
database: process.env.DB_NAME || 'yuheng',
|
database: process.env.DB_NAME || 'yuheng',
|
||||||
ssl: process.env.NODE_ENV === 'production' ? {
|
ssl:
|
||||||
|
process.env.NODE_ENV === 'production'
|
||||||
|
? {
|
||||||
rejectUnauthorized: false,
|
rejectUnauthorized: false,
|
||||||
servername: '' // 明确置空servername参数
|
servername: '', // 明确置空servername参数
|
||||||
} : null,
|
}
|
||||||
|
: null,
|
||||||
},
|
},
|
||||||
|
redis: {
|
||||||
|
host: process.env.REDIS_HOST || '127.0.0.1',
|
||||||
|
port: process.env.REDIS_PORT || 6379,
|
||||||
|
connectName: 'yuheng',
|
||||||
|
database: process.env.REDIS_DB || 9,
|
||||||
|
username: 'default',
|
||||||
|
password: process.env.REDIS_PASSWORD || 'Hxl1314521',
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 环境特定配置
|
// 环境特定配置
|
||||||
@ -72,5 +88,6 @@ function deepMerge(target, source) {
|
|||||||
}
|
}
|
||||||
return Object.assign({}, target, source);
|
return Object.assign({}, target, source);
|
||||||
}
|
}
|
||||||
|
const configInfo = deepMerge(baseConfig, envConfig[process.env.NODE_ENV] || envConfig.development);
|
||||||
|
|
||||||
export default deepMerge(baseConfig, envConfig[process.env.NODE_ENV] || envConfig.development);
|
export default configInfo;
|
||||||
|
97
package-lock.json
generated
97
package-lock.json
generated
@ -22,7 +22,8 @@
|
|||||||
"mysql2": "^3.13.0",
|
"mysql2": "^3.13.0",
|
||||||
"pino": "^9.6.0",
|
"pino": "^9.6.0",
|
||||||
"pino-multi-stream": "^6.0.0",
|
"pino-multi-stream": "^6.0.0",
|
||||||
"pino-pretty": "^13.0.0"
|
"pino-pretty": "^13.0.0",
|
||||||
|
"redis": "^4.7.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
@ -1307,6 +1308,65 @@
|
|||||||
"integrity": "sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog==",
|
"integrity": "sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@redis/bloom": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@redis/bloom/-/bloom-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@redis/client": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@redis/client": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@redis/client/-/client-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"cluster-key-slot": "1.1.2",
|
||||||
|
"generic-pool": "3.9.0",
|
||||||
|
"yallist": "4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@redis/graph": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@redis/graph/-/graph-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@redis/client": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@redis/json": {
|
||||||
|
"version": "1.0.7",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@redis/json/-/json-1.0.7.tgz",
|
||||||
|
"integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@redis/client": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@redis/search": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@redis/search/-/search-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@redis/client": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@redis/time-series": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@redis/time-series/-/time-series-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@redis/client": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rtsao/scc": {
|
"node_modules/@rtsao/scc": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@rtsao/scc/-/scc-1.1.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@rtsao/scc/-/scc-1.1.0.tgz",
|
||||||
@ -1862,6 +1922,15 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cluster-key-slot": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/color-convert": {
|
"node_modules/color-convert": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
@ -3368,6 +3437,15 @@
|
|||||||
"is-property": "^1.0.2"
|
"is-property": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/generic-pool": {
|
||||||
|
"version": "3.9.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/generic-pool/-/generic-pool-3.9.0.tgz",
|
||||||
|
"integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/get-intrinsic": {
|
"node_modules/get-intrinsic": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||||
@ -5241,6 +5319,23 @@
|
|||||||
"node": ">= 12.13.0"
|
"node": ">= 12.13.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/redis": {
|
||||||
|
"version": "4.7.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/redis/-/redis-4.7.0.tgz",
|
||||||
|
"integrity": "sha512-zvmkHEAdGMn+hMRXuMBtu4Vo5P6rHQjLoHftu+lBqq8ZTA3RCVC/WzD790bkKKiNFp7d5/9PcSD19fJyyRvOdQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"workspaces": [
|
||||||
|
"./packages/*"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"@redis/bloom": "1.2.0",
|
||||||
|
"@redis/client": "1.6.0",
|
||||||
|
"@redis/graph": "1.1.1",
|
||||||
|
"@redis/json": "1.0.7",
|
||||||
|
"@redis/search": "1.2.0",
|
||||||
|
"@redis/time-series": "1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/reflect.getprototypeof": {
|
"node_modules/reflect.getprototypeof": {
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmmirror.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
"resolved": "https://registry.npmmirror.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
"node": ">=22"
|
"node": ">=22"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "cross-env NODE_ENV=production node src/application.js",
|
"start": "cross-env NODE_ENV=production node src/cluster.js",
|
||||||
"dev": "cross-env NODE_ENV=development nodemon src/application.js",
|
"dev": "cross-env NODE_ENV=development nodemon src/cluster.js",
|
||||||
"lint": "eslint src --ext .js",
|
"lint": "eslint src --ext .js",
|
||||||
"format": "prettier --write . --config ./.prettier.config.cjs --ignore-path .prettierignore",
|
"format": "prettier --write . --config ./.prettier.config.cjs --ignore-path .prettierignore",
|
||||||
"lint:format": "prettier --check . --config ./.prettier.config.cjs --ignore-path .prettierignore",
|
"lint:format": "prettier --check . --config ./.prettier.config.cjs --ignore-path .prettierignore",
|
||||||
@ -48,7 +48,8 @@
|
|||||||
"mysql2": "^3.13.0",
|
"mysql2": "^3.13.0",
|
||||||
"pino": "^9.6.0",
|
"pino": "^9.6.0",
|
||||||
"pino-multi-stream": "^6.0.0",
|
"pino-multi-stream": "^6.0.0",
|
||||||
"pino-pretty": "^13.0.0"
|
"pino-pretty": "^13.0.0",
|
||||||
|
"redis": "^4.7.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
// ESM
|
// ESM
|
||||||
import '#start';
|
|
||||||
import Fastify from 'fastify';
|
import Fastify from 'fastify';
|
||||||
import config from '#config/index';
|
import config from '#config/index';
|
||||||
import plugin from '#src/plugins/index';
|
import plugin from '#src/plugins/index';
|
||||||
import routes from '#src/routes/index';
|
import routes from '#src/routes/index';
|
||||||
import logger from '#src/utils/logger';
|
import loggerConfig from '#src/utils/logger';
|
||||||
import { ajvConfig } from '#utils/ajv/index';
|
import { ajvConfig } from '#utils/ajv/index';
|
||||||
|
|
||||||
async function start() {
|
export default async function Application(machineId = 1) {
|
||||||
|
config.deviceInfo.machineId = machineId;
|
||||||
// 创建Fastify实例
|
// 创建Fastify实例
|
||||||
const fastify = new Fastify({
|
const fastify = new Fastify({
|
||||||
logger,
|
logger: loggerConfig(config),
|
||||||
ajv: ajvConfig
|
ajv: ajvConfig,
|
||||||
});
|
});
|
||||||
// 加载插件
|
// 加载插件
|
||||||
await fastify.register(plugin, { config });
|
await fastify.register(plugin, { config });
|
||||||
@ -20,4 +20,3 @@ async function start() {
|
|||||||
// 启动服务器
|
// 启动服务器
|
||||||
await fastify.listen(config.server); // 使用配置中的服务器参数
|
await fastify.listen(config.server); // 使用配置中的服务器参数
|
||||||
}
|
}
|
||||||
start();
|
|
||||||
|
63
src/cluster.js
Normal file
63
src/cluster.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import echo from '#start';
|
||||||
|
import cluster from 'cluster';
|
||||||
|
import os from 'os';
|
||||||
|
import Application from './application.js';
|
||||||
|
|
||||||
|
// 获取 CPU 核心数
|
||||||
|
const numCPUs = os.cpus().length;
|
||||||
|
|
||||||
|
function sleep(time = 1000) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve();
|
||||||
|
}, time);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动集群
|
||||||
|
async function clusterStart() {
|
||||||
|
// 检查是否为主进程
|
||||||
|
if (cluster.isPrimary) {
|
||||||
|
echo();
|
||||||
|
// 设置负载均衡策略
|
||||||
|
cluster.schedulingPolicy = cluster.SCHED_RR;
|
||||||
|
console.log(`Primary ${process.pid} is running`);
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
console.log('>>>>>>>>>>>>>>多线程模式');
|
||||||
|
// 为每个 CPU 核心创建一个工作进程
|
||||||
|
for (let i = 0; i < /*numCPUs*/ 2; i++) {
|
||||||
|
const worker = cluster.fork();
|
||||||
|
worker.on('message', async message => {
|
||||||
|
if (message.type === 'workerStarted') {
|
||||||
|
worker.send({ type: 'workerId', id: i + 1 });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await sleep(100);
|
||||||
|
}
|
||||||
|
// 监听工作进程退出事件
|
||||||
|
cluster.on('exit', (worker, code, signal) => {
|
||||||
|
console.log(`Worker ${worker.process.pid} died`);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('==============单线程模式');
|
||||||
|
Application();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 工作进程
|
||||||
|
// 告诉主进程工作进程已启动
|
||||||
|
process.send({ type: 'workerStarted', pid: process.pid });
|
||||||
|
// 监听主进程发送的消息
|
||||||
|
process.on('message', message => {
|
||||||
|
if (message.type === 'workerId') {
|
||||||
|
const workerId = message.id;
|
||||||
|
console.log(
|
||||||
|
`Worker (ID ${workerId.toString().padStart(2, 0)}) ${process.pid.toString().padEnd(8, ' ')} started`,
|
||||||
|
);
|
||||||
|
// 启动服务器
|
||||||
|
Application(workerId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clusterStart();
|
27
src/entities/customType.js
Normal file
27
src/entities/customType.js
Normal 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); // 确保写入时为数字类型
|
||||||
|
}
|
||||||
|
});
|
@ -1,242 +1,341 @@
|
|||||||
import { mysqlTable, mysqlSchema, primaryKey, unique, bigint, int, tinyint, varchar, datetime } from "drizzle-orm/mysql-core"
|
import {
|
||||||
import { sql } from "drizzle-orm"
|
mysqlTable,
|
||||||
|
mysqlSchema,
|
||||||
|
primaryKey,
|
||||||
|
unique,
|
||||||
|
int,
|
||||||
|
tinyint,
|
||||||
|
varchar,
|
||||||
|
datetime,
|
||||||
|
} from 'drizzle-orm/mysql-core';
|
||||||
|
import { sql } from 'drizzle-orm';
|
||||||
|
|
||||||
export const sysDict = mysqlTable("sys_dict", {
|
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
import { bigintString } from './customType.js';
|
||||||
|
const bigint = bigintString;
|
||||||
|
|
||||||
|
export const sysDict = mysqlTable(
|
||||||
|
'sys_dict',
|
||||||
|
{
|
||||||
|
id: bigint({ mode: 'number' }).notNull(),
|
||||||
version: int().default(0).notNull(),
|
version: int().default(0).notNull(),
|
||||||
pid: bigint({ mode: "number" }).notNull(),
|
pid: bigint({ mode: 'number' }).notNull(),
|
||||||
module: tinyint(),
|
module: tinyint(),
|
||||||
dictKey: varchar("dict_key", { length: 255 }),
|
dictKey: varchar('dict_key', { length: 255 }),
|
||||||
value: varchar({ length: 255 }),
|
value: varchar({ length: 255 }),
|
||||||
description: varchar({ length: 255 }),
|
description: varchar({ length: 255 }),
|
||||||
sort: int().default(0).notNull(),
|
sort: int().default(0).notNull(),
|
||||||
status: int().notNull(),
|
status: int().notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.id], name: "sys_dict_id"}),
|
primaryKey({ columns: [table.id], name: 'sys_dict_id' }),
|
||||||
unique("uniq_dict_key").on(table.dictKey, table.pid),
|
unique('uniq_dict_key').on(table.dictKey, table.pid),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysOrganization = mysqlTable("sys_organization", {
|
export const sysOrganization = mysqlTable(
|
||||||
orgId: bigint("org_id", { mode: "number" }).autoincrement().notNull(),
|
'sys_organization',
|
||||||
pid: bigint({ mode: "number" }).notNull(),
|
{
|
||||||
orgName: varchar("org_name", { length: 255 }),
|
orgId: bigint('org_id', { mode: 'number' }).notNull(),
|
||||||
orgCode: varchar("org_code", { length: 128 }),
|
pid: bigint({ mode: 'number' }).notNull(),
|
||||||
orgType: int("org_type").notNull(),
|
orgName: varchar('org_name', { length: 255 }),
|
||||||
|
orgCode: varchar('org_code', { length: 128 }),
|
||||||
|
orgType: int('org_type').notNull(),
|
||||||
description: varchar({ length: 255 }),
|
description: varchar({ length: 255 }),
|
||||||
sort: int().default(0).notNull(),
|
sort: int().default(0).notNull(),
|
||||||
status: int().notNull(),
|
status: int().notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.orgId], name: "sys_organization_org_id"}),
|
primaryKey({ columns: [table.orgId], name: 'sys_organization_org_id' }),
|
||||||
unique("uniq_org_code").on(table.orgCode, table.pid),
|
unique('uniq_org_code').on(table.orgCode, table.pid),
|
||||||
unique("uniq_org_name").on(table.orgName, table.pid),
|
unique('uniq_org_name').on(table.orgName, table.pid),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysOrganizationManager = mysqlTable("sys_organization_manager", {
|
export const sysOrganizationManager = mysqlTable(
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
'sys_organization_manager',
|
||||||
|
{
|
||||||
|
id: bigint({ mode: 'number' }).notNull(),
|
||||||
version: int().default(0).notNull(),
|
version: int().default(0).notNull(),
|
||||||
orgId: bigint("org_id", { mode: "number" }).notNull(),
|
orgId: bigint('org_id', { mode: 'number' }).notNull(),
|
||||||
userId: bigint("user_id", { mode: "number" }).notNull(),
|
userId: bigint('user_id', { mode: 'number' }).notNull(),
|
||||||
rank: int().notNull(),
|
rank: int().notNull(),
|
||||||
description: varchar({ length: 255 }),
|
description: varchar({ length: 255 }),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.id], name: "sys_organization_manager_id"}),
|
primaryKey({ columns: [table.id], name: 'sys_organization_manager_id' }),
|
||||||
unique("uniq_org_user").on(table.orgId, table.userId),
|
unique('uniq_org_user').on(table.orgId, table.userId),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysPermission = mysqlTable("sys_permission", {
|
export const sysPermission = mysqlTable(
|
||||||
permId: bigint("perm_id", { mode: "number" }).autoincrement().notNull(),
|
'sys_permission',
|
||||||
pid: bigint({ mode: "number" }).notNull(),
|
{
|
||||||
permName: varchar("perm_name", { length: 255 }).notNull(),
|
permId: bigint('perm_id', { mode: 'number' }).notNull(),
|
||||||
permKey: varchar("perm_key", { length: 255 }).notNull(),
|
pid: bigint({ mode: 'number' }).notNull(),
|
||||||
|
permName: varchar('perm_name', { length: 255 }).notNull(),
|
||||||
|
permKey: varchar('perm_key', { length: 255 }).notNull(),
|
||||||
url: varchar({ length: 255 }),
|
url: varchar({ length: 255 }),
|
||||||
avatarUrl: varchar("avatar_url", { length: 255 }),
|
avatarUrl: varchar('avatar_url', { length: 255 }),
|
||||||
description: varchar({ length: 255 }),
|
description: varchar({ length: 255 }),
|
||||||
permType: int("perm_type").notNull(),
|
permType: int('perm_type').notNull(),
|
||||||
isVisible: int("is_visible").default(0).notNull(),
|
isVisible: int('is_visible').default(0).notNull(),
|
||||||
version: int().default(0).notNull(),
|
version: int().default(0).notNull(),
|
||||||
sort: int().default(0).notNull(),
|
sort: int().default(0).notNull(),
|
||||||
status: int().notNull(),
|
status: int().notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.permId], name: "sys_permission_perm_id"}),
|
primaryKey({ columns: [table.permId], name: 'sys_permission_perm_id' }),
|
||||||
unique("uniq_pid_name").on(table.permName, table.pid),
|
unique('uniq_pid_name').on(table.permName, table.pid),
|
||||||
unique("uniq_perm_key").on(table.permKey),
|
unique('uniq_perm_key').on(table.permKey),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysReRolePermission = mysqlTable("sys_re_role_permission", {
|
export const sysReRolePermission = mysqlTable(
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
'sys_re_role_permission',
|
||||||
roleId: bigint("role_id", { mode: "number" }).notNull(),
|
{
|
||||||
permId: bigint("perm_id", { mode: "number" }).notNull(),
|
id: bigint({ mode: 'number' }).notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
roleId: bigint('role_id', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
permId: bigint('perm_id', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.id], name: "sys_re_role_permission_id"}),
|
primaryKey({ columns: [table.id], name: 'sys_re_role_permission_id' }),
|
||||||
unique("uniq_perm_role").on(table.roleId, table.permId),
|
unique('uniq_perm_role').on(table.roleId, table.permId),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysReUserOrganization = mysqlTable("sys_re_user_organization", {
|
export const sysReUserOrganization = mysqlTable(
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
'sys_re_user_organization',
|
||||||
userId: bigint("user_id", { mode: "number" }).notNull(),
|
{
|
||||||
orgId: bigint("org_id", { mode: "number" }).notNull(),
|
id: bigint({ mode: 'number' }).notNull(),
|
||||||
|
userId: bigint('user_id', { mode: 'number' }).notNull(),
|
||||||
|
orgId: bigint('org_id', { mode: 'number' }).notNull(),
|
||||||
version: int().default(0).notNull(),
|
version: int().default(0).notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.id], name: "sys_re_user_organization_id"}),
|
primaryKey({ columns: [table.id], name: 'sys_re_user_organization_id' }),
|
||||||
unique("uniq_user_org").on(table.userId, table.orgId),
|
unique('uniq_user_org').on(table.userId, table.orgId),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysReUserRole = mysqlTable("sys_re_user_role", {
|
export const sysReUserRole = mysqlTable(
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
'sys_re_user_role',
|
||||||
userId: bigint("user_id", { mode: "number" }).notNull(),
|
{
|
||||||
roleId: bigint("role_id", { mode: "number" }).notNull(),
|
id: bigint({ mode: 'number' }).notNull(),
|
||||||
|
userId: bigint('user_id', { mode: 'number' }).notNull(),
|
||||||
|
roleId: bigint('role_id', { mode: 'number' }).notNull(),
|
||||||
version: int().default(0).notNull(),
|
version: int().default(0).notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.id], name: "sys_re_user_role_id"}),
|
primaryKey({ columns: [table.id], name: 'sys_re_user_role_id' }),
|
||||||
unique("uniq_user_role").on(table.userId, table.roleId),
|
unique('uniq_user_role').on(table.userId, table.roleId),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysRole = mysqlTable("sys_role", {
|
export const sysRole = mysqlTable(
|
||||||
roleId: bigint("role_id", { mode: "number" }).autoincrement().notNull(),
|
'sys_role',
|
||||||
pid: bigint({ mode: "number" }).notNull(),
|
{
|
||||||
roleName: varchar("role_name", { length: 255 }).notNull(),
|
roleId: bigint('role_id', { mode: 'number' }).notNull(),
|
||||||
roleKey: varchar("role_key", { length: 255 }).notNull(),
|
pid: bigint({ mode: 'number' }).notNull(),
|
||||||
|
roleName: varchar('role_name', { length: 255 }).notNull(),
|
||||||
|
roleKey: varchar('role_key', { length: 255 }).notNull(),
|
||||||
description: varchar({ length: 255 }),
|
description: varchar({ length: 255 }),
|
||||||
status: int().notNull(),
|
status: int().notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.roleId], name: "sys_role_role_id"}),
|
primaryKey({ columns: [table.roleId], name: 'sys_role_role_id' }),
|
||||||
unique("uniq_role_pid").on(table.roleName, table.pid),
|
unique('uniq_role_pid').on(table.roleName, table.pid),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysUser = mysqlTable("sys_user", {
|
export const sysUser = mysqlTable(
|
||||||
userId: bigint("user_id", { mode: "number" }).notNull(),
|
'sys_user',
|
||||||
pid: bigint({ mode: "number" }).notNull(),
|
{
|
||||||
|
userId: bigint('user_id', { mode: 'number' }).notNull(),
|
||||||
|
pid: bigint({ mode: 'number' }).notNull(),
|
||||||
username: varchar({ length: 255 }).notNull(),
|
username: varchar({ length: 255 }).notNull(),
|
||||||
email: varchar({ length: 255 }).notNull(),
|
email: varchar({ length: 255 }).notNull(),
|
||||||
phone: varchar({ length: 255 }),
|
phone: varchar({ length: 255 }),
|
||||||
avatarUrl: varchar("avatar_url", { length: 255 }),
|
avatarUrl: varchar('avatar_url', { length: 255 }),
|
||||||
userType: tinyint("user_type"),
|
userType: tinyint('user_type'),
|
||||||
status: tinyint().default(0).notNull(),
|
status: tinyint().default(0).notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.userId], name: "sys_user_user_id"}),
|
primaryKey({ columns: [table.userId], name: 'sys_user_user_id' }),
|
||||||
unique("uniq_username").on(table.username),
|
unique('uniq_username').on(table.username),
|
||||||
unique("uniq_email").on(table.email),
|
unique('uniq_email').on(table.email),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysUserAuth = mysqlTable("sys_user_auth", {
|
export const sysUserAuth = mysqlTable(
|
||||||
userId: bigint("user_id", { mode: "number" }).notNull(),
|
'sys_user_auth',
|
||||||
passwordHash: varchar("password_hash", { length: 255 }).notNull(),
|
{
|
||||||
passwordModified: datetime("password_modified", { mode: 'string'}).notNull(),
|
userId: bigint('user_id', { mode: 'number' }).notNull(),
|
||||||
passwordExpire: datetime("password_expire", { mode: 'string'}),
|
passwordHash: varchar('password_hash', { length: 255 }).notNull(),
|
||||||
|
passwordModified: datetime('password_modified', { mode: 'string' }).notNull(),
|
||||||
|
passwordExpire: datetime('password_expire', { mode: 'string' }),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [primaryKey({ columns: [table.userId], name: 'sys_user_auth_user_id' })],
|
||||||
primaryKey({ columns: [table.userId], name: "sys_user_auth_user_id"}),
|
);
|
||||||
]);
|
|
||||||
|
|
||||||
export const sysUserAuthHistory = mysqlTable("sys_user_auth_history", {
|
export const sysUserAuthHistory = mysqlTable(
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
'sys_user_auth_history',
|
||||||
userId: bigint("user_id", { mode: "number" }).notNull(),
|
{
|
||||||
passwordHash: varchar("password_hash", { length: 255 }).notNull(),
|
id: bigint({ mode: 'number' }).notNull(),
|
||||||
modifiedAt: varchar("modified_at", { length: 255 }).notNull(),
|
userId: bigint('user_id', { mode: 'number' }).notNull(),
|
||||||
|
passwordHash: varchar('password_hash', { length: 255 }).notNull(),
|
||||||
|
modifiedAt: varchar('modified_at', { length: 255 }).notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [primaryKey({ columns: [table.id], name: 'sys_user_auth_history_id' })],
|
||||||
primaryKey({ columns: [table.id], name: "sys_user_auth_history_id"}),
|
);
|
||||||
]);
|
|
||||||
|
|
||||||
export const sysUserFieldDefinition = mysqlTable("sys_user_field_definition", {
|
export const sysUserFieldDefinition = mysqlTable(
|
||||||
fieldId: bigint("field_id", { mode: "number" }).autoincrement().notNull(),
|
'sys_user_field_definition',
|
||||||
|
{
|
||||||
|
fieldId: bigint('field_id', { mode: 'number' }).notNull(),
|
||||||
version: int().default(0).notNull(),
|
version: int().default(0).notNull(),
|
||||||
fieldName: varchar("field_name", { length: 255 }).notNull(),
|
fieldName: varchar('field_name', { length: 255 }).notNull(),
|
||||||
fieldKey: varchar("field_key", { length: 255 }).notNull(),
|
fieldKey: varchar('field_key', { length: 255 }).notNull(),
|
||||||
fieldType: tinyint("field_type").notNull(),
|
fieldType: tinyint('field_type').notNull(),
|
||||||
dictModule: int("dict_module"),
|
dictModule: int('dict_module'),
|
||||||
isRequired: tinyint("is_required").default(0).notNull(),
|
isRequired: tinyint('is_required').default(0).notNull(),
|
||||||
limit: int(),
|
limit: int(),
|
||||||
description: varchar({ length: 255 }),
|
description: varchar({ length: 255 }),
|
||||||
defaultValue: varchar("default_value", { length: 255 }),
|
defaultValue: varchar('default_value', { length: 255 }),
|
||||||
defaultOptions: varchar("default_options", { length: 255 }),
|
defaultOptions: varchar('default_options', { length: 255 }),
|
||||||
sort: int().default(0).notNull(),
|
sort: int().default(0).notNull(),
|
||||||
status: int().notNull(),
|
status: int().notNull(),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.fieldId], name: "sys_user_field_definition_field_id"}),
|
primaryKey({ columns: [table.fieldId], name: 'sys_user_field_definition_field_id' }),
|
||||||
unique("uniq_field_name").on(table.fieldName),
|
unique('uniq_field_name').on(table.fieldName),
|
||||||
unique("uniq_field_key").on(table.fieldKey),
|
unique('uniq_field_key').on(table.fieldKey),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysUserFieldValue = mysqlTable("sys_user_field_value", {
|
export const sysUserFieldValue = mysqlTable(
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
'sys_user_field_value',
|
||||||
userId: bigint("user_id", { mode: "number" }).notNull(),
|
{
|
||||||
fieldId: int("field_id").notNull(),
|
id: bigint({ mode: 'number' }).notNull(),
|
||||||
|
userId: bigint('user_id', { mode: 'number' }).notNull(),
|
||||||
|
fieldId: int('field_id').notNull(),
|
||||||
value: varchar({ length: 4096 }),
|
value: varchar({ length: 4096 }),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.id], name: "sys_user_field_value_id"}),
|
primaryKey({ columns: [table.id], name: 'sys_user_field_value_id' }),
|
||||||
unique("uniq_user_field").on(table.userId, table.fieldId),
|
unique('uniq_user_field').on(table.userId, table.fieldId),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
export const sysUserProfile = mysqlTable("sys_user_profile", {
|
export const sysUserProfile = mysqlTable(
|
||||||
id: bigint({ mode: "number" }).autoincrement().notNull(),
|
'sys_user_profile',
|
||||||
|
{
|
||||||
|
id: bigint({ mode: 'number' }).notNull(),
|
||||||
version: int().default(0).notNull(),
|
version: int().default(0).notNull(),
|
||||||
name: varchar({ length: 32 }).notNull(),
|
name: varchar({ length: 32 }).notNull(),
|
||||||
profileKey: varchar("profile_key", { length: 255 }).notNull(),
|
profileKey: varchar('profile_key', { length: 255 }).notNull(),
|
||||||
description: varchar({ length: 255 }),
|
description: varchar({ length: 255 }),
|
||||||
content: varchar({ length: 255 }),
|
content: varchar({ length: 255 }),
|
||||||
createdBy: bigint("created_by", { mode: "number" }).notNull(),
|
createdBy: bigint('created_by', { mode: 'number' }).notNull(),
|
||||||
updatedBy: bigint("updated_by", { mode: "number" }).notNull(),
|
updatedBy: bigint('updated_by', { mode: 'number' }).notNull(),
|
||||||
createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
createdAt: datetime('created_at', { mode: 'string' })
|
||||||
updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(),
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
|
updatedAt: datetime('updated_at', { mode: 'string' })
|
||||||
|
.default(sql`(CURRENT_TIMESTAMP)`)
|
||||||
|
.notNull(),
|
||||||
},
|
},
|
||||||
(table) => [
|
table => [
|
||||||
primaryKey({ columns: [table.id], name: "sys_user_profile_id"}),
|
primaryKey({ columns: [table.id], name: 'sys_user_profile_id' }),
|
||||||
unique("uniq_name").on(table.name),
|
unique('uniq_name').on(table.name),
|
||||||
unique("uniq_profile_key").on(table.profileKey),
|
unique('uniq_profile_key').on(table.profileKey),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
|
22
src/plugins/const/index.js
Normal file
22
src/plugins/const/index.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import fastifyPlugin from 'fastify-plugin';
|
||||||
|
async function constData(fastify, options) {
|
||||||
|
fastify.log.warn('Register CONSTDATA Plugin!');
|
||||||
|
|
||||||
|
const CONST = {
|
||||||
|
// 系统名称
|
||||||
|
SYSTEM_NAME: 'Fastify',
|
||||||
|
|
||||||
|
// 分布式锁前缀
|
||||||
|
DISTRIBUTED_LOCK_PREFIX: {
|
||||||
|
// 注册用户
|
||||||
|
REGISTER_USER: 'REGISTER_USER:',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fastify.decorate('const', CONST);
|
||||||
|
|
||||||
|
// 读取数据库基本信息
|
||||||
|
fastify.log.warn('Register CONSTDATA Complete!');
|
||||||
|
|
||||||
|
}
|
||||||
|
export default fastifyPlugin(constData);
|
@ -23,6 +23,13 @@ async function database(fastify, options) {
|
|||||||
// 启用此选项后,MySQL驱动程序将在接收 bigint 或其他大数值时,将其作为字符串返回,而不是作为JavaScript数字。
|
// 启用此选项后,MySQL驱动程序将在接收 bigint 或其他大数值时,将其作为字符串返回,而不是作为JavaScript数字。
|
||||||
// 这种处理方式可以避免JavaScript本身的数值精度限制问题,确保大数值在应用程序中保持精确。
|
// 这种处理方式可以避免JavaScript本身的数值精度限制问题,确保大数值在应用程序中保持精确。
|
||||||
bigNumberStrings: true,
|
bigNumberStrings: true,
|
||||||
|
|
||||||
|
// typeCast: function (field, next) {
|
||||||
|
// if (field.type === 'LONGLONG') { // 处理 BIGINT 类型
|
||||||
|
// return field.string(); // 强制转换为字符串
|
||||||
|
// }
|
||||||
|
// return next();
|
||||||
|
// }
|
||||||
});
|
});
|
||||||
// 暴露数据库
|
// 暴露数据库
|
||||||
const db = drizzle(pool);
|
const db = drizzle(pool);
|
||||||
@ -33,6 +40,8 @@ async function database(fastify, options) {
|
|||||||
fastify.decorate('db', db);
|
fastify.decorate('db', db);
|
||||||
|
|
||||||
// 读取数据库基本信息
|
// 读取数据库基本信息
|
||||||
fastify.log.warn('Register Database Complete! => DATABASE TABLES: ' + fastify.db.tableList.length);
|
fastify.log.warn(
|
||||||
|
'Register Database Complete! => DATABASE TABLES: ' + fastify.db.tableList.length,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
export default fastifyPlugin(database);
|
export default fastifyPlugin(database);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { hash } from 'bcrypt';
|
import { hash } from 'bcrypt';
|
||||||
import fastifyPlugin from "fastify-plugin";
|
import fastifyPlugin from 'fastify-plugin';
|
||||||
// 加密
|
// 加密
|
||||||
async function encryption(fastify, options) {
|
async function encryption(fastify, options) {
|
||||||
// 注册swagger插件(新版配置方式)
|
// 注册swagger插件(新版配置方式)
|
||||||
|
@ -1,51 +1,64 @@
|
|||||||
import fastifyPlugin from 'fastify-plugin';
|
import fastifyPlugin from 'fastify-plugin';
|
||||||
function errorHandler(fastify) {
|
function errorHandler(fastify) {
|
||||||
|
// 添加 404 处理器 (关键修改)
|
||||||
|
fastify.setNotFoundHandler((request, reply) => {
|
||||||
|
const error = new Error(`路由 ${request.url} 不存在`);
|
||||||
|
error.code = 'ROUTE_NOT_FOUND';
|
||||||
|
error.statusCode = 404;
|
||||||
|
return reply.code(404).send(error);
|
||||||
|
});
|
||||||
|
|
||||||
fastify.setErrorHandler((error, request, reply) => {
|
fastify.setErrorHandler((error, request, reply) => {
|
||||||
// 记录原始错误
|
// 记录原始错误
|
||||||
fastify.log.error(`[ErrorHandler] ${error.message}`, error);
|
// fastify.log.error(`[ErrorHandler] ${error.message}`, error);
|
||||||
|
|
||||||
|
console.log('AAAA1validation', error.validation);
|
||||||
|
console.log('AAAA2statusCode', error.statusCode);
|
||||||
|
console.log('AAAA3code', error.code);
|
||||||
|
console.log('AAAA4message', error.message);
|
||||||
|
|
||||||
// 保留AJV验证错误处理
|
// 保留AJV验证错误处理
|
||||||
if (error.validation) {
|
if (error.validation) {
|
||||||
console.log(error)
|
// 没有请求体
|
||||||
const bodyError = error.validation.find(e =>
|
const bodyError = error.validation.find(
|
||||||
|
e =>
|
||||||
e.keyword === 'type' ||
|
e.keyword === 'type' ||
|
||||||
e.keyword === 'required' && e.validationContext == 'body'
|
(e.keyword === 'required' && e.validationContext == 'body'),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (bodyError) {
|
if (bodyError) {
|
||||||
return reply.code(400).send({
|
return reply.code(400).send({
|
||||||
error: '请求体不能为空,请提供有效的JSON数据',
|
code: error.statusCode,
|
||||||
details: error.validation
|
codeString: error.code,
|
||||||
|
error: `请求体不能为空,请提供有效的JSON数据!`,
|
||||||
|
details: error.validation,
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
return reply.code(400).send({
|
||||||
|
code: error.statusCode,
|
||||||
|
codeString: error.code,
|
||||||
|
error: error.message,
|
||||||
|
details: error.validation,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return reply.code(400).send({
|
|
||||||
error: error.message,
|
|
||||||
details: error.validation
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用sensible的HTTP错误处理
|
// 使用sensible的HTTP错误处理
|
||||||
if (error.statusCode && error.statusCode >= 400) {
|
if (error.statusCode && error.statusCode >= 400) {
|
||||||
return reply
|
return reply.code(error.statusCode).send({
|
||||||
.code(error.statusCode)
|
code: error.statusCode,
|
||||||
.send({
|
codeString: error.code,
|
||||||
code: error.code || 'HTTP_ERROR',
|
error: error.message,
|
||||||
error: error.message
|
...(error.details && { details: error.details }),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理Fastify自动生成的404错误
|
|
||||||
if (error.code === 'FST_ERR_NOT_FOUND') {
|
|
||||||
return reply.code(404).send({
|
|
||||||
code: 'ROUTE_NOT_FOUND',
|
|
||||||
error: `路由 ${request.url} 不存在`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// 最终未处理错误(生产环境隐藏细节)
|
// 最终未处理错误(生产环境隐藏细节)
|
||||||
const isProduction = process.env.NODE_ENV === 'production';
|
const isProduction = process.env.NODE_ENV === 'production';
|
||||||
reply.code(500).send({
|
reply.code(500).send({
|
||||||
code: 'SERVER_ERROR',
|
code: '500',
|
||||||
error: isProduction ? '服务器内部错误' : error.message,
|
error: isProduction ? '服务器内部错误' : error.message,
|
||||||
...(!isProduction && { stack: error.stack })
|
...(!isProduction && { stack: error.stack }),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@ import database from '#plugins/database/index';
|
|||||||
import swagger from '#plugins/swagger/index';
|
import swagger from '#plugins/swagger/index';
|
||||||
import errorHandler from '#plugins/error/errorHandler';
|
import errorHandler from '#plugins/error/errorHandler';
|
||||||
import encryption from '#plugins/encryption/index';
|
import encryption from '#plugins/encryption/index';
|
||||||
|
import snowflake from '#plugins/snowflake/index';
|
||||||
|
import redis from '#plugins/redis/index';
|
||||||
|
import conseData from '#plugins/const/index';
|
||||||
|
|
||||||
async function plugin(fastify, opts) {
|
async function plugin(fastify, opts) {
|
||||||
fastify.log.warn('Register Global Plugin!');
|
fastify.log.warn('Register Global Plugin!');
|
||||||
@ -10,16 +13,19 @@ async function plugin(fastify, opts) {
|
|||||||
fastify.decorate('config', opts.config);
|
fastify.decorate('config', opts.config);
|
||||||
// 注册数据库
|
// 注册数据库
|
||||||
await fastify.register(database);
|
await fastify.register(database);
|
||||||
|
// 注册redis
|
||||||
|
await fastify.register(redis);
|
||||||
// 注册swagger
|
// 注册swagger
|
||||||
fastify.config.env === 'development' && await fastify.register(swagger);
|
fastify.config.env === 'development' && (await fastify.register(swagger));
|
||||||
// 注册加密工具
|
// 注册加密工具
|
||||||
await fastify.register(encryption);
|
await fastify.register(encryption);
|
||||||
|
// 注册雪花ID
|
||||||
|
await fastify.register(snowflake);
|
||||||
|
// 注册常量
|
||||||
|
await fastify.register(conseData);
|
||||||
// 注册错误处理工具
|
// 注册错误处理工具
|
||||||
await fastify.register(import('@fastify/sensible'));
|
await fastify.register(import('@fastify/sensible'));
|
||||||
fastify.register(errorHandler)
|
fastify.register(errorHandler);
|
||||||
|
|
||||||
fastify.log.warn('Register Global Plugin complete!');
|
fastify.log.warn('Register Global Plugin complete!');
|
||||||
}
|
}
|
||||||
|
31
src/plugins/redis/index.js
Normal file
31
src/plugins/redis/index.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import fastifyPlugin from 'fastify-plugin';
|
||||||
|
import { createClient } from 'redis';
|
||||||
|
async function redis(fastify, options) {
|
||||||
|
fastify.log.warn('Register Redis Plugin!');
|
||||||
|
const config = fastify.config.redis;
|
||||||
|
const redisConnect = createClient({
|
||||||
|
name: config.connectName,
|
||||||
|
username: config.username,
|
||||||
|
password: config.password,
|
||||||
|
database: config.database,
|
||||||
|
url: `redis://${config.username}:${config.password}@${config.host}:${config.port}/${config.database}`,
|
||||||
|
});
|
||||||
|
redisConnect.on('connect', async () => {
|
||||||
|
fastify.log.info(await redisConnect.set('SI HI', 'YuHeng'));
|
||||||
|
});
|
||||||
|
|
||||||
|
redisConnect.on('error', (err) => {
|
||||||
|
console.log(err)
|
||||||
|
fastify.log.error('Redis error: ', err);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 连接到 Redis
|
||||||
|
await redisConnect.connect();
|
||||||
|
|
||||||
|
fastify.decorate('redis', redisConnect);
|
||||||
|
|
||||||
|
// 读取数据库基本信息
|
||||||
|
fastify.log.warn('Register Redis Complete! => REDIS SI HI: ' + await redisConnect.get('SI HI'));
|
||||||
|
|
||||||
|
}
|
||||||
|
export default fastifyPlugin(redis);
|
73
src/plugins/snowflake/index.js
Normal file
73
src/plugins/snowflake/index.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import fastifyPlugin from 'fastify-plugin';
|
||||||
|
// 雪花ID
|
||||||
|
class Snowflake {
|
||||||
|
constructor({ workerId = 0n, dataCenterId = 0n, sequence = 0n } = {}) {
|
||||||
|
this.workerIdBits = 3n; // 工作节点ID位数
|
||||||
|
this.dataCenterIdBits = 6n; // 数据中心ID位数
|
||||||
|
this.sequenceBits = 12n; // 序列号位数
|
||||||
|
|
||||||
|
this.maxWorkerId = -1n ^ (-1n << this.workerIdBits);
|
||||||
|
this.maxDataCenterId = -1n ^ (-1n << this.dataCenterIdBits);
|
||||||
|
|
||||||
|
this.workerIdShift = this.sequenceBits;
|
||||||
|
this.dataCenterIdShift = this.sequenceBits + this.workerIdBits;
|
||||||
|
this.timestampShift = this.sequenceBits + this.workerIdBits + this.dataCenterIdBits;
|
||||||
|
this.sequenceMask = -1n ^ (-1n << this.sequenceBits);
|
||||||
|
|
||||||
|
this.epoch = 1577836800000n; // 2020-01-01 00:00:00 UTC
|
||||||
|
|
||||||
|
this.lastTimestamp = -1n;
|
||||||
|
this.sequence = sequence;
|
||||||
|
this.workerId = BigInt(workerId);
|
||||||
|
this.dataCenterId = BigInt(dataCenterId);
|
||||||
|
|
||||||
|
if (this.workerId > this.maxWorkerId || this.workerId < 0n) {
|
||||||
|
throw new Error(`Worker ID must be between 0 and ${this.maxWorkerId}`);
|
||||||
|
}
|
||||||
|
if (this.dataCenterId > this.maxDataCenterId || this.dataCenterId < 0n) {
|
||||||
|
throw new Error(`Data Center ID must be between 0 and ${this.maxDataCenterId}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nextId() {
|
||||||
|
let timestamp = BigInt(Date.now());
|
||||||
|
|
||||||
|
if (timestamp < this.lastTimestamp) {
|
||||||
|
throw new Error('Clock moved backwards!');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.lastTimestamp === timestamp) {
|
||||||
|
this.sequence = (this.sequence + 1n) & this.sequenceMask;
|
||||||
|
if (this.sequence === 0n) {
|
||||||
|
while (timestamp <= this.lastTimestamp) {
|
||||||
|
timestamp = BigInt(Date.now());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.sequence = 0n;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lastTimestamp = timestamp;
|
||||||
|
|
||||||
|
return (
|
||||||
|
((timestamp - this.epoch) << this.timestampShift) |
|
||||||
|
(this.dataCenterId << this.dataCenterIdShift) |
|
||||||
|
(this.workerId << this.workerIdShift) |
|
||||||
|
this.sequence
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function snowflake(fastify, options) {
|
||||||
|
// 注册swagger插件(新版配置方式)
|
||||||
|
fastify.log.warn('Register Snowflake Plugin!');
|
||||||
|
// 初始化生成器(工作节点ID范围 0-31)
|
||||||
|
const generator = new Snowflake({
|
||||||
|
workerId: BigInt(fastify.config.deviceInfo.machineId), // 工作节点ID
|
||||||
|
dataCenterId: BigInt(fastify.config.deviceInfo.dataCenterId), // 数据中心ID
|
||||||
|
});
|
||||||
|
// 初始化时注册插件
|
||||||
|
fastify.decorate('snowflake', () => generator.nextId().toString());
|
||||||
|
fastify.log.warn('Register Snowflake complete!');
|
||||||
|
}
|
||||||
|
|
||||||
|
export default fastifyPlugin(snowflake);
|
@ -1,6 +1,6 @@
|
|||||||
import fastifyPlugin from "fastify-plugin";
|
import fastifyPlugin from 'fastify-plugin';
|
||||||
import fastifySwagger from "@fastify/swagger";
|
import fastifySwagger from '@fastify/swagger';
|
||||||
import fastifySwaggerUI from "@fastify/swagger-ui";
|
import fastifySwaggerUI from '@fastify/swagger-ui';
|
||||||
async function swagger(fastify, options) {
|
async function swagger(fastify, options) {
|
||||||
// 注册swagger插件(新版配置方式)
|
// 注册swagger插件(新版配置方式)
|
||||||
fastify.log.warn('Register Swagger Plugin!');
|
fastify.log.warn('Register Swagger Plugin!');
|
||||||
@ -9,18 +9,20 @@ async function swagger(fastify, options) {
|
|||||||
info: {
|
info: {
|
||||||
title: `${fastify.config.serviceName} API`,
|
title: `${fastify.config.serviceName} API`,
|
||||||
version: fastify.config.version,
|
version: fastify.config.version,
|
||||||
description: fastify.config.description
|
description: fastify.config.description,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// staticCSP: true, // 启用安全策略
|
// staticCSP: true, // 启用安全策略
|
||||||
exposeRoute: true // 自动暴露路由
|
exposeRoute: true, // 自动暴露路由
|
||||||
});
|
});
|
||||||
// 注册swagger-ui界面 (新增部分)
|
// 注册swagger-ui界面 (新增部分)
|
||||||
await fastify.register(fastifySwaggerUI, {
|
await fastify.register(fastifySwaggerUI, {
|
||||||
routePrefix: '/docs',
|
routePrefix: '/docs',
|
||||||
});
|
});
|
||||||
fastify.log.warn('Register Swagger complete!');
|
fastify.log.warn('Register Swagger complete!');
|
||||||
fastify.log.info(`Swagger documentation available at http://127.0.0.1:${fastify.config.server.port}/docs`);
|
fastify.log.info(
|
||||||
|
`Swagger documentation available at http://127.0.0.1:${fastify.config.server.port}/docs`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default fastifyPlugin(swagger);
|
export default fastifyPlugin(swagger);
|
@ -1,29 +1,18 @@
|
|||||||
import { testSchema } from "#src/schema/test.schema";
|
import { testSchema } from '#src/schema/test.schema';
|
||||||
import { testService } from "#src/services/test.service";
|
import { testService } from '#src/services/test.service';
|
||||||
import userRoute from "#routes/user.route";
|
import userRoute from '#routes/user.route';
|
||||||
|
|
||||||
export default async function routes(fastify, options) {
|
export default async function routes(fastify, options) {
|
||||||
// 定义一个GET请求的路由,路径为根路径
|
// 定义一个GET请求的路由,路径为根路径
|
||||||
fastify.get('/', async (request, reply) => {
|
fastify.get('/', async (request, reply) => {
|
||||||
fastify.log.info(fastify.config);
|
fastify.log.info(fastify.config);
|
||||||
return fastify.config;
|
return fastify.config.deviceInfo;
|
||||||
});
|
});
|
||||||
fastify.get('/test', testSchema, testService);
|
fastify.get('/test', testSchema, testService);
|
||||||
|
|
||||||
|
|
||||||
// 注册子路由
|
// 注册子路由
|
||||||
fastify.register(userRoute, { prefix: '/user' });
|
fastify.register(userRoute, { prefix: '/user' });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fastify.route({
|
fastify.route({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: '/login',
|
url: '/login',
|
||||||
@ -31,15 +20,14 @@ export default async function routes(fastify, options) {
|
|||||||
tags: ['认证体系'], // 接口分组
|
tags: ['认证体系'], // 接口分组
|
||||||
summary: '用户登录',
|
summary: '用户登录',
|
||||||
description: '使用用户名密码进行身份认证',
|
description: '使用用户名密码进行身份认证',
|
||||||
security: [{
|
security: [{}],
|
||||||
}],
|
|
||||||
body: {
|
body: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['username', 'password'],
|
required: ['username', 'password'],
|
||||||
properties: {
|
properties: {
|
||||||
username: { type: 'string', default: 'user1' },
|
username: { type: 'string', default: 'user1' },
|
||||||
password: { type: 'string', default: '123456' }
|
password: { type: 'string', default: '123456' },
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
response: {
|
response: {
|
||||||
200: {
|
200: {
|
||||||
@ -47,22 +35,22 @@ export default async function routes(fastify, options) {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
token: { type: 'string' },
|
token: { type: 'string' },
|
||||||
expire: { type: 'number' }
|
expire: { type: 'number' },
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
401: {
|
401: {
|
||||||
description: '认证失败',
|
description: '认证失败',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
code: { type: 'number', enum: [401] },
|
code: { type: 'number', enum: [401] },
|
||||||
error: { type: 'string' }
|
error: { type: 'string' },
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
handler: async (req, reply) => {
|
handler: async (req, reply) => {
|
||||||
// ...业务逻辑...
|
// ...业务逻辑...
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 输出路由树
|
// 输出路由树
|
||||||
|
@ -1,20 +1,10 @@
|
|||||||
import { userDefaultSchema, userRegisterSchema } from "#src/schema/user.schema";
|
import { userDefaultSchema, userRegisterSchema } from '#src/schema/user.schema';
|
||||||
import { userDefaultService, } from "#src/services/user.service";
|
import { userDefaultService } from '#src/services/user.service';
|
||||||
import {userRegisterService} from "#src/services/user/user.service"
|
import { userRegisterService } from '#src/services/user/user.service';
|
||||||
|
|
||||||
export default async function userRoute(fastify, options) {
|
export default async function userRoute(fastify, options) {
|
||||||
|
|
||||||
// 新用户注册
|
// 新用户注册
|
||||||
fastify.post('/register', {
|
fastify.post('/register', { schema: userRegisterSchema }, userRegisterService);
|
||||||
schema: userRegisterSchema,
|
|
||||||
}, userRegisterService);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fastify.get('/', userDefaultSchema, userDefaultService);
|
fastify.get('/', userDefaultSchema, userDefaultService);
|
||||||
/**
|
/**
|
||||||
@ -62,6 +52,4 @@ export default async function userRoute(fastify, options) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// 获取拓展字段列表
|
// 获取拓展字段列表
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import { isTrim } from "#utils/ajv/method";
|
import { isTrim } from '#utils/ajv/method';
|
||||||
import { is } from "drizzle-orm";
|
import { is } from 'drizzle-orm';
|
||||||
|
|
||||||
// 原子schema定义
|
// 原子schema定义
|
||||||
export const username = {
|
export const username = {
|
||||||
@ -12,8 +12,8 @@ export const username = {
|
|||||||
errorMessage: {
|
errorMessage: {
|
||||||
minLength: '用户名至少需要4个字符',
|
minLength: '用户名至少需要4个字符',
|
||||||
maxLength: '用户名不能超过20个字符',
|
maxLength: '用户名不能超过20个字符',
|
||||||
pattern: '必须全部小写,且只能包含字母、数字和下划线,并以字母开头'
|
pattern: '必须全部小写,且只能包含字母、数字和下划线,并以字母开头',
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const email = {
|
export const email = {
|
||||||
@ -22,8 +22,8 @@ export const email = {
|
|||||||
maxLength: 128,
|
maxLength: 128,
|
||||||
errorMessage: {
|
errorMessage: {
|
||||||
format: '邮箱格式不正确',
|
format: '邮箱格式不正确',
|
||||||
maxLength: '邮箱不能超过128个字符'
|
maxLength: '邮箱不能超过128个字符',
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const password = {
|
export const password = {
|
||||||
@ -34,6 +34,6 @@ export const password = {
|
|||||||
errorMessage: {
|
errorMessage: {
|
||||||
minLength: '密码长度至少8位',
|
minLength: '密码长度至少8位',
|
||||||
maxLength: '密码不能超过128个字符',
|
maxLength: '密码不能超过128个字符',
|
||||||
pattern: '必须包含至少一个小写字母、一个大写字母、一个数字和一个特殊字符'
|
pattern: '必须包含至少一个小写字母、一个大写字母、一个数字和一个特殊字符',
|
||||||
}
|
},
|
||||||
};
|
};
|
@ -7,8 +7,8 @@ export const testSchema = {
|
|||||||
required: ['username', 'password'],
|
required: ['username', 'password'],
|
||||||
properties: {
|
properties: {
|
||||||
username: { type: 'string', default: 'user1' },
|
username: { type: 'string', default: 'user1' },
|
||||||
password: { type:'string', default: '123456' }
|
password: { type: 'string', default: '123456' },
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
response: {
|
response: {
|
||||||
200: {
|
200: {
|
||||||
@ -16,16 +16,16 @@ export const testSchema = {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
token: { type: 'string' },
|
token: { type: 'string' },
|
||||||
expire: { type: 'number' }
|
expire: { type: 'number' },
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
401: {
|
401: {
|
||||||
description: '认证失败',
|
description: '认证失败',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
code: { type: 'number', enum: [401] },
|
code: { type: 'number', enum: [401] },
|
||||||
error: { type:'string' }
|
error: { type: 'string' },
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import { email, username, password } from "#schema/atomSchema";
|
import { email, username, password } from '#schema/atomSchema';
|
||||||
// 默认schema
|
// 默认schema
|
||||||
export const userDefaultSchema = {
|
export const userDefaultSchema = {};
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新用户注册
|
// 新用户注册
|
||||||
export const userRegisterSchema = {
|
export const userRegisterSchema = {
|
||||||
@ -22,18 +20,67 @@ export const userRegisterSchema = {
|
|||||||
properties: {
|
properties: {
|
||||||
username,
|
username,
|
||||||
email,
|
email,
|
||||||
password
|
password,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
response: {
|
response: {
|
||||||
201: {
|
201: {
|
||||||
description: '注册成功',
|
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
userId: { type: 'number', example: 1001 },
|
code: { type: 'number' },
|
||||||
|
data: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
username: { type: 'string' },
|
username: { type: 'string' },
|
||||||
email: { type: 'string' },
|
email: { type: 'string' },
|
||||||
createdAt: { type: 'string', format: 'date-time' }
|
userId: {
|
||||||
|
type: 'string',
|
||||||
|
examples: ["692397256422330400"]
|
||||||
|
},
|
||||||
|
pid: {
|
||||||
|
type: 'string',
|
||||||
|
enum: [0] // 固定值
|
||||||
|
},
|
||||||
|
phone: {
|
||||||
|
type: ['string', 'null'],
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
avatarUrl: {
|
||||||
|
type: ['string', 'null'],
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
userType: {
|
||||||
|
type: ['number', 'null'],
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
type: 'number',
|
||||||
|
enum: [0, 1] // 假设 0-正常 1-禁用
|
||||||
|
},
|
||||||
|
createdBy: {
|
||||||
|
type: 'number',
|
||||||
|
enum: [0] // 个人注册固定值
|
||||||
|
},
|
||||||
|
updatedBy: {
|
||||||
|
type: ['number', 'null'],
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'date-time'
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'date-time'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
required: [
|
||||||
|
'username', 'email', 'userId', 'pid',
|
||||||
|
'status', 'createdBy', 'createdAt', 'updatedAt'
|
||||||
|
],
|
||||||
|
additionalProperties: false // 严格模式
|
||||||
|
},
|
||||||
|
message: { type: 'string' }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
400: {
|
400: {
|
||||||
@ -41,17 +88,17 @@ export const userRegisterSchema = {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
code: { type: 'number', enum: [400] },
|
code: { type: 'number', enum: [400] },
|
||||||
error: { type: 'string' }
|
error: { type: 'string' },
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
409: {
|
409: {
|
||||||
description: '用户名/邮箱已存在',
|
description: '用户名/邮箱已存在',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
code: { type: 'number', enum: [409] },
|
code: { type: 'number', enum: [409] },
|
||||||
error: { type: 'string' }
|
error: { type: 'string' },
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
security: [{}] // 不需要认证
|
},
|
||||||
|
},
|
||||||
|
security: [{}], // 不需要认证
|
||||||
};
|
};
|
@ -1,6 +1,6 @@
|
|||||||
export async function testService(request, reply) {
|
export async function testService(request, reply) {
|
||||||
this.log.warn('testService');
|
this.log.warn('testService');
|
||||||
return {
|
return {
|
||||||
test: 'test'
|
test: 'test',
|
||||||
}
|
};
|
||||||
}
|
}
|
@ -25,6 +25,6 @@ export async function userRegisterService(request, reply) {
|
|||||||
userId: newUser.id,
|
userId: newUser.id,
|
||||||
username: newUser.username,
|
username: newUser.username,
|
||||||
email: newUser.email,
|
email: newUser.email,
|
||||||
createdAt: newUser.created_at.toISOString()
|
createdAt: newUser.created_at.toISOString(),
|
||||||
});
|
});
|
||||||
}
|
}
|
@ -1,24 +1,32 @@
|
|||||||
import { sysUser } from "#entity";
|
import { sysUser } from '#entity';
|
||||||
import { or, eq } from "drizzle-orm";
|
import { or, eq } from 'drizzle-orm';
|
||||||
// 查重用户名和邮箱
|
// 查重用户名和邮箱
|
||||||
export async function checkExistsUsernameAndEmail(username, email) {
|
export async function checkExistsUsernameAndEmail(username, email) {
|
||||||
const result = await this.db
|
const result = await this.db
|
||||||
.select()
|
.select()
|
||||||
.from(sysUser)
|
.from(sysUser)
|
||||||
.where(or(
|
.where(
|
||||||
|
or(
|
||||||
eq(sysUser.username, username), // 明确指定字段比较
|
eq(sysUser.username, username), // 明确指定字段比较
|
||||||
eq(sysUser.email, email)
|
eq(sysUser.email, email),
|
||||||
));
|
),
|
||||||
|
);
|
||||||
|
|
||||||
return result.length > 0; // 正确判断结果集是否为空
|
return result.length > 0; // 正确判断结果集是否为空
|
||||||
}
|
}
|
||||||
// 个人注册账户
|
// 个人注册账户
|
||||||
export async function registerAccountForMyself(userData) {
|
export async function registerAccountForMyself(userData) {
|
||||||
const [newUser] = await this.db.insert(sysUser)
|
const result = await this.db.insert(sysUser).values({
|
||||||
.values({
|
|
||||||
username: userData.username,
|
username: userData.username,
|
||||||
email: userData.email,
|
email: userData.email,
|
||||||
password: userData.password, // 实际应存储加密后的密码
|
password: userData.password, // 实际应存储加密后的密码
|
||||||
|
userId: userData.userId, // 使用雪花算法生成唯一ID
|
||||||
|
pid: 0, // 个人注册账户父节点ID为0
|
||||||
|
createdBy: 0, // 个人注册账户创建者ID为0
|
||||||
})
|
})
|
||||||
|
const [newUser] = await this.db
|
||||||
|
.select()
|
||||||
|
.from(sysUser)
|
||||||
|
.where(eq(sysUser.userId, userData.userId));
|
||||||
return newUser;
|
return newUser;
|
||||||
}
|
}
|
@ -1,23 +1,59 @@
|
|||||||
import { checkExistsUsernameAndEmail, registerAccountForMyself } from "#services/user/user.db";
|
import { checkExistsUsernameAndEmail, registerAccountForMyself } from '#services/user/user.db';
|
||||||
// 新用户注册
|
// 新用户注册
|
||||||
export async function userRegisterService(request, reply) {
|
export async function userRegisterService(request, reply) {
|
||||||
// 1. 获取已验证的参数
|
// 1. 获取已验证的参数
|
||||||
const { username, email, password } = request.body;
|
const { username, email, password } = request.body;
|
||||||
|
|
||||||
|
// 2. 分布式锁
|
||||||
|
// 生成分布式锁 key
|
||||||
|
const lockKey = `${this.const.DISTRIBUTED_LOCK_PREFIX.REGISTER_USER}${username}:${email}`;
|
||||||
|
|
||||||
|
const userId = this.snowflake();
|
||||||
|
const lockIdentifier = userId;
|
||||||
|
let renewInterval;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 尝试获取分布式锁(NX: 仅当key不存在时设置,EX: 过期时间5秒)
|
||||||
|
const locked = await this.redis.SET(lockKey, lockIdentifier, { NX: true, EX: 5 });
|
||||||
|
if (!locked) {
|
||||||
|
throw this.httpErrors.tooManyRequests('操作正在进行,请稍后重试');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动续锁定时器(每3秒续期一次)
|
||||||
|
renewInterval = setInterval(async () => {
|
||||||
|
const currentVal = await this.redis.GET(lockKey);
|
||||||
|
if (currentVal === lockIdentifier) {
|
||||||
|
await this.redis.EXPIRE(lockKey, 5); // 重置过期时间
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 3000));
|
||||||
// 2. 检测用户名和邮箱是否已存在
|
// 2. 检测用户名和邮箱是否已存在
|
||||||
const exists = await checkExistsUsernameAndEmail.call(this, username, email);
|
const exists = await checkExistsUsernameAndEmail.call(this, username, email);
|
||||||
if (exists) {
|
if (exists) {
|
||||||
throw reply.code(409).send({
|
throw this.httpErrors.conflict('用户名或邮箱已存在');
|
||||||
code: 'USER_EXISTS',
|
|
||||||
message: '用户名或邮箱已存在'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 注册用户
|
// 3. 注册用户
|
||||||
await registerAccountForMyself.call(this,{
|
const newUser = await registerAccountForMyself.call(this, {
|
||||||
username,
|
username,
|
||||||
email,
|
email,
|
||||||
password: await this.hash(password)
|
password: await this.hash(password),
|
||||||
|
userId
|
||||||
});
|
});
|
||||||
|
reply.code(201) // <-- 关键修改
|
||||||
|
.send({
|
||||||
|
code: 201,
|
||||||
|
data: newUser,
|
||||||
|
message: '用户创建成功'
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
if (renewInterval) clearInterval(renewInterval);
|
||||||
|
// 释放锁逻辑(移除Lua脚本)
|
||||||
|
const currentVal = await this.redis.GET(lockKey);
|
||||||
|
if (currentVal === lockIdentifier) {
|
||||||
|
await this.redis.DEL(lockKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,16 +1,16 @@
|
|||||||
import ajvErrors from "ajv-errors";
|
import ajvErrors from 'ajv-errors';
|
||||||
import { isLowerCase, isTrim } from "#utils/ajv/method";
|
import { isLowerCase, isTrim } from '#utils/ajv/method';
|
||||||
export const ajvConfig = {
|
export const ajvConfig = {
|
||||||
customOptions: {
|
customOptions: {
|
||||||
removeAdditional: true, // 自动删除schema未定义的额外属性
|
removeAdditional: true, // 自动删除schema未定义的额外属性
|
||||||
useDefaults: true, // 使用schema中定义的默认值填充缺失字段
|
useDefaults: true, // 使用schema中定义的默认值填充缺失字段
|
||||||
coerceTypes: true, // 自动转换数据类型(如字符串"123"→数字123)
|
coerceTypes: true, // 自动转换数据类型(如字符串"123"→数字123)
|
||||||
allErrors: true, // 收集所有验证错误(不止第一个错误)
|
allErrors: true, // 收集所有验证错误(不止第一个错误)
|
||||||
allowUnionTypes: true // 允许联合类型(如 type: ["string", "number"])
|
allowUnionTypes: true, // 允许联合类型(如 type: ["string", "number"])
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
ajvErrors, // 支持自定义错误消息
|
ajvErrors, // 支持自定义错误消息
|
||||||
isLowerCase, // 自定义验证:强制小写(如用户名)
|
isLowerCase, // 自定义验证:强制小写(如用户名)
|
||||||
isTrim, // 自定义验证:自动trim字符串
|
isTrim, // 自定义验证:自动trim字符串
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
|
@ -14,8 +14,6 @@ import Ajv from 'ajv';
|
|||||||
// ajv错误消息回应
|
// ajv错误消息回应
|
||||||
import ajvErrors from 'ajv-errors';
|
import ajvErrors from 'ajv-errors';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// // 将字符串转化为全小写
|
// // 将字符串转化为全小写
|
||||||
// export function isLowerCase(ajv){
|
// export function isLowerCase(ajv){
|
||||||
// ajv.addKeyword({
|
// ajv.addKeyword({
|
||||||
@ -63,19 +61,17 @@ import ajvErrors from 'ajv-errors';
|
|||||||
export function isLowerCase(ajv) {
|
export function isLowerCase(ajv) {
|
||||||
ajv.addKeyword({
|
ajv.addKeyword({
|
||||||
keyword: 'isLowerCase',
|
keyword: 'isLowerCase',
|
||||||
validate: (schema, data) => typeof data === 'string' && data === data.toLowerCase()
|
validate: (schema, data) => typeof data === 'string' && data === data.toLowerCase(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isTrim(ajv) {
|
export function isTrim(ajv) {
|
||||||
ajv.addKeyword({
|
ajv.addKeyword({
|
||||||
keyword: 'isTrim',
|
keyword: 'isTrim',
|
||||||
validate: (schema, data) => typeof data === 'string' && data === data.trim()
|
validate: (schema, data) => typeof data === 'string' && data === data.trim(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 给fastify添加自定义的参数校验规则
|
// 给fastify添加自定义的参数校验规则
|
||||||
function customAjv(fastify, options) {
|
function customAjv(fastify, options) {
|
||||||
// 创建一个新的 AJV 实例
|
// 创建一个新的 AJV 实例
|
||||||
@ -85,7 +81,7 @@ function customAjv(fastify, options){
|
|||||||
useDefaults: true,
|
useDefaults: true,
|
||||||
coerceTypes: true,
|
coerceTypes: true,
|
||||||
// jsonPointers: true,
|
// jsonPointers: true,
|
||||||
allErrors: true
|
allErrors: true,
|
||||||
});
|
});
|
||||||
ajvErrors(ajv);
|
ajvErrors(ajv);
|
||||||
isLowerCase(ajv);
|
isLowerCase(ajv);
|
||||||
@ -94,4 +90,3 @@ function customAjv(fastify, options){
|
|||||||
return ajv.compile(schema);
|
return ajv.compile(schema);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import config from '#config/index';
|
export default function loggerConfig(config) {
|
||||||
export default {
|
return {
|
||||||
// 日志级别顺序(从高到低):
|
// 日志级别顺序(从高到低):
|
||||||
// fatal(致命) > error(错误) > warn(警告) > info(信息) > debug(调试) > trace(追踪)
|
// fatal(致命) > error(错误) > warn(警告) > info(信息) > debug(调试) > trace(追踪)
|
||||||
// 高级别日志会包含低级别日志(设置warn会包含error和fatal)
|
// 高级别日志会包含低级别日志(设置warn会包含error和fatal)
|
||||||
level: config.logger.level,
|
level: config.logger.level,
|
||||||
|
base: { machineId: config.deviceInfo.machineId },
|
||||||
transport: {
|
transport: {
|
||||||
// 修正为独立的多传输配置
|
// 修正为独立的多传输配置
|
||||||
targets: [
|
targets: [
|
||||||
@ -13,7 +14,7 @@ export default {
|
|||||||
options: {
|
options: {
|
||||||
colorize: true,
|
colorize: true,
|
||||||
translateTime: 'yyyy-mm-dd HH:MM:ss',
|
translateTime: 'yyyy-mm-dd HH:MM:ss',
|
||||||
ignore: 'pid,hostname,reqId,res,responseTime',
|
ignore: 'hostname,reqId,',
|
||||||
// 可用字段列表:
|
// 可用字段列表:
|
||||||
// - pid: 进程ID
|
// - pid: 进程ID
|
||||||
// - hostname: 主机名
|
// - hostname: 主机名
|
||||||
@ -41,3 +42,4 @@ export default {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
@ -2,6 +2,8 @@ const text = '> Si Hi <'; // 需要显示的文本
|
|||||||
const terminalWidth = process.stdout.columns || 100;
|
const terminalWidth = process.stdout.columns || 100;
|
||||||
const padding = Math.max(0, Math.floor((terminalWidth - text.length * 1.5) / 2)); // 中文每个字占2字符宽度
|
const padding = Math.max(0, Math.floor((terminalWidth - text.length * 1.5) / 2)); // 中文每个字占2字符宽度
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
|
|
||||||
|
export default function echo() {
|
||||||
console.log(
|
console.log(
|
||||||
'\x1B[48;5;0m%s\x1B[0m', // 灰色背景
|
'\x1B[48;5;0m%s\x1B[0m', // 灰色背景
|
||||||
'\x1B[32;5;12m\x1B[1m ' + // 白色加粗
|
'\x1B[32;5;12m\x1B[1m ' + // 白色加粗
|
||||||
@ -10,3 +12,4 @@ console.log(
|
|||||||
'-'.repeat(padding) +
|
'-'.repeat(padding) +
|
||||||
' \x1B[0m', // 重置样式
|
' \x1B[0m', // 重置样式
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
26
yuheng.sql
26
yuheng.sql
@ -9,7 +9,7 @@ CREATE TABLE `sys_dict` (
|
|||||||
`sort` int NOT NULL DEFAULT 0 COMMENT '排序',
|
`sort` int NOT NULL DEFAULT 0 COMMENT '排序',
|
||||||
`status` int NOT NULL COMMENT '状态 0启用 1禁用',
|
`status` int NOT NULL COMMENT '状态 0启用 1禁用',
|
||||||
`created_by` bigint NOT NULL COMMENT '创建人',
|
`created_by` bigint NOT NULL COMMENT '创建人',
|
||||||
`updated_by` bigint NOT NULL COMMENT '更新人',
|
`updated_by` bigint NULL COMMENT '更新人',
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
@ -26,7 +26,7 @@ CREATE TABLE `sys_organization` (
|
|||||||
`sort` int NOT NULL DEFAULT 0 COMMENT '排序',
|
`sort` int NOT NULL DEFAULT 0 COMMENT '排序',
|
||||||
`status` int NOT NULL COMMENT '状态',
|
`status` int NOT NULL COMMENT '状态',
|
||||||
`created_by` bigint NOT NULL COMMENT '创建人',
|
`created_by` bigint NOT NULL COMMENT '创建人',
|
||||||
`updated_by` bigint NOT NULL COMMENT '更新人',
|
`updated_by` bigint NULL COMMENT '更新人',
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`org_id`),
|
PRIMARY KEY (`org_id`),
|
||||||
@ -43,7 +43,7 @@ CREATE TABLE `sys_organization_manager` (
|
|||||||
`status` int NOT NULL COMMENT '状态',
|
`status` int NOT NULL COMMENT '状态',
|
||||||
`description` varchar(255) NULL,
|
`description` varchar(255) NULL,
|
||||||
`created_by` bigint NOT NULL COMMENT '创建人',
|
`created_by` bigint NOT NULL COMMENT '创建人',
|
||||||
`updated_by` bigint NOT NULL COMMENT '更新人',
|
`updated_by` bigint NULL COMMENT '更新人',
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
@ -64,7 +64,7 @@ CREATE TABLE `sys_permission` (
|
|||||||
`sort` int NOT NULL DEFAULT 0 COMMENT '排序',
|
`sort` int NOT NULL DEFAULT 0 COMMENT '排序',
|
||||||
`status` int NOT NULL COMMENT '状态',
|
`status` int NOT NULL COMMENT '状态',
|
||||||
`created_by` bigint NOT NULL COMMENT '创建人',
|
`created_by` bigint NOT NULL COMMENT '创建人',
|
||||||
`updated_by` bigint NOT NULL COMMENT '更新人',
|
`updated_by` bigint NULL COMMENT '更新人',
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`perm_id`),
|
PRIMARY KEY (`perm_id`),
|
||||||
@ -77,7 +77,7 @@ CREATE TABLE `sys_re_role_permission` (
|
|||||||
`role_id` BIGINT NOT NULL COMMENT '角色ID',
|
`role_id` BIGINT NOT NULL COMMENT '角色ID',
|
||||||
`perm_id` BIGINT NOT NULL COMMENT '权限ID',
|
`perm_id` BIGINT NOT NULL COMMENT '权限ID',
|
||||||
`created_by` bigint NOT NULL COMMENT '创建人',
|
`created_by` bigint NOT NULL COMMENT '创建人',
|
||||||
`updated_by` bigint NOT NULL COMMENT '更新人',
|
`updated_by` bigint NULL COMMENT '更新人',
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
@ -90,7 +90,7 @@ CREATE TABLE `sys_re_user_organization` (
|
|||||||
`org_id` BIGINT NOT NULL COMMENT '组织ID',
|
`org_id` BIGINT NOT NULL COMMENT '组织ID',
|
||||||
`version` INT NOT NULL DEFAULT 0,
|
`version` INT NOT NULL DEFAULT 0,
|
||||||
`created_by` bigint NOT NULL COMMENT '创建人',
|
`created_by` bigint NOT NULL COMMENT '创建人',
|
||||||
`updated_by` bigint NOT NULL COMMENT '更新人',
|
`updated_by` bigint NULL COMMENT '更新人',
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
@ -103,7 +103,7 @@ CREATE TABLE `sys_re_user_role` (
|
|||||||
`role_id` BIGINT NOT NULL COMMENT '角色ID',
|
`role_id` BIGINT NOT NULL COMMENT '角色ID',
|
||||||
`version` INT NOT NULL DEFAULT 0,
|
`version` INT NOT NULL DEFAULT 0,
|
||||||
`created_by` bigint NOT NULL COMMENT '创建人',
|
`created_by` bigint NOT NULL COMMENT '创建人',
|
||||||
`updated_by` bigint NOT NULL COMMENT '更新人',
|
`updated_by` bigint NULL COMMENT '更新人',
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
@ -118,7 +118,7 @@ CREATE TABLE `sys_role` (
|
|||||||
`description` varchar(255) NULL COMMENT '角色描述',
|
`description` varchar(255) NULL COMMENT '角色描述',
|
||||||
`status` int NOT NULL COMMENT '状态',
|
`status` int NOT NULL COMMENT '状态',
|
||||||
`created_by` bigint NOT NULL COMMENT '创建人',
|
`created_by` bigint NOT NULL COMMENT '创建人',
|
||||||
`updated_by` bigint NOT NULL COMMENT '更新人',
|
`updated_by` bigint NULL COMMENT '更新人',
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`role_id`),
|
PRIMARY KEY (`role_id`),
|
||||||
@ -135,7 +135,7 @@ CREATE TABLE `sys_user` (
|
|||||||
`user_type` tinyint NULL DEFAULT NULL COMMENT '用户类型从字典取',
|
`user_type` tinyint NULL DEFAULT NULL COMMENT '用户类型从字典取',
|
||||||
`status` tinyint DEFAULT 0 NOT NULL COMMENT '状态',
|
`status` tinyint DEFAULT 0 NOT NULL COMMENT '状态',
|
||||||
`created_by` bigint NOT NULL COMMENT '创建人',
|
`created_by` bigint NOT NULL COMMENT '创建人',
|
||||||
`updated_by` bigint NOT NULL COMMENT '更新人',
|
`updated_by` bigint NULL COMMENT '更新人',
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`user_id`),
|
PRIMARY KEY (`user_id`),
|
||||||
@ -174,7 +174,7 @@ CREATE TABLE `sys_user_field_definition` (
|
|||||||
`sort` int NOT NULL DEFAULT 0 COMMENT '排序',
|
`sort` int NOT NULL DEFAULT 0 COMMENT '排序',
|
||||||
`status` int NOT NULL COMMENT '状态',
|
`status` int NOT NULL COMMENT '状态',
|
||||||
`created_by` bigint NOT NULL COMMENT '创建人',
|
`created_by` bigint NOT NULL COMMENT '创建人',
|
||||||
`updated_by` bigint NOT NULL COMMENT '更新人',
|
`updated_by` bigint NULL COMMENT '更新人',
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`field_id`),
|
PRIMARY KEY (`field_id`),
|
||||||
@ -188,7 +188,7 @@ CREATE TABLE `sys_user_field_value` (
|
|||||||
`field_id` int NOT NULL COMMENT '字段ID',
|
`field_id` int NOT NULL COMMENT '字段ID',
|
||||||
`value` varchar(4096) NULL COMMENT '用户拓展字段值',
|
`value` varchar(4096) NULL COMMENT '用户拓展字段值',
|
||||||
`created_by` bigint NOT NULL COMMENT '创建人',
|
`created_by` bigint NOT NULL COMMENT '创建人',
|
||||||
`updated_by` bigint NOT NULL COMMENT '更新人',
|
`updated_by` bigint NULL COMMENT '更新人',
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
@ -203,7 +203,7 @@ CREATE TABLE `sys_profile` (
|
|||||||
`description` varchar(255) NULL COMMENT '系统配置记录描述',
|
`description` varchar(255) NULL COMMENT '系统配置记录描述',
|
||||||
`content` varchar(255) NULL COMMENT '系统配置记录值',
|
`content` varchar(255) NULL COMMENT '系统配置记录值',
|
||||||
`created_by` bigint NOT NULL COMMENT '创建人',
|
`created_by` bigint NOT NULL COMMENT '创建人',
|
||||||
`updated_by` bigint NOT NULL COMMENT '更新人',
|
`updated_by` bigint NULL COMMENT '更新人',
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
@ -220,7 +220,7 @@ CREATE TABLE `sys_module` (
|
|||||||
`sort` int NOT NULL DEFAULT 0 COMMENT '排序',
|
`sort` int NOT NULL DEFAULT 0 COMMENT '排序',
|
||||||
`status` int NOT NULL COMMENT '状态',
|
`status` int NOT NULL COMMENT '状态',
|
||||||
`created_by` bigint NOT NULL COMMENT '创建人',
|
`created_by` bigint NOT NULL COMMENT '创建人',
|
||||||
`updated_by` bigint NOT NULL COMMENT '更新人',
|
`updated_by` bigint NULL COMMENT '更新人',
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
|
Loading…
Reference in New Issue
Block a user