# diet-back **Repository Path**: lventou/diet-back ## Basic Information - **Project Name**: diet-back - **Description**: 外接-diet服务 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-05-10 - **Last Updated**: 2026-03-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: 外接 ## README ### 目录结构 ``` src ├── main.ts # 应用入口文件 ├── app.module.ts # 根模块 ├── app.controller.ts # 根控制器(可选) ├── app.service.ts # 根服务(可选) ├── common # 公共模块和通用工具 │ ├── decorators # 自定义装饰器 │ ├── exceptions # 自定义异常 │ ├── filters # 全局过滤器 │ │ └── all-exceptions.filter.ts │ ├── guards # 守卫 │ ├── interceptors # 拦截器 │ ├── middlewares # 中间件 │ └── pipes # 管道 ├── config # 配置模块 │ ├── config.module.ts # 配置模块主文件 │ ├── app.config.ts # 应用配置 │ ├── database.config.ts # 数据库配置 │ └── swagger.config.ts # Swagger 配置 ├── modules # 业务模块 │ ├── demo # 示例模块 │ │ ├── demo.module.ts # 模块主文件 │ │ ├── demo.controller.ts # 控制器 │ │ ├── demo.service.ts # 服务 │ │ ├── entities # 数据实体 │ │ │ └── demo.entity.ts │ │ └── dto # 数据传输对象 │ │ ├── create-demo.dto.ts │ │ └── update-demo.dto.ts ├── shared # 可复用的工具或逻辑(如日志、常量、帮助函数) │ ├── logger # 日志工具 │ ├── helpers # 通用帮助函数 │ └── constants # 常量定义 ├── swagger # Swagger 文档相关 │ ├── swagger.config.ts └── test # 测试 ├── e2e # 端到端测试 ├── unit # 单元测试 └── jest-e2e.json ``` ### 文档 [swagger插件](https://nest.nodejs.cn/openapi/cli-plugin#google_vignette) > classValidatorShim 意思是写了@Max(10),会带到描述里面 ### 模块 小程序: ~~食物~~ ~~用户~~ 我可以这样理解吗,一个食物有多个单位,每个食物下的每个单位代表的分量也不同 一份青菜你定的300g 一盘青菜你订的600g 一份牛奶你订的100g 一盘牛奶你订的500g 一箱牛奶你订的1000g **这个还不确定先不做** 打卡记录(一份固定 100g) 早中晚餐记录(不要了) 营养分析(当天) 营养教育 ~~留言~~ ~~积分~~ ### 坑点 1. 该版本有 mysql 带有json数据,这是 mysql8以上才支持的,请注意 2. @Column({default:0,select:false }) 这里的 default 比xxx:number = 0 优先级低 select开了 false 之后,每次查询都是返回=后面的数值,因为每次都是新对象,同理修改数据的时候比如递增,也是不行的,必须查询出来拿到原本的值再去加才可以 不建议设置默认值和 select:false同用,要么就用 default:xxx,然后默认值再用 @ApiProperty({ default: []}) 去声明。要么就查询的时候手动去掉对应的字段 也就是 用viewCount?: number = 0; 就不要用 @Column({ select:false }) 如果要用就这样用 @Column({ default: false, select: false }) 如果需要文档,使用 @ApiProperty 去声明 3. ```ts @ApiHideProperty() @ManyToOne(() => User, (user) => user.analyticsEvents, { /** * 当主表中的一条记录被删除时,数据库会自动删除与之关联的外键记录 * 也就是 user 被删除,该条数据也会被删除 * 是针对外键的 */ onDelete: 'CASCADE', /** * 保存或删除主表记录时,TypeORM 会自动对关联的实体执行相应的操作 * 针对主表的 */ // cascade: true }) @JoinColumn({ name: 'userId' }) user?: User; // 就是子表开启onDelete ,主表开启 cascade ``` ### 部署 NODE_ENV=production node dist/main.js NODE_ENV=production nest start envFilePath: [`.env.${process.env.NODE_ENV}`, '.env'], 然后创建对应的 env 环境变量文件 plainToInstance 去同步dto和返回的字段 ### 关于 joinColumn joinColumn (外键)放在谁上,谁就有外键,就必须指向某个地方,不放外键的那个表绑定的数据可以为 null 简单来说,谁依附谁,外键就放谁身上。 按照 punch和 point 来举例 关系是:Punch (必须有 Point) → Point (可单独存在) 而不是 Point 必须依附 Punch(Point → Punch 是可选) punch必须会有一个 point,point 不一定要有punch 外键可以为 null 所以 这个外键应该放在 Punch 但是如果是死循环 创建 Punch 需要先有 Point ID,创建 Point 又需要先有 Punch ID,无法先后创建。 需要只保留一个方向的外键,另一端用普通关系即可,不要两个表都互相持有对方的外键。 把 pointId 放到 Punch 表(你已经做了) Point 表不存 punchId 字段,只是用 @OneToOne(() => Punch) 反向引用(不持有外键) 创建流程先创建 Punch(先插入 pointId=null), 创建 Point,拿到 pointId, 再更新 Punch,写入 pointI