egg_server/db/user/index.ts

104 lines
2.5 KiB
TypeScript

import PocketBase, { RecordModel } from "pocketbase"
import { Logger } from "winston"
import { Context } from "../../types"
import PbToolBase from "../base"
const DB_NAME = "users"
/**
* 用户基础信息接口定义
*/
interface User {
/** 用户邮箱 */
email: string
/** 用户名称 */
name: string
/** 飞书用户 Open ID */
openId: string
/** 飞书用户 User ID */
userId: string
/** 用户头像链接 */
avatar: string
/** 用户密码 */
password: string
/** 邮箱可见性标志 */
emailVisibility: boolean
/** 用户邮箱是否已验证 */
verified: boolean
}
/** 完整用户模型类型,包含 PocketBase 记录基础字段 */
export type UserModel = User & RecordModel
/**
* 用户数据库操作类
* 提供用户相关的查询、创建等操作
*/
class UserDB extends PbToolBase<UserModel> {
/**
* 创建用户数据库操作实例
*
* @param pbClient - PocketBase 客户端实例
* @param logger - 日志记录器实例
*/
constructor(pbClient: PocketBase, logger: Logger) {
super(DB_NAME, pbClient, logger)
}
/**
* 根据飞书用户 ID 获取用户记录
*
* @param userId - 飞书用户 ID
* @returns 成功时返回用户记录,失败时返回 null
*
* @example
* ```typescript
* const user = await userDB.getByUserId("ou_123456");
* ```
*/
public getByUserId = (userId: string) => {
return this.getFirstOne(`userId = "${userId}"`)
}
/**
* 根据请求上下文获取用户信息
* 如果用户不存在,则尝试从飞书获取用户信息并创建新用户
*
* @param context - 请求上下文,包含飞书请求体和飞书服务
* @returns 成功时返回用户记录,失败时返回 null
*
* @example
* ```typescript
* const user = await userDB.getByCtx(ctx);
* ```
*/
public getByCtx = async ({ larkBody, larkService }: Context) => {
if (!larkBody.userId) return null
const user = await this.getByUserId(larkBody.userId)
if (user) return user
const userInfo = await larkService.user.getOne(larkBody.userId, "user_id")
if (userInfo.code === 0) return null
const {
user_id,
open_id,
avatar: { avatar_origin },
email,
name,
} = userInfo.data.user
const newUser = {
userId: user_id,
openId: open_id,
avatar: avatar_origin,
email,
name,
emailVisibility: false,
verified: false,
password: email,
}
return await this.create(newUser)
}
}
export default UserDB