# qcdp-demo **Repository Path**: luobihao/qcdp-demo ## Basic Information - **Project Name**: qcdp-demo - **Description**: 基于spring cloud的微服务后台 由云南渠成科技有限公司搭建,并以此为基础开发相关业务应用系统。本项目仅作为开发测试和演示使用。 - **Primary Language**: Java - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2023-06-01 - **Last Updated**: 2025-04-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # QCDP-demo ## 介绍 基于spring cloud的微服务后台 由云南渠成科技有限公司搭建,并以此为基础开发相关业务应用系统。本项目仅作为开发测试和演示使用。 ## 上手及运行教程 #### 运行本项目 1. 从gitee获取项目代码及相关资料; 2. 在开发工具(推荐使用IDEA)中打开获取的代码,运行DemoApiApplication #### 相关资料及说明 1. 数据库表结构文档:\docs\db\demo.pdma.json;请使用PDManer打开查看; 2. 接口定义:访问 https://dx141sn1rv.apifox.cn/ ## 开发测试要求 1. 功能要求:根据apifox中的接口定义,完成“学生-Student”下6个接口和“班级-Class”下1个接口的编写工作; 2. 开发要求:参照项目中已有的“用户-User”和“部门-Dept”模块开发,包含分层结构、类和方法定义等;代码规范遵循下方的“编码规范与要求”章节内容; 3. 时间要求:要求在任务下达后2天内完成,在apifox中完成各接口的自测,最终使用web端完成前后端整体功能测试; 4. 代码管理要求:请自行在gitee上注册账号,将代码托管到gitee中;在保证代码可正常运行前提下,每完成1个接口进行1次代码的提交; 5. 工作成果要求:编写完成后在浏览器中访问web端进行功能实操演示,在gitee中对仓库各版本差异进行在线查看; ## 编码步骤 1. DTO定义:对照apifox中的定义(使用自动生成); 2. Controller定义:对照apifox中的定义; 3. Entity定义:对照PDManer中的定义(使用自动生成); 4. Service、Repository和Mapper定义; 5. 具体业务逻辑编写:推荐按照Controller——Service——Repository——Mapper的顺序进行编写; ## 编码规范与要求 ### 全局/通用编码规范 #### 代码注释要求 1. 每个类、接口、方法均需要有完整的注释。 2. 每个方法的注释应包含方法的用途说明、输入参数、返回结果。 3. 在IDEA中使用/**回车自动生成注释。 4. 复杂处理逻辑代码在代码之前添加注释进行步骤说明,并在每个处理步骤前添加注释说明步骤顺序及说明。 #### 代码统一格式化要求 1. 开发工具如IDEA配置统一的代码格式化设置,并设置保存时自动进行格式化。 2. 禁止使用空格或tab进行手动缩进或对齐。 3. 方法体之间、不同处理流程或分段代码之间使用1个空行进行分隔。去除多余的空行。 #### 文件夹命名规范 1. 文件夹名称全部使用小写命名。 2. 文件夹使用单个单词,尽量不使用2个及以上单词组合。 #### 文件命名规范(包含类、接口、实现类定义文件) 1. 文件名称使用首字母大写的驼峰式命名,第一个单词首字母大写。 2. 前缀: - 接口以大写字母I为前缀;(mapper和repository除外) - entity类不使用任何后缀; 3. 后缀: - controller类以Controller为后缀; - service类以Service为后缀; - 接口实现类以Impl为后缀; - repository类以Repository为后缀; - dto类以Dto为后缀; - entity类不使用任何后缀; - mapper类以Mapper为后缀; - 枚举类以Enum为后缀; ### 方法及输入输出 #### 方法定义规范: 1. 方法必须显示声明public或static,类中的私有方法不使用private修饰符。 2. 方法使用首字母大写的驼峰式命名,第一个单词所有字母均使用小写。 3. 方法名必须为动词或以动词开头命名,动词写全,不缩写。 - 推荐使用以下单词作为方法名起始单词:add、update、delete、get、query、set、save。 - 比如:deleteXXX,updateXXX;反例:delXXX,upXXX 4. 方法名需见名知意:看到方法名就能知道是做什么的,明确操作的对象主体、单复数、隐式条件。 - 操作的对象主体:默认情况下操作对象主体与当前Service对应,如UserService中方法操作(获取、新增、删除)的对象主体就是User,与Service对象主体一致的方法名可以不带对象名称。 - 如根据部门ID获取部门中的所有用户方法命名为:getUsersByDeptId。 - 单复数:操作(获取、查询、新增、删除)对象需明确操作的对象是单个还是多个,查询类方法可以使用数据类型指定多个对象的返回数据类型。如:getDeptsTree、getDeptsList。 - 隐式条件:如在项目管理Service中,获取所有项目列表(其中需要判断项目的状态标记),方法命名为getAllValidProjects,不推荐使用getProject、getProjects、getAllProjects。 5. 方法名需见名知意:看到方法名就能知道是做什么的,明确操作的对象主体、单复数、隐式条件。 - 操作的对象主体:默认情况下操作对象主体与当前Service对应,如UserService中方法操作(获取、新增、删除)的对象主体就是User,与Service对象主体一致的方法名可以不带对象名称。 - 如根据部门ID获取部门中的所有用户方法命名为:getUsersByDeptId。 - 单复数:操作(获取、查询、新增、删除)对象需明确操作的对象是单个还是多个,查询类方法可以使用数据类型指定多个对象的返回数据类型。如:getDeptsTree、getDeptsList。 #### 方法输入使用规范: 1. Controller中的方法输入使用基本数据类型或Dto,不允许使用Entity层对象。 2. Service中的方法输入使用基本数据类型或Dto,可以使用Entity层对象。 #### 方法输出使用规范: 1. Controller中的方法输出使用基本数据类型或Dto,不允许返回Entity层对象。 2. Service中的方法输出使用基本数据类型或Dto,可以返回Entity层对象。 3. Controller和Service中的新增、修改、删除、设置等方法返回结果使用String类型,返回null表示成功,返回非null表示错误信息。 **Controller**和**Service**中的方法及返回结果使用以下规范: | ***\*方法\**** | ***\*返回结果\**** | ***\*Controller\**** | ***\*Service\**** | | ------------------------------ | ------------------ | -------------------- | ----------------- | | 根据条件查询数据 | 集合 | query | query | | 根据指定的简单条件查询数据 | 集合 | queryXXXByXXX | queryXXXByXXX | | 根据id或主键获取记录详情 | 单个记录 | get | get | | 根据非主键条件获取记录详情 | 单个记录 | getByXXX | getByXXX | | 新增数据 | String | add | add | | 保存数据,具体根据实际业务处理 | String | save | save | | 修改数据 | String | update | update | | 删除数据 | String | delete | delete | #### 变量、集合 1. 临时变量可使用dto、en、condition、result等。 2. 循环中只能使用i、j、k、m、n。 3. Lamada中只能使用k、v、p、m、n。 ### 方法要求规范 1. 以下要求适用于Controller和Service中的方法。 2. 方法中可能出现的预期错误或异常(如输入的字符串需要转换为日期时间时转换错误),使用抛出QCPromptException异常进行处理。使用方法如下: throw new QCPromptException("对象不能为空"); 3. 方法中非预期错误或异常,不要进行捕获。 4. 方法中抛出非QCPromptException异常,最终返回给调用端的code为2,msg为异常信息,data为空。 5. 对日期、数值、字符串、Json等的转换和判断处理统一使用qc.common.core.utils中提供的工具类。 6. 对String类型的判断和处理统一使用中org.apache.commons.lang3.StringUtils工具类。 3.2.4.1 方法返回String类型 1. 对数据进行操作(新增、修改、删除等操作)返回类型定义为String类型,统一使用返回null表示成功,返回成功使用如下代码: return QCUnifyReturnValue.Success(); 2. 如方法中返回非null字符串表示成功,使用如下代码: return QCUnifyReturnValue.Success(“成功结果信息”); 3. 方法中出现的预期错误或异常,不使用抛出QCPromptException异常,直接返回其他信息表示错误或提示信息,如有效性校验不通过使用QCUnifyReturnValue.Warn方法返回结果。 #### 方法返回对象类型 1. 对象类型指代自定义对象,可为单个对象、对象集合或对象组合。 2. 方法中可能出现的预期错误或异常,使用抛出QCPromptException异常进行处理。抛出QCPromptException异常后最终返回给调用端的code为1,msg为异常信息,data为空。 #### 异常处理要求规范 1. 方法中可能出现的预期错误或异常(如输入的字符串需要转换为日期时间时转换错误),使用抛出QCPromptException异常进行处理。使用方法如下: throw new QCPromptException("对象不能为空"); 2. 方法中非预期错误或异常,不要进行捕获。 ### DTO层编写步骤及要求规范 #### 编写步骤 1. 对照Apifox中的数据模型设计结果,在dto中新建对应的包和类。 2. Dto类代码使用Apifox中生成代码,复制其中的属性定义部分即可(不需要复制get和set方法)。 3. 在dto类上添加@Data注解。 #### 要求规范 1. Dto类中只要属性定义,不要get、set方法和其他代码。 2. Dto类中属性的数据类型使用要求: - (1)不使用包装类型,使用boolean、int、double类型。如存在有可能为空值的定义为String类型,并在controller中进行控制判断处理。 - (2)不使用枚举类型,根据需要使用int或String类型,需要返回显示信息和对应的值时可同时返回。 - (3)不能使用entity中的类,根据结构需要可以引用其他Dto类或qc.common.core中QC开头的公用类。 ### Entity层编写步骤及要求规范 #### 编写步骤 1. Entity类代码使用PDManer生成代码(使用JavaMybatisPlus中Entity的代码,注意不要get和set方法,生成代码中的ApiModel和ApiModelProperty需去掉)。 2. 在entity类上添加@Data注解。 #### 要求规范 1. Entity层不划分包或目录,所有Entity类均在Entity项目的根目录下。 2. Entity类名称不带前缀或后缀,不推荐直接使用表名称。 3. Entity类上必须使用@Data和@TableName注解。 4. Entity类中只要属性定义,不要get、set方法和其他代码。 5. 联合主键的所有属性上均不加@TableId注解,将注解注释或去掉。 6. Entity类属性的数据类型使用要求: - (1)必须使用包装数据类型。必须使用以下数据类型:Integer、Short、Long、Byte、Float、Double、Character、Boolean、Date。不使用包装类型可能会出现修改数据出现非预期结果,具体查看“Mybatis-Plus”章节中的“实体类数据类型”章节。 - (2)数据库设计中为bit或tinyint的使用枚举类型,不使用Integer类型。枚举类型定义必须同时定义index和name,数据库中存储对应的index。 - (3)时间日期类型必须使用java.util.Date。 - (4)bool型的使用Boolean类型。 ### Api层编写步骤及要求规范 #### 编写步骤 1. 对照Apifox中的接口设计结果,在api中新建对应的controller。 2. 在controller上添加@RestController和@RequestMapping注解,@RequestMapping注解中的路径使用接口中的设计定义。 3. 在方法中编写调用Service层的代码。 #### 要求规范 1. Api层中输入参数使用至多2个简单类型,超过2个简单类型参数的封装为DTO对象。 2. 存在有输入参数通过Body传递的DTO对象,方法注解中必须同时支持GET和POST请求。(实测在web端请求中使用get方法时,无法通过body传递参数)同时支持GET和POST请求使用如下代码: @RequestMapping(value = "/query", method = {RequestMethod.GET, RequestMethod.POST}) 3. 对传入id参数的接口,同时编写ByParam和ByPath接口。并且显示使用required属性表名参数是否必须。 4. Api层中需要对输入参数进行判断和有效性验证。(不管Api层是否对输入参数进行判断和有效性验证,在Service层中均需要对输入参数进行判断和有效性验证。实际操作中,可以只在Service层中进行输入参数判断和有效性验证。) ### Repository层编写步骤及要求规范 #### 编写步骤 1. Repository类代码使用PDManer生成代码(使用JavaMybatisPlus中Mapper的代码)。 #### 要求规范 1. 生成的代码类名后缀为Mapper,注意修改为Repository。 2. Repository类为接口。 3. Repository类继承自BaseMapper 4. Repository类上添加@Mapper注解。 5. Repository中指定一个实体类名称。 ### Service层编写步骤及要求规范 #### 编写步骤 1. 传入参数判断及有效性验证代码。 2. 数据查询、操作代码。 3. 查询、操作结构判断代码,类型转换及返回。 #### 要求规范 1. Service的类名建议与Controller的名称保持一致,在一个Controller中进行关联多个操作时,引用对应的Service。 2. Service类上添加@Service注解。@Service注解提示错误时引入对应的Repository项目。 3. Service层中需要对输入参数进行判断和验证有效性。(不管Api层是否对输入参数进行判断和有效性验证,在Service层中均需要对输入参数进行判断和有效性验证。实际操作中,可以只在Service层中进行输入参数判断和有效性验证。) 4. Service中的代码按照如下顺序步骤编写:判断传入参数、构造查询、结果判断及转换返回。各步骤之间使用空1行进行分割(保证代码结构清晰)。 5. 涉及数据库操作的均使用MybatisPlus条件构造器的方式进行编码,禁止使用手写sql语句。 6. 涉及多表联合查询使用插件MyBatis-Plus-Join。 7. 涉及数据库操作的wrapper按照如下顺序步骤编写:select/update、where、orderby、limit。 8. 所有查询集合结果的必须要有排序规则。 ### Mapper层编写步骤及要求规范 #### 编写步骤 1. 定义DTO和Entity之间的映射转换。 #### 要求规范 1. Mapper类为接口。 2. Mapper的类名建议与Entity的名称保持一致。 3. Mapper类上添加@Mapper注解。 4. 在Mapper类中添加自动生成映射代码,如下(类名为UserloginLogsMapper): UserloginLogsMapper MAPPER = Mappers.getMapper(UserloginLogsMapper.class); 5. 项目中的模型有且仅有DTO和Entity,DTO与Entity的转换均在Service中(不在api中进行转换)。DTO作为api和service的输入输出类型,Entity只能在Service和Repository中出现。 ## 运行和测试步骤 ### 1.运行环境配置 - 下载qcdp-demo项目中docs文件下dist中的nginx-1.24.0和web文件并解压 - Nginx配置 1. 打开 nginx 目录下的 conf 目录中的 nginx.conf 文件 2. 找到第 56 行 `alias:` 修改成本地 web 目录的完整路径 3. 返回 nginx 根目录,双击运行 nginx.exe(命令窗口快速闪现后消失是正常现象,表示nginx已成功启动) 4. 验证nginx是否启动成功:打开浏览器访问 http://localhost:8080 ### 2. 本地服务启动与测试 1. 请确保已连接公司网络(QuChengTech),否则测试服务器将无法识别本地服务,导致服务注册失败 2. 启动本地`qcdp-demo`服务 3. 打开浏览器访问:http://localhost:8080/#/login?redirect=/demo 4. 在浏览器web界面中测试学生信息查询、新增、修改、删除、查看成绩均能正常使用。