# 本项目使用cursou说明 ## 服务注入 > 大部分服务已经全局注入,直接在service中使用即可 - 日志服务:private readonly logger: CustomLogger, - redis服务:private readonly redis: RedisService, - 配置服务:private readonly config: ConfigService, - 工具服务:private readonly utils: UtilsService, - 数据库服务:private readonly database: DatabaseService, 以上服务均已在appModule全局注入,不需要再向module中注入 ## 路径别名 @代指src目录,请注意,引入任何文件采用路径别名,除开当前目录下的文件,不允许使用../获取上级目录 ## 数据库 1. 数据库实体在@/drizzle/schema,通过这样导入: ```ts import { user, userPassword, userProfile, userSignatureHistory, } from '@/drizzle/schema'; ``` **注意**操作数据严格按照数据库实体的定义 2. 数据库使用drizzle和mysql2,下面是使用示例 ```ts import { user } from '@/drizzle/schema'; // dto为参数 const userExists = await this.database.db .select({ userId: user.userId, }) .from(user) .where( or( eq(user.email, dto.email), eq(user.username, dto.username), ), ) .execute(); if (userExists.length > 0) { throw new BadRequestException('用户已存在'); } ``` ## 注释 **非常重要** !!!!!!!!!!! 1. 编写代码已经要有非常详细的注释,最好每行都有注释 参考 ```ts // 检查邮箱是否可用 async checkEmail(dto: CheckEmailDto) { const exists = await this.database.db .select() .from(user) .where(and(eq(user.email, dto.email), eq(user.isDeleted, 0))) .execute(); return { available: exists.length === 0 }; } // 发送验证码 async sendEmailCode(dto: SendEmailCodeDto) { // 邮箱验证码key const codeKey = `${EmailCodeType[dto.type]}:${dto.email}`; // 判断Key是否存在 const keyExists = await this.redis.exists(codeKey); // 验证码过期时间 const codeEX = this.config.get('email.codeEX') || 300; // 验证码冷却时间 const codeEP = this.config.get('email.codeEP') || 60; // 判断是否存在验证码 if (keyExists) { // 获取Key的过期时间 const ttl = await this.redis.ttl(codeKey); if (ttl > codeEX - codeEP) { // 再等等吧 throw new BadRequestException(`请等待${ttl}秒后再试`); } else { // 续杯 await this.redis.expire(codeKey, codeEX); // 获取验证码 const code = await this.redis.get(codeKey); // todo重新发送验证码 this.logger.debug(`重新发送验证码: ${code}`); await this.utils.sendEmail({ to: dto.email, subject: '账户注册验证码', text: `您的验证码是:${code},5分钟内有效`, }); } } else { // 生成验证码 const code = Math.random().toString().slice(2, 8); // todo发送验证码 this.logger.debug(`发送验证码: ${code}`); await this.utils.sendEmail({ to: dto.email, subject: '账户注册验证码', text: `您的验证码是:${code},5分钟内有效`, }); // 存储验证码 await this.redis.set(codeKey, code, codeEX); } return { message: '验证码已发送' }; } ``` 2. 每个方法前都要携带写作者、写作时间、方法描述,写作者为`Nie` ## 常量 常量这样导入 `import { EmailCodeType } from '@/type/enum';` 常量用于一些系统的关键字 ## redis 使用参考 ```ts // 加锁 const lock = await this.redis.lock( `${EmailCodeType.REGISTER}:${dto.email}`, ); ``` 方法一般在RedisService中定义 ## 文件命名 采用小驼峰加`.service`、`.dto`类似的方式命名,禁止使用中划线 错误示例 `add-user.dto.ts` 正确示例 `addUser.dto.ts