# vitamin-project-management **Repository Path**: scut-skyworth-club/vitamin-project-management ## Basic Information - **Project Name**: vitamin-project-management - **Description**: 项目管理项目demo - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2021-01-15 - **Last Updated**: 2021-05-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # vitamin-project-management #### 介绍 维生素俱乐部项目管理项目后端demo 开发接口时尽量站在前端开发角度,考虑需要什么参数、返回值、接口功能等。 有问题一起讨论:-) #### 软件架构 demo目前有三个模块:1. 项目管理模块;2. 文件上传下载模块;3. 登录认证模块 #### 安装教程 1. clone到本地,用idea打开 #### 任务 1. 登录认证模块服务与接口设计与编写(一人) 2. 项目管理模块服务与接口设计与编写(两人) 3. 文件上传下载模块服务与接口设计与编写(一人) #### 服务与接口描述 ##### 用户认证服务与接口: ``` 1. 用户登录:用户名密码登录,记录token于数据库,返回token作为登录凭证 2. 用户认证:根据用户名和token认证用户登录信息是否有效 3. 权限认证:用户是否有权限对当前项目进行改动,如只有项目创建者才可以修改项目信息 ``` ##### 项目管理服务与接口: ``` 1. 发布新项目,在数据库中写入数据 2. 发布新需求,在数据库中写入数据 3. 查看现有项目(返回项目描述、文件(包含下载链接)、项目需求、参与者等有关信息) 4. 对现有项目进行更改(创建者) ``` ##### 文件加载服务与接口: ``` 1. 上传文件 2. 下载文件 3. 生成文件下载链接 4. 查看项目对应文件 5. FileUtils类 ``` #### 代码规范: 1. 除了用户登录接口以外,其他接口在调用服务执行业务逻辑前都要调用*用户认证服务*确保用户登录信息有效。 2. 基本属性用project_id这种形式,方法用getUsername()这种驼峰法写。 3. 项目使用swagger2创建接口文档,每一个接口类上的注释要写上负责人,修改日期,每一个接口都要写上用途、参数、返回值类型,接口内调用服务时最好写好调用逻辑。swagger2常用注解如下: ```sql @Api:用在请求的类上,表示对类的说明 tags="说明该类的作用,可以在UI界面上看到的注解" value="该参数没什么意义,在UI界面上也看到,所以不需要配置" @ApiOperation:用在请求的方法上,说明方法的用途、作用 value="说明方法的用途、作用" notes="方法的备注说明" @ApiImplicitParams:用在请求的方法上,表示一组参数说明 @ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面 name:参数名 value:参数的汉字说明、解释 required:参数是否必须传 paramType:参数放在哪个地方 · header --> 请求参数的获取:@RequestHeader · query --> 请求参数的获取:@RequestParam · path(用于restful接口)--> 请求参数的获取:@PathVariable · body(不常用) · form(不常用) dataType:参数类型,默认String,其它值dataType="Integer" defaultValue:参数的默认值 @ApiResponses:用在请求的方法上,表示一组响应 @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息 code:数字,例如400 message:信息,例如"请求参数没填好" response:抛出异常的类 @ApiModel:用于响应类上,表示一个返回响应数据的信息 (这种一般用在post创建的时候,使用@RequestBody这样的场景, 请求参数无法使用@ApiImplicitParam注解进行描述的时候) @ApiModelProperty:用在属性上,描述响应类的属性 ``` 参考代码如下: ```java /** * 负责人:某美女 * 修改日期:1.15 */ @RestController @Api(tags = "用户认证接口") // swagger2注解 public class CertificationController { @Autowired CertificationMapper mapper; @Autowired CertificationService service; @PostMapping("/login") @ApiOperation("用户登录接口") // swagger2注解 @ApiImplicitParams({ @ApiImplicitParam(name = "username", value = "用户名"), @ApiImplicitParam(name = "password", value = "密码") }) public String login(HttpServletRequest request, @RequestBody Project p){ // 调用用户登录服务进行登录,传入用户名和密码,返回用户token return service.loginService(request.getParameter("username"), request.getParameter("password")); } } ``` 4. 编写各类方法时,注释应写上名称、用途、负责人、修改日期、参数、返回值。 除了返回实际信息的,其他以成功/失败为返回值的服务直接用ResultUtils工具类里的方法作为返回值: ```java /** * 做某事 * 通过这个方法完成某件事情 * * 负责人:某帅哥 * 修改日期:1.15 * * @param username 用户名 * @return 成功200 失败-100 */ public String doSomething(String username){ return ResultUtils.doFail(); // ResultUtils.doSuccess(); } ``` 5. 工具包内包含各类辅助方法,可以写也可以用: ```java /** * 创建人:某靓女 * 普通工具类 */ public class Utils { // 生成n为随机数字+字母组合的字符串 public static String getRandCode(int n){ StringBuilder rand = new StringBuilder(); Random random = new Random(); for (int i = 0; i < n; i++) { // 输出字母还是数字 boolean charOrNum = random.nextInt(2) % 2 == 0; // 字符串 if (charOrNum) { // 取得大写字母还是小写字母 int choice = random.nextInt(2) % 2 == 0 ? 65 : 97; rand.append((char) (choice + random.nextInt(26))); } else { // 数字 rand.append(String.valueOf(random.nextInt(10))); } } return rand.toString(); } } ``` 6. Mapper接口与Mybatis接口编写,mapper接口写上负责人、修改日期、接口功能,xml里写上功能: ```java @Repository public interface CertificationMapper { /* * 负责人:某某 * 修改日期:1.15 * * 通过用户名查找密码 */ String findPwdByUsername(String username); } ``` ```xml ``` 7. 目前已有默认的与数据库表对应的实体类,数据库具体参数详见实体类注释;需要进一步封装实体类时,参考数据库设计,属性名与数据库一致,写上负责人,实体类用途,修改日期,写明swagger2的注解: ```java /** * 负责人:某靓仔 * 创建新实体类的示例,用于返回项目信息 * 修改日期:1.15 */ @ApiModel public class ProjectExtends { @ApiModelProperty(value = "项目id") private String project_id; @ApiModelProperty(value = "创建者昵称") private String creator_nickname; @ApiModelProperty(value = "参与者列表") private List participants; @ApiModelProperty(value = "文件列表") private List file_list; @ApiModelProperty(value = "基本描述") private String basic_description; @ApiModelProperty(value = "详细描述") private String detailed_description; @ApiModelProperty(value = "技术栈") private String technology_stack; @ApiModelProperty(value = "创建时间") private String create_time; @ApiModelProperty(value = "预计完成时间") private String finish_time; public Project() { } // 全参数构造函数,getter和setter方法 public Project(String project_id, String creator_username, String basic_description, String detailed_description, String technology_stack, String create_time, String finish_time) { this.project_id = project_id; this.creator_username = creator_username; this.basic_description = basic_description; this.detailed_description = detailed_description; this.technology_stack = technology_stack; this.create_time = create_time; this.finish_time = finish_time; } public String getProject_id() { return project_id; } public void setProject_id(String project_id) { this.project_id = project_id; } ```