npmrun 2 years ago
parent
commit
0e1faab05f
  1. 4911
      pnpm-lock.yaml
  2. 5
      readme.md
  3. 4
      route.txt
  4. BIN
      source/db/data.db
  5. 18
      source/models/User.ts
  6. 75
      source/models/UserInfo.ts
  7. 20
      source/models/ha/user.ts
  8. 31
      source/models/ha/user_info.ts
  9. 10
      source/route/views/register.ts
  10. 2
      tsconfig.json
  11. 12
      types/global.d.ts

4911
pnpm-lock.yaml

File diff suppressed because it is too large

5
readme.md

@ -41,4 +41,7 @@ docker image rm 镜像名
docker image ls -a docker image ls -a
docker container ls -a docker container ls -a
https://blog.csdn.net/LIFENG0402/article/details/117930091 https://blog.csdn.net/LIFENG0402/article/details/117930091
## 使用事务
https://sequelize.org/docs/v6/other-topics/transactions/#:~:text=The%20sequelize.transaction%20method%20accepts%20options.%20For%20unmanaged%20transactions%2C,%28options%29.%20For%20managed%20transactions%2C%20use%20sequelize.transaction%20%28options%2C%20callback%29.

4
route.txt

@ -1,6 +1,6 @@
/home/topuser/Code/@project/hapi-demo/source/route/htmx对应路径: D:\1XYX\pro\hapi-demo\source\route\htmx对应路径:
不需权限 : GET /htmx/path/{path*} 不需权限 : GET /htmx/path/{path*}
/home/topuser/Code/@project/hapi-demo/source/route/views对应路径: D:\1XYX\pro\hapi-demo\source\route\views对应路径:
不需权限(提供无需验证): GET /404 不需权限(提供无需验证): GET /404
不需权限(提供无需验证): GET / 不需权限(提供无需验证): GET /
不需权限(提供无需验证): GET /about 不需权限(提供无需验证): GET /about

BIN
source/db/data.db

Binary file not shown.

18
source/models/User.ts

@ -4,15 +4,13 @@ interface UserAttributes {
id: number id: number
username: string username: string
password: string password: string
nickname: string
email: string
createdAt?: Date createdAt?: Date
updatedAt?: Date updatedAt?: Date
deletedAt?: Date deletedAt?: Date
} }
export interface UserInput extends Optional<UserAttributes, "id" | "email" | "nickname"> {} export interface UserInput extends Optional<UserAttributes, "id"> {}
export interface UserOuput extends Required<UserAttributes> {} export interface UserOuput extends Required<UserAttributes> {}
export type TUserModel = ReturnType<typeof UserModel> export type TUserModel = ReturnType<typeof UserModel>
@ -22,8 +20,6 @@ export default function UserModel(sequelize: Sequelize, DataTypes: DT) {
public id: number public id: number
public username: string public username: string
public password: string public password: string
public nickname: string
public email: string
// timestamps! // timestamps!
public readonly createdAt!: Date public readonly createdAt!: Date
@ -44,15 +40,10 @@ export default function UserModel(sequelize: Sequelize, DataTypes: DT) {
password: { password: {
type: DataTypes.STRING, type: DataTypes.STRING,
allowNull: false, allowNull: false,
}, }
nickname: {
type: DataTypes.STRING,
},
email: {
type: DataTypes.STRING,
},
}, },
{ {
modelName: "User",
sequelize, sequelize,
timestamps: true, timestamps: true,
paranoid: true, // 对模型施加了一个软删除 paranoid: true, // 对模型施加了一个软删除
@ -62,5 +53,8 @@ export default function UserModel(sequelize: Sequelize, DataTypes: DT) {
interface User { interface User {
toJSON: () => UserOuput toJSON: () => UserOuput
} }
User.associate = function (models) {
models["User"].hasOne(models["UserInfo"])
}
return User return User
} }

75
source/models/UserInfo.ts

@ -0,0 +1,75 @@
import { Sequelize, DataTypes, Optional, Model } from "sequelize"
interface UserInfoAttributes {
id: number
user_id: number
nickname: string
email: string
avatar: string
tel: string
createdAt?: Date
updatedAt?: Date
deletedAt?: Date
}
export interface UserInfoInput extends Optional<UserInfoAttributes, "id" | "email" | "nickname" | "avatar" | "tel"> {}
export interface UserInfoOuput extends Required<UserInfoAttributes> {}
export type TUserInfoModel = ReturnType<typeof UserInfoModel>
type DT = typeof DataTypes
export default function UserInfoModel(sequelize: Sequelize, DataTypes: DT) {
class UserInfo extends Model<UserInfoAttributes, UserInfoInput> implements UserInfoAttributes {
public id: number
public user_id: number
public nickname: string
public email: string
public avatar: string
public tel: string
// timestamps!
public readonly createdAt!: Date
public readonly updatedAt!: Date
public readonly deletedAt!: Date
}
UserInfo.init(
{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
user_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
nickname: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
},
avatar: {
type: DataTypes.STRING,
},
tel: {
type: DataTypes.STRING,
},
},
{
modelName: "UserInfo",
sequelize,
timestamps: true,
paranoid: true, // 对模型施加了一个软删除
},
)
// 覆盖User的toJSON方法
interface UserInfo {
toJSON: () => UserInfoOuput
}
UserInfo.associate = function (models) {
models["UserInfo"].belongsTo(models["User"], { foreignKey: "user_id" })
}
return UserInfo
}

