diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..dfc8d74
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 03d9549..49798c3 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -1,6 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..712ab9d
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..2b63946
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/backend/src/main/java/lsgwr/exam/controller/ExamController.java b/backend/src/main/java/lsgwr/exam/controller/ExamController.java
index 4230346..99b50ad 100644
--- a/backend/src/main/java/lsgwr/exam/controller/ExamController.java
+++ b/backend/src/main/java/lsgwr/exam/controller/ExamController.java
@@ -29,39 +29,39 @@ public class ExamController {
@GetMapping("/question/all")
@ApiOperation("获取所有问题的列表")
- // 获取全部问题列表
+ // 获取全部问题列表。
ResultVO> getQuestionAll() {
- // 定义返回值
+ // 定义返回值。
ResultVO> resultVO;
try {
- // 调用examService获取全部问题列表
+ // 调用examService获取全部问题列表。
List questionAll = examService.getQuestionAll();
- // 返回成功结果
+ // 返回成功结果。
resultVO = new ResultVO<>(0, "获取全部问题列表成功", questionAll);
} catch (Exception e) {
- // 打印异常信息
+ // 打印异常信息。
e.printStackTrace();
- // 返回失败结果
+ // 返回失败结果。
resultVO = new ResultVO<>(-1, "获取全部问题列表失败", null);
}
- // 返回结果
+ // 返回结果。
return resultVO;
}
@PostMapping("/question/update")
@ApiOperation("更新问题")
ResultVO questionUpdate(@RequestBody QuestionVo questionVo) {
- // 完成问题的更新
+ // 完成问题的更新。
System.out.println(questionVo);
try {
- // 调用examService的updateQuestion方法,更新问题
+ // 调用examService的updateQuestion方法,更新问题。
QuestionVo questionVoResult = examService.updateQuestion(questionVo);
- // 返回更新成功的结果
+ // 返回更新成功的结果。
return new ResultVO<>(0, "更新问题成功", questionVoResult);
} catch (Exception e) {
- // 打印异常信息
+ // 打印异常信息。
e.printStackTrace();
- // 返回更新失败的结果
+ // 返回更新失败的结果。
return new ResultVO<>(-1, "更新问题失败", null);
}
}
@@ -69,75 +69,75 @@ ResultVO> getQuestionAll() {
@PostMapping("/question/create")
@ApiOperation("创建问题")
ResultVO questionCreate(@RequestBody QuestionCreateSimplifyVo questionCreateSimplifyVo, HttpServletRequest request) {
- // 创建一个QuestionCreateVo对象
+ // 创建一个QuestionCreateVo对象。
QuestionCreateVo questionCreateVo = new QuestionCreateVo();
- // 把能拷贝过来的属性都拷贝过来
+ // 把能拷贝过来的属性都拷贝过来。
BeanUtils.copyProperties(questionCreateSimplifyVo, questionCreateVo);
- // 设置创建者信息
+ // 设置创建者信息。
String userId = (String) request.getAttribute("user_id");
questionCreateVo.setQuestionCreatorId(userId);
System.out.println(questionCreateVo);
try {
- // 调用examService的questionCreate方法创建问题
+ // 调用examService的questionCreate方法创建问题。
examService.questionCreate(questionCreateVo);
- // 返回问题创建成功的ResultVO
+ // 返回问题创建成功的ResultVO。
return new ResultVO<>(0, "问题创建成功", null);
} catch (Exception e) {
- // 打印异常信息
+ // 打印异常信息。
e.printStackTrace();
- // 返回创建问题失败的ResultVO
+ // 返回创建问题失败的ResultVO。
return new ResultVO<>(-1, "创建问题失败", null);
}
}
@GetMapping("/question/selection")
@ApiOperation("获取问题分类的相关选项")
- // 获取问题分类选项
+ // 获取问题分类选项。
ResultVO getSelections() {
- // 调用examService的getSelections方法获取问题分类选项
+ // 调用examService的getSelections方法获取问题分类选项。
QuestionSelectionVo questionSelectionVo = examService.getSelections();
- // 如果获取成功
+ // 如果获取成功。
if (questionSelectionVo != null) {
- // 返回成功的结果
+ // 返回成功的结果。
return new ResultVO<>(0, "获取问题分类选项成功", questionSelectionVo);
} else {
- // 否则返回失败的结果
+ // 否则返回失败的结果。
return new ResultVO<>(-1, "获取问题分类选项失败", null);
}
}
@GetMapping("/question/detail/{id}")
@ApiOperation("根据问题的id获取问题的详细信息")
ResultVO getQuestionDetail(@PathVariable String id) {
- // 根据问题id获取问题的详细信息
+ // 根据问题id获取问题的详细信息。
System.out.println(id);
ResultVO resultVO;
try {
- // 调用examService的getQuestionDetail方法,根据问题id获取问题的详细信息
+ // 调用examService的getQuestionDetail方法,根据问题id获取问题的详细信息。
QuestionDetailVo questionDetailVo = examService.getQuestionDetail(id);
- // 如果获取成功,则返回ResultVO对象,状态码为0,提示信息为"获取问题详情成功",数据为questionDetailVo
+ // 如果获取成功,则返回ResultVO对象,状态码为0,提示信息为"获取问题详情成功",数据为questionDetailVo。
resultVO = new ResultVO<>(0, "获取问题详情成功", questionDetailVo);
} catch (Exception e) {
- // 如果获取失败,则打印异常信息,并返回ResultVO对象,状态码为-1,提示信息为"获取问题详情失败",数据为null
+ // 如果获取失败,则打印异常信息,并返回ResultVO对象,状态码为-1,提示信息为"获取问题详情失败",数据为null。
e.printStackTrace();
resultVO = new ResultVO<>(-1, "获取问题详情失败", null);
}
- // 返回ResultVO对象
+ // 返回ResultVO对象。
return resultVO;
}
@GetMapping("/all")
@ApiOperation("获取全部考试的列表")
ResultVO> getExamAll() {
- // 需要拼接前端需要的考试列表对象
+ // 需要拼接前端需要的考试列表对象。
ResultVO> resultVO;
try {
- // 调用examService的getExamAll方法获取全部考试的列表
+ // 调用examService的getExamAll方法获取全部考试的列表。
List examVos = examService.getExamAll();
- // 将获取到的考试列表封装到ResultVO对象中,并返回
+ // 将获取到的考试列表封装到ResultVO对象中,并返回。
resultVO = new ResultVO<>(0, "获取全部考试的列表成功", examVos);
} catch (Exception e) {
- // 捕获异常,并打印异常信息
+ // 捕获异常,并打印异常信息。
e.printStackTrace();
- // 将异常信息封装到ResultVO对象中,并返回
+ // 将异常信息封装到ResultVO对象中,并返回。
resultVO = new ResultVO<>(-1, "获取全部考试的列表失败", null);
}
return resultVO;
@@ -145,58 +145,58 @@ ResultVO getSelections() {
@GetMapping("/question/type/list")
@ApiOperation("获取问题列表,按照单选、多选和判断题分类返回")
ResultVO getExamQuestionTypeList() {
- // 获取问题的分类列表
+ // 获取问题的分类列表。
ResultVO resultVO;
try {
- // 调用examService的getExamQuestionType方法获取问题分类列表
+ // 调用examService的getExamQuestionType方法获取问题分类列表。
ExamQuestionTypeVo examQuestionTypeVo = examService.getExamQuestionType();
- // 如果获取成功,则返回成功的结果
+ // 如果获取成功,则返回成功的结果。
resultVO = new ResultVO<>(0, "获取问题列表成功", examQuestionTypeVo);
} catch (Exception e) {
- // 如果获取失败,则打印异常信息,并返回失败的结果
+ // 如果获取失败,则打印异常信息,并返回失败的结果。
e.printStackTrace();
resultVO = new ResultVO<>(-1, "获取问题列表失败", null);
}
- // 返回结果
+ // 返回结果。
return resultVO;
}
@PostMapping("/create")
@ApiOperation("创建考试")
ResultVO createExam(@RequestBody ExamCreateVo examCreateVo, HttpServletRequest request) {
- // 从前端传参数过来,在这里完成考试的入库
+ // 从前端传参数过来,在这里完成考试的入库。
ResultVO resultVO;
- // 获取当前用户的id
+ // 获取当前用户的id。
String userId = (String) request.getAttribute("user_id");
try {
- // 调用examService的create方法,将examCreateVo和userId作为参数传入,创建考试
+ // 调用examService的create方法,将examCreateVo和userId作为参数传入,创建考试。
Exam exam = examService.create(examCreateVo, userId);
- // 创建一个ResultVO对象,将创建成功的考试信息返回
+ // 创建一个ResultVO对象,将创建成功的考试信息返回。
resultVO = new ResultVO<>(0, "创建考试成功", exam);
} catch (Exception e) {
- // 捕获异常,打印异常信息,并创建一个ResultVO对象,将创建失败的考试信息返回
+ // 捕获异常,打印异常信息,并创建一个ResultVO对象,将创建失败的考试信息返回。
e.printStackTrace();
resultVO = new ResultVO<>(-1, "创建考试失败", null);
}
- // 返回ResultVO对象
+ // 返回ResultVO对象。
return resultVO;
}
@PostMapping("/update")
@ApiOperation("更新考试")
ResultVO updateExam(@RequestBody ExamVo examVo, HttpServletRequest request) {
- // 从前端传参数过来,在这里完成考试的入库
+ // 从前端传参数过来,在这里完成考试的入库。
ResultVO resultVO;
- // 获取当前用户id
+ // 获取当前用户id。
String userId = (String) request.getAttribute("user_id");
try {
- // 调用service层更新考试
+ // 调用service层更新考试。
Exam exam = examService.update(examVo, userId);
- // 返回更新成功的resultVO
+ // 返回更新成功的resultVO。
resultVO = new ResultVO<>(0, "更新考试成功", exam);
} catch (Exception e) {
- // 打印异常信息
+ // 打印异常信息。
e.printStackTrace();
- // 返回更新失败的resultVO
+ // 返回更新失败的resultVO。
resultVO = new ResultVO<>(-1, "更新考试失败", null);
}
return resultVO;
@@ -205,15 +205,15 @@ ResultVO getSelections() {
@GetMapping("/card/list")
@ApiOperation("获取考试列表,适配前端卡片列表")
ResultVO> getExamCardList() {
- // 获取考试列表卡片
+ // 获取考试列表卡片。
ResultVO> resultVO;
try {
- // 调用examService的getExamCardList方法获取考试列表卡片
+ // 调用examService的getExamCardList方法获取考试列表卡片。
List examCardVoList = examService.getExamCardList();
- // 如果获取成功,则返回成功的结果
+ // 如果获取成功,则返回成功的结果。
resultVO = new ResultVO<>(0, "获取考试列表卡片成功", examCardVoList);
} catch (Exception e) {
- // 如果获取失败,则打印异常信息,并返回失败的结果
+ // 如果获取失败,则打印异常信息,并返回失败的结果。
e.printStackTrace();
resultVO = new ResultVO<>(-1, "获取考试列表卡片失败", null);
}
@@ -224,7 +224,7 @@ ResultVO getSelections() {
@GetMapping("/detail/{id}")
@ApiOperation("根据考试的id,获取考试详情")
ResultVO getExamDetail(@PathVariable String id) {
- // 根据id获取考试详情
+ // 根据id获取考试详情。
ResultVO resultVO;
try {
ExamDetailVo examDetail = examService.getExamDetail(id);
@@ -239,18 +239,18 @@ ResultVO getSelections() {
@ApiOperation("根据用户提交的答案对指定id的考试判分")
// 完成考试
ResultVO finishExam(@PathVariable String examId, @RequestBody HashMap> answersMap, HttpServletRequest request) {
- // 定义返回结果
+ // 定义返回结果。
ResultVO resultVO;
try {
- // 拦截器里设置上的用户id
+ // 拦截器里设置上的用户id。
String userId = (String) request.getAttribute("user_id");
- // 下面根据用户提交的信息进行判分,返回用户的得分情况
+ // 下面根据用户提交的信息进行判分,返回用户的得分情况。
ExamRecord examRecord = examService.judge(userId, examId, answersMap);
- // 返回结果
+ // 返回结果。
resultVO = new ResultVO<>(0, "考卷提交成功", examRecord);
} catch (Exception e) {
e.printStackTrace();
- // 返回错误结果
+ // 返回错误结果。
resultVO = new ResultVO<>(-1, "考卷提交失败", null);
}
return resultVO;
@@ -258,13 +258,13 @@ ResultVO getSelections() {
@GetMapping("/record/list")
@ApiOperation("获取当前用户的考试记录")
- // 获取考试记录列表
+ // 获取考试记录列表。
ResultVO> getExamRecordList(HttpServletRequest request) {
ResultVO> resultVO;
try {
- // 拦截器里设置上的用户id
+ // 拦截器里设置上的用户id。
String userId = (String) request.getAttribute("user_id");
- // 下面根据用户账号拿到他(她所有的考试信息),注意要用VO封装下
+ // 下面根据用户账号拿到他(她所有的考试信息),注意要用VO封装下。
List examRecordVoList = examService.getExamRecordList(userId);
resultVO = new ResultVO<>(0, "获取考试记录成功", examRecordVoList);
} catch (Exception e) {
@@ -277,20 +277,20 @@ ResultVO getSelections() {
@GetMapping("/record/detail/{recordId}")
@ApiOperation("根据考试记录id获取考试记录详情")
ResultVO getExamRecordDetail(@PathVariable String recordId) {
- // 定义返回结果
+ // 定义返回结果。
ResultVO resultVO;
try {
- // 调用examService获取考试记录详情
+ // 调用examService获取考试记录详情。
RecordDetailVo recordDetailVo = examService.getRecordDetail(recordId);
- // 返回成功结果
+ // 返回成功结果。
resultVO = new ResultVO<>(0, "获取考试记录详情成功", recordDetailVo);
} catch (Exception e) {
- // 打印异常信息
+ // 打印异常信息。
e.printStackTrace();
- // 返回失败结果
+ // 返回失败结果。
resultVO = new ResultVO<>(-1, "获取考试记录详情失败", null);
}
- // 返回结果
+ // 返回结果。
return resultVO;
}
}
diff --git a/backend/src/main/java/lsgwr/exam/controller/UploadDownloadController.java b/backend/src/main/java/lsgwr/exam/controller/UploadDownloadController.java
index 55f3352..35c7cc2 100644
--- a/backend/src/main/java/lsgwr/exam/controller/UploadDownloadController.java
+++ b/backend/src/main/java/lsgwr/exam/controller/UploadDownloadController.java
@@ -42,33 +42,33 @@ public class UploadDownloadController {
@ApiOperation("单文件上传,支持同时传入参数")
@PostMapping("/api/upload/singleAndparas")
- // 单文件上传
+ // 单文件上传。
public String uploadFileSingle(@RequestParam("dir") String dir, @RequestParam("file") MultipartFile uploadfile) {
- // 调用FileTransUtil工具类中的uploadFile方法,将上传的文件和目录作为参数传入
+ // 调用FileTransUtil工具类中的uploadFile方法,将上传的文件和目录作为参数传入。
return FileTransUtil.uploadFile(uploadfile, dir);
}
- // 单文件上传,支持同时传入参数,Model
+ // 单文件上传,支持同时传入参数,Model。
@ApiOperation("单文件上传,支持同时传入参数,Model")
@PostMapping("/upload/single/model")
public String singleUploadFileModel(@ModelAttribute("model") UploadModel2 model) {
- // 调用FileTransUtil工具类中的uploadFile方法,将上传的文件和目录作为参数传入
+ // 调用FileTransUtil工具类中的uploadFile方法,将上传的文件和目录作为参数传入。
return FileTransUtil.uploadFile(model.getFile(), model.getDir());
}
- // 多文件上传,支持同时传入参数
+ // 多文件上传,支持同时传入参数。
@ApiOperation("多文件上传,支持同时传入参数")
@PostMapping("upload/multiAndparas")
public String uploadFileMulti(@RequestParam("dir") String dir, @RequestParam("files") MultipartFile[] uploadfiles) {
- // 调用FileTransUtil工具类中的uploadFiles方法,将上传的文件数组和目录作为参数传入
+ // 调用FileTransUtil工具类中的uploadFiles方法,将上传的文件数组和目录作为参数传入。
return FileTransUtil.uploadFiles(uploadfiles, dir);
}
- // 多文件上传,支持同时传入参数
+ // 多文件上传,支持同时传入参数。
@ApiOperation("多文件上传,支持同时传入参数")
@PostMapping(value = "/upload/multi/model")
public String multiUploadFileModel(@ModelAttribute(("model")) UploadModel model) {
- // 调用FileTransUtil工具类中的uploadFiles方法,将上传的文件数组和目录作为参数传入
+ // 调用FileTransUtil工具类中的uploadFiles方法,将上传的文件数组和目录作为参数传入。
return FileTransUtil.uploadFiles(model.getFiles(), model.getDir());
}
@@ -76,7 +76,7 @@ public class UploadDownloadController {
@ApiOperation("Get下载文件")
@GetMapping(value = "/download/get")
public ResponseEntity downloadFileGet(@RequestParam String filePath) throws IOException {
- // 调用FileTransUtil工具类中的downloadFile方法,将文件路径作为参数传入
+ // 调用FileTransUtil工具类中的downloadFile方法,将文件路径作为参数传入。
return FileTransUtil.downloadFile(filePath);
}
@@ -84,7 +84,7 @@ public class UploadDownloadController {
@ApiOperation("Post下载文件")
@PostMapping(value = "/download/post")
public ResponseEntity downloadFilePost(@RequestBody DownloadQo downloadQo) throws IOException {
- // 调用FileTransUtil工具类中的downloadFile方法,将文件路径作为参数传入
+ // 调用FileTransUtil工具类中的downloadFile方法,将文件路径作为参数传入。
return FileTransUtil.downloadFile(downloadQo.getPath());
}
}
diff --git a/backend/src/main/java/lsgwr/exam/controller/UserController.java b/backend/src/main/java/lsgwr/exam/controller/UserController.java
index e594d70..af0536a 100644
--- a/backend/src/main/java/lsgwr/exam/controller/UserController.java
+++ b/backend/src/main/java/lsgwr/exam/controller/UserController.java
@@ -1,10 +1,99 @@
-// 使用Spring Boot框架
-@SpringBootApplication
-public class ExamApplication {
-
- // 主方法
- public static void main(String[] args) {
- // 运行Spring Boot应用程序
- SpringApplication.run(ExamApplication.class, args);
+/***********************************************************
+ * @Description : 对外REST接口
+ * @author : 梁山广(Laing Shan Guang)
+ * @date : 2019-05-16 23:45
+ * @email : liangshanguang2@gmail.com
+ ***********************************************************/
+package lsgwr.exam.controller;
+
+import lsgwr.exam.dto.RegisterDTO;
+import lsgwr.exam.entity.User;
+import lsgwr.exam.enums.ResultEnum;
+import lsgwr.exam.qo.LoginQo;
+import lsgwr.exam.service.UserService;
+import lsgwr.exam.vo.ResultVO;
+import lsgwr.exam.vo.UserInfoVo;
+import lsgwr.exam.vo.UserVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@Api(tags = "User APIs")
+@RequestMapping("/api/user")
+public class UserController {
+
+ @Autowired
+ private UserService userService;
+
+ @PostMapping("/register")
+ @ApiOperation("注册")
+ ResultVO register(@RequestBody RegisterDTO registerDTO) {
+ ResultVO resultVO;
+ // 注册信息的完善,还有唯一性校验没(用户名、邮箱和手机号)已经在user表中通过unique来设置了
+ User user = userService.register(registerDTO);
+ if (user != null) {
+ // 注册成功
+ resultVO = new ResultVO<>(ResultEnum.REGISTER_SUCCESS.getCode(), ResultEnum.REGISTER_SUCCESS.getMessage(), user);
+ } else {
+ resultVO = new ResultVO<>(ResultEnum.REGISTER_FAILED.getCode(), ResultEnum.REGISTER_FAILED.getMessage(), null);
+ }
+ return resultVO;
+ }
+
+ @PostMapping("/login")
+ @ApiOperation("根据用户名或邮箱登录,登录成功返回token")
+ ResultVO login(@RequestBody LoginQo loginQo) { // 这里不用手机号是因为手机号和用户名难以进行格式区分,而用户名和
+ // 用户登录
+ ResultVO resultVO;
+ String token = userService.login(loginQo);
+ if (token != null) {
+ // 登录成功
+ resultVO = new ResultVO<>(ResultEnum.LOGIN_SUCCESS.getCode(), ResultEnum.LOGIN_SUCCESS.getMessage(), token);
+ } else {
+ // 登录失败
+ resultVO = new ResultVO<>(ResultEnum.LOGIN_FAILED.getCode(), ResultEnum.LOGIN_FAILED.getMessage(), null);
+ }
+ return resultVO;
+ }
+
+ @GetMapping("/user-info")
+ @ApiOperation("获取用户信息")
+ // 根据请求获取用户信息
+ ResultVO getUserInfo(HttpServletRequest request) {
+ // 从请求中获取用户ID
+ String userId = (String) request.getAttribute("user_id");
+ // 根据用户ID获取用户信息
+ UserVo userVo = userService.getUserInfo(userId);
+ // 返回用户信息
+ return new ResultVO<>(ResultEnum.GET_INFO_SUCCESS.getCode(), ResultEnum.GET_INFO_SUCCESS.getMessage(), userVo);
+ }
+
+ @GetMapping("/info")
+ @ApiOperation("获取用户的详细信息,包括个人信息页面和操作权限")
+ // 获取用户信息的接口
+ ResultVO getInfo(HttpServletRequest request) {
+ // 打印进入接口的日志
+ System.out.println("进入/user/info的获取用户信息的接口");
+ // 获取用户ID
+ String userId = (String) request.getAttribute("user_id");
+ // 调用userService获取用户信息
+ UserInfoVo userInfoVo = userService.getInfo(userId);
+ // 返回结果
+ return new ResultVO<>(ResultEnum.GET_INFO_SUCCESS.getCode(), ResultEnum.GET_INFO_SUCCESS.getMessage(), userInfoVo);
+ }
+
+ @GetMapping("/test")
+ @ApiOperation("测试接口")
+ String test(HttpServletRequest request) {
+ // 下面这两个属性都是登录拦截器从token中解析地,当用户名不对或者token过期时是走不到接口内的
+ String userId = (String) request.getAttribute("user_id");
+ String username = (String) request.getAttribute("username");
+ System.out.println("用户id:" + userId);
+ System.out.println("用户名:" + username);
+ return "用户id:" + userId + "\n用户名:" + username;
}
}
\ No newline at end of file