{"id":27754102,"url":"https://github.com/Carole007/carole-admin","last_synced_at":"2025-04-29T06:02:02.838Z","repository":{"id":243990568,"uuid":"813957380","full_name":"Carole007/carole-admin","owner":"Carole007","description":"nest全栈快速开发平台","archived":false,"fork":false,"pushed_at":"2025-02-09T09:10:48.000Z","size":27788,"stargazers_count":120,"open_issues_count":1,"forks_count":30,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-09T10:21:51.577Z","etag":null,"topics":["carole-admin","ioredis","nestjs","nodejs","prisma","vue"],"latest_commit_sha":null,"homepage":"https://carole.top","language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Carole007.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-12T04:28:17.000Z","updated_at":"2025-02-09T09:10:52.000Z","dependencies_parsed_at":"2024-07-23T07:08:15.162Z","dependency_job_id":"26d9ddab-56af-41ee-8403-5f0d3a2ad783","html_url":"https://github.com/Carole007/carole-admin","commit_stats":null,"previous_names":["carole007/carole-admin"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Carole007%2Fcarole-admin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Carole007%2Fcarole-admin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Carole007%2Fcarole-admin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Carole007%2Fcarole-admin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Carole007","download_url":"https://codeload.github.com/Carole007/carole-admin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251446168,"owners_count":21590668,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["carole-admin","ioredis","nestjs","nodejs","prisma","vue"],"created_at":"2025-04-29T06:01:19.048Z","updated_at":"2025-04-29T06:02:02.798Z","avatar_url":"https://github.com/Carole007.png","language":"Vue","funding_links":[],"categories":["Vue"],"sub_categories":[],"readme":"\u003cdiv  align=\"center\"\u003e\r\n \u003cimg src=\"assets/68747470733a2f2f6e6573746a732e636f6d2f6c6f676f2d736d616c6c2d6772616469656e742e37363631363430352e737667.svg\" alt=\"68747470733a2f2f6e6573746a732e636f6d2f6c6f676f2d736d616c6c2d6772616469656e742e37363631363430352e737667\" style=\"width: 25%;\" /\u003e\r\n \u003ch1 \u003eCarole-Admin\u003c/h1\u003e\r\n    \u003ch3 \u003e一款基于 Nestjs+Vue前后端分离的后台框架\u003c/h3\u003e\r\n\u003c/div\u003e\r\n\r\n# 介绍\r\n\r\n## 平台简介\r\n\r\n`carole-admin` 是一款[Nestjs](https://nestjs.com/)+[Prisma](https://www.prisma.io/)+[Vue](https://vuejs.org/)+[Vite](https://vitejs.dev/)前后端分离的全栈快速开发平台, 前端基于[若依](https://github.com/yangzongzhuan/RuoYi-Vue3)。\r\n\r\n- 前端采用[Vue3](https://vuejs.org/)、[Element-Plus](https://element-plus.org/)、[Vite](https://vitejs.dev/)。\r\n- 后端采用[Nest](https://nestjs.com/)、[Prisma](https://www.prisma.io/)、[ioredis](https://github.com/redis/ioredis) \u0026 [Jwt](https://github.com/auth0/node-jsonwebtoken)。\r\n- 权限认证使用[Jwt](https://github.com/auth0/node-jsonwebtoken)，支持多终端认证系统。\r\n- 支持加载动态权限菜单，多方式轻松权限控制。\r\n- 支持接口限流\r\n- 高效率开发，使用代码生成器可以一键生成前后端代码。\r\n\r\n## 项目\r\n\r\n\u003e 演示地址：[https://carole.top](https://carole.top)\r\n\u003e\r\n\u003e 默认有两个用户： admin的密码为carole test的密码为123456\r\n\u003e\r\n\u003e github: \u003chttps://github.com/Carole007/carole-admin\u003e\r\n\u003e\r\n\u003e gitee: \u003chttps://gitee.com/Carole007/carole-admin\u003e\r\n\r\n## 环境\r\n\r\n- nodejs: v20.12.0\r\n- mysql: 8.0.12\r\n- redis\r\n\r\n## 开始\r\n\r\n```bash\r\n# 克隆项目\r\ngit clone https://github.com/Carole007/carole-admin.git\r\n\r\n# 导入sql\r\n\r\n# 启动redis\r\n\r\n# 进入项目目录\r\ncd carole-admin/server\r\n\r\n# 安装依赖\r\nnpm i  \r\n\r\n# 生成当前平台的引擎 下载失败多执行几次或者换网络\r\nnpx prisma generate\r\n\r\n# 修改server/src/里面的.env数据库连接配置，以及config.ts里面的redis连接配置，文件上传路径。\r\n\r\n# 启动服务\r\nnpm run start:dev\r\n\r\n# 前台\r\ncd carole-admin/front \r\nnpm i\r\nnpm run dev\r\n```\r\n\r\n## 内置功能\r\n\r\n1. 用户管理：用户是系统操作者，该功能主要完成系统用户配置。\r\n\r\n2. 部门管理：配置系统组织机构。\r\n\r\n3. 岗位管理：配置系统用户所属担任职务。\r\n\r\n4. 菜单管理：配置系统菜单，操作权限，按钮权限标识等。\r\n\r\n5. 角色管理：角色菜单权限分配、设置角色按机构进行数据范围权限划分。\r\n\r\n6. 字典管理：对系统中经常使用的一些较为固定的数据进行维护。\r\n\r\n7. 参数管理：对系统动态配置常用参数。\r\n\r\n8. 通知公告：系统通知公告信息发布维护。\r\n\r\n9. 登录日志：系统登录日志记录查询包含登录异常。\r\n\r\n10. 代码生成：前后端代码的生成（js、vue、sql）支持CRUD下载 。\r\n\r\n11. 系统接口：根据业务代码自动生成相关的api接口文档。\r\n\r\n12. 在线用户：当前系统中活跃用户状态监控。\r\n\r\n13. 服务监控：监视当前系统CPU、内存、磁盘、堆栈等相关信息。\r\n\r\n14. 缓存监控：对系统的缓存信息查询，命令统计等。\r\n\r\n## 演示图\r\n\r\n| ![image-20240611165616048](assets/image-20240611165616048.png) | ![image-20240611120045810](assets/image-20240611120045810.png) |\r\n| ------------------------------------------------------------ | ------------------------------------------------------------ |\r\n| ![image-20240610155809785](assets/image-20240610155809785.png) | ![image-20240610155824377](assets/image-20240610155824377.png) |\r\n| ![image-20240610155853085](assets/image-20240610155853085.png) | ![image-20240610155914577](assets/image-20240610155914577.png) |\r\n| ![image-20240610155928620](assets/image-20240610155928620.png) | ![image-20240610155939603](assets/image-20240610155939603.png) |\r\n| ![image-20240610155953022](assets/image-20240610155953022.png) | ![image-20240610160014116](assets/image-20240610160014116.png) |\r\n| ![image-20240610160033126](assets/image-20240610160033126.png) | ![image-20240610160106498](assets/image-20240610160106498.png) |\r\n| ![image-20240610160120728](assets/image-20240610160120728.png) | ![image-20240610160137315](assets/image-20240610160137315.png) |\r\n| ![image-20240610160152700](assets/image-20240610160152700.png) | ![image-20240610160221567](assets/image-20240610160221567.png) |\r\n| ![image-20240610160231844](assets/image-20240610160231844.png) | ![image-20240611170317679](./assets/image-20240611170317679.png) |\r\n\r\n# 文档\r\n\r\n## 主要文件结构\r\n\r\n```\r\n server   #系统后端\r\n front    #系统前端\r\n server/src目录\r\n           ├─admin                 #系统管理模块\r\n           │  ├─gen                #代码生成\r\n           │  └─system             #系统代码\r\n           │  └─admin.module.ts    #系统模块配置\r\n           \r\n           ├─common                #工具类 \r\n           │  ├─decorator          #自定义注解    \r\n           │  ├─filter             #异常处理 \r\n           │  ├─guard\r\n           │  │  ├─permission      #权限校验 \r\n           │  ├─middleware         #中间件\r\n           │  │  └─auth        #身份校验 \r\n           │  ├─pipe         #自定义管道\r\n           │  ├─prisma-client     #prisma客户端\r\n           │  ├─result         #返回对象\r\n           │  ├─service\r\n           │  │  ├─auth            #身份相关处理逻辑\r\n           │  │  ├─gen         #代码生成逻辑\r\n           │  │  │  └─gen-template #代码模板\r\n           │  └─utils         #通用工具\r\n           \r\n           ├─prisma\r\n           │  └─schema        #数据库模型定义\r\n           │  └─schema.prisma      #prisma主文件\r\n           \r\n           ├─schedule         #定时任务\r\n           \r\n           ├─.env            #环境变量配置， 密码\r\n           ├─main.ts               #主文件\r\n           ├─config.ts             #系统配置文件\r\n           ├─app.module.ts         #系统主模块\r\n\r\n```\r\n\r\n## 配置文件\r\n\r\n- 主要配置 `src/config.ts`\r\n\r\n```typescript\r\nimport * as dotenv from \"dotenv\";\r\nimport { join } from \"path\";\r\nimport { config } from \"./common/types/config\";\r\ndotenv.config({ path: join(__dirname, \".env\") })\r\nexport const Config: config = {\r\n  //服务器的HTTP端口，默认为3000\r\n  port: 3000,\r\n  //# 应用的访问路径前缀\r\n  contextPath: \"/v1\",\r\n  swagger: {\r\n    //是否启用swagger\r\n    enable: true,\r\n    //接口文档路径\r\n    prefix: \"/api\"\r\n  },\r\n  captcha: {\r\n    //验证码类型 math或text \r\n    mode: \"math\",\r\n    //验证码过期时间\r\n    expiresIn: 60 * 2,\r\n  },\r\n  //接口限流 2分钟内同一个接口允许60次请求\r\n  rateLimit: {\r\n    //数据存储在redis or memory\r\n    storage:\"redis\",\r\n    ttl: 2 * 60 * 1000,\r\n    limit: 60,\r\n  },\r\n  crypto: {\r\n    //密码加密秘钥\r\n    psdSecret: process.env.psdSecret || \"carole123456\",\r\n  },\r\n  token: {\r\n    // token加密秘钥\r\n    secret: process.env.tokenSecret || \"carole123456\",\r\n    //过期时间秒\r\n    expiresIn: 60 * 60 * 24\r\n  },\r\n  prisma: {\r\n    //是否显示执行的sql指令\r\n    logEnable: false,\r\n    //显示那些日志\r\n    log: ['query', 'info', 'warn', 'error']\r\n  },\r\n  //redis连接配置\r\n  redis: {\r\n    //主机地址\r\n    host: '127.0.0.1',\r\n    //端口\r\n    port: 6379,\r\n    //数据库\r\n    db: 5,\r\n    //密码\r\n    //password:\"\"\r\n  },\r\n  upload: {\r\n    //上传文件存储基目录 请设置一个绝对路径\r\n    path: \"d:/uploads\",\r\n    config: {\r\n      img: {\r\n        fileSize: 2 * 1024 * 1024,\r\n        files: 1,\r\n        fieldSize: 0.5 * 1024 * 1024,\r\n        fields: 100,\r\n        fieldNameSize: 100,\r\n        parts: 100,\r\n        headerPairs: 100,\r\n      },\r\n      file: {\r\n        fileSize: 100 * 1024 * 1024,\r\n        files: 10,\r\n        fieldSize: 0.5 * 1024 * 1024,\r\n        fields: 100,\r\n        fieldNameSize: 100,\r\n        parts: 100,\r\n        headerPairs: 100,\r\n      },\r\n    },\r\n  },\r\n  //生成配置\r\n  gen: {\r\n    //作者\r\n    author: \"carole\",\r\n    //默认生成模块\r\n    packageName: \"admin\",\r\n    //子模块目录\r\n    moduleName: \"system\",\r\n    //是否去除表前缀，默认是false\r\n    autoRemovePre: false, \r\n    //表前缀（生成类名不会包含表前缀，多个用逗号分隔）\r\n    tablePrefix: [\"sys_\"]\r\n  },\r\n  //邮件发送配置\r\n  mail: {\r\n    //是否启用邮箱\r\n    enable: false,\r\n    //超时设置， 30秒未发送邮件，则返回失败\r\n    timeout: 30 * 1000,\r\n    config: {\r\n      //邮箱服务器 qq：smtp.qq.com 网易： smtp.163.com\r\n      host: process.env.mailHost,\r\n      //端口\r\n      port: 465,\r\n      auth: {\r\n        //用户名\r\n        user: process.env.mailUser,\r\n        //密码\r\n        pass: process.env.mailPass,\r\n      },\r\n      // 端口465设置true, 其他false \r\n      secure: true,\r\n      tls: {\r\n        //建立 TLS 连接时是否应该拒绝未经授权的服务器证书\r\n        rejectUnauthorized: false,\r\n      },\r\n    },\r\n  },\r\n};\r\n\r\n```\r\n\r\n- 环境变量配置 `src/.env`文件\r\n\r\n  ```bash\r\n  DATABASE_URL=\"mysql://root:123456@localhost:3306/carole\" #url格式  mysql://用户名:密码@ip:端口/数据库?参数charset=utf8mb4\r\n  psdSecret = \"carole123456\"#密码加密秘钥 加密算法：HmacSHA256\r\n  tokenSecret = \"carole123456\" #token加密秘钥\r\n  mailHost = \"\"#邮箱服务器 qq：smtp.qq.com 网易： smtp.163.com\r\n  mailUser = \"\" #发件邮箱账号\r\n  mailPass = \"\" #发件邮箱密码\r\n  ```\r\n\r\n### 配置注意点\r\n\r\n\u003e 数据库中的用户密码使用默认秘钥加密，如果你修改了密码加密秘钥，请手动执行 `server\\test\\password.js`获取新密码，并手动更新数据库。\r\n\r\n## 权限注解\r\n\r\n  注解权限控制\r\n\r\n- `@RequirePermission`当前用户需要拥有特定的权限时，才能执行被该注解标注的方法。如果当前用户不具有这样的权限，则方法不会被执行。\r\n- `@RequireRole`当前用户必须拥有所有指定的角色时，才能访问被该注解标注的方法。如果当前用户不拥有指定的角色，则方法不会执行。\r\n\r\n### @RequireRole\r\n\r\n`@RequireRole`注解用于配置接口要求用户拥有指定角色才可访问\r\n\r\n| 参数  | 类型   | 描述 |\r\n| ----- | ------ | ---- |\r\n| value | String | 角色 |\r\n\r\n示例:以下代码表示必须拥有`admin`角色才可访问\r\n\r\n```typescript\r\n\r\n@RequireRole(\"admin\")\r\nasync test() {\r\n    return Result.ok()\r\n}\r\n```\r\n\r\n### @RequirePermission\r\n\r\n`@RequirePermission`注解用于配置接口要求用户拥有指定权限才可访问\r\n\r\n| 参数  | 类型   | 描述 |\r\n| ----- | ------ | ---- |\r\n| value | String | 权限 |\r\n\r\n示例:以下代码表示必须拥有`system:user:remove`权限才可访问\r\n\r\n```typescript\r\n@RequirePermission(\"system:user:remove\")\r\nasync test() {\r\n    return Result.ok()\r\n}\r\n```\r\n\r\n## Prisma相关\r\n\r\n[prisma官方文档](https://www.prisma.io/docs/getting-started)\r\n\r\n### server目录下的两个Prisma的bat脚本功能解释\r\n\r\n##### 更新prisma的model.bat\r\n\r\n- 此脚本用于当你已经编写好Prisma的model文件，但数据库结构发生了更改时。它可以同步数据库的最新结构到Prisma的schema文件中。\r\n\r\n  相当于执行 `npx prisma db pull \u0026\u0026 npx prisma generate`\r\n\r\n##### 驼峰生成prisma的model.bat\r\n\r\n- 此脚本用于从数据库中生成Prisma的model定义，适用于数据库表没有在Prisma中的model定义过。（代码生成模板会使用驼峰命名法,并自动添加字段和表的map映射关系。）\r\n\r\n  相当于执行 `npx prisma db pull` 然后把生成Model字段名改为驼峰  执行 `npx prisma generate`\r\n  \r\n- 生成之后会在src/prisma目录中有个`introspected.prisma`文件，可以更改名字并移动到 `src/prisma/schema`里面。\r\n\r\n\u003e 当然，你也可以手动执行Prisma指令之后修改Model。\r\n\u003e\r\n### 注意\r\n\r\n- 项目打包时，可以在schema.prisma里的binaryTargets添加你想要运行的目标平台，执行 `npx prisma generate` 生成引擎，或者不动代码，到目标平台再执行一次 `npx prisma generate`\r\n\r\n- 执行时，确保model都写好表和字段的映射关系了 @@map映射表 @Map映射字段\r\n\r\n  model名称使用PascalCase命名 比如： test -\u003e Test, sys_config -\u003e SysConfig，  如果你不使用代码生成器，无需这样。\r\n\r\n​       示例：\r\n\r\n```javascript\r\nmodel SysConfig {\r\n  configId    Int     @id @default(autoincrement()) @map(\"config_id\")\r\n  configName  String? @default(\"\") @map(\"config_name\") @db.VarChar(100)\r\n  configKey   String? @default(\"\") @map(\"config_key\") @db.VarChar(100)\r\n  configValue String? @default(\"\") @map(\"config_value\") @db.VarChar(500)\r\n  configType  String? @default(\"N\") @map(\"config_type\") @db.Char(1)\r\n  createBy    String? @default(\"\") @map(\"create_by\") @db.VarChar(64)\r\n  createTime  String? @map(\"create_time\") @db.VarChar(25)\r\n  updateBy    String? @default(\"\") @map(\"update_by\") @db.VarChar(64)\r\n  updateTime  String? @map(\"update_time\") @db.VarChar(25)\r\n  remark      String? @map(\"remark\") @db.VarChar(500)\r\n  @@map(\"sys_config\")\r\n}\r\n```\r\n\r\n- prisma中日期类型字段插入时存在时差问题  \r\n  \r\n  \u003e 解决办法：把sql中的日期类型改成字符串，插入更新时手动设置时间\r\n  \r\n- 当数据库使用 `long` 类型时，查询出来的数据会自动转换为 `bigint`。在将这些数据转换为 JSON 时可能会出现问题。可以转换为字符串返回前端，但前端传来数据后端也需要转换为long才能正常使用。\r\n\r\n  当数字超出±(2^53 - 1)转换为Number也会出现问题![image-20240612094525584](./assets/image-20240612094525584.png)\r\n\r\n  ```javascript\r\n  BigInt.prototype.toJSON = function(){\r\n   return this.toString()\r\n  }\r\n  ```\r\n\r\n  \u003e 如果您考虑更改数据类型，以下是两种可能的解决方案：\r\n  \u003e 1.使用Int 无符号最大可以存4,294,967,295多条数据，作为主键一般场景完全够用了\r\n  \u003e 2.使用字符串，存uuid （无限制）\r\n\r\n## 代码生成使用\r\n\r\n详细教程：\u003chttps://juejin.cn/post/7385743189636808719\u003e\r\n\r\n1、在prisma\\schema写好对应表的Model，字段名驼峰映射\r\n\r\n2、登录系统（系统工具 -\u003e 代码生成 -\u003e 导入对应表）\r\n\r\n3、代码生成列表中找到需要表（可预览、编辑、同步、删除生成配置）\r\n\r\n4、点击生成代码会得到一个`carole.zip`执行`sql`文件生成菜单权限，按照包内目录结构复制到自己的项目中\r\n\r\n5、修改对应模块的module.ts文件，在providers中注册生成的Service，controllers注册生成的Controller类\r\n\r\n\u003e 代码生成支持编辑、预览、同步\r\n\u003e\r\n\u003e 预览：对生成的代码提前预览，防止出现一些不符合预期的情况。\r\n\u003e\r\n\u003e 同步：对原表的字段进行同步，包括新增、删除、修改的字段处理。\r\n\u003e\r\n\u003e 修改：对生成的代码基本信息、字段信息、生成信息做一系列的调整。\r\n\r\n## 定时任务\r\n\r\n[@nestjs/schedule文档](https://docs.nestjs.com/techniques/task-scheduling#task-scheduling)\r\n\r\n\u003e 使用定时任务非常容易，只需在 `server\\src\\schedule\\index.ts`中添加添加需要执行的方法并加上@Cron注解并携带cron表达式即可\r\n\r\n示例：\r\n\r\n```javascript\r\n //cron任务，每隔两秒执行一次\r\n  @Cron('*/2 * * * * *')\r\n  testCron() {\r\n    console.log(\"cron excute...\")\r\n  }\r\n```\r\n\r\n## 接口限流\r\n\r\n[@nestjs/throttler文档](https://docs.nestjs.com/security/rate-limiting#multiple-throttler-definitions)\r\n\r\n\u003e 默认所有接口2分钟内都只允许60次请求，可以在config.ts里面配置rateLimit，\r\n\u003e 单独定义某个接口，只需加上@Throttle根据自己需要配置即可\r\n\u003e\r\n\u003e 默认使用请求ip进行限流，可添加@ThrottleUser()注解对用户进行限流（比如限制用户一天只能修改一次密码）\r\n\r\n示例:\r\n\r\n```typescript\r\n//1个小时之内只能请求8次  \r\n@Throttle({\r\n    default: {\r\n      limit: 8,\r\n      ttl: 1000 * 60 * 60\r\n    }\r\n  })\r\n  async test1() {\r\n    return Result.ok()\r\n  }\r\n//5s内只能请求一次\r\n@Throttle({\r\n    default: {\r\n      limit: 1,\r\n      ttl: 1000 * 5\r\n    }\r\n  })\r\n  async test2() {\r\n    return Result.ok()\r\n  }\r\n//用户1天只能请求一次\r\n@ThrottleUser()\r\n@Throttle({\r\n    default: {\r\n      limit: 1,\r\n      ttl: 1000 * 60 * 60 * 24\r\n    }\r\n  })\r\nasync test3() {\r\n    return Result.ok()\r\n  }\r\n```\r\n\r\n## 请求跳过登录验证\r\n\r\n修改：`server\\src\\app.module.ts`\r\n\r\n![image-20240705211039862](assets/image-20240705211039862.png)\r\n\r\n```typescript\r\n支持通配符\r\n.exclude('/test(.*)','/a') // 排除/test开头和/a的路由 \r\n.forRoutes('*') // 应用到所有路由\r\n.forRoutes('/admin(*)') //应用到所有/admin开头的路由 \r\n```\r\n\r\n## 使用redis\r\n\r\n文件：`server\\src\\common\\utils\\redisUtils.ts`\r\n\r\n封装了一个redis连接池，里面包含一些常用的方法，如果没有你想要的，可以自己加进去。\r\n\r\n![image-20240705213300262](assets/image-20240705213300262.png)\r\n\r\n使用：\r\n\r\n```typescript\r\nimport { redisUtils } from '@/common/utils/redisUtils'; //导入\r\n\r\n//使用直接调用方法即可\r\nconst r = await redisUtils.get('demo');\r\nawait redisUtils.set(\"demo\",\"hello world!\",10); //过期时间秒为单位 10s过期\r\n...\r\n```\r\n\r\n## 请求参数验证\r\n\r\n\u003e 前言：\r\n\u003e\r\n\u003e 使用类定义参数的模型规则，请求时会对参数做校验，不通过直接返回错误，以及自动删除不在类中的字段，更加安全方便。\r\n\u003e\r\n\u003e 比如你有个用户修改的接口，但是只允许修改 nickname,和age,email 但是别人恶意传了个password，\r\n\u003e\r\n\u003e 你使用user=req.body()\r\n\u003e\r\n\u003e 代码是这样写的: prisma.user.update({where:{id},data:user}) 这样会导致别人把password也修改了，\r\n\u003e\r\n\u003e 当然你会这样写 :  cosnt {username,age,email} = user; prisma.user.update({where:{id},data:{nickname,age,email}}),这样写避免了上面的问题，但是如果你还要对参数做校验呢，比如nickname不能为空，age是否在1-150之内，email是否有效等等，将这些逻辑全写在controller中将会非常麻烦。\r\n\u003e\r\n\u003e 所以我们使用class-validator\r\n\r\n官方github： [class-validator](https://github.com/typestack/class-validator) ，可以看看有哪些方法，这里我就不列举了。\r\n\r\n使用时在类的字段上加需要的验证规则，如果不需要什么验证，请务必加上@IsOptional()注解，\r\n\r\n如果你需要的是一个number类型，但是传的参数可能是string，你可以使用@Transform处理值，((v) =\u003e +v.value)  注意v.value才是值\r\n\r\n@ApiProperty是swagger的注解，可不填写\r\n\r\n示例：\r\n\r\ndto类\r\n\r\n```typescript\r\nexport class CreateDictDataDto extends BaseDomain {\r\n  @ApiProperty({ description: '字典类型' })\r\n  @IsNotEmpty({ message: '字典类型不能为空' })\r\n  @IsString()\r\n  dictType: string;\r\n  @ApiProperty({ description: '数据标签' })\r\n  @IsNotEmpty({ message: '数据标签不能为空' })\r\n  @IsString()\r\n  dictLabel: string;\r\n  @ApiProperty({ description: '数据键值' })\r\n  @IsNotEmpty({ message: '数据键值不能为空' })\r\n  @IsString()\r\n  dictValue?: string;\r\n  @ApiProperty({ description: '样式属性' })\r\n  @IsOptional()\r\n  cssClass?: string;\r\n  @ApiProperty({ description: '回显样式' })\r\n  @IsOptional()\r\n  listClass?: string;\r\n  @ApiProperty({ description: '显示排序' })\r\n  @IsNotEmpty({ message: '排序值不能为空' })\r\n  @Transform((v) =\u003e +v.value)\r\n  @IsNumber()\r\n  dictSort: number;\r\n  @ApiProperty({ description: '字典状态（0停用，1正常）' })\r\n  @IsOptional()\r\n  status?: string = '1';\r\n}\r\n```\r\n\r\ncontroller使用时,只需加上刚才定义的类，可以放心安全使用。\r\n\r\n![image-20240705214655897](assets/image-20240705214655897.png)\r\n\r\n### 注意\r\n\r\n在 `server\\src\\app.module.ts`里设置了whiteList:true,会自动删除不在dto类中的字段，\r\n\r\n所以如果你使用了类来修饰参数类型，某个参数不想要验证，请务必加上@IsOptional()注解，标识可选的，否则这个字段会被直接删除掉\r\n\r\n![image-20240705213938007](assets/image-20240705213938007.png)\r\n\r\n## 发送邮件\r\n\r\n1. 修改.env里面的 邮箱连接账号密码，和服务器地址\r\n2. 按需修改config.ts的mail配置项,enable为true\r\n3. 参考`server\\src\\common\\utils\\emial.ts`文件使用\r\n\r\n## 部署\r\n\r\n```bash\r\n#后端\r\n\r\ncd server\r\n# 建议在server/src/schema.prisma里的binaryTargets添加上自己的服务器平台，在本地执行 npx prisma generate生成目标平台的引擎，\r\n# 否则就把源代码上传上去，执行npx prisma generate \u0026\u0026 npm run build, 修改配置文件,运行dist/main.js \r\nnpm run build\r\n# 把package.json移动到dist目录，上传dist目录到服务器，修改配置文件，\r\nnpm i \r\npm2 start main.js\r\n\r\n\r\n#前端\r\nnpm run build:prod\r\n#上传dist目录到服务器\r\n# 添加nginx配置\r\nlocation / {\r\n  try_files $uri $uri/ /index.html;\r\n}\r\n```\r\n\r\n# 更新日志\r\n\r\n## v1.0.0\r\n\r\n- 系统发布    -2024-06-11\r\n\r\n# Footer\r\n\r\n## 贡献\r\n\r\n欢迎大家一起参与:\r\n\r\n- 提交 [issues](https://github.com/Carole007/carole-admin/issues) 来报告问题和优化建议.\r\n- 主动 [pull requests](https://github.com/Carole007/carole-admin/pulls) 来优化代码.\r\n\r\n## 联系方式\r\n\r\nqq交流群：[952834924](https://qm.qq.com/q/CspBa2r6h2)\r\n\r\n\u003cimg src=\"assets/qun.jpg\" alt=\"qun\" style=\"width:25%;\" /\u003e\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCarole007%2Fcarole-admin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FCarole007%2Fcarole-admin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCarole007%2Fcarole-admin/lists"}