20
source/models/ha/user.ts

@ -1,20 +0,0 @@
import { Sequelize, DataTypes } from "sequelize"
type DT = typeof DataTypes
module.exports = function (sequelize: Sequelize, DataTypes: DT) {
const User = sequelize.define(
"ha-user",
{
username: {
type: DataTypes.STRING,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
},
{},
)
return User
}

31
source/models/ha/user_info.ts

@ -1,31 +0,0 @@
import { Sequelize, DataTypes } from "sequelize"
type DT = typeof DataTypes
module.exports = function (sequelize: Sequelize, DataTypes: DT) {
const UserInfo = sequelize.define(
"ha-user_info",
{
nickname: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
},
avatar: {
type: DataTypes.STRING,
},
tel: {
type: DataTypes.STRING,
},
},
{},
)
// @ts-ignore
UserInfo.associate = function (models) {
models["ha-user"].hasOne(models["ha-user_info"])
models["ha-user_info"].belongsTo(models["ha-user"], { foreignKey: "user_id" })
}
return UserInfo
}

10
source/route/views/register.ts

@ -3,6 +3,7 @@ import { LoginUserSchema, RegisterUserSchema, UserSchema } from "@/schema"
import { gFail, gSuccess } from "@/util" import { gFail, gSuccess } from "@/util"
import { auth, config, method, route, route_path, validate } from "@noderun/hapi-router" import { auth, config, method, route, route_path, validate } from "@noderun/hapi-router"
import * as bcrypt from "bcrypt" import * as bcrypt from "bcrypt"
import sequelize from "sequelize"
/** /**
* *
*/ */
@ -29,9 +30,9 @@ export default class {
@method("POST") @method("POST")
@route_path("/register") @route_path("/register")
async register_POST(request: Req, h: Res): ReturnValue { async register_POST(request: Req, h: Res): ReturnValue {
console.log(request)
let { username, password } = request.payload as any let { username, password } = request.payload as any
const User = request.getModel("User") const User = request.getModel("User")
const UserInfoModel = request.getModel("UserInfo")
logger.trace("当前注册用户:" + username) logger.trace("当前注册用户:" + username)
try { try {
const result = await User.findOne({ where: { username: username } }) const result = await User.findOne({ where: { username: username } })
@ -41,7 +42,12 @@ export default class {
} }
let salt = bcrypt.genSaltSync(10) let salt = bcrypt.genSaltSync(10)
let pwdLock = bcrypt.hashSync(password, salt) let pwdLock = bcrypt.hashSync(password, salt)
await User.create({ username, password: pwdLock, nickname: username }) // 使用事务插入
await sequelize.transaction(async t => {
const user = await User.create({ username, password: pwdLock }, { transaction: t })
await UserInfoModel.create({ nickname: username, user_id: user.id }, { transaction: t })
return user
})
request.yar.flash("success", "用户注册成功") request.yar.flash("success", "用户注册成功")
return h.redirect("/login") return h.redirect("/login")
} catch (e) { } catch (e) {

2
tsconfig.json

@ -19,6 +19,6 @@
"#/*": ["types/*"] "#/*": ["types/*"]
} }
}, },
"include": ["source", "types", "test"], "include": ["source", "types", "test", "log/ha"],
"exclude": ["node_modules"] "exclude": ["node_modules"]
} }

12
types/global.d.ts

@ -3,6 +3,7 @@ import { Server } from "@hapi/hapi"
import { Request, ResponseToolkit, Lifecycle } from "@hapi/hapi" import { Request, ResponseToolkit, Lifecycle } from "@hapi/hapi"
import { TUserModel } from "@/models/User" import { TUserModel } from "@/models/User"
import yar from "@hapi/yar" import yar from "@hapi/yar"
import { TUserInfoModel } from "@/models/UserInfo"
declare global { declare global {
var server: Server var server: Server
@ -13,15 +14,22 @@ declare global {
interface Models { interface Models {
User: TUserModel User: TUserModel
UserInfo: TUserInfoModel
}
declare module "sequelize" {
namespace Model {
export let associate: (models: Models) => void
}
} }
declare module "@hapi/hapi" { declare module "@hapi/hapi" {
interface Request { interface Request {
getModel<T extends keyof Models, M extends Models[T]>(name: T): M getModel<T extends keyof Models, M extends Models[T]>(name: T): M
yar: yar.Yar; yar: yar.Yar
} }
interface Server { interface Server {
yar: yar.ServerYar; yar: yar.ServerYar
} }
interface ResponseToolkit {} interface ResponseToolkit {}
} }

Loading…
Cancel
Save