From dcf4b04e435ea75afe338b2780dcb1e981c1e8f7 Mon Sep 17 00:00:00 2001 From: Pope Date: Fri, 19 Mar 2021 20:49:22 +0800 Subject: [PATCH] =?UTF-8?q?2021-3-19=20=E4=BF=AE=E6=94=B9=E4=BA=86?= =?UTF-8?q?=E8=B0=83=E6=9F=A5=E5=AF=B9=E8=B1=A1=E4=B8=8E=E6=B5=81=E8=B0=83?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E9=83=A8=E5=88=86=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- log/survey-INFO-2021-03-04_1.log.gz | Bin 0 -> 36967 bytes log/survey-INFO-2021-03-12_1.log.gz | Bin 0 -> 19955 bytes log/survey-INFO-2021-03-18_1.log.gz | Bin 0 -> 93792 bytes .../survey/config/AuthFilterConfig.java | 17 +- .../InvestigationRecordController.java | 120 ----- .../survey/controller/MetaDataController.java | 73 +++ .../survey/controller/ProjectController.java | 73 +++ .../survey/controller/RecordController.java | 85 ++++ .../controller/RespondentController.java | 74 +-- .../survey/controller/RoleController.java | 89 ++-- .../survey/controller/UserController.java | 115 ++--- .../advice/GlobalExceptionHandler.java | 76 ++-- .../survey/dao/InvestigationRecordDao.java | 88 ---- .../com/example/survey/dao/MetaDataDao.java | 67 +++ .../com/example/survey/dao/ProjectDao.java | 53 +++ .../com/example/survey/dao/RecordDao.java | 78 ++++ .../com/example/survey/dao/RespondentDao.java | 80 +++- .../java/com/example/survey/dao/RoleDao.java | 33 +- .../java/com/example/survey/dao/UserDao.java | 59 +-- .../survey/dao/impl/DepartmentDaoImpl.java | 5 - .../dao/impl/InvestigationRecordDaoImpl.java | 125 ----- .../survey/dao/impl/MetaDataDaoImpl.java | 77 ++++ .../survey/dao/impl/ProjectDaoImpl.java | 67 +++ .../survey/dao/impl/RecordDaoImpl.java | 124 +++++ .../survey/dao/impl/RespondentDaoImpl.java | 126 +++-- .../example/survey/dao/impl/RoleDaoImpl.java | 36 +- .../example/survey/dao/impl/UserDaoImpl.java | 97 ++-- .../com/example/survey/dto/RespondentDto.java | 62 --- .../java/com/example/survey/dto/UserDto.java | 35 -- .../survey/dto/inner/RelevantUserInfo.java | 35 -- .../dto/metaData/CreateMetaDataDTO.java | 18 + .../dto/metaData/DeleteMetaDataDTO.java | 11 + .../dto/metaData/ModifyMetaDataDTO.java | 18 + .../survey/dto/project/CreateProjectDTO.java | 46 ++ .../survey/dto/project/ModifyProjectDTO.java | 20 + .../survey/dto/project/ModifyStateDTO.java | 12 + .../survey/dto/record/ModifyRecordDTO.java | 18 + .../survey/dto/record/ReviewRecordDTO.java | 20 + .../survey/dto/record/SubmitRecordDTO.java | 26 ++ .../respondent/CreateRespondentDTO.java} | 30 +- .../dto/respondent/DeleteRespondentDTO.java | 18 + .../dto/respondent/ModifyRespondentDTO.java | 52 +++ .../respondent/ModifyRespondentUserDTO.java | 13 + .../survey/dto/role/CreateRoleDTO.java | 29 ++ .../role/DeleteRoleDTO.java} | 6 +- .../survey/dto/role/ModifyRoleDTO.java | 19 + .../user/CreateUserDTO.java} | 6 +- .../user/DeleteUserDTO.java} | 6 +- .../LoginVo.java => dto/user/LoginDTO.java} | 6 +- .../user/ModifyUserInfoDTO.java} | 6 +- .../survey/dto/user/ModifyUserRoleDTO.java | 19 + .../user/ResetPwdDTO.java} | 6 +- .../java/com/example/survey/entity/Audit.java | 20 + .../com/example/survey/entity/Department.java | 6 +- .../survey/entity/InvestigationRecord.java | 339 -------------- .../com/example/survey/entity/MetaData.java | 23 + .../com/example/survey/entity/Project.java | 73 +++ .../com/example/survey/entity/Record.java | 63 +++ .../com/example/survey/entity/Respondent.java | 49 +- .../java/com/example/survey/entity/Role.java | 7 +- .../java/com/example/survey/entity/User.java | 22 +- .../entity/inner/AdministrativeArea.java | 5 +- .../survey/entity/inner/Detection.java | 36 -- .../survey/entity/inner/EntryExperience.java | 120 ----- .../survey/entity/inner/EntryPort.java | 41 -- .../survey/entity/inner/FieldToName.java | 12 + .../survey/entity/inner/LiveHistory.java | 41 -- .../example/survey/entity/inner/Location.java | 30 -- .../survey/entity/inner/Operation.java | 107 +++++ .../entity/inner/OperationInformation.java | 113 ----- .../survey/entity/inner/ProjectPart.java | 34 ++ .../inner/SuperiorInfectedIndividual.java | 72 --- .../survey/entity/inner/TempHistory.java | 30 -- .../survey/entity/inner/TravelHistory.java | 43 -- .../survey/enumeration/OpTypeEnum.java | 42 ++ .../survey/enumeration/ProjectStateEnum.java | 32 ++ .../survey/enumeration/RecordStateEnum.java | 41 ++ .../enumeration/RespondentStateEnum.java | 8 +- .../survey/enumeration/ResultEnum.java | 74 +++ .../survey/exception/AuthException.java | 11 +- .../survey/exception/DepartmentException.java | 13 +- .../survey/exception/MetaDataException.java | 17 + .../survey/exception/ProjectException.java | 17 + .../survey/exception/RecordException.java | 10 +- .../survey/exception/RespondentException.java | 11 +- .../survey/exception/RoleException.java | 13 +- .../survey/exception/UserException.java | 13 +- .../service/InvestigationRecordService.java | 69 --- .../survey/service/MetaDataService.java | 64 +++ .../survey/service/ProjectService.java | 72 +++ .../example/survey/service/RecordService.java | 84 ++++ .../survey/service/RespondentService.java | 63 ++- .../example/survey/service/RoleService.java | 30 +- .../example/survey/service/UserService.java | 45 +- .../impl/InvestigationRecordServiceImpl.java | 163 ------- .../service/impl/MetaDataServiceImpl.java | 96 ++++ .../service/impl/ProjectServiceImpl.java | 139 ++++++ .../service/impl/RecordServiceImpl.java | 274 +++++++++++ .../service/impl/RespondentServiceImpl.java | 153 ++++++- .../survey/service/impl/RoleServiceImpl.java | 75 +-- .../survey/service/impl/UserServiceImpl.java | 182 +++++--- .../com/example/survey/util/WordUtil.java | 430 ------------------ .../com/example/survey/vo/CreateRoleVo.java | 29 -- .../survey/vo/InvestigationRecordVo.java | 228 ---------- .../{dto/LoginDto.java => vo/LoginVO.java} | 12 +- .../com/example/survey/vo/MetaDataVO.java | 18 + .../com/example/survey/vo/ModifyRoleVo.java | 18 - .../java/com/example/survey/vo/ProjectVO.java | 46 ++ .../java/com/example/survey/vo/RecordVO.java | 28 ++ .../com/example/survey/vo/RespondentVO.java | 57 +++ .../vo/{ResultVo.java => ResultVO.java} | 11 +- .../java/com/example/survey/vo/ReviewVo.java | 30 -- .../java/com/example/survey/vo/RoleVO.java | 25 + .../java/com/example/survey/vo/RoleVo.java | 30 -- .../com/example/survey/vo/UserRoleVo.java | 18 - .../java/com/example/survey/vo/UserVO.java | 25 + .../survey/vo/inner/OperationInfo.java | 42 ++ .../com/example/survey/vo/inner/UserInfo.java | 13 + src/main/resources/application.yml | 2 +- .../com/example/survey/controller/Init.http | 58 --- .../controller/InvestigationRecordApi.http | 224 --------- .../example/survey/controller/ProjectApi.http | 49 ++ .../example/survey/controller/RecordApi.http | 61 +++ .../survey/controller/RespondentApi.http | 53 ++- .../example/survey/controller/RoleApi.http | 51 +++ .../survey/controller/RoleControllerApi.http | 79 ---- .../example/survey/controller/UserApi.http | 86 ++++ .../survey/controller/UserControllerApi.http | 89 ---- 128 files changed, 3751 insertions(+), 3532 deletions(-) create mode 100644 log/survey-INFO-2021-03-04_1.log.gz create mode 100644 log/survey-INFO-2021-03-12_1.log.gz create mode 100644 log/survey-INFO-2021-03-18_1.log.gz delete mode 100644 src/main/java/com/example/survey/controller/InvestigationRecordController.java create mode 100644 src/main/java/com/example/survey/controller/MetaDataController.java create mode 100644 src/main/java/com/example/survey/controller/ProjectController.java create mode 100644 src/main/java/com/example/survey/controller/RecordController.java delete mode 100644 src/main/java/com/example/survey/dao/InvestigationRecordDao.java create mode 100644 src/main/java/com/example/survey/dao/MetaDataDao.java create mode 100644 src/main/java/com/example/survey/dao/ProjectDao.java create mode 100644 src/main/java/com/example/survey/dao/RecordDao.java delete mode 100644 src/main/java/com/example/survey/dao/impl/InvestigationRecordDaoImpl.java create mode 100644 src/main/java/com/example/survey/dao/impl/MetaDataDaoImpl.java create mode 100644 src/main/java/com/example/survey/dao/impl/ProjectDaoImpl.java create mode 100644 src/main/java/com/example/survey/dao/impl/RecordDaoImpl.java delete mode 100644 src/main/java/com/example/survey/dto/RespondentDto.java delete mode 100644 src/main/java/com/example/survey/dto/UserDto.java delete mode 100644 src/main/java/com/example/survey/dto/inner/RelevantUserInfo.java create mode 100644 src/main/java/com/example/survey/dto/metaData/CreateMetaDataDTO.java create mode 100644 src/main/java/com/example/survey/dto/metaData/DeleteMetaDataDTO.java create mode 100644 src/main/java/com/example/survey/dto/metaData/ModifyMetaDataDTO.java create mode 100644 src/main/java/com/example/survey/dto/project/CreateProjectDTO.java create mode 100644 src/main/java/com/example/survey/dto/project/ModifyProjectDTO.java create mode 100644 src/main/java/com/example/survey/dto/project/ModifyStateDTO.java create mode 100644 src/main/java/com/example/survey/dto/record/ModifyRecordDTO.java create mode 100644 src/main/java/com/example/survey/dto/record/ReviewRecordDTO.java create mode 100644 src/main/java/com/example/survey/dto/record/SubmitRecordDTO.java rename src/main/java/com/example/survey/{vo/CreateRespondentVo.java => dto/respondent/CreateRespondentDTO.java} (72%) create mode 100644 src/main/java/com/example/survey/dto/respondent/DeleteRespondentDTO.java create mode 100644 src/main/java/com/example/survey/dto/respondent/ModifyRespondentDTO.java create mode 100644 src/main/java/com/example/survey/dto/respondent/ModifyRespondentUserDTO.java create mode 100644 src/main/java/com/example/survey/dto/role/CreateRoleDTO.java rename src/main/java/com/example/survey/{vo/DeleteRoleVo.java => dto/role/DeleteRoleDTO.java} (55%) create mode 100644 src/main/java/com/example/survey/dto/role/ModifyRoleDTO.java rename src/main/java/com/example/survey/{vo/CreateUserVo.java => dto/user/CreateUserDTO.java} (83%) rename src/main/java/com/example/survey/{vo/DeleteUserVo.java => dto/user/DeleteUserDTO.java} (54%) rename src/main/java/com/example/survey/{vo/LoginVo.java => dto/user/LoginDTO.java} (61%) rename src/main/java/com/example/survey/{vo/UserInfoVo.java => dto/user/ModifyUserInfoDTO.java} (83%) create mode 100644 src/main/java/com/example/survey/dto/user/ModifyUserRoleDTO.java rename src/main/java/com/example/survey/{vo/ResetPwdVo.java => dto/user/ResetPwdDTO.java} (62%) create mode 100644 src/main/java/com/example/survey/entity/Audit.java delete mode 100644 src/main/java/com/example/survey/entity/InvestigationRecord.java create mode 100644 src/main/java/com/example/survey/entity/MetaData.java create mode 100644 src/main/java/com/example/survey/entity/Project.java create mode 100644 src/main/java/com/example/survey/entity/Record.java delete mode 100644 src/main/java/com/example/survey/entity/inner/Detection.java delete mode 100644 src/main/java/com/example/survey/entity/inner/EntryExperience.java delete mode 100644 src/main/java/com/example/survey/entity/inner/EntryPort.java create mode 100644 src/main/java/com/example/survey/entity/inner/FieldToName.java delete mode 100644 src/main/java/com/example/survey/entity/inner/LiveHistory.java delete mode 100644 src/main/java/com/example/survey/entity/inner/Location.java create mode 100644 src/main/java/com/example/survey/entity/inner/Operation.java delete mode 100644 src/main/java/com/example/survey/entity/inner/OperationInformation.java create mode 100644 src/main/java/com/example/survey/entity/inner/ProjectPart.java delete mode 100644 src/main/java/com/example/survey/entity/inner/SuperiorInfectedIndividual.java delete mode 100644 src/main/java/com/example/survey/entity/inner/TempHistory.java delete mode 100644 src/main/java/com/example/survey/entity/inner/TravelHistory.java create mode 100644 src/main/java/com/example/survey/enumeration/OpTypeEnum.java create mode 100644 src/main/java/com/example/survey/enumeration/ProjectStateEnum.java create mode 100644 src/main/java/com/example/survey/enumeration/RecordStateEnum.java create mode 100644 src/main/java/com/example/survey/enumeration/ResultEnum.java create mode 100644 src/main/java/com/example/survey/exception/MetaDataException.java create mode 100644 src/main/java/com/example/survey/exception/ProjectException.java delete mode 100644 src/main/java/com/example/survey/service/InvestigationRecordService.java create mode 100644 src/main/java/com/example/survey/service/MetaDataService.java create mode 100644 src/main/java/com/example/survey/service/ProjectService.java create mode 100644 src/main/java/com/example/survey/service/RecordService.java delete mode 100644 src/main/java/com/example/survey/service/impl/InvestigationRecordServiceImpl.java create mode 100644 src/main/java/com/example/survey/service/impl/MetaDataServiceImpl.java create mode 100644 src/main/java/com/example/survey/service/impl/ProjectServiceImpl.java create mode 100644 src/main/java/com/example/survey/service/impl/RecordServiceImpl.java delete mode 100644 src/main/java/com/example/survey/util/WordUtil.java delete mode 100644 src/main/java/com/example/survey/vo/CreateRoleVo.java delete mode 100644 src/main/java/com/example/survey/vo/InvestigationRecordVo.java rename src/main/java/com/example/survey/{dto/LoginDto.java => vo/LoginVO.java} (67%) create mode 100644 src/main/java/com/example/survey/vo/MetaDataVO.java delete mode 100644 src/main/java/com/example/survey/vo/ModifyRoleVo.java create mode 100644 src/main/java/com/example/survey/vo/ProjectVO.java create mode 100644 src/main/java/com/example/survey/vo/RecordVO.java create mode 100644 src/main/java/com/example/survey/vo/RespondentVO.java rename src/main/java/com/example/survey/vo/{ResultVo.java => ResultVO.java} (60%) delete mode 100644 src/main/java/com/example/survey/vo/ReviewVo.java create mode 100644 src/main/java/com/example/survey/vo/RoleVO.java delete mode 100644 src/main/java/com/example/survey/vo/RoleVo.java delete mode 100644 src/main/java/com/example/survey/vo/UserRoleVo.java create mode 100644 src/main/java/com/example/survey/vo/UserVO.java create mode 100644 src/main/java/com/example/survey/vo/inner/OperationInfo.java create mode 100644 src/main/java/com/example/survey/vo/inner/UserInfo.java delete mode 100644 src/test/java/com/example/survey/controller/Init.http delete mode 100644 src/test/java/com/example/survey/controller/InvestigationRecordApi.http create mode 100644 src/test/java/com/example/survey/controller/ProjectApi.http create mode 100644 src/test/java/com/example/survey/controller/RecordApi.http create mode 100644 src/test/java/com/example/survey/controller/RoleApi.http delete mode 100644 src/test/java/com/example/survey/controller/RoleControllerApi.http create mode 100644 src/test/java/com/example/survey/controller/UserApi.http delete mode 100644 src/test/java/com/example/survey/controller/UserControllerApi.http diff --git a/log/survey-INFO-2021-03-04_1.log.gz b/log/survey-INFO-2021-03-04_1.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..039aa5c403815ec7046c312c0c99cb107abe6da8 GIT binary patch literal 36967 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 URIS = new HashSet() {{ add("/user/login"); add("/user/signup"); -// add("/user/userRole"); -// add("/role/role"); }}; @@ -65,13 +62,13 @@ public class AuthFilterConfig implements Filter { } if (token == null) { log.error("请求无token"); - returnJson(response, new ResultVo(ResultVo.FAILED, "请先登录!", null)); + returnJson(response, new ResultVO(ResultEnum.NO_TOKEN)); return; } if (!TokenUtil.isPass(token, uri, method)) { - log.error("token错误"); - returnJson(response, new ResultVo(ResultVo.FAILED, "权限不够!", null)); + log.error("非法token或权限不够"); + returnJson(response, new ResultVO(ResultEnum.INSUFFICIENT_PRIVILEGE)); return; } @@ -85,7 +82,7 @@ public class AuthFilterConfig implements Filter { } - public static void returnJson(HttpServletResponse response, ResultVo resultVo) { + public static void returnJson(HttpServletResponse response, ResultVO resultVo) { response.setCharacterEncoding("UTF-8"); response.setContentType("application/json;charset=utf-8"); try (PrintWriter writer = response.getWriter()) { diff --git a/src/main/java/com/example/survey/controller/InvestigationRecordController.java b/src/main/java/com/example/survey/controller/InvestigationRecordController.java deleted file mode 100644 index cca2b5f..0000000 --- a/src/main/java/com/example/survey/controller/InvestigationRecordController.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.example.survey.controller; - -import com.example.survey.entity.InvestigationRecord; -import com.example.survey.service.InvestigationRecordService; -import com.example.survey.vo.InvestigationRecordVo; -import com.example.survey.vo.ResultVo; -import com.example.survey.vo.ReviewVo; -import lombok.extern.log4j.Log4j2; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletResponse; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author Pope - */ -@Log4j2 -@RestController -@RequestMapping("/investigationRecord") -public class InvestigationRecordController { - - @Autowired - private InvestigationRecordService investigationRecordService; - - @GetMapping("/underReviewRecord") - public ResultVo getUnderReviewRecord(@RequestParam(value = "currentPage") Integer currentPage, - @RequestParam(value = "pageSize", defaultValue = "30") Integer pageSize, - @RequestParam(value = "userPhone", required = false) String userPhone, - @RequestParam(value = "state", required = false) String state, - @RequestParam(value = "idNumber", required = false) String idNumber, - @RequestParam(value = "version", required = false) String version, - @RequestParam(value = "questionnaireNumber", required = false) String questionnaireNumber, - @RequestParam(value = "diseased", required = false) Boolean diseased) { - - ResultVo resultVo = new ResultVo(); - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("查询成功"); - Map resultMap = new HashMap<>(16, 0.75F); - List records = investigationRecordService.listUnderReviewRecordLimit(userPhone, currentPage, pageSize, state, idNumber, version, questionnaireNumber, diseased); - resultMap.put("totalCount", records.size()); - resultMap.put("currentPage", currentPage); - resultMap.put("pageSize", pageSize); - resultMap.put("data", records); - resultVo.setData(resultMap); - - return resultVo; - } - - @GetMapping("/underReviewRecordCount") - public ResultVo countUnderReviewRecord(@RequestParam(value = "userPhone") String userPhone) { - ResultVo resultVo = new ResultVo(); - - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("查询成功"); - resultVo.setData(investigationRecordService.countUnderReviewRecord(userPhone)); - - return resultVo; - } - - - @PutMapping("/underReviewRecord") - public ResultVo reviewRecord(@RequestBody ReviewVo reviewVo) { - ResultVo resultVo = new ResultVo(); - - boolean result = investigationRecordService.reviewRecord(reviewVo); - if (result) { - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("审核成功"); - } else { - resultVo.setCode(ResultVo.FAILED); - resultVo.setMsg("审核失败"); - } - - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setData(result); - - return resultVo; - } - - @PutMapping("/investigationRecord") - public ResultVo updateInvestigationRecord(@RequestBody InvestigationRecordVo investigationRecordVo) { - ResultVo resultVo = new ResultVo(); - - investigationRecordService.changeInvestigationRecord(investigationRecordVo); - - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("修改提交成功,等待审核"); - resultVo.setData(true); - - return resultVo; - } - - @PostMapping("/investigationRecord") - public ResultVo addInvestigationRecord(@RequestBody InvestigationRecordVo investigationRecordVo) { - - ResultVo resultVo = new ResultVo(); - boolean result = investigationRecordService.addInvestigationRecord(investigationRecordVo); - if (result) { - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("提交成功"); - } else { - resultVo.setCode(ResultVo.FAILED); - resultVo.setMsg("提交失败"); - } - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setData(result); - return resultVo; - } - - @GetMapping("/record2word") - public void record2Word(@RequestParam("token") String token, - @RequestParam("idNumber") String idNumber, - HttpServletResponse response) { - investigationRecordService.export2Word(idNumber, response); - } - -} diff --git a/src/main/java/com/example/survey/controller/MetaDataController.java b/src/main/java/com/example/survey/controller/MetaDataController.java new file mode 100644 index 0000000..97f26a0 --- /dev/null +++ b/src/main/java/com/example/survey/controller/MetaDataController.java @@ -0,0 +1,73 @@ +package com.example.survey.controller; + +import com.example.survey.dto.metaData.CreateMetaDataDTO; +import com.example.survey.dto.metaData.DeleteMetaDataDTO; +import com.example.survey.dto.metaData.ModifyMetaDataDTO; +import com.example.survey.enumeration.ResultEnum; +import com.example.survey.service.MetaDataService; +import com.example.survey.vo.ResultVO; +import lombok.Getter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Pope + */ +@RestController +@RequestMapping("/metaData") +public class MetaDataController { + + @Autowired + MetaDataService metaDataService; + + @PostMapping("/metaData") + public ResultVO createMetaData(@RequestBody CreateMetaDataDTO createMetaDataDTO){ + metaDataService.addMetaData(createMetaDataDTO); + return new ResultVO(ResultEnum.SUCCESS); + } + + @GetMapping("/metaDataList") + public ResultVO listMetaData(@RequestParam(value = "name",required = false) String name, + @RequestParam("currentPage")int currentPage, + @RequestParam(value = "pageSize",defaultValue = "30")int pageSize){ + Map resultMap = new HashMap<>(16,0.75F); + resultMap.put("totalCount", metaDataService.countMetaData(name)); + resultMap.put("currentPage", currentPage); + resultMap.put("pageSize", pageSize); + resultMap.put("data", metaDataService.listMetaDataLimit(name,currentPage,pageSize)); + + ResultVO resultVO = new ResultVO(ResultEnum.SUCCESS); + resultVO.setData(resultMap); + return resultVO; + } + + @GetMapping("/nameList") + public ResultVO getNameList(){ + ResultVO resultVO = new ResultVO(ResultEnum.SUCCESS); + resultVO.setData(metaDataService.getNameList()); + return resultVO; + } + + @PutMapping("/metaData") + public ResultVO modifyMetaData(@RequestBody ModifyMetaDataDTO modifyMetaDataDTO){ + metaDataService.modifyMetaData(modifyMetaDataDTO); + return new ResultVO(ResultEnum.SUCCESS); + } + + @GetMapping("/metaData") + public ResultVO getMetaData(@RequestParam("name")String name){ + ResultVO resultVO = new ResultVO(); + resultVO.setData(metaDataService.getMetaData(name)); + return resultVO; + } + + @DeleteMapping("/metaData") + public ResultVO deleteMetaData(@RequestBody DeleteMetaDataDTO deleteMetaDataDTO){ + metaDataService.deleteMetaData(deleteMetaDataDTO); + return new ResultVO(ResultEnum.SUCCESS); + } + +} diff --git a/src/main/java/com/example/survey/controller/ProjectController.java b/src/main/java/com/example/survey/controller/ProjectController.java new file mode 100644 index 0000000..1157285 --- /dev/null +++ b/src/main/java/com/example/survey/controller/ProjectController.java @@ -0,0 +1,73 @@ +package com.example.survey.controller; + +import com.example.survey.dto.project.CreateProjectDTO; +import com.example.survey.dto.project.ModifyProjectDTO; +import com.example.survey.dto.project.ModifyStateDTO; +import com.example.survey.enumeration.RespondentStateEnum; +import com.example.survey.enumeration.ResultEnum; +import com.example.survey.service.ProjectService; +import com.example.survey.vo.ProjectVO; +import com.example.survey.vo.ResultVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Pope + */ +@RestController +@RequestMapping("/project") +public class ProjectController { + + @Autowired + ProjectService projectService; + + + @PostMapping("/project") + public ResultVO createProject(@RequestBody CreateProjectDTO createProjectDTO) { + projectService.createProject(createProjectDTO); + return new ResultVO(ResultEnum.SUCCESS); + } + + @GetMapping("/projectList") + public ResultVO getProject(@RequestParam(value = "name",required = false) String name, + @RequestParam(value = "currentPage") int currentPage, + @RequestParam(value = "pageSize", defaultValue = "30") int pageSize) { + Map resultMap = new HashMap<>(16,0.75F); + resultMap.put("totalCount", projectService.countProject(name)); + resultMap.put("currentPage", currentPage); + resultMap.put("pageSize", pageSize); + resultMap.put("data", projectService.listProjectLimit(name, currentPage, pageSize)); + ResultVO resultVO = new ResultVO(ResultEnum.SUCCESS); + resultVO.setData(resultMap); + return resultVO; + } + + @GetMapping("/respondentCount") + public ResultVO getRespondentCount(@RequestParam(value = "name") String name) { + + Map resultMap = new HashMap<>(16, 0.75F); + resultMap.put("respondentCount", projectService.countRespondent(name)); + resultMap.put("notInvestigatedRespondentCount", projectService.countRespondent(name, RespondentStateEnum.NOT_INVESTIGATED.getValue())); + + ResultVO resultVO = new ResultVO(ResultEnum.SUCCESS); + resultVO.setData(resultMap); + return resultVO; + } + + @PutMapping("/projectState") + public ResultVO modifyProjectState(@RequestBody ModifyStateDTO modifyStateDTO){ + projectService.modifyProjectState(modifyStateDTO); + return new ResultVO(ResultEnum.SUCCESS); + } + + @PutMapping("/project") + public ResultVO modifyProject(@RequestBody ModifyProjectDTO modifyProjectDTO){ + projectService.modifyProject(modifyProjectDTO); + return new ResultVO(ResultEnum.SUCCESS); + } + +} diff --git a/src/main/java/com/example/survey/controller/RecordController.java b/src/main/java/com/example/survey/controller/RecordController.java new file mode 100644 index 0000000..59a1d7d --- /dev/null +++ b/src/main/java/com/example/survey/controller/RecordController.java @@ -0,0 +1,85 @@ +package com.example.survey.controller; + +import com.example.survey.dto.record.ModifyRecordDTO; +import com.example.survey.dto.record.ReviewRecordDTO; +import com.example.survey.dto.record.SubmitRecordDTO; +import com.example.survey.enumeration.ResultEnum; +import com.example.survey.service.RecordService; +import com.example.survey.vo.ResultVO; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Pope + */ +@Log4j2 +@RestController +@RequestMapping("/record") +public class RecordController { + + @Autowired + private RecordService recordService; + + @GetMapping("/recordList") + public ResultVO getRecord(@RequestParam(value = "idNumber", required = false) String idNumber, + @RequestParam(value = "userPhone", required = false) String userPhone, + @RequestParam(value = "projectName", required = false) String projectName, + @RequestParam(value = "state", required = false) String state, + @RequestParam(value = "version", required = false) String version, + @RequestParam(value = "questionnaireNumber", required = false) String questionnaireNumber, + @RequestParam(value = "currentPage") Integer currentPage, + @RequestParam(value = "pageSize", defaultValue = "30") Integer pageSize + ) { + Map resultMap = new HashMap<>(16, 0.75F); + resultMap.put("totalCount", recordService.countRecord(idNumber, userPhone, projectName, state, version, questionnaireNumber)); + resultMap.put("currentPage", currentPage); + resultMap.put("pageSize", pageSize); + resultMap.put("data", recordService.listRecordLimit(idNumber, userPhone, projectName, state, version, questionnaireNumber, currentPage, pageSize)); + ResultVO resultVo = new ResultVO(ResultEnum.SUCCESS); + resultVo.setData(resultMap); + + return resultVo; + } + + @GetMapping("/recordValues") + public ResultVO getRecordValue(@RequestParam("projectName")String projectName, + @RequestParam("idNumber")String idNumber, + @RequestParam(value = "version",required = false) String version){ + ResultVO resultVO = new ResultVO(ResultEnum.SUCCESS); + resultVO.setData(recordService.getRecordValues(projectName,idNumber,version)); + return resultVO; + } + + @GetMapping("/underReviewRecordCount") + public ResultVO countUnderReviewRecord(@RequestParam(value = "userPhone") String userPhone, + @RequestParam(value = "projectName")String projectName) { + ResultVO resultVo = new ResultVO(ResultEnum.SUCCESS); + resultVo.setData(recordService.countRecord(userPhone, projectName)); + return resultVo; + } + + @PutMapping("/underReviewRecord") + public ResultVO reviewRecord(@RequestBody ReviewRecordDTO reviewRecordDTO) { + recordService.reviewRecord(reviewRecordDTO); + return new ResultVO(ResultEnum.SUCCESS); + } + + @PutMapping("/record") + public ResultVO modifyRecord(@RequestBody ModifyRecordDTO modifyRecordDTO) { + recordService.modifyRecord(modifyRecordDTO); + return new ResultVO(ResultEnum.SUCCESS); + } + + @PostMapping("/record") + public ResultVO submitRecord(@RequestBody SubmitRecordDTO submitRecordDTO) { + recordService.createRecord(submitRecordDTO); + + return new ResultVO(ResultEnum.SUCCESS); + } + + +} diff --git a/src/main/java/com/example/survey/controller/RespondentController.java b/src/main/java/com/example/survey/controller/RespondentController.java index 9b8c5f3..1e71621 100644 --- a/src/main/java/com/example/survey/controller/RespondentController.java +++ b/src/main/java/com/example/survey/controller/RespondentController.java @@ -1,15 +1,13 @@ package com.example.survey.controller; -import com.example.survey.entity.inner.AdministrativeArea; +import com.example.survey.dto.respondent.*; +import com.example.survey.enumeration.ResultEnum; import com.example.survey.service.RespondentService; -import com.example.survey.dto.RespondentDto; -import com.example.survey.vo.CreateRespondentVo; -import com.example.survey.vo.ResultVo; +import com.example.survey.vo.ResultVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -23,44 +21,52 @@ public class RespondentController { private RespondentService respondentService; @PostMapping("/respondent") - public ResultVo addRespondent(@RequestBody CreateRespondentVo createRespondentVo) { - ResultVo resultVo = new ResultVo(); - - boolean result = respondentService.addRespondent(createRespondentVo); - if (result) { - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("创建成功"); - } else { - resultVo.setCode(ResultVo.FAILED); - resultVo.setMsg("创建失败"); - } - resultVo.setData(result); - - return resultVo; + public ResultVO addRespondent(@RequestBody CreateRespondentDTO createRespondentDTO) { + respondentService.createRespondent(createRespondentDTO); + return new ResultVO(ResultEnum.SUCCESS); } - @GetMapping("/respondent") - public ResultVo countRespondent(@RequestParam(value = "userPhone") String userPhone, - @RequestParam(value = "state", required = false) String state, - @RequestParam(value = "province", required = false) String province, - @RequestParam(value = "city", required = false) String city, - @RequestParam(value = "county", required = false) String county, - @RequestParam(value = "currentPage") int currentPage, - @RequestParam(value = "pageSize", defaultValue = "30") int pageSize) { - ResultVo resultVo = new ResultVo(); + @GetMapping("/respondentList") + public ResultVO listRespondent(@RequestParam(value = "userPhone", required = false) String userPhone, + @RequestParam(value = "projectName", required = false) String projectName, + @RequestParam(value = "state", required = false) String state, + @RequestParam(value = "idNumber", required = false) String idNumber, + @RequestParam(value = "name", required = false) String name, + @RequestParam(value = "phone", required = false) String phone, + @RequestParam(value = "province", required = false) String province, + @RequestParam(value = "city", required = false) String city, + @RequestParam(value = "county", required = false) String county, + @RequestParam(value = "currentPage") int currentPage, + @RequestParam(value = "pageSize", defaultValue = "30") int pageSize + ) { Map resultMap = new HashMap<>(16, 0.75F); - AdministrativeArea administrativeArea = new AdministrativeArea(province, city, county); - List voList = respondentService.listRespondentLimit(userPhone, state, administrativeArea, currentPage, pageSize); - resultMap.put("totalCount", respondentService.countRespondent(userPhone, state, administrativeArea)); + resultMap.put("totalCount", respondentService.countRespondent(userPhone, state, idNumber, name, phone, province, city, county, projectName)); resultMap.put("currentPage", currentPage); resultMap.put("pageSize", pageSize); - resultMap.put("data", voList); + resultMap.put("data", respondentService.listRespondentLimit(userPhone, state, idNumber, name, phone, province, city, county, projectName, currentPage, pageSize)); - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("查询成功"); + ResultVO resultVo = new ResultVO(ResultEnum.SUCCESS); resultVo.setData(resultMap); return resultVo; } + @PutMapping("/respondent") + public ResultVO modifyRespondent(@RequestBody ModifyRespondentDTO modifyRespondentDTO) { + respondentService.modifyRespondent(modifyRespondentDTO); + return new ResultVO(ResultEnum.SUCCESS); + } + + @DeleteMapping("/respondent") + public ResultVO deleteRespondent(@RequestBody DeleteRespondentDTO deleteRespondentDTO) { + respondentService.deleteRespondent(deleteRespondentDTO); + return new ResultVO(ResultEnum.SUCCESS); + } + + @PutMapping("/user") + public ResultVO modifyUser(@RequestBody ModifyRespondentUserDTO modifyRespondentUserDTO) { + respondentService.modifyUser(modifyRespondentUserDTO); + return new ResultVO(ResultEnum.SUCCESS); + } + } diff --git a/src/main/java/com/example/survey/controller/RoleController.java b/src/main/java/com/example/survey/controller/RoleController.java index d7e3ebb..b9eed81 100644 --- a/src/main/java/com/example/survey/controller/RoleController.java +++ b/src/main/java/com/example/survey/controller/RoleController.java @@ -1,16 +1,16 @@ package com.example.survey.controller; import com.example.survey.enumeration.AuthEnum; +import com.example.survey.enumeration.ResultEnum; import com.example.survey.service.RoleService; -import com.example.survey.vo.DeleteRoleVo; -import com.example.survey.vo.CreateRoleVo; -import com.example.survey.vo.ModifyRoleVo; -import com.example.survey.vo.ResultVo; +import com.example.survey.dto.role.DeleteRoleDTO; +import com.example.survey.dto.role.CreateRoleDTO; +import com.example.survey.dto.role.ModifyRoleDTO; +import com.example.survey.vo.ResultVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -23,78 +23,43 @@ public class RoleController { @Autowired private RoleService roleService; - @GetMapping("/role") - public ResultVo getRole(@RequestParam(value = "pageSize", defaultValue = "30") int pageSize, + @PostMapping("/role") + public ResultVO addRole(@RequestBody CreateRoleDTO createRoleDTO) { + roleService.addRole(createRoleDTO); + return new ResultVO(ResultEnum.SUCCESS); + } + + @GetMapping("/roleList") + public ResultVO getRole(@RequestParam(value = "pageSize", defaultValue = "30") int pageSize, @RequestParam(value = "currentPage") int currentPage, - @RequestParam(value = "roleName", required = false) String roleName) { - ResultVo resultVo = new ResultVo(); - - - List roleVoList = roleService.getRole(roleName, currentPage, pageSize); + @RequestParam(value = "name", required = false) String name) { Map resultMap = new HashMap<>(16, 0.75F); - resultMap.put("totalCount",roleVoList.size()); + resultMap.put("totalCount",roleService.countRole(name)); resultMap.put("pageSize", pageSize); resultMap.put("currentPage", currentPage); - resultMap.put("data",roleVoList); + resultMap.put("data",roleService.listRoleLimit(name, currentPage, pageSize)); - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("查询成功"); + ResultVO resultVo = new ResultVO(ResultEnum.SUCCESS); resultVo.setData(resultMap); - return resultVo; } - @PostMapping("/role") - public ResultVo addRole(@RequestBody CreateRoleVo createRoleVo) { - ResultVo resultVo = new ResultVo(); - - boolean result = roleService.addRole(createRoleVo); - if (result) { - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("创建成功"); - } else { - resultVo.setCode(ResultVo.FAILED); - resultVo.setMsg("创建失败"); - } - resultVo.setData(result); - return resultVo; - } - - - @DeleteMapping("/role") - public ResultVo deleteRole(@RequestBody DeleteRoleVo deleteRoleVo) { - ResultVo resultVo = new ResultVo(); - - roleService.deleteRole(deleteRoleVo.getRoleName()); - - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("删除成功"); - return resultVo; + public ResultVO deleteRole(@RequestBody DeleteRoleDTO deleteRoleDTO) { + roleService.deleteRole(deleteRoleDTO); + return new ResultVO(ResultEnum.SUCCESS); } @PutMapping("/role") - public ResultVo modifyRole(@RequestBody ModifyRoleVo modifyRoleVo) { - ResultVo resultVo = new ResultVo(); - - roleService.modifyRole(modifyRoleVo); - - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("修改成功"); - - return resultVo; + public ResultVO modifyRole(@RequestBody ModifyRoleDTO modifyRoleDTO) { + roleService.modifyRole(modifyRoleDTO); + return new ResultVO(ResultEnum.SUCCESS); } - @GetMapping("/authList") - public ResultVo getAuthList() { - ResultVo resultVo = new ResultVo(); - - Map resultMap = new HashMap<>(); - resultMap.put("authList", AuthEnum.getNameList()); - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("查询成功"); - resultVo.setData(resultMap); - + @GetMapping("/authorityList") + public ResultVO getAuthList() { + ResultVO resultVo = new ResultVO(ResultEnum.SUCCESS); + resultVo.setData(AuthEnum.getNameList()); return resultVo; } diff --git a/src/main/java/com/example/survey/controller/UserController.java b/src/main/java/com/example/survey/controller/UserController.java index 544ce76..8a17742 100644 --- a/src/main/java/com/example/survey/controller/UserController.java +++ b/src/main/java/com/example/survey/controller/UserController.java @@ -1,14 +1,13 @@ package com.example.survey.controller; -import com.example.survey.dto.LoginDto; -import com.example.survey.dto.UserDto; +import com.example.survey.dto.user.*; +import com.example.survey.enumeration.ResultEnum; import com.example.survey.service.UserService; import com.example.survey.vo.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.HashMap; -import java.util.List; import java.util.Map; @@ -22,122 +21,66 @@ public class UserController { @Autowired UserService userService; - @GetMapping("/user") - public ResultVo getUser(@RequestParam(value = "pageSize", defaultValue = "30") int pageSize, + @GetMapping("/userList") + public ResultVO getUser(@RequestParam(value = "pageSize", defaultValue = "30") int pageSize, @RequestParam(value = "currentPage") int currentPage, @RequestParam(value = "username", required = false) String username, - @RequestParam(value = "phoneNumber", required = false) String phoneNumber) { - ResultVo resultVo = new ResultVo(); + @RequestParam(value = "phone", required = false) String phone) { - - List userDtoList = userService.listUserLimit(username, phoneNumber, currentPage, pageSize); Map resultMap = new HashMap<>(16, 0.75F); - resultMap.put("totalCount", userDtoList.size()); + resultMap.put("totalCount", userService.countUser(username,phone)); resultMap.put("pageSize", pageSize); resultMap.put("currentPage", currentPage); - resultMap.put("data", userDtoList); + resultMap.put("data", userService.listUserLimit(username, phone, currentPage, pageSize)); - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("查询成功"); + ResultVO resultVo = new ResultVO(ResultEnum.SUCCESS); resultVo.setData(resultMap); return resultVo; } @DeleteMapping("/user") - public ResultVo deleteUser(@RequestBody DeleteUserVo deleteUserVo) { - ResultVo resultVo = new ResultVo(); - - boolean result = userService.deleteUser(deleteUserVo.getPhoneNumber()); - if (result) { - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("删除成功"); - } else { - resultVo.setCode(ResultVo.FAILED); - resultVo.setMsg("删除失败"); - } - return resultVo; + public ResultVO deleteUser(@RequestBody DeleteUserDTO deleteUserDTO) { + userService.deleteUser(deleteUserDTO); + return new ResultVO(ResultEnum.SUCCESS); } @PostMapping("/login") - public ResultVo login(@RequestBody LoginVo loginVo) { - ResultVo resultVo = new ResultVo(); + public ResultVO login(@RequestBody LoginDTO loginDTO) { //用户名密码验证 - LoginDto loginDto = userService.matchAuth(loginVo); - if (loginDto == null) { + LoginVO loginVO = userService.matchAuth(loginDTO); + if (loginVO == null) { //登录失败 - resultVo.setCode(ResultVo.FAILED); - resultVo.setMsg("登录失败"); - return resultVo; + return new ResultVO(ResultEnum.WRONG_PASSWORD); } - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("登录成功"); - resultVo.setData(loginDto); + ResultVO resultVo = new ResultVO(ResultEnum.SUCCESS); + resultVo.setData(loginVO); return resultVo; } @PutMapping("/userRole") - public ResultVo modifyUserRoles(@RequestBody UserRoleVo userRoleVo) { - ResultVo resultVo = new ResultVo(); - - userService.modifyRole(userRoleVo); - resultVo.setCode(0); - resultVo.setMsg("修改成功"); - - return resultVo; + public ResultVO modifyUserRole(@RequestBody ModifyUserRoleDTO modifyUserRoleDTO) { + userService.modifyRole(modifyUserRoleDTO); + return new ResultVO(ResultEnum.SUCCESS); } @PutMapping("/userInfo") - public ResultVo changeUserInfo(@RequestBody UserInfoVo userInfoVo) { - ResultVo resultVo = new ResultVo(); - - userService.modifyUserInfo(userInfoVo); - - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("修改成功"); - - return resultVo; + public ResultVO changeUserInfo(@RequestBody ModifyUserInfoDTO modifyUserInfoDTO) { + userService.modifyUserInfo(modifyUserInfoDTO); + return new ResultVO(ResultEnum.SUCCESS); } @PutMapping("/pwd") - public ResultVo resetPwd(@RequestBody ResetPwdVo resetPwdVo) { - ResultVo resultVo = new ResultVo(); - - userService.resetPwd(resetPwdVo.getPhoneNumber()); - - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("重置成功"); - - return resultVo; + public ResultVO resetPwd(@RequestBody ResetPwdDTO resetPwdDTO) { + userService.resetPwd(resetPwdDTO); + return new ResultVO(ResultEnum.SUCCESS); } @PostMapping("/user") - public ResultVo createUser(@RequestBody CreateUserVo createUserVo) { - ResultVo resultVo = new ResultVo(); - - userService.addUser(createUserVo); - - resultVo.setCode(ResultVo.SUCCESS); - resultVo.setMsg("创建成功"); - - return resultVo; + public ResultVO createUser(@RequestBody CreateUserDTO createUserDTO) { + userService.addUser(createUserDTO); + return new ResultVO(ResultEnum.SUCCESS); } -// @PostMapping("/signup") -// public ResultVo signup(@RequestBody SignupVo signupVo) { -// ResultVo resultVo = new ResultVo(); -// -// resultVo.setCode(ResultVo.SUCCESS); -// boolean result = userService.addUser(signupVo); -// if (result) { -// resultVo.setCode(ResultVo.SUCCESS); -// resultVo.setMsg("注册成功"); -// } else { -// resultVo.setCode(ResultVo.FAILED); -// resultVo.setMsg("注册失败"); -// } -// return resultVo; -// } - } diff --git a/src/main/java/com/example/survey/controller/advice/GlobalExceptionHandler.java b/src/main/java/com/example/survey/controller/advice/GlobalExceptionHandler.java index dfd3383..58ce420 100644 --- a/src/main/java/com/example/survey/controller/advice/GlobalExceptionHandler.java +++ b/src/main/java/com/example/survey/controller/advice/GlobalExceptionHandler.java @@ -1,76 +1,64 @@ package com.example.survey.controller.advice; import com.example.survey.exception.*; -import com.example.survey.vo.ResultVo; -import org.springframework.web.bind.annotation.ControllerAdvice; +import com.example.survey.vo.ResultVO; +import lombok.extern.log4j.Log4j2; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; /** * @author Pope */ +@Log4j2 @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(UserException.class) - public ResultVo handleUserException(UserException e) { - ResultVo resultVo = new ResultVo(); - - resultVo.setCode(ResultVo.FAILED); - resultVo.setMsg(e.getMessage()); - - return resultVo; + public ResultVO handleUserException(UserException e) { + log.error(e.getMessage()); + return new ResultVO(e.getResultEnum()); } @ExceptionHandler(RecordException.class) - public ResultVo handleRecordException(RecordException e) { - ResultVo resultVo = new ResultVo(); - - resultVo.setCode(ResultVo.FAILED); - resultVo.setMsg(e.getMessage()); - - return resultVo; + public ResultVO handleRecordException(RecordException e) { + log.error(e.getMessage()); + return new ResultVO(e.getResultEnum()); } @ExceptionHandler(RespondentException.class) - public ResultVo handleRespondentException(RespondentException e) { - ResultVo resultVo = new ResultVo(); - - resultVo.setCode(ResultVo.FAILED); - resultVo.setMsg(e.getMessage()); - - return resultVo; + public ResultVO handleRespondentException(RespondentException e) { + log.error(e.getMessage()); + return new ResultVO(e.getResultEnum()); } @ExceptionHandler(RoleException.class) - public ResultVo handleRoleException(RoleException e) { - ResultVo resultVo = new ResultVo(); - - resultVo.setCode(ResultVo.FAILED); - resultVo.setMsg(e.getMessage()); - - return resultVo; + public ResultVO handleRoleException(RoleException e) { + log.error(e.getMessage()); + return new ResultVO(e.getResultEnum()); } @ExceptionHandler(DepartmentException.class) - public ResultVo handleDepartmentException(DepartmentException e) { - ResultVo resultVo = new ResultVo(); - - resultVo.setCode(ResultVo.FAILED); - resultVo.setMsg(e.getMessage()); - - return resultVo; + public ResultVO handleDepartmentException(DepartmentException e) { + log.error(e.getMessage()); + return new ResultVO(e.getResultEnum()); } @ExceptionHandler(AuthException.class) - public ResultVo handleAuthException(AuthException e) { - ResultVo resultVo = new ResultVo(); - - resultVo.setCode(ResultVo.FAILED); - resultVo.setMsg(e.getMessage()); - - return resultVo; + public ResultVO handleAuthException(AuthException e) { + log.error(e.getMessage()); + return new ResultVO(e.getResultEnum()); } + @ExceptionHandler(ProjectException.class) + public ResultVO handleProjectException(ProjectException e) { + log.error(e.getMessage()); + return new ResultVO(e.getResultEnum()); + } + + @ExceptionHandler(MetaDataException.class) + public ResultVO handleMetaDataException(MetaDataException e) { + log.error(e.getMessage()); + return new ResultVO(e.getResultEnum()); + } } diff --git a/src/main/java/com/example/survey/dao/InvestigationRecordDao.java b/src/main/java/com/example/survey/dao/InvestigationRecordDao.java deleted file mode 100644 index 03d4bae..0000000 --- a/src/main/java/com/example/survey/dao/InvestigationRecordDao.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.example.survey.dao; - -import com.example.survey.entity.InvestigationRecord; -import com.example.survey.entity.User; -import com.example.survey.entity.inner.OperationInformation; - -import java.util.List; - -/** - * @author Pope - */ -public interface InvestigationRecordDao { - - /** - * 插入调查记录 - * - * @param record 调查记录 - * @return 是否插入成功 - */ - boolean insertInvestigationRecord(InvestigationRecord record); - - /** - * 根据筛选条件分页查询记录 - * - * @param userPhone 用户电话号码 - * @param offset 偏移量 - * @param number 数量 - * @param state 调查记录状态 - * @param idNumber 调查对象身份证号 - * @param version 调查记录版本 - * @param questionnaireNumber 问卷编号 - * @param diseased 调查对象是否患病 - * @return 筛选结果 - */ - List listInvestigationRecordLimit(String userPhone, int offset, int number, String state, String idNumber, String version, String questionnaireNumber, Boolean diseased); - - /** - * 根据流调人员电话号码查询对应状态的记录数量 - * - * @param userPhone 流调人员电话号码 - * @param state 记录状态 - * @return 记录数量 - */ - long countInvestigationRecordByUserPhone(String userPhone, String state); - - /** - * 更新记录状态 - * - * @param idNumber 调查对象的身份证号 - * @param oldState 旧状态 - * @param newState 新状态 - */ - void updateRecordState(String idNumber, String oldState, String newState); - - /** - * 根据调查对象身份证号与记录状态查询记录 - * - * @param idNumber 调查对象的身份证号 - * @param state 记录状态 - * @return 相应记录 - */ - InvestigationRecord selectInvestigationRecord(String idNumber, String state); - - /** - * 将待审核调查记录修改为审核后的结果 - * - * @param record 审核后的记录 - */ - void reviewRecord(InvestigationRecord record); - - /** - * 是否存在当前状态调查记录 - * - * @param idNumber 调查对象身份证号 - * @param states 调查记录状态 - * @return 是否存在 - */ - boolean existInvestigationRecord(String idNumber, String... states); - - - /** - * 更新所有匹配的调查记录的userPhone字段 - * - * @param oldUserPhone 旧的userPhone字段 - * @param newUserPhone 新的userPhone字段 - */ - void updateManyRecordUserPhone(String oldUserPhone, String newUserPhone); -} diff --git a/src/main/java/com/example/survey/dao/MetaDataDao.java b/src/main/java/com/example/survey/dao/MetaDataDao.java new file mode 100644 index 0000000..7944c9d --- /dev/null +++ b/src/main/java/com/example/survey/dao/MetaDataDao.java @@ -0,0 +1,67 @@ +package com.example.survey.dao; + +import com.example.survey.entity.MetaData; +import com.example.survey.vo.MetaDataVO; +import org.springframework.data.mongodb.core.query.Meta; + +import java.util.List; + +/** + * @author Pope + */ +public interface MetaDataDao { + + /** + * 判断元数据是否存在 + * + * @param name 元数据名 + * @return 是否存在 + */ + boolean existMetaData(String name); + + /** + * 查询元数据 + * + * @param name 元数据名 + * @return 元数据 + */ + MetaData selectMetaData(String name); + + /** + * 创建元数据,若已有元数据则更新 + * + * @param metaData 元数据 + */ + void saveMetaData(MetaData metaData); + + /** + * + * + * @param name 元数据名 + * @param offset 偏移量 + * @param pageSize 页大小 + * @return 元数据 + */ + List listMetaDataLimit(String name, int offset, int pageSize); + + /** + * 根据元数据名查询数量 + * + * @param name 元数据名 + * @return 数量 + */ + long countMetaData(String name); + + /** + * 获取所有元数据 + * @return 元数据列表 + */ + List selectAllMetaData(); + + /** + * 删除元数据 + * + * @param name 名字 + */ + void deleteMetaData(String name); +} diff --git a/src/main/java/com/example/survey/dao/ProjectDao.java b/src/main/java/com/example/survey/dao/ProjectDao.java new file mode 100644 index 0000000..b6f0ad4 --- /dev/null +++ b/src/main/java/com/example/survey/dao/ProjectDao.java @@ -0,0 +1,53 @@ +package com.example.survey.dao; + +import com.example.survey.entity.Project; + +import java.util.List; + +/** + * @author Pope + */ +public interface ProjectDao { + + + /** + * 根据项目名查询项目是否存在 + * + * @param name 项目名 + * @return 项目是否存在 + */ + boolean existProject(String name); + + /** + * 根据项目名查询项目 + * + * @param name 项目名 + * @return 项目 + */ + Project selectProject(String name); + + /** + * 插入项目 + * + * @param project 项目 + */ + void saveProject(Project project); + + /** + * 根绝筛选条件分页查询项目 + * + * @param name 项目名 + * @param offset 偏移量 + * @param pageSize 页大小 + * @return 项目列表 + */ + List listProjectLimit(String name, int offset, int pageSize); + + /** + * 根据项目名查询数量 + * + * @param name 项目名 + * @return 数量 + */ + long countProject(String name); +} diff --git a/src/main/java/com/example/survey/dao/RecordDao.java b/src/main/java/com/example/survey/dao/RecordDao.java new file mode 100644 index 0000000..43f2e88 --- /dev/null +++ b/src/main/java/com/example/survey/dao/RecordDao.java @@ -0,0 +1,78 @@ +package com.example.survey.dao; + +import com.example.survey.entity.Project; +import com.example.survey.entity.Record; +import com.example.survey.entity.Respondent; +import com.example.survey.entity.User; + +import java.util.List; + +/** + * @author Pope + */ +public interface RecordDao { + /** + * 判断是否存在符合条件的流调记录 + * + * @param respondent 调查对象 + * @param project 项目 + * @param state 流调记录状态 + * @return 是否存在符合条件的流调记录 + */ + boolean existRecord(Respondent respondent, Project project, String state); + + /** + * 根据调查对象身份证号与流调记录状态查询流调记录 + * + * @param respondent 调查对象 + * @param project 项目 + * @param state 流调记录状态 + * @return 流调记录 + */ + Record getRecord(Respondent respondent,Project project, String state); + + /** + * 保存流调记录,若已有相同id的则更新 + * + * @param record 流调记录 + */ + void saveRecord(Record record); + + /** + * 根据筛选条件查询流调记录数量 + * + * @param respondent 调查对象 + * @param user 分配的人员 + * @param project 项目 + * @param state 流调记录状态 + * @param version 流调记录版本 + * @param questionnaireNumber 问卷编号 + * @return 数量 + */ + long countRecord(Respondent respondent, User user, Project project, String state, String version, String questionnaireNumber); + + /** + * 根据筛选条件分页查询流调记录 + * + * @param respondent 调查对象 + * @param user 分配的人员 + * @param project 项目 + * @param state 流调记录状态 + * @param version 流调记录版本 + * @param questionnaireNumber 问卷编号 + * @param offset 偏移量 + * @param pageSize 页大小 + * @return 流调记录 + */ + List listRecordLimit(Respondent respondent, User user, Project project, String state, String version, String questionnaireNumber, int offset, int pageSize); + + /** + * 根据筛选条件查询流调记录 + * + * @param respondent 调查对象 + * @param project 项目 + * @param version 版本号 + * @return 流调记录 + */ + Record selectRecord(Respondent respondent, Project project, String version); +} diff --git a/src/main/java/com/example/survey/dao/RespondentDao.java b/src/main/java/com/example/survey/dao/RespondentDao.java index d358459..f73e904 100644 --- a/src/main/java/com/example/survey/dao/RespondentDao.java +++ b/src/main/java/com/example/survey/dao/RespondentDao.java @@ -1,47 +1,99 @@ package com.example.survey.dao; +import com.example.survey.entity.Project; import com.example.survey.entity.Respondent; -import com.example.survey.entity.inner.AdministrativeArea; +import com.example.survey.entity.User; import java.util.List; /** * @author Pope - * */ public interface RespondentDao { /** * 插入待调查对象 + * * @param respondent 待调查对象 - * @return 是否插入成功 */ - boolean insertRespondent(Respondent respondent); + void saveRespondent(Respondent respondent); /** * 根据流调人员电话号码分页查询待调查对象列表 - * @param userPhone 分配的人员电话号码 - * @param state 状态 - * @param administrativeArea 行政区划 - * @param offset 偏移量 - * @param number 大小 + * + * @param user 分配的人员 + * @param state 状态 + * @param idNumber 身份证号 + * @param name 调查对象姓名 + * @param phone 调查对象电话 + * @param province 省份 + * @param city 城市 + * @param county 区县 + * @param project 项目 + * @param offset 偏移量 + * @param pageSize 大小 * @return 待调查对象列表 */ - List listRespondentLimit(String userPhone, String state, AdministrativeArea administrativeArea, int offset, int number); + List listRespondentLimit(User user, String state, String idNumber, String name, String phone, String province, String city, String county, Project project, int offset, int pageSize); /** * 判断是否存在对应id的调查对象 + * * @param idNumber 身份证号 * @return 是否存在该调查对象 */ boolean existRespondent(String idNumber); + /** + * 判断是否存在符合条件的调查对象 + * + * @param idNumber 身份证号 + * @param state 调查对象状态 + * @return 是否存在该调查对象 + */ + boolean existRespondent(String idNumber, String state); + /** * 根绝筛选条件获取调查对象数量 * - * @param userPhone 分配的人员电话号码 - * @param state 状态 - * @param administrativeArea 行政区划 + * @param user 分配的人员 + * @param state 状态 + * @param idNumber 身份证号 + * @param name 调查对象姓名 + * @param phone 调查对象电话 + * @param province 省份 + * @param city 城市 + * @param county 区县 + * @param project 项目 * @return 数量 */ - long countRespondent(String userPhone, String state, AdministrativeArea administrativeArea); + long countRespondent(User user, String state, String idNumber, String name, String phone, String province, String city, String county, Project project); + + + /** + * 根据身份证号查询调查对象 + * + * @param idNumber 身份证号 + * @param project 项目 + * @return 调查对象 + */ + Respondent selectRespondent(String idNumber,Project project); + + /** + * 删除调查对象 + * + * @param idNumber 身份证号 + */ + void deleteRespondent(String idNumber); + + + /** + * 根据项目与调查对象状态查询调查对象数量 + * + * @param project 项目 + * @param state 调查对象状态 + * @return 调查对象数量 + */ + long countRespondent(Project project, String state); + + } diff --git a/src/main/java/com/example/survey/dao/RoleDao.java b/src/main/java/com/example/survey/dao/RoleDao.java index 8e79575..382b3c6 100644 --- a/src/main/java/com/example/survey/dao/RoleDao.java +++ b/src/main/java/com/example/survey/dao/RoleDao.java @@ -12,12 +12,12 @@ import java.util.Set; public interface RoleDao { /** - * 插入新权限 + * 插入新角色,如果已有角色则更新 * - * @param role 新权限 + * @param role 新角色 * @return 是否插入成功 */ - boolean insertRole(Role role); + void saveRole(Role role); /** * 根据权限名查询对应权限 @@ -37,18 +37,27 @@ public interface RoleDao { /** * 根据角色名模糊匹配角色 * - * @param name 角色名 模糊匹配 - * @param offset 偏移量 - * @param limit 大小 - * @return + * @param name 角色名 模糊匹配 + * @param offset 偏移量 + * @param pageSize 页大小 + * @return 角色列表 */ - List listLimitRole(String name, int offset, int limit); + List listRoleLimit(String name, int offset, int pageSize); + /** - * 更改角色的权限列表 + * 根据角色名模糊查询角色数量 * - * @param roleName 角色名 - * @param authEnumSet 权限集合 + * @param name 角色名 + * @return 角色数量 */ - void updateRole(String roleName, Set authEnumSet); + long countRole(String name); + + /** + * 根据角色名判断角色是否存在 + * + * @param name 角色名 + * @return 是否存在 + */ + boolean existRole(String name); } diff --git a/src/main/java/com/example/survey/dao/UserDao.java b/src/main/java/com/example/survey/dao/UserDao.java index e994a37..1a55304 100644 --- a/src/main/java/com/example/survey/dao/UserDao.java +++ b/src/main/java/com/example/survey/dao/UserDao.java @@ -2,8 +2,6 @@ package com.example.survey.dao; import com.example.survey.entity.Role; import com.example.survey.entity.User; -import com.example.survey.vo.UserInfoVo; -import org.bson.types.ObjectId; import java.util.List; @@ -12,24 +10,6 @@ import java.util.List; */ public interface UserDao { - - /** - * 根据用户名密码查询用户 - * - * @param phoneNumber 用户电话号码 - * @param password 密码 - * @return 对应用户 - */ - User selectUser(String phoneNumber, String password); - - /** - * 插入用户 - * - * @param user 用户 - * @return 是否插入成功 - */ - boolean insertUser(User user); - /** * 根据筛选条件分页查询用户 * @@ -52,9 +32,9 @@ public interface UserDao { /** * 删除用户 * - * @param phoneNumber 电话号码 + * @param phone 电话号码 */ - void deleteUser(String phoneNumber); + void deleteUser(String phone); /** @@ -64,42 +44,27 @@ public interface UserDao { */ void clearRole(Role role); - /** - * 更改用户角色 - * - * @param phoneNumber 电话号码 - * @param roleList 角色列表 - */ - void updateUserRole(String phoneNumber, List roleList); - - /** - * 根据调查人员电话查询用户名 - * - * @param investigatorPhone 调查人员电话号码 - * @return 用户名 - */ - String selectUsername(String investigatorPhone); - /** * 根据电话号码查询用户 * - * @param phoneNumber 电话 + * @param phone 电话 * @return 用户 */ - User selectUser(String phoneNumber); - + User selectUser(String phone); /** - * 重置密码 + * 根据用户名与电话号码查询用户数量 * - * @param phoneNumber 电话号码 + * @param username 用户名 + * @param phone 电话号码 + * @return 用户数量 */ - void resetPwd(String phoneNumber); + long countUser(String username, String phone); /** - * 更新用户信息 + * 保存用户至数据库,如果是已有用户则更新信息 * - * @param userInfoVo 用户信息 + * @param user 用户 */ - void modifyUser(UserInfoVo userInfoVo); + void saveUser(User user); } diff --git a/src/main/java/com/example/survey/dao/impl/DepartmentDaoImpl.java b/src/main/java/com/example/survey/dao/impl/DepartmentDaoImpl.java index c8a6397..fe9c9a3 100644 --- a/src/main/java/com/example/survey/dao/impl/DepartmentDaoImpl.java +++ b/src/main/java/com/example/survey/dao/impl/DepartmentDaoImpl.java @@ -25,11 +25,6 @@ public class DepartmentDaoImpl implements DepartmentDao { try { mongoTemplate.save(department); }catch (Exception e){ - - log.error("部门插入失败"); - log.error(e.getMessage()); - - return false; } return true; } diff --git a/src/main/java/com/example/survey/dao/impl/InvestigationRecordDaoImpl.java b/src/main/java/com/example/survey/dao/impl/InvestigationRecordDaoImpl.java deleted file mode 100644 index bc4493b..0000000 --- a/src/main/java/com/example/survey/dao/impl/InvestigationRecordDaoImpl.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.example.survey.dao.impl; - -import com.example.survey.dao.InvestigationRecordDao; -import com.example.survey.entity.InvestigationRecord; -import com.example.survey.entity.inner.OperationInformation; -import com.example.survey.exception.RecordException; -import lombok.extern.log4j.Log4j2; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.aggregation.ArrayOperators; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.mongodb.core.query.Update; -import org.springframework.stereotype.Repository; - -import java.util.*; - -/** - * @author Pope - */ -@Log4j2 -@Repository -public class InvestigationRecordDaoImpl implements InvestigationRecordDao { - - @Autowired - MongoTemplate mongoTemplate; - - @Override - public boolean insertInvestigationRecord(InvestigationRecord record) { - try { - mongoTemplate.save(record); - } catch (Exception e) { - log.error("调查记录插入失败"); - log.error(e.getMessage()); - throw new RecordException("已存在对应调查对象的调查记录"); - } - return true; - } - - @Override - public List listInvestigationRecordLimit(String investigatorPhone, int offset, int number, String state, String idNumber, String version, String questionnaireNumber, Boolean diseased) { - ; - - Criteria criteria = new Criteria(); - //流调人员电话号码 - if (investigatorPhone != null) { - criteria.and("investigatorPhone").is(investigatorPhone); - } - - //调查记录状态 - if (state != null) { - criteria.and("state").is(state); - } else { - criteria.and("state").in(InvestigationRecord.UNDER_REVIEW, InvestigationRecord.REVIEWED); - } - - //调查对象身份证号 - if (idNumber != null) { - criteria.and("idNumber").is(idNumber); - } - - //版本 - if (version != null) { - criteria.and("version").is(version); - } - - //问卷编号 - if (questionnaireNumber != null) { - criteria.and("questionnaireNumber").is(questionnaireNumber); - } - - //是否患病 - if (diseased != null) { - criteria.and("diseased").is(diseased); - } - Query query = new Query(criteria); - query = query.skip(offset).limit(number); - return mongoTemplate.find(query, InvestigationRecord.class); - - } - - @Override - public long countInvestigationRecordByUserPhone(String userPhone, String state) { - Query query = new Query(Criteria.where("userPhone").is(userPhone).and("state").is(state)); - return mongoTemplate.count(query, InvestigationRecord.class); - } - - @Override - public void updateRecordState(String idNumber, String oldState, String newState) { - Query query = new Query(Criteria.where("idNumber").is(idNumber).and("state").is(oldState)); - Update update = new Update().set("state", newState); - mongoTemplate.updateFirst(query, update, InvestigationRecord.class); - } - - @Override - public InvestigationRecord selectInvestigationRecord(String idNumber, String state) { - Query query = new Query(Criteria.where("idNumber").is(idNumber).and("state").is(state)); - return mongoTemplate.findOne(query, InvestigationRecord.class); - } - - @Override - public void reviewRecord(InvestigationRecord record) { - Query query = new Query(Criteria.where("idNumber").is(record.getIdNumber()).and("state").is(InvestigationRecord.UNDER_REVIEW)); - Update update = new Update() - .set("state", record.getState()) - .set("operationInformationList", record.getOperationInformationList()); - mongoTemplate.updateFirst(query, update, InvestigationRecord.class); - } - - @Override - public boolean existInvestigationRecord(String idNumber, String... states) { - Query query = new Query(Criteria.where("idNumber").is(idNumber).and("state").in(states)); - return mongoTemplate.exists(query, InvestigationRecord.class); - } - - @Override - public void updateManyRecordUserPhone(String oldUserPhone, String newUserPhone) { - Query query = new Query(Criteria.where("userPhone").is(oldUserPhone)); - Update update = new Update().set("userPhone", newUserPhone); - mongoTemplate.updateMulti(query, update, InvestigationRecord.class); - } - - -} diff --git a/src/main/java/com/example/survey/dao/impl/MetaDataDaoImpl.java b/src/main/java/com/example/survey/dao/impl/MetaDataDaoImpl.java new file mode 100644 index 0000000..e8afce6 --- /dev/null +++ b/src/main/java/com/example/survey/dao/impl/MetaDataDaoImpl.java @@ -0,0 +1,77 @@ +package com.example.survey.dao.impl; + +import com.example.survey.dao.MetaDataDao; +import com.example.survey.entity.MetaData; +import com.example.survey.enumeration.ResultEnum; +import com.example.survey.exception.MetaDataException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.stereotype.Repository; + +import java.util.List; + + +/** + * @author Pope + */ +@Repository +public class MetaDataDaoImpl implements MetaDataDao { + + @Autowired + MongoTemplate mongoTemplate; + + @Override + public boolean existMetaData(String name) { + Query query = new Query(Criteria.where("name").is(name)); + return mongoTemplate.exists(query, MetaData.class); + } + + @Override + public MetaData selectMetaData(String name) { + Query query = new Query(Criteria.where("name").is(name)); + return mongoTemplate.findOne(query, MetaData.class); + } + + @Override + public void saveMetaData(MetaData metaData) { + try { + mongoTemplate.save(metaData); + } catch (Exception e) { + throw new MetaDataException(ResultEnum.ALREADY_EXIST_METADATA); + } + } + + @Override + public List listMetaDataLimit(String name, int offset, int pageSize) { + Criteria criteria = new Criteria(); + if (name != null) { + criteria.and("name").regex(name); + } + Query query = new Query(criteria).skip(offset).limit(pageSize); + return mongoTemplate.find(query, MetaData.class); + + } + + @Override + public long countMetaData(String name) { + Criteria criteria = new Criteria(); + if (name != null) { + criteria.and("name").regex(name); + } + Query query = new Query(criteria); + return mongoTemplate.count(query, MetaData.class); + } + + @Override + public List selectAllMetaData() { + return mongoTemplate.findAll(MetaData.class); + } + + @Override + public void deleteMetaData(String name) { + Query query = new Query(Criteria.where("name").is(name)); + mongoTemplate.remove(query,MetaData.class); + } +} diff --git a/src/main/java/com/example/survey/dao/impl/ProjectDaoImpl.java b/src/main/java/com/example/survey/dao/impl/ProjectDaoImpl.java new file mode 100644 index 0000000..b9de9b9 --- /dev/null +++ b/src/main/java/com/example/survey/dao/impl/ProjectDaoImpl.java @@ -0,0 +1,67 @@ +package com.example.survey.dao.impl; + +import com.example.survey.dao.ProjectDao; +import com.example.survey.entity.Project; +import com.example.survey.enumeration.ResultEnum; +import com.example.survey.exception.ProjectException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.stereotype.Repository; + +import java.util.List; + + +/** + * @author Pope + */ +@Repository +public class ProjectDaoImpl implements ProjectDao { + + @Autowired + private MongoTemplate mongoTemplate; + + @Override + public boolean existProject(String name) { + Query query = new Query(Criteria.where("name").is(name)); + return mongoTemplate.exists(query, Project.class); + } + + @Override + public Project selectProject(String name) { + Query query = new Query(Criteria.where("name").is(name)); + return mongoTemplate.findOne(query, Project.class); + } + + @Override + public void saveProject(Project project) { + try { + mongoTemplate.save(project); + } catch (Exception e) { + throw new ProjectException(ResultEnum.ALREADY_EXIST_PROJECT); + } + + } + + @Override + public List listProjectLimit(String name, int offset, int pageSize) { + Criteria criteria = new Criteria(); + if (name != null) { + criteria.and("name").regex(name); + } + Query query = new Query(criteria).skip(offset).limit(pageSize); + return mongoTemplate.find(query, Project.class); + } + + + @Override + public long countProject(String name) { + Criteria criteria = new Criteria(); + if (name != null) { + criteria.and("name").regex(name); + } + Query query = new Query(criteria); + return mongoTemplate.count(query, Project.class); + } +} diff --git a/src/main/java/com/example/survey/dao/impl/RecordDaoImpl.java b/src/main/java/com/example/survey/dao/impl/RecordDaoImpl.java new file mode 100644 index 0000000..46c18fb --- /dev/null +++ b/src/main/java/com/example/survey/dao/impl/RecordDaoImpl.java @@ -0,0 +1,124 @@ +package com.example.survey.dao.impl; + +import com.example.survey.dao.RecordDao; +import com.example.survey.entity.Project; +import com.example.survey.entity.Record; +import com.example.survey.entity.Respondent; +import com.example.survey.entity.User; +import com.example.survey.enumeration.RecordStateEnum; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * @author Pope + */ +@Log4j2 +@Repository +public class RecordDaoImpl implements RecordDao { + + @Autowired + MongoTemplate mongoTemplate; + + + @Override + public boolean existRecord(Respondent respondent, Project project, String state) { + Criteria criteria = new Criteria() + .and("respondent.$id").is(respondent.getId()) + .elemMatch(Criteria.where("project.$id").is(project.getId()).and("state").is(state)); + Query query = new Query(criteria); + return mongoTemplate.exists(query, Record.class); + } + + @Override + public Record getRecord(Respondent respondent, Project project, String state) { + Criteria criteria = new Criteria() + .and("respondent.$id").is(respondent.getId()) + .and("project.$id").is(project.getId()) + .and("state").is(state); + Query query = new Query(criteria); + + return mongoTemplate.findOne(query, Record.class); + } + + @Override + public void saveRecord(Record record) { + mongoTemplate.save(record); + } + + @Override + public long countRecord(Respondent respondent, User user, Project project, String state, String version, String questionnaireNumber) { + Criteria criteria = new Criteria(); + if (respondent != null) { + criteria.and("respondent.$id").is(respondent.getId()); + } + if (user != null) { + criteria.and("user.$id").is(user.getId()); + } + if (project != null) { + criteria.and("project.$id").is(project.getId()); + } + + if (state != null) { + criteria.and("state").is(state); + } else { + criteria.and("state").in(RecordStateEnum.REVIEWED.getValue(), RecordStateEnum.UNDER_REVIEW.getValue()); + } + + if (version != null) { + criteria.and("version").is(version); + } + if (questionnaireNumber != null) { + criteria.and("value.questionnaireNumber").is(questionnaireNumber); + } + Query query = new Query(criteria); + return mongoTemplate.count(query, Record.class); + } + + @Override + public List listRecordLimit(Respondent respondent, User user, Project project, String state, String version, String questionnaireNumber, int offset, int pageSize) { + Criteria criteria = new Criteria(); + if (respondent != null) { + criteria.and("respondent.$id").is(respondent.getId()); + } + if (user != null) { + criteria.and("user.$id").is(user.getId()); + } + if (project != null) { + criteria.and("project.$id").is(project.getId()); + } + + if (state != null) { + criteria.and("state").is(state); + } else { + criteria.and("state").in(RecordStateEnum.REVIEWED.getValue(), RecordStateEnum.UNDER_REVIEW.getValue()); + } + + if (version != null) { + criteria.and("version").is(version); + } + if (questionnaireNumber != null) { + criteria.and("value.questionnaireNumber").is(questionnaireNumber); + } + Query query = new Query(criteria).skip(offset).limit(pageSize); + return mongoTemplate.find(query, Record.class); + } + + @Override + public Record selectRecord(Respondent respondent, Project project, String version) { + + Criteria criteria = Criteria + .where("respondent.$id").is(respondent.getId()) + .and("project.$id").is(project.getId()); + if (version != null) { + criteria.and("version").is(version); + } + Query query = new Query(criteria); + return mongoTemplate.findOne(query, Record.class); + } +} diff --git a/src/main/java/com/example/survey/dao/impl/RespondentDaoImpl.java b/src/main/java/com/example/survey/dao/impl/RespondentDaoImpl.java index 89b3e8c..ef6e2f9 100644 --- a/src/main/java/com/example/survey/dao/impl/RespondentDaoImpl.java +++ b/src/main/java/com/example/survey/dao/impl/RespondentDaoImpl.java @@ -1,8 +1,10 @@ package com.example.survey.dao.impl; import com.example.survey.dao.RespondentDao; +import com.example.survey.entity.Project; import com.example.survey.entity.Respondent; -import com.example.survey.entity.inner.AdministrativeArea; +import com.example.survey.entity.User; +import com.example.survey.enumeration.ResultEnum; import com.example.survey.exception.RespondentException; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; @@ -24,42 +26,81 @@ public class RespondentDaoImpl implements RespondentDao { private MongoTemplate mongoTemplate; @Override - public boolean insertRespondent(Respondent respondent) { + public void saveRespondent(Respondent respondent) { try { mongoTemplate.save(respondent); } catch (Exception e) { - log.error("调查对象插入失败"); - log.error(e.getMessage()); - throw new RespondentException("调查对象已存在"); + throw new RespondentException(ResultEnum.ALREADY_EXIST_RESPONDENT); } - return true; } @Override - public List listRespondentLimit(String userPhone, String state, AdministrativeArea administrativeArea, int offset, int number) { + public List listRespondentLimit(User user, String state, String idNumber, String name, String phone, String province, String city, String county, Project project, int offset, int pageSize) { Criteria criteria = new Criteria(); - if (userPhone != null) { - criteria.and("userPhone").is(userPhone); + if (idNumber != null) { + criteria.and("idNumber").is(idNumber); + } + if (name != null) { + criteria.and("name").regex(name); + } + if (phone != null) { + criteria.and("phone").is(phone); } + if (province != null) { + criteria.and("administrativeArea.province").is(province); + } + if (city != null) { + criteria.and("administrativeArea.city").is(city); + } + if (county != null) { + criteria.and("administrativeArea.county").is(county); + } + + Criteria elementMatch = new Criteria(); + if (project != null) { + elementMatch.and("project.$id").is(project.getId()); + } + if (user != null) { + elementMatch.and("user.$id").is(user.getId()); + } if (state != null) { - criteria.and("state").is(state); + elementMatch.and("state").is(state); + } + criteria.and("projectPartSet").elemMatch(elementMatch); + + Query query = new Query(criteria).skip(offset).limit(pageSize); + return mongoTemplate.find(query, Respondent.class); + } + + @Override + public long countRespondent(User user, String state, String idNumber, String name, String phone, String province, String city, String county, Project project) { + Criteria criteria = new Criteria(); + + if (province != null) { + criteria.and("administrativeArea.province").is(province); + } + if (city != null) { + criteria.and("administrativeArea.city").is(city); + } + if (county != null) { + criteria.and("administrativeArea.county").is(county); } - if (administrativeArea != null) { - if(administrativeArea.getProvince()!=null){ - criteria.and("administrativeArea.province").is(administrativeArea.getProvince()); - } - if(administrativeArea.getCity()!=null){ - criteria.and("administrativeArea.city").is(administrativeArea.getCity()); - } - if(administrativeArea.getCounty()!=null){ - criteria.and("administrativeArea.county").is(administrativeArea.getCounty()); - } + Criteria elementMatch = new Criteria(); + if (project != null) { + elementMatch.and("project.$id").is(project.getId()); } - Query query = new Query(criteria).skip(offset).limit(number); - return mongoTemplate.find(query, Respondent.class); + if (user != null) { + elementMatch.and("user.$id").is(user.getId()); + } + if (state != null) { + elementMatch.and("state").is(state); + } + criteria.and("projectPartSet").elemMatch(elementMatch); + Query query = new Query(criteria); + return mongoTemplate.count(query, Respondent.class); } @Override @@ -69,29 +110,30 @@ public class RespondentDaoImpl implements RespondentDao { } @Override - public long countRespondent(String userPhone, String state, AdministrativeArea administrativeArea) { - Criteria criteria = new Criteria(); + public boolean existRespondent(String idNumber, String state) { + Query query = new Query( + Criteria.where("idNumber").is(idNumber) + .and("state").is(state)); + return mongoTemplate.exists(query, Respondent.class); + } - if (userPhone != null) { - criteria.and("userPhone").is(userPhone); - } - if (state != null) { - criteria.and("state").is(state); - } + @Override + public Respondent selectRespondent(String idNumber, Project project) { + Query query = new Query(Criteria.where("idNumber").is(idNumber).and("project.$id").is(project.getId())); + return mongoTemplate.findOne(query, Respondent.class); + } - if (administrativeArea != null) { - if(administrativeArea.getProvince()!=null){ - criteria.and("administrativeArea.province").is(administrativeArea.getProvince()); - } - if(administrativeArea.getCity()!=null){ - criteria.and("administrativeArea.city").is(administrativeArea.getCity()); - } - if(administrativeArea.getCounty()!=null){ - criteria.and("administrativeArea.county").is(administrativeArea.getCounty()); - } - } - Query query = new Query(criteria); + @Override + public void deleteRespondent(String idNumber) { + Query query = new Query(Criteria.where("idNumber").is(idNumber)); + mongoTemplate.remove(query, Respondent.class); + } + + @Override + public long countRespondent(Project project, String state) { + Criteria elementMatch = Criteria.where("project.$id").is(project.getId()).and("state").is(state); + Query query = new Query(Criteria.where("projectPartSet").elemMatch(elementMatch)); return mongoTemplate.count(query, Respondent.class); } diff --git a/src/main/java/com/example/survey/dao/impl/RoleDaoImpl.java b/src/main/java/com/example/survey/dao/impl/RoleDaoImpl.java index 559c660..9ddfeda 100644 --- a/src/main/java/com/example/survey/dao/impl/RoleDaoImpl.java +++ b/src/main/java/com/example/survey/dao/impl/RoleDaoImpl.java @@ -2,17 +2,15 @@ package com.example.survey.dao.impl; import com.example.survey.dao.RoleDao; import com.example.survey.entity.Role; -import com.example.survey.entity.User; import com.example.survey.enumeration.AuthEnum; +import com.example.survey.enumeration.ResultEnum; import com.example.survey.exception.RoleException; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Repository; -import org.springframework.stereotype.Service; import java.util.List; import java.util.Set; @@ -27,15 +25,12 @@ public class RoleDaoImpl implements RoleDao { private MongoTemplate mongoTemplate; @Override - public boolean insertRole(Role role) { + public void saveRole(Role role) { try { mongoTemplate.save(role); } catch (Exception e) { - log.error("权限插入失败"); - log.error(e.getMessage()); - throw new RoleException("已存在权限"); + throw new RoleException(ResultEnum.ALREADY_EXIST_ROLE); } - return true; } @Override @@ -50,25 +45,30 @@ public class RoleDaoImpl implements RoleDao { mongoTemplate.remove(query, Role.class); } - @Override - public List listLimitRole(String name, int offset, int limit) { + public List listRoleLimit(String name, int offset, int pageSize) { Criteria criteria = new Criteria(); if (name != null) { criteria.and("name").regex(name); } - Query query = new Query(criteria).skip(offset).limit(limit); + Query query = new Query(criteria).skip(offset).limit(pageSize); return mongoTemplate.find(query, Role.class); } + @Override - public void updateRole(String roleName, Set authEnumSet) { - Query query = new Query(Criteria.where("name").is(roleName)); - Role role = mongoTemplate.findOne(query, Role.class); - if(role == null){ - throw new RoleException("角色不存在"); + public long countRole(String name) { + Criteria criteria = new Criteria(); + if (name != null) { + criteria.and("name").regex(name); } - role.setAuthoritySet(authEnumSet); - mongoTemplate.save(role); + Query query = new Query(criteria); + return mongoTemplate.count(query, Role.class); + } + + @Override + public boolean existRole(String name) { + Query query = new Query(Criteria.where("name").is(name)); + return mongoTemplate.exists(query,Role.class); } } diff --git a/src/main/java/com/example/survey/dao/impl/UserDaoImpl.java b/src/main/java/com/example/survey/dao/impl/UserDaoImpl.java index 0b2cd8c..d1f424e 100644 --- a/src/main/java/com/example/survey/dao/impl/UserDaoImpl.java +++ b/src/main/java/com/example/survey/dao/impl/UserDaoImpl.java @@ -3,21 +3,19 @@ package com.example.survey.dao.impl; import com.example.survey.dao.UserDao; import com.example.survey.entity.Role; import com.example.survey.entity.User; +import com.example.survey.enumeration.ResultEnum; import com.example.survey.exception.UserException; -import com.example.survey.vo.UserInfoVo; -import com.mongodb.client.result.DeleteResult; import lombok.extern.log4j.Log4j2; -import org.bson.types.ObjectId; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Repository; -import org.springframework.stereotype.Service; import java.util.Iterator; import java.util.List; +import java.util.Set; /** @@ -29,24 +27,6 @@ public class UserDaoImpl implements UserDao { @Autowired private MongoTemplate mongoTemplate; - @Override - public User selectUser(String phoneNumber, String password) { - Query query = new Query(Criteria.where("phoneNumber").is(phoneNumber).and("password").is(password)); - return mongoTemplate.findOne(query, User.class); - } - - @Override - public boolean insertUser(User user) { - try { - mongoTemplate.save(user); - } catch (Exception e) { - log.error("用户插入失败"); - log.error(e.getMessage()); - throw new UserException("已存在用户"); - } - return true; - } - @Override public List listUserLimit(String username, String phoneNumber, int offset, int limit) { Criteria criteria = new Criteria(); @@ -58,7 +38,7 @@ public class UserDaoImpl implements UserDao { //电话号码精确查询 if (phoneNumber != null) { - criteria.and("phoneNumber").is(phoneNumber); + criteria.and("phone").is(phoneNumber); } Query query = new Query(criteria).skip(offset).limit(limit); @@ -67,81 +47,62 @@ public class UserDaoImpl implements UserDao { @Override public boolean existUser(String phoneNumber) { - Query query = new Query(Criteria.where("phoneNumber").is(phoneNumber)); - + Query query = new Query(Criteria.where("phone").is(phoneNumber)); return mongoTemplate.exists(query, User.class); } @Override - public void deleteUser(String phoneNumber) { - Query query = new Query(Criteria.where("phoneNumber").is(phoneNumber)); + public void deleteUser(String phone) { + Query query = new Query(Criteria.where("phone").is(phone)); mongoTemplate.remove(query, User.class); } @Override public void clearRole(Role role) { - Query query = new Query(Criteria.where("roleList").elemMatch(Criteria.where("$id").is(role.getId()))); + Query query = new Query(Criteria.where("roleSet").elemMatch(Criteria.where("$id").is(role.getId()))); List users = mongoTemplate.find(query, User.class); for (User user : users) { - List roleList = user.getRoleList(); - Iterator it = roleList.iterator(); + Set roleSet = user.getRoleSet(); + Iterator it = roleSet.iterator(); while (it.hasNext()) { if (role.getName().equals(it.next().getName())) { it.remove(); break; } } - Query userQuery = new Query(Criteria.where("phoneNumber").is(user.getPhoneNumber())); - Update update = new Update().set("roleList", roleList); + Query userQuery = new Query(Criteria.where("phone").is(user.getPhone())); + Update update = new Update().set("roleSet", roleSet); mongoTemplate.updateFirst(userQuery, update, User.class); } } - @Override - public void updateUserRole(String phoneNumber, List roleList) { - Query query = new Query(Criteria.where("phoneNumber").is(phoneNumber)); - User user = mongoTemplate.findOne(query, User.class); - if (user == null) { - throw new UserException("用户不存在"); - } - user.setRoleList(roleList); - mongoTemplate.save(user); - } @Override - public String selectUsername(String phoneNumber) { - Query query = new Query(Criteria.where("phoneNumber").is(phoneNumber)); - User user = mongoTemplate.findOne(query, User.class); - if(user == null){ - log.error("用户不存在"); - throw new UserException("用户不存在"); - } - return user.getUsername(); - } - - @Override - public User selectUser(String phoneNumber) { - Query query = new Query(Criteria.where("phoneNumber").is(phoneNumber)); + public User selectUser(String phone) { + Query query = new Query(Criteria.where("phone").is(phone)); return mongoTemplate.findOne(query, User.class); } @Override - public void resetPwd(String phoneNumber) { - Query query = new Query(Criteria.where("phoneNumber").is(phoneNumber)); - Update update = new Update().set("password", "123456"); - - mongoTemplate.updateFirst(query, update, User.class); - + public long countUser(String username, String phone) { + Criteria criteria = new Criteria(); + if (username != null) { + criteria.and("username").regex(username); + } + if (phone != null) { + criteria.and("phone").is(phone); + } + Query query = new Query(criteria); + return mongoTemplate.count(query, User.class); } @Override - public void modifyUser(UserInfoVo userInfoVo) { - Query query = new Query(Criteria.where("phoneNumber").is(userInfoVo.getPhoneNumber())); - Update update = new Update() - .set("username", userInfoVo.getUsername()) - .set("idNumber", userInfoVo.getIdNumber()) - .set("administrativeArea", userInfoVo.getAdministrativeArea()); - mongoTemplate.updateFirst(query, update, User.class); + public void saveUser(User user) { + try { + mongoTemplate.save(user); + } catch (Exception e) { + throw new UserException(ResultEnum.ALREADY_EXIST_USER); + } } diff --git a/src/main/java/com/example/survey/dto/RespondentDto.java b/src/main/java/com/example/survey/dto/RespondentDto.java deleted file mode 100644 index 98f620a..0000000 --- a/src/main/java/com/example/survey/dto/RespondentDto.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.example.survey.dto; - -import com.example.survey.dto.inner.RelevantUserInfo; -import com.example.survey.entity.Respondent; -import com.example.survey.entity.User; -import lombok.*; - -/** - * @author Pope - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -public class RespondentDto { - - /** - * 身份证号 - */ - private String idNumber; - - /** - * 电话 - */ - private String phoneNumber; - - /** - * 姓名 - */ - private String name; - - /** - * 备注 - */ - private String msg; - - /** - * 分配的人员 - */ - private RelevantUserInfo relevantUserInfo; - - /** - * 是否发病 - */ - private boolean diseased; - - /** - * 性别 - */ - private String gender; - - public RespondentDto(Respondent respondent, User user){ - this.idNumber = respondent.getIdNumber(); - this.name = respondent.getName(); - this.phoneNumber = respondent.getPhoneNumber(); - this.relevantUserInfo = new RelevantUserInfo(user); - this.diseased = respondent.isDiseased(); - this.gender = respondent.getGender(); - this.msg = respondent.getMsg(); - } -} diff --git a/src/main/java/com/example/survey/dto/UserDto.java b/src/main/java/com/example/survey/dto/UserDto.java deleted file mode 100644 index d31933f..0000000 --- a/src/main/java/com/example/survey/dto/UserDto.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.example.survey.dto; - -import com.example.survey.dao.UserDao; -import com.example.survey.entity.Department; -import com.example.survey.entity.Role; -import com.example.survey.entity.User; -import lombok.*; - -import java.util.LinkedList; -import java.util.List; - -/** - * @author Pope - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -public class UserDto { - private String username; - private String phoneNumber; - private List roleList; - private List departmentList; - - public UserDto(User user){ - username = user.getUsername(); - phoneNumber = user.getPhoneNumber(); - roleList = new LinkedList<>(); - for (Role role : user.getRoleList()) { - roleList.add(role.getName()); - } - departmentList = user.getDepartmentList(); - } -} diff --git a/src/main/java/com/example/survey/dto/inner/RelevantUserInfo.java b/src/main/java/com/example/survey/dto/inner/RelevantUserInfo.java deleted file mode 100644 index 54cfdc3..0000000 --- a/src/main/java/com/example/survey/dto/inner/RelevantUserInfo.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.example.survey.dto.inner; - -import com.example.survey.entity.User; -import lombok.*; - -/** - * @author Pope - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -public class RelevantUserInfo { - /** - * 身份证号 - */ - private String idNumber; - - /** - * 电话号码 - */ - private String phoneNumber; - - /** - * 用户名 - */ - private String username; - - public RelevantUserInfo(User user) { - this.idNumber = user.getIdNumber(); - this.phoneNumber = user.getPhoneNumber(); - this.username = user.getUsername(); - } -} diff --git a/src/main/java/com/example/survey/dto/metaData/CreateMetaDataDTO.java b/src/main/java/com/example/survey/dto/metaData/CreateMetaDataDTO.java new file mode 100644 index 0000000..85be0a3 --- /dev/null +++ b/src/main/java/com/example/survey/dto/metaData/CreateMetaDataDTO.java @@ -0,0 +1,18 @@ +package com.example.survey.dto.metaData; + +import com.example.survey.entity.inner.FieldToName; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @author Pope + */ +@Data +public class CreateMetaDataDTO { + private String name; + private Map form; + private List fieldToNameList; + private Map config; +} diff --git a/src/main/java/com/example/survey/dto/metaData/DeleteMetaDataDTO.java b/src/main/java/com/example/survey/dto/metaData/DeleteMetaDataDTO.java new file mode 100644 index 0000000..3a4d864 --- /dev/null +++ b/src/main/java/com/example/survey/dto/metaData/DeleteMetaDataDTO.java @@ -0,0 +1,11 @@ +package com.example.survey.dto.metaData; + +import lombok.Data; + +/** + * @author Pope + */ +@Data +public class DeleteMetaDataDTO { + private String name; +} diff --git a/src/main/java/com/example/survey/dto/metaData/ModifyMetaDataDTO.java b/src/main/java/com/example/survey/dto/metaData/ModifyMetaDataDTO.java new file mode 100644 index 0000000..63b5a25 --- /dev/null +++ b/src/main/java/com/example/survey/dto/metaData/ModifyMetaDataDTO.java @@ -0,0 +1,18 @@ +package com.example.survey.dto.metaData; + +import com.example.survey.entity.inner.FieldToName; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @author Pope + */ +@Data +public class ModifyMetaDataDTO { + private String name; + private Map form; + private List fieldToNameList; + private Map config; +} diff --git a/src/main/java/com/example/survey/dto/project/CreateProjectDTO.java b/src/main/java/com/example/survey/dto/project/CreateProjectDTO.java new file mode 100644 index 0000000..daa0859 --- /dev/null +++ b/src/main/java/com/example/survey/dto/project/CreateProjectDTO.java @@ -0,0 +1,46 @@ +package com.example.survey.dto.project; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; + +/** + * @author Pope + */ +@Data +public class CreateProjectDTO { + + /** + * 项目名 + */ + private String name; + + /** + * 描述信息 + */ + private String detail; + + /** + * 元数据名字 + */ + private String metaDataName; + + /** + * 开始时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date startTime; + + /** + * 结束时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date endTime; + + /** + * 负责人电话号码 + */ + private String userPhone; + +} diff --git a/src/main/java/com/example/survey/dto/project/ModifyProjectDTO.java b/src/main/java/com/example/survey/dto/project/ModifyProjectDTO.java new file mode 100644 index 0000000..70086be --- /dev/null +++ b/src/main/java/com/example/survey/dto/project/ModifyProjectDTO.java @@ -0,0 +1,20 @@ +package com.example.survey.dto.project; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; + +/** + * @author Pope + */ +@Data +public class ModifyProjectDTO { + private String name; + private String detail; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date startTime; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date endTime; + private String userPhone; +} diff --git a/src/main/java/com/example/survey/dto/project/ModifyStateDTO.java b/src/main/java/com/example/survey/dto/project/ModifyStateDTO.java new file mode 100644 index 0000000..089cd33 --- /dev/null +++ b/src/main/java/com/example/survey/dto/project/ModifyStateDTO.java @@ -0,0 +1,12 @@ +package com.example.survey.dto.project; + +import lombok.Data; + +/** + * @author Pope + */ +@Data +public class ModifyStateDTO { + private String name; + private String state; +} diff --git a/src/main/java/com/example/survey/dto/record/ModifyRecordDTO.java b/src/main/java/com/example/survey/dto/record/ModifyRecordDTO.java new file mode 100644 index 0000000..18470c2 --- /dev/null +++ b/src/main/java/com/example/survey/dto/record/ModifyRecordDTO.java @@ -0,0 +1,18 @@ +package com.example.survey.dto.record; + +import lombok.*; + +import java.util.Map; +import java.util.Set; + +/** + * @author Pope + */ +@Data +public class ModifyRecordDTO { + private String idNumber; + private Map values; + private String userPhone; + private String msg; + private String projectName; +} diff --git a/src/main/java/com/example/survey/dto/record/ReviewRecordDTO.java b/src/main/java/com/example/survey/dto/record/ReviewRecordDTO.java new file mode 100644 index 0000000..7be8215 --- /dev/null +++ b/src/main/java/com/example/survey/dto/record/ReviewRecordDTO.java @@ -0,0 +1,20 @@ +package com.example.survey.dto.record; + +import lombok.*; + +/** + * @author Pope + */ +@Getter +@Setter +@ToString +@NoArgsConstructor +@AllArgsConstructor +public class ReviewRecordDTO { + private String idNumber; + private String projectName; + private Boolean pass; + private String msg; + private String reviewerPhone; + +} diff --git a/src/main/java/com/example/survey/dto/record/SubmitRecordDTO.java b/src/main/java/com/example/survey/dto/record/SubmitRecordDTO.java new file mode 100644 index 0000000..ca2ef3d --- /dev/null +++ b/src/main/java/com/example/survey/dto/record/SubmitRecordDTO.java @@ -0,0 +1,26 @@ +package com.example.survey.dto.record; + +import lombok.*; + +import java.util.Map; + +/** + * @author Pope + */ +@Getter +@Setter +@ToString +@NoArgsConstructor +@AllArgsConstructor +public class SubmitRecordDTO { + private String idNumber; + + private Map values; + + private String userPhone; + + private String msg; + + private String projectName; + +} diff --git a/src/main/java/com/example/survey/vo/CreateRespondentVo.java b/src/main/java/com/example/survey/dto/respondent/CreateRespondentDTO.java similarity index 72% rename from src/main/java/com/example/survey/vo/CreateRespondentVo.java rename to src/main/java/com/example/survey/dto/respondent/CreateRespondentDTO.java index b52aa25..a967553 100644 --- a/src/main/java/com/example/survey/vo/CreateRespondentVo.java +++ b/src/main/java/com/example/survey/dto/respondent/CreateRespondentDTO.java @@ -1,9 +1,12 @@ -package com.example.survey.vo; +package com.example.survey.dto.respondent; +import com.example.survey.entity.Project; import com.example.survey.entity.inner.AdministrativeArea; import lombok.*; import org.springframework.data.mongodb.core.index.Indexed; +import java.util.Set; + /** * @author Pope */ @@ -12,7 +15,7 @@ import org.springframework.data.mongodb.core.index.Indexed; @ToString @NoArgsConstructor @AllArgsConstructor -public class CreateRespondentVo { +public class CreateRespondentDTO { /** * 身份证号 */ @@ -21,7 +24,7 @@ public class CreateRespondentVo { /** * 电话 */ - private String phoneNumber; + private String phone; /** * 姓名 @@ -33,16 +36,6 @@ public class CreateRespondentVo { */ private String msg; - /** - * 分配的调查人员 - */ - private String userPhone; - - /** - * 是否发病 - */ - private boolean diseased; - /** * 性别 */ @@ -52,4 +45,15 @@ public class CreateRespondentVo { * 行政区划 */ private AdministrativeArea administrativeArea; + + /** + * 分配人员 + */ + private String userPhone; + + /** + * 项目名集合 + */ + private String projectName; + } diff --git a/src/main/java/com/example/survey/dto/respondent/DeleteRespondentDTO.java b/src/main/java/com/example/survey/dto/respondent/DeleteRespondentDTO.java new file mode 100644 index 0000000..6c71f52 --- /dev/null +++ b/src/main/java/com/example/survey/dto/respondent/DeleteRespondentDTO.java @@ -0,0 +1,18 @@ +package com.example.survey.dto.respondent; + +import lombok.*; + +/** + * @author Pope + */ +@Getter +@Setter +@ToString +@NoArgsConstructor +@AllArgsConstructor +public class DeleteRespondentDTO { + + private String idNumber; + private String projectName; + +} diff --git a/src/main/java/com/example/survey/dto/respondent/ModifyRespondentDTO.java b/src/main/java/com/example/survey/dto/respondent/ModifyRespondentDTO.java new file mode 100644 index 0000000..d2b8b3e --- /dev/null +++ b/src/main/java/com/example/survey/dto/respondent/ModifyRespondentDTO.java @@ -0,0 +1,52 @@ +package com.example.survey.dto.respondent; + +import com.example.survey.entity.inner.AdministrativeArea; +import lombok.*; + +/** + * @author Pope + */ +@Getter +@Setter +@ToString +@NoArgsConstructor +@AllArgsConstructor +public class ModifyRespondentDTO { + + /** + * 身份证号 + */ + private String idNumber; + + /** + * 电话 + */ + private String phone; + + /** + * 姓名 + */ + private String name; + + /** + * 备注 + */ + private String msg; + + /** + * 性别 + */ + private String gender; + + /** + * 行政区划 + */ + private AdministrativeArea administrativeArea; + + /** + * 项目名 + */ + private String projectName; + + +} diff --git a/src/main/java/com/example/survey/dto/respondent/ModifyRespondentUserDTO.java b/src/main/java/com/example/survey/dto/respondent/ModifyRespondentUserDTO.java new file mode 100644 index 0000000..7609503 --- /dev/null +++ b/src/main/java/com/example/survey/dto/respondent/ModifyRespondentUserDTO.java @@ -0,0 +1,13 @@ +package com.example.survey.dto.respondent; + +import lombok.Data; + +/** + * @author Pope + */ +@Data +public class ModifyRespondentUserDTO { + private String idNumber; + private String projectName; + private String userPhone; +} diff --git a/src/main/java/com/example/survey/dto/role/CreateRoleDTO.java b/src/main/java/com/example/survey/dto/role/CreateRoleDTO.java new file mode 100644 index 0000000..550098c --- /dev/null +++ b/src/main/java/com/example/survey/dto/role/CreateRoleDTO.java @@ -0,0 +1,29 @@ +package com.example.survey.dto.role; + +import com.example.survey.entity.Role; +import com.example.survey.enumeration.AuthEnum; +import lombok.*; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author Pope + */ +@Getter +@Setter +@ToString +@NoArgsConstructor +@AllArgsConstructor +public class CreateRoleDTO { + private String name; + private Set authoritySet; + + public CreateRoleDTO(Role role) { + name = role.getName(); + authoritySet = new HashSet<>(); + for (AuthEnum authEnum : role.getAuthoritySet()) { + authoritySet.add(authEnum.getName()); + } + } +} diff --git a/src/main/java/com/example/survey/vo/DeleteRoleVo.java b/src/main/java/com/example/survey/dto/role/DeleteRoleDTO.java similarity index 55% rename from src/main/java/com/example/survey/vo/DeleteRoleVo.java rename to src/main/java/com/example/survey/dto/role/DeleteRoleDTO.java index 80608ab..ec06737 100644 --- a/src/main/java/com/example/survey/vo/DeleteRoleVo.java +++ b/src/main/java/com/example/survey/dto/role/DeleteRoleDTO.java @@ -1,4 +1,4 @@ -package com.example.survey.vo; +package com.example.survey.dto.role; import lombok.*; @@ -10,8 +10,8 @@ import lombok.*; @ToString @NoArgsConstructor @AllArgsConstructor -public class DeleteRoleVo { +public class DeleteRoleDTO { - private String roleName; + private String name; } diff --git a/src/main/java/com/example/survey/dto/role/ModifyRoleDTO.java b/src/main/java/com/example/survey/dto/role/ModifyRoleDTO.java new file mode 100644 index 0000000..b489124 --- /dev/null +++ b/src/main/java/com/example/survey/dto/role/ModifyRoleDTO.java @@ -0,0 +1,19 @@ +package com.example.survey.dto.role; + +import lombok.*; + +import java.util.List; +import java.util.Set; + +/** + * @author Pope + */ +@Getter +@Setter +@ToString +@NoArgsConstructor +@AllArgsConstructor +public class ModifyRoleDTO { + private String name; + private Set authoritySet; +} diff --git a/src/main/java/com/example/survey/vo/CreateUserVo.java b/src/main/java/com/example/survey/dto/user/CreateUserDTO.java similarity index 83% rename from src/main/java/com/example/survey/vo/CreateUserVo.java rename to src/main/java/com/example/survey/dto/user/CreateUserDTO.java index e74c32c..a668fb2 100644 --- a/src/main/java/com/example/survey/vo/CreateUserVo.java +++ b/src/main/java/com/example/survey/dto/user/CreateUserDTO.java @@ -1,4 +1,4 @@ -package com.example.survey.vo; +package com.example.survey.dto.user; import com.example.survey.entity.inner.AdministrativeArea; import lombok.*; @@ -11,7 +11,7 @@ import lombok.*; @ToString @NoArgsConstructor @AllArgsConstructor -public class CreateUserVo { +public class CreateUserDTO { /** * 身份证号 */ @@ -23,7 +23,7 @@ public class CreateUserVo { /** * 手机号 */ - private String phoneNumber; + private String phone; /** * 密码 */ diff --git a/src/main/java/com/example/survey/vo/DeleteUserVo.java b/src/main/java/com/example/survey/dto/user/DeleteUserDTO.java similarity index 54% rename from src/main/java/com/example/survey/vo/DeleteUserVo.java rename to src/main/java/com/example/survey/dto/user/DeleteUserDTO.java index b965738..261eded 100644 --- a/src/main/java/com/example/survey/vo/DeleteUserVo.java +++ b/src/main/java/com/example/survey/dto/user/DeleteUserDTO.java @@ -1,4 +1,4 @@ -package com.example.survey.vo; +package com.example.survey.dto.user; import lombok.*; @@ -10,8 +10,8 @@ import lombok.*; @ToString @NoArgsConstructor @AllArgsConstructor -public class DeleteUserVo { +public class DeleteUserDTO { - private String phoneNumber; + private String phone; } diff --git a/src/main/java/com/example/survey/vo/LoginVo.java b/src/main/java/com/example/survey/dto/user/LoginDTO.java similarity index 61% rename from src/main/java/com/example/survey/vo/LoginVo.java rename to src/main/java/com/example/survey/dto/user/LoginDTO.java index a69eb00..c5a44bc 100644 --- a/src/main/java/com/example/survey/vo/LoginVo.java +++ b/src/main/java/com/example/survey/dto/user/LoginDTO.java @@ -1,4 +1,4 @@ -package com.example.survey.vo; +package com.example.survey.dto.user; import lombok.*; @@ -10,7 +10,7 @@ import lombok.*; @ToString @NoArgsConstructor @AllArgsConstructor -public class LoginVo { - private String phoneNumber; +public class LoginDTO { + private String phone; private String password; } diff --git a/src/main/java/com/example/survey/vo/UserInfoVo.java b/src/main/java/com/example/survey/dto/user/ModifyUserInfoDTO.java similarity index 83% rename from src/main/java/com/example/survey/vo/UserInfoVo.java rename to src/main/java/com/example/survey/dto/user/ModifyUserInfoDTO.java index 582590e..1c654f9 100644 --- a/src/main/java/com/example/survey/vo/UserInfoVo.java +++ b/src/main/java/com/example/survey/dto/user/ModifyUserInfoDTO.java @@ -1,4 +1,4 @@ -package com.example.survey.vo; +package com.example.survey.dto.user; import com.example.survey.entity.Department; import com.example.survey.entity.inner.AdministrativeArea; @@ -14,12 +14,12 @@ import java.util.List; @ToString @NoArgsConstructor @AllArgsConstructor -public class UserInfoVo { +public class ModifyUserInfoDTO { /** * 电话号码 */ - private String phoneNumber; + private String phone; /** * 用户名 diff --git a/src/main/java/com/example/survey/dto/user/ModifyUserRoleDTO.java b/src/main/java/com/example/survey/dto/user/ModifyUserRoleDTO.java new file mode 100644 index 0000000..d88d3cc --- /dev/null +++ b/src/main/java/com/example/survey/dto/user/ModifyUserRoleDTO.java @@ -0,0 +1,19 @@ +package com.example.survey.dto.user; + +import lombok.*; + +import java.util.List; +import java.util.Set; + +/** + * @author Pope + */ +@Getter +@Setter +@ToString +@NoArgsConstructor +@AllArgsConstructor +public class ModifyUserRoleDTO { + private String phone; + private Set roleSet; +} diff --git a/src/main/java/com/example/survey/vo/ResetPwdVo.java b/src/main/java/com/example/survey/dto/user/ResetPwdDTO.java similarity index 62% rename from src/main/java/com/example/survey/vo/ResetPwdVo.java rename to src/main/java/com/example/survey/dto/user/ResetPwdDTO.java index 9eb3327..c63eef6 100644 --- a/src/main/java/com/example/survey/vo/ResetPwdVo.java +++ b/src/main/java/com/example/survey/dto/user/ResetPwdDTO.java @@ -1,4 +1,4 @@ -package com.example.survey.vo; +package com.example.survey.dto.user; import lombok.*; @@ -10,10 +10,10 @@ import lombok.*; @ToString @NoArgsConstructor @AllArgsConstructor -public class ResetPwdVo { +public class ResetPwdDTO { /** * 电话号码 */ - private String phoneNumber; + private String phone; } diff --git a/src/main/java/com/example/survey/entity/Audit.java b/src/main/java/com/example/survey/entity/Audit.java new file mode 100644 index 0000000..bb70964 --- /dev/null +++ b/src/main/java/com/example/survey/entity/Audit.java @@ -0,0 +1,20 @@ +package com.example.survey.entity; + +import lombok.Data; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.util.Date; + +/** + * @author Pope + */ +@Data +@Document(collection = "audit") +public class Audit { + + private String userPhone; + private String ip; + private Date time; + private String route; + +} diff --git a/src/main/java/com/example/survey/entity/Department.java b/src/main/java/com/example/survey/entity/Department.java index d8d5e98..e14028d 100644 --- a/src/main/java/com/example/survey/entity/Department.java +++ b/src/main/java/com/example/survey/entity/Department.java @@ -11,11 +11,7 @@ import java.util.List; /** * @author Pope */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor +@Data @Document(collection = "department") public class Department { diff --git a/src/main/java/com/example/survey/entity/InvestigationRecord.java b/src/main/java/com/example/survey/entity/InvestigationRecord.java deleted file mode 100644 index 0a29e45..0000000 --- a/src/main/java/com/example/survey/entity/InvestigationRecord.java +++ /dev/null @@ -1,339 +0,0 @@ -package com.example.survey.entity; - -import com.example.survey.entity.inner.*; -import com.example.survey.vo.InvestigationRecordVo; -import lombok.*; -import org.bson.types.ObjectId; -import org.springframework.data.mongodb.core.index.Indexed; -import org.springframework.data.mongodb.core.mapping.DBRef; -import org.springframework.data.mongodb.core.mapping.Document; - -import java.util.*; - -/** - * @author Pope - * 调查记录表 - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -@Document(collection = "investigationRecord") -public class InvestigationRecord { - - /** - * 调查记录审核中状态 - */ - public static final String UNDER_REVIEW = "待审核"; - - /** - * 调查记录已审核状态 - */ - public static final String REVIEWED = "已通过"; - - /** - * 调查记录已删除状态 - */ - public static final String DELETED = "已删除"; - - /** - * 调查记录审核未通过状态 - */ - public static final String NOT_PASS = "未通过"; - - /** - * 调查记录旧档状态 - */ - public static final String OUT_OF_DATE = "已归档"; - - /** - * 调查对象性别为男 - */ - public static final String MAN = "男"; - - /** - * 调查对象性别为女 - */ - public static final String WOMAN = "女"; - - - /** - * id - */ - private ObjectId id; - - /** - * 问卷编号 - */ - private String questionnaireNumber; - - /** - * 身份证号 - * 唯一索引 - */ - private String idNumber; - - //==================================基本信息================================== - - /** - * 姓名 - */ - private String name; - - /** - * 性别 - * true为男性,false为女性 - */ - private String gender; - - /** - * 是否为境外病例 - */ - private boolean overseasCase; - - /** - * 是否为病例 - * 区分病例与密切接触者 - */ - private boolean diseased; - - /** - * 入境经历 - * 选填 - */ - private EntryExperience entryExperience; - - //==================================病例发现与就诊================================== - - /** - * 病例被发现途径 - */ - private String wayOfBeingDiscovered; - - /** - * 入院时间 - */ - private Date dateOfAdmission; - - /** - * 入院时症状和体征 - */ - private List symptomAndSign; - - /** - * 有无并发症 - */ - private boolean existComplication; - - /** - * 并发症 - * 选填 - */ - private List complication; - - /** - * 并发症存在发热时记录最高体温 - */ - private String maxTemp; - - /** - * 胸部X线或 CT 检测是否有肺炎影像学特征 - */ - private boolean existImagingFeatureOfPneumonia; - - /** - * 如果肺炎影像学特征为是,此处填检测时间 - */ - private Date testDate; - - /** - * 出院日期 - * 年月日 - */ - private Date dateOfDischarge; - - //==================================危险因素与暴露史================================== - - /** - * 是否为特定职业人群 - */ - private String specificOccupation; - - /** - * 当specificOccupation为other时起作用 - */ - private String otherSpecificOccupation; - - /** - * 如为医护人员,填写具体工作性质 - */ - private String workInformation; - - /** - * 当workInformation为other时起作用 - */ - private String otherWorkInformation; - - /** - * 是否为孕妇 - */ - private boolean pregnant; - - /** - * 孕周 - */ - private int pregnantWeek; - - /** - * 病史 - */ - private List medicalHistory; - - /** - * 对既往病史的详细描述 - */ - private String medicalHistoryDetail; - - //==================================发病或检测阳性前14天内是否有以下暴露史或接触史================================== - - /** - * 是否有境外疫情严重国家或地区的旅行史或居住史 - */ - private boolean nearSeriousRegion; - - /** - * 是否接触过来自境外疫情严重的国家或地区的发热或有呼吸道症状的患者 - */ - private boolean contactWithSeriousRegionPatients; - - /** - * 是否曾有确诊病例或无症状感染者的接触史 - */ - private boolean contactWithConfirmedCase; - - /** - * 患者同一家庭、办公室、学校或托幼机构班级、车间等集体单位是否有聚集性发病 - */ - private boolean aggregationDisease; - - - //==================================实验室检测================================== - - /** - * 实验室检测结果,未采集则value为null - */ - private List detectionList; - - /** - * 调查单位 - */ - private String investigationCompany; - - /** - * 调查者(电话号码) - * 外键 - */ - @Indexed - private String userPhone; - - /** - * 调查日期 - * 年月日 - */ - private Date investigationDate; - - /** - * 体温历史 - */ - private List tempHistoryList; - - /** - * 居住史 - */ - private List liveHistoryList; - - /** - * 旅行史 - */ - private List travelHistoryList; - - /** - * 状态信息 - */ - private String state; - - /** - * 版本号 - */ - private String version; - - /** - * 操作列表 - */ - private List operationInformationList; - - //========================================保留字段============================================ - - /** - * 密切接触者(身份证) - * 外键 - */ - @DBRef - private List closeContactList; - - /** - * 上级感染者 - */ - private List superiorInfectedIndividualList; - - /** - * 存放一些url - */ - private Map urlMap; - - - public InvestigationRecord(InvestigationRecordVo vo) { - questionnaireNumber = vo.getQuestionnaireNumber(); - idNumber = vo.getIdNumber(); - name = vo.getName(); - gender = vo.getGender(); - overseasCase = vo.isOverseasCase(); - diseased = vo.isDiseased(); - entryExperience = vo.getEntryExperience(); - wayOfBeingDiscovered = vo.getWayOfBeingDiscovered(); - dateOfAdmission = vo.getDateOfAdmission(); - symptomAndSign = vo.getSymptomAndSign(); - existComplication = vo.isExistComplication(); - complication = vo.getComplication(); - maxTemp = vo.getMaxTemp(); - existImagingFeatureOfPneumonia = vo.isExistImagingFeatureOfPneumonia(); - testDate = vo.getTestDate(); - dateOfDischarge = vo.getDateOfDischarge(); - specificOccupation = vo.getSpecificOccupation(); - otherSpecificOccupation = vo.getOtherSpecificOccupation(); - workInformation = vo.getWorkInformation(); - otherWorkInformation = vo.getOtherWorkInformation(); - pregnant = vo.isPregnant(); - pregnantWeek = vo.getPregnantWeek(); - medicalHistory = vo.getMedicalHistory(); - medicalHistoryDetail = vo.getMedicalHistoryDetail(); - nearSeriousRegion = vo.isNearSeriousRegion(); - contactWithSeriousRegionPatients = vo.isContactWithSeriousRegionPatients(); - contactWithConfirmedCase = vo.isContactWithConfirmedCase(); - aggregationDisease = vo.isAggregationDisease(); - detectionList = vo.getDetectionList(); - investigationCompany = vo.getInvestigationCompany(); - userPhone = vo.getUserPhone(); - investigationDate = vo.getInvestigationDate(); - tempHistoryList = vo.getTempHistoryList(); - liveHistoryList = vo.getLiveHistoryList(); - travelHistoryList = vo.getTravelHistoryList(); - closeContactList = new ArrayList<>(); - superiorInfectedIndividualList = new ArrayList<>(); - urlMap = vo.getUrlMap(); - } - - -} - diff --git a/src/main/java/com/example/survey/entity/MetaData.java b/src/main/java/com/example/survey/entity/MetaData.java new file mode 100644 index 0000000..dce82e3 --- /dev/null +++ b/src/main/java/com/example/survey/entity/MetaData.java @@ -0,0 +1,23 @@ +package com.example.survey.entity; + +import com.example.survey.entity.inner.FieldToName; +import lombok.*; +import org.bson.types.ObjectId; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.util.List; +import java.util.Map; + +/** + * @author Pope + */ +@Data +@Document(collection = "metaData") +public class MetaData { + private ObjectId id; + private String name; + private Map form; + private List fieldToNameList; + private String wordTemplate; + private Map config; +} diff --git a/src/main/java/com/example/survey/entity/Project.java b/src/main/java/com/example/survey/entity/Project.java new file mode 100644 index 0000000..d185246 --- /dev/null +++ b/src/main/java/com/example/survey/entity/Project.java @@ -0,0 +1,73 @@ +package com.example.survey.entity; + +import lombok.*; +import org.bson.types.ObjectId; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.index.Indexed; +import org.springframework.data.mongodb.core.mapping.DBRef; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.util.Date; +import java.util.Set; + +/** + * @author Pope + */ +@Data +@Document(collection = "project") +public class Project { + + /** + * id + */ + @Id + private ObjectId id; + + /** + * 项目名 + */ + @Indexed(unique = true) + private String name; + + /** + * 描述信息 + */ + private String detail; + + /** + * 元数据 + */ + @DBRef + private MetaData metaData; + + /** + * 调查对象数量 + */ + private long respondentCount; + + /** + * 未调查调查对象数量 + */ + private long notInvestigatedRespondentCount; + + /** + * 负责人 + */ + @DBRef + private User user; + + /** + * 开始时间 + */ + private Date startTime; + + /** + * 结束时间 + */ + private Date endTime; + + /** + * 状态 + */ + private String state; +} diff --git a/src/main/java/com/example/survey/entity/Record.java b/src/main/java/com/example/survey/entity/Record.java new file mode 100644 index 0000000..0613ec7 --- /dev/null +++ b/src/main/java/com/example/survey/entity/Record.java @@ -0,0 +1,63 @@ +package com.example.survey.entity; + +import com.example.survey.entity.inner.Operation; +import lombok.*; +import org.bson.types.ObjectId; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.DBRef; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.util.List; +import java.util.Map; + +/** + * @author Pope + * 调查记录表 + */ +@Data +@Document(collection = "record") +public class Record { + + @Id + private ObjectId id; + + /** + * 调查对象 + */ + @DBRef + private Respondent respondent; + + /** + * 用于存放前端传的字段 + */ + private Map values; + + /** + * 分配的用户 + */ + @DBRef + private User user; + + /** + * 操作列表 + */ + private List operationList; + + /** + * 记录版本 + */ + private String version; + + /** + * 记录状态 + */ + private String state; + + /** + * 项目集合 + */ + @DBRef + private Project project; + +} + diff --git a/src/main/java/com/example/survey/entity/Respondent.java b/src/main/java/com/example/survey/entity/Respondent.java index f128323..49dac78 100644 --- a/src/main/java/com/example/survey/entity/Respondent.java +++ b/src/main/java/com/example/survey/entity/Respondent.java @@ -1,23 +1,21 @@ package com.example.survey.entity; import com.example.survey.entity.inner.AdministrativeArea; -import com.example.survey.enumeration.RespondentStateEnum; -import com.example.survey.vo.CreateRespondentVo; +import com.example.survey.entity.inner.ProjectPart; import lombok.*; import org.bson.types.ObjectId; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.index.Indexed; +import org.springframework.data.mongodb.core.mapping.DBRef; import org.springframework.data.mongodb.core.mapping.Document; +import java.util.Set; + /** * @author Pope * 调查对象表 */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor +@Data @Document(collection = "respondent") public class Respondent { @@ -36,7 +34,7 @@ public class Respondent { /** * 电话 */ - private String phoneNumber; + private String phone; /** * 姓名 @@ -48,17 +46,6 @@ public class Respondent { */ private String msg; - /** - * 分配的调查人员 - */ - @Indexed - private String userPhone; - - /** - * 是否发病 - */ - private boolean diseased; - /** * 性别 */ @@ -70,19 +57,17 @@ public class Respondent { private AdministrativeArea administrativeArea; /** - * 状态 + * 分配的人员 + */ + private User user; + + /** + * 项目 + */ + private Project project; + + /** + * 调查对象状态 */ private String state; - - public Respondent(CreateRespondentVo createRespondentVo) { - this.idNumber = createRespondentVo.getIdNumber(); - this.phoneNumber = createRespondentVo.getPhoneNumber(); - this.name = createRespondentVo.getName(); - this.msg = createRespondentVo.getMsg(); - this.userPhone = createRespondentVo.getUserPhone(); - this.diseased = createRespondentVo.isDiseased(); - this.gender = createRespondentVo.getGender(); - this.administrativeArea = createRespondentVo.getAdministrativeArea(); - this.state = RespondentStateEnum.NOT_INVESTIGATED.getValue(); - } } diff --git a/src/main/java/com/example/survey/entity/Role.java b/src/main/java/com/example/survey/entity/Role.java index 645edf7..79bd11e 100644 --- a/src/main/java/com/example/survey/entity/Role.java +++ b/src/main/java/com/example/survey/entity/Role.java @@ -7,16 +7,13 @@ import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.index.Indexed; import org.springframework.data.mongodb.core.mapping.Document; +import java.util.Objects; import java.util.Set; /** * @author Pope */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor +@Data @Document(collection = "role") public class Role { diff --git a/src/main/java/com/example/survey/entity/User.java b/src/main/java/com/example/survey/entity/User.java index acd769e..39961f0 100644 --- a/src/main/java/com/example/survey/entity/User.java +++ b/src/main/java/com/example/survey/entity/User.java @@ -1,7 +1,7 @@ package com.example.survey.entity; import com.example.survey.entity.inner.AdministrativeArea; -import com.example.survey.vo.CreateUserVo; +import com.example.survey.dto.user.CreateUserDTO; import lombok.*; import org.bson.types.ObjectId; import org.springframework.data.annotation.Id; @@ -14,11 +14,7 @@ import java.util.*; /** * @author Pope */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor +@Data @Document(collection = "user") public class User { @@ -52,13 +48,13 @@ public class User { * 手机号 */ @Indexed(unique = true) - private String phoneNumber; + private String phone; /** * 一个人可以拥有多个角色 */ @DBRef - private List roleList; + private Set roleSet; /** * 一个人所属的部门 @@ -66,14 +62,4 @@ public class User { @DBRef private List departmentList; - - public User(CreateUserVo vo) { - username = vo.getUsername(); - password = vo.getPassword(); - idNumber = vo.getIdNumber(); - phoneNumber = vo.getPhoneNumber(); - roleList = new LinkedList<>(); - departmentList = new LinkedList<>(); - } - } diff --git a/src/main/java/com/example/survey/entity/inner/AdministrativeArea.java b/src/main/java/com/example/survey/entity/inner/AdministrativeArea.java index e8b1063..dee978c 100644 --- a/src/main/java/com/example/survey/entity/inner/AdministrativeArea.java +++ b/src/main/java/com/example/survey/entity/inner/AdministrativeArea.java @@ -5,10 +5,7 @@ import lombok.*; /** * @author Pope */ -@Getter -@Setter -@ToString -@NoArgsConstructor +@Data @AllArgsConstructor public class AdministrativeArea { /** diff --git a/src/main/java/com/example/survey/entity/inner/Detection.java b/src/main/java/com/example/survey/entity/inner/Detection.java deleted file mode 100644 index 34892c8..0000000 --- a/src/main/java/com/example/survey/entity/inner/Detection.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.example.survey.entity.inner; - -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.*; -import org.springframework.format.annotation.DateTimeFormat; - -import java.util.Date; - -/** - * @author Pope - * 检测项目 - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -public class Detection { - - /** - * 检测项目名称 - */ - private String name; - - /** - * 检测时间 - * 年月日 - */ - @JsonFormat(pattern = "yyyy-MM-dd") - private Date date; - - /** - * 检测结果 - */ - private String result; -} diff --git a/src/main/java/com/example/survey/entity/inner/EntryExperience.java b/src/main/java/com/example/survey/entity/inner/EntryExperience.java deleted file mode 100644 index e0bec2d..0000000 --- a/src/main/java/com/example/survey/entity/inner/EntryExperience.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.example.survey.entity.inner; - -import com.fasterxml.jackson.annotation.JsonFormat; -import org.springframework.format.annotation.DateTimeFormat; - -import java.util.Date; - -/** - * @author Pope\ - * 入境经历 - */ -public class EntryExperience { - /** - * 入境前居住或旅行的国家或地区 - */ - private String areaOfResidence; - - /** - * 入境前途径的国家或地区 - */ - private String areaOfAccess; - - /** - * 国籍 - */ - private String nationality; - - /** - * 护照号码 - */ - private String passportNumber; - - /** - * 入境口岸 - */ - private EntryPort entryPort; - - /** - * 入境日期 - * 年月日 - */ - @JsonFormat(pattern = "yyyy-MM-dd") - private Date entryDate; - - /** - * 入境交通方式 - * 航班号、车次、船号等 - */ - private String transportation; - - - public EntryExperience() { - } - - public EntryExperience(String areaOfResidence, String areaOfAccess, String nationality, String passportNumber, EntryPort entryPort, Date entryDate, String transportation) { - this.areaOfResidence = areaOfResidence; - this.areaOfAccess = areaOfAccess; - this.nationality = nationality; - this.passportNumber = passportNumber; - this.entryPort = entryPort; - this.entryDate = entryDate; - this.transportation = transportation; - } - - public String getAreaOfResidence() { - return areaOfResidence; - } - - public void setAreaOfResidence(String areaOfResidence) { - this.areaOfResidence = areaOfResidence; - } - - public String getAreaOfAccess() { - return areaOfAccess; - } - - public void setAreaOfAccess(String areaOfAccess) { - this.areaOfAccess = areaOfAccess; - } - - public String getNationality() { - return nationality; - } - - public void setNationality(String nationality) { - this.nationality = nationality; - } - - public String getPassportNumber() { - return passportNumber; - } - - public void setPassportNumber(String passportNumber) { - this.passportNumber = passportNumber; - } - - public EntryPort getEntryPort() { - return entryPort; - } - - public void setEntryPort(EntryPort entryPort) { - this.entryPort = entryPort; - } - - public Date getEntryDate() { - return entryDate; - } - - public void setEntryDate(Date entryDate) { - this.entryDate = entryDate; - } - - public String getTransportation() { - return transportation; - } - - public void setTransportation(String transportation) { - this.transportation = transportation; - } -} diff --git a/src/main/java/com/example/survey/entity/inner/EntryPort.java b/src/main/java/com/example/survey/entity/inner/EntryPort.java deleted file mode 100644 index df9363d..0000000 --- a/src/main/java/com/example/survey/entity/inner/EntryPort.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.example.survey.entity.inner; - -/** - * @author Pope - * 入境口岸 - */ -public class EntryPort { - /** - * 入境省份 - */ - private String province; - - /** - * 入境机场、码头、车站等 - */ - private String port; - - public EntryPort() { - } - - public EntryPort(String province, String port) { - this.province = province; - this.port = port; - } - - public String getProvince() { - return province; - } - - public void setProvince(String province) { - this.province = province; - } - - public String getPort() { - return port; - } - - public void setPort(String port) { - this.port = port; - } -} diff --git a/src/main/java/com/example/survey/entity/inner/FieldToName.java b/src/main/java/com/example/survey/entity/inner/FieldToName.java new file mode 100644 index 0000000..c5e1eaf --- /dev/null +++ b/src/main/java/com/example/survey/entity/inner/FieldToName.java @@ -0,0 +1,12 @@ +package com.example.survey.entity.inner; + +import lombok.*; + +/** + * @author Pope + */ +@Data +public class FieldToName { + private String field; + private String name; +} diff --git a/src/main/java/com/example/survey/entity/inner/LiveHistory.java b/src/main/java/com/example/survey/entity/inner/LiveHistory.java deleted file mode 100644 index 3849dd6..0000000 --- a/src/main/java/com/example/survey/entity/inner/LiveHistory.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.example.survey.entity.inner; - -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.*; - -import java.util.Date; -import java.util.List; - -/** - * @author Pope - * 居旅史 - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -public class LiveHistory { - - /** - * 起始时间 - */ - @JsonFormat(pattern = "yyyy-MM-dd") - private Date beginTime; - - /** - * 结束时间 - */ - @JsonFormat(pattern = "yyyy-MM-dd") - private Date endTime; - - /** - * 地点 - */ - private Location location; - - /** - * 事件 - */ - private String detail; -} diff --git a/src/main/java/com/example/survey/entity/inner/Location.java b/src/main/java/com/example/survey/entity/inner/Location.java deleted file mode 100644 index cc3170f..0000000 --- a/src/main/java/com/example/survey/entity/inner/Location.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.example.survey.entity.inner; - -import lombok.*; - -/** - * @author Pope - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -public class Location { - - /** - * 地点信息 - */ - private String msg; - - /** - * 经度 - */ - private double longitude; - - /** - * 纬度 - */ - private double latitude; - -} diff --git a/src/main/java/com/example/survey/entity/inner/Operation.java b/src/main/java/com/example/survey/entity/inner/Operation.java new file mode 100644 index 0000000..1d1e29c --- /dev/null +++ b/src/main/java/com/example/survey/entity/inner/Operation.java @@ -0,0 +1,107 @@ +package com.example.survey.entity.inner; + +import com.example.survey.entity.User; +import com.example.survey.enumeration.OpTypeEnum; +import lombok.*; +import org.springframework.data.mongodb.core.mapping.DBRef; + +import java.util.Date; + +/** + * @author Pope + * 操作信息 + */ +@Data +public class Operation { + + /** + * 操作 + */ + private String type; + + /** + * 时间 + */ + private Date time; + + /** + * 操作者 + */ + @DBRef + private User user; + + /** + * 版本信息 + */ + private String version; + + /** + * 备注 + */ + private String msg; + + /** + * 操作结果 + */ + private String result; + + + public static Operation submitOp(User user, String msg, String version) { + Operation submit = new Operation(); + submit.setType(OpTypeEnum.SUBMIT.getValue()); + submit.setTime(new Date()); + submit.setUser(user); + submit.setVersion(version); + submit.setMsg(msg); + submit.setResult("提交成功"); + return submit; + } + + public static Operation modifyOp(User user, String msg, String version) { + Operation modify = new Operation(); + modify.setType(OpTypeEnum.MODIFY.getValue()); + modify.setTime(new Date()); + modify.setUser(user); + modify.setVersion(version); + modify.setMsg(msg); + modify.setResult("提交修改"); + return modify; + } + + public static Operation deleteOp(User user, String msg, String version) { + Operation delete = new Operation(); + delete.setType(OpTypeEnum.DELETE.getValue()); + delete.setTime(new Date()); + delete.setUser(user); + delete.setVersion(version); + delete.setMsg(msg); + delete.setResult("删除成功"); + return delete; + } + + public static Operation reviewOp(User user, String msg, String version, boolean result) { + Operation review = new Operation(); + review.setType(OpTypeEnum.REVIEW.getValue()); + review.setTime(new Date()); + review.setUser(user); + review.setVersion(version); + review.setMsg(msg); + if (result) { + review.setResult("审核通过"); + } else { + review.setResult("审核不通过"); + } + return review; + } + + public static Operation coverOp(User user, String version) { + Operation cover = new Operation(); + cover.setType(OpTypeEnum.COVER.getValue()); + cover.setTime(new Date()); + cover.setUser(user); + cover.setVersion(version); + cover.setMsg("因重复提交覆盖"); + cover.setResult("被覆盖"); + return cover; + } +} diff --git a/src/main/java/com/example/survey/entity/inner/OperationInformation.java b/src/main/java/com/example/survey/entity/inner/OperationInformation.java deleted file mode 100644 index 9830156..0000000 --- a/src/main/java/com/example/survey/entity/inner/OperationInformation.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.example.survey.entity.inner; - -import lombok.*; - -import java.util.Date; - -/** - * @author Pope - * 操作信息 - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -public class OperationInformation { - - public static final String SUBMIT = "提交"; - - /** - * 修改操作 - */ - public static final String MODIFY = "修改"; - - /** - * 删除操作 - */ - public static final String DELETE = "删除"; - - /** - * 恢复记录 - */ - public static final String RECOVERY = "恢复"; - - /** - * - */ - public static final String REVIEW = "审核"; - - /** - * 操作 - */ - private String type; - - /** - * 时间 - */ - private Date time; - - /** - * 操作者id - */ - private String userPhone; - - /** - * 版本信息 - */ - private String version; - - /** - * 备注 - */ - private String msg; - - /** - * 操作结果 - */ - private String result; - - public static OperationInformation submitOp(String userPhone, String msg) { - OperationInformation submit = new OperationInformation(); - submit.setType(SUBMIT); - submit.setTime(new Date()); - submit.setUserPhone(userPhone); - submit.setVersion(userPhone + new Date().toString()); - submit.setMsg(msg); - submit.setResult("提交成功"); - return submit; - } - - public static OperationInformation modifyOp(String investigatorPhone, String msg) { - OperationInformation modify = new OperationInformation(); - modify.setType(MODIFY); - modify.setTime(new Date()); - modify.setUserPhone(investigatorPhone); - modify.setVersion(investigatorPhone + new Date().toString()); - modify.setMsg(msg); - modify.setResult("提交修改"); - return modify; - } - - public static OperationInformation deleteOp(String investigatorPhone, String msg) { - OperationInformation delete = new OperationInformation(); - delete.setType(MODIFY); - delete.setTime(new Date()); - delete.setUserPhone(investigatorPhone); - delete.setVersion(investigatorPhone + new Date().toString()); - delete.setMsg(msg); - delete.setResult("删除成功"); - return delete; - } - - public static OperationInformation reviewOp(String investigatorPhone, String msg, String result) { - OperationInformation review = new OperationInformation(); - review.setType(REVIEW); - review.setTime(new Date()); - review.setUserPhone(investigatorPhone); - review.setVersion(investigatorPhone + new Date().toString()); - review.setMsg(msg); - review.setResult(result); - return review; - } -} diff --git a/src/main/java/com/example/survey/entity/inner/ProjectPart.java b/src/main/java/com/example/survey/entity/inner/ProjectPart.java new file mode 100644 index 0000000..12de287 --- /dev/null +++ b/src/main/java/com/example/survey/entity/inner/ProjectPart.java @@ -0,0 +1,34 @@ +package com.example.survey.entity.inner; + +import com.example.survey.entity.Project; +import com.example.survey.entity.User; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import org.springframework.data.mongodb.core.index.Indexed; +import org.springframework.data.mongodb.core.mapping.DBRef; + +/** + * @author Pope + */ +@Data +public class ProjectPart { + /** + * 项目 + */ + @Indexed + @DBRef + Project project; + + /** + * 用户 + */ + @Indexed + @DBRef + User user; + + /** + * 状态 + */ + String state; +} diff --git a/src/main/java/com/example/survey/entity/inner/SuperiorInfectedIndividual.java b/src/main/java/com/example/survey/entity/inner/SuperiorInfectedIndividual.java deleted file mode 100644 index f450e96..0000000 --- a/src/main/java/com/example/survey/entity/inner/SuperiorInfectedIndividual.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.example.survey.entity.inner; - -import java.util.Date; - -/** - * @author Pope - * 上级感染者 - */ -public class SuperiorInfectedIndividual { - - /** - * 身份证 - */ - private String idNumber; - - /** - * 地点 - */ - private String place; - - /** - * 时间 - */ - private Date date; - - /** - * 事件 - */ - private String event; - - public SuperiorInfectedIndividual() { - } - - public SuperiorInfectedIndividual(String idNumber, String place, Date date, String event) { - this.idNumber = idNumber; - this.place = place; - this.date = date; - this.event = event; - } - - public String getIdNumber() { - return idNumber; - } - - public void setIdNumber(String idNumber) { - this.idNumber = idNumber; - } - - public String getPlace() { - return place; - } - - public void setPlace(String place) { - this.place = place; - } - - public Date getDate() { - return date; - } - - public void setDate(Date date) { - this.date = date; - } - - public String getEvent() { - return event; - } - - public void setEvent(String event) { - this.event = event; - } -} diff --git a/src/main/java/com/example/survey/entity/inner/TempHistory.java b/src/main/java/com/example/survey/entity/inner/TempHistory.java deleted file mode 100644 index 6a5cb89..0000000 --- a/src/main/java/com/example/survey/entity/inner/TempHistory.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.example.survey.entity.inner; - -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.*; - -import java.util.Date; - -/** - * @author Pope - * 体温历史 - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -public class TempHistory { - - /** - * 检测时间 - */ - @JsonFormat(pattern = "yyyy-MM-dd:HH:mm:ss") - private Date time; - - /** - * 体温 - */ - private String data; - -} diff --git a/src/main/java/com/example/survey/entity/inner/TravelHistory.java b/src/main/java/com/example/survey/entity/inner/TravelHistory.java deleted file mode 100644 index b18f21c..0000000 --- a/src/main/java/com/example/survey/entity/inner/TravelHistory.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.example.survey.entity.inner; - -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.*; - -import java.util.Date; - -/** - * @author Pope - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -public class TravelHistory { - /** - * 起始时间 - */ - @JsonFormat(pattern = "yyyy-MM-dd") - private Date beginTime; - - /** - * 结束时间 - */ - @JsonFormat(pattern = "yyyy-MM-dd") - private Date endTime; - - /** - * 开始地点 - */ - private Location startLocation; - - /** - * 结束地点 - */ - private Location endLocation; - - /** - * 事件 - */ - private String detail; -} diff --git a/src/main/java/com/example/survey/enumeration/OpTypeEnum.java b/src/main/java/com/example/survey/enumeration/OpTypeEnum.java new file mode 100644 index 0000000..2d04e68 --- /dev/null +++ b/src/main/java/com/example/survey/enumeration/OpTypeEnum.java @@ -0,0 +1,42 @@ +package com.example.survey.enumeration; + +/** + * @author Pope + */ +public enum OpTypeEnum { + /** + * 提交操作 + */ + SUBMIT("提交"), + /** + * 修改操作 + */ + MODIFY("修改"), + /** + * 删除操作 + */ + DELETE("删除"), + /** + * 恢复操作 + */ + RECOVERY("恢复"), + /** + * 审核操作 + */ + REVIEW("审核"), + /** + * 覆盖 + */ + COVER("覆盖"), + ; + + private final String value; + + OpTypeEnum(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/com/example/survey/enumeration/ProjectStateEnum.java b/src/main/java/com/example/survey/enumeration/ProjectStateEnum.java new file mode 100644 index 0000000..b441a48 --- /dev/null +++ b/src/main/java/com/example/survey/enumeration/ProjectStateEnum.java @@ -0,0 +1,32 @@ +package com.example.survey.enumeration; + +/** + * @author Pope + */ +public enum ProjectStateEnum { + /** + * 进行中状态 + */ + IN_PROGRESS("进行中"), + /** + * 已完成状态 + */ + FINISHED("已完成"), + /** + * 已作废状态 + */ + INVALID("已作废"), + ; + + + private final String value; + + ProjectStateEnum(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + +} diff --git a/src/main/java/com/example/survey/enumeration/RecordStateEnum.java b/src/main/java/com/example/survey/enumeration/RecordStateEnum.java new file mode 100644 index 0000000..77cb815 --- /dev/null +++ b/src/main/java/com/example/survey/enumeration/RecordStateEnum.java @@ -0,0 +1,41 @@ +package com.example.survey.enumeration; + +/** + * @author Pope + * 调查记录状态枚举 + */ + +public enum RecordStateEnum { + /** + * 已审核状态 + */ + REVIEWED("已审核"), + /** + * 待审核状态 + */ + UNDER_REVIEW("待审核"), + /** + * 未通过状态 + */ + NOT_PASS("未通过"), + /** + * 已删除状态 + */ + DELETED("已删除"), + /** + * 已归档状态 + */ + FILED("已归档") + ; + + + private final String value; + + RecordStateEnum(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/com/example/survey/enumeration/RespondentStateEnum.java b/src/main/java/com/example/survey/enumeration/RespondentStateEnum.java index 9680eef..21ad8ee 100644 --- a/src/main/java/com/example/survey/enumeration/RespondentStateEnum.java +++ b/src/main/java/com/example/survey/enumeration/RespondentStateEnum.java @@ -11,7 +11,13 @@ public enum RespondentStateEnum { /** * 未调查状态 */ - NOT_INVESTIGATED("未调查"); + NOT_INVESTIGATED("未调查"), + /** + * 已归档 + */ + FILED("已归档"), + + ; private final String value; diff --git a/src/main/java/com/example/survey/enumeration/ResultEnum.java b/src/main/java/com/example/survey/enumeration/ResultEnum.java new file mode 100644 index 0000000..8c91aa7 --- /dev/null +++ b/src/main/java/com/example/survey/enumeration/ResultEnum.java @@ -0,0 +1,74 @@ +package com.example.survey.enumeration; + +/** + * @author Pope + */ +public enum ResultEnum { + /** + * 请求成功 + */ + SUCCESS(0, "请求成功!"), + + + NO_TOKEN(100, "请先登录!"), + INSUFFICIENT_PRIVILEGE(101, "非法token或权限不够!"), + NOT_EXIST_AUTHORITY(102, "权限不存在!"), + + /** + * 用户模块 + */ + WRONG_PASSWORD(200, "密码错误!"), + NOT_EXIST_USER(201, "用户不存在!"), + ALREADY_EXIST_USER(202, "用户已存在!"), + + /** + * 角色模块 + */ + NOT_EXIST_ROLE(300, "角色不存在!"), + ALREADY_EXIST_ROLE(301, "角色已存在!"), + + + /** + * 调查对象模块 + */ + NOT_EXIST_RESPONDENT(400, "调查对象不存在!"), + ALREADY_EXIST_RESPONDENT(401, "调查对象已存在!"), + + + /** + * 调查记录模块 + */ + NOT_EXIST_RECORD(500, "调查记录不存在!"), + + + /** + * 调查记录模块 + */ + NOT_EXIST_PROJECT(600, "项目不存在!"), + ALREADY_EXIST_PROJECT(601, "项目已存在!"), + NOT_EXIST_PROJECT_STATE(602, "项目状态不存在!"), + + /** + * 元数据模块 + */ + NOT_EXIST_METADATA(700,"元数据不存在!"), + ALREADY_EXIST_METADATA(601,"元数据已存在!"), + ; + + + private final int code; + private final String msg; + + ResultEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + public int getCode() { + return code; + } + + public String getMsg() { + return msg; + } +} diff --git a/src/main/java/com/example/survey/exception/AuthException.java b/src/main/java/com/example/survey/exception/AuthException.java index 6e26740..00b7965 100644 --- a/src/main/java/com/example/survey/exception/AuthException.java +++ b/src/main/java/com/example/survey/exception/AuthException.java @@ -1,10 +1,17 @@ package com.example.survey.exception; +import com.example.survey.enumeration.ResultEnum; +import lombok.Getter; + /** * @author Pope */ +@Getter public class AuthException extends RuntimeException{ - public AuthException(String message) { - super(message); + private final ResultEnum resultEnum; + + public AuthException(ResultEnum resultEnum) { + super(resultEnum.getMsg()); + this.resultEnum = resultEnum; } } diff --git a/src/main/java/com/example/survey/exception/DepartmentException.java b/src/main/java/com/example/survey/exception/DepartmentException.java index bad820e..50d0016 100644 --- a/src/main/java/com/example/survey/exception/DepartmentException.java +++ b/src/main/java/com/example/survey/exception/DepartmentException.java @@ -1,10 +1,17 @@ package com.example.survey.exception; +import com.example.survey.enumeration.ResultEnum; +import lombok.Getter; + /** * @author Pope */ -public class DepartmentException extends RuntimeException{ - public DepartmentException(String message) { - super(message); +@Getter +public class DepartmentException extends RuntimeException { + private final ResultEnum resultEnum; + + public DepartmentException(ResultEnum resultEnum) { + super(resultEnum.getMsg()); + this.resultEnum = resultEnum; } } diff --git a/src/main/java/com/example/survey/exception/MetaDataException.java b/src/main/java/com/example/survey/exception/MetaDataException.java new file mode 100644 index 0000000..5935dd6 --- /dev/null +++ b/src/main/java/com/example/survey/exception/MetaDataException.java @@ -0,0 +1,17 @@ +package com.example.survey.exception; + +import com.example.survey.enumeration.ResultEnum; +import lombok.Getter; + +/** + * @author Pope + */ +@Getter +public class MetaDataException extends RuntimeException { + private final ResultEnum resultEnum; + + public MetaDataException(ResultEnum resultEnum) { + super(resultEnum.getMsg()); + this.resultEnum = resultEnum; + } +} diff --git a/src/main/java/com/example/survey/exception/ProjectException.java b/src/main/java/com/example/survey/exception/ProjectException.java new file mode 100644 index 0000000..14c3326 --- /dev/null +++ b/src/main/java/com/example/survey/exception/ProjectException.java @@ -0,0 +1,17 @@ +package com.example.survey.exception; + +import com.example.survey.enumeration.ResultEnum; +import lombok.Getter; + +/** + * @author Pope + */ +@Getter +public class ProjectException extends RuntimeException{ + private final ResultEnum resultEnum; + + public ProjectException(ResultEnum resultEnum) { + super(resultEnum.getMsg()); + this.resultEnum = resultEnum; + } +} diff --git a/src/main/java/com/example/survey/exception/RecordException.java b/src/main/java/com/example/survey/exception/RecordException.java index b68543f..a6648e2 100644 --- a/src/main/java/com/example/survey/exception/RecordException.java +++ b/src/main/java/com/example/survey/exception/RecordException.java @@ -1,11 +1,17 @@ package com.example.survey.exception; +import com.example.survey.enumeration.ResultEnum; +import lombok.Getter; + /** * @author Pope */ +@Getter public class RecordException extends RuntimeException{ + private final ResultEnum resultEnum; - public RecordException(String message) { - super(message); + public RecordException(ResultEnum resultEnum) { + super(resultEnum.getMsg()); + this.resultEnum = resultEnum; } } diff --git a/src/main/java/com/example/survey/exception/RespondentException.java b/src/main/java/com/example/survey/exception/RespondentException.java index a7cd292..825ff9a 100644 --- a/src/main/java/com/example/survey/exception/RespondentException.java +++ b/src/main/java/com/example/survey/exception/RespondentException.java @@ -1,10 +1,17 @@ package com.example.survey.exception; +import com.example.survey.enumeration.ResultEnum; +import lombok.Getter; + /** * @author Pope */ +@Getter public class RespondentException extends RuntimeException{ - public RespondentException(String message) { - super(message); + private final ResultEnum resultEnum; + + public RespondentException(ResultEnum resultEnum) { + super(resultEnum.getMsg()); + this.resultEnum = resultEnum; } } diff --git a/src/main/java/com/example/survey/exception/RoleException.java b/src/main/java/com/example/survey/exception/RoleException.java index e88ce80..a422553 100644 --- a/src/main/java/com/example/survey/exception/RoleException.java +++ b/src/main/java/com/example/survey/exception/RoleException.java @@ -1,10 +1,17 @@ package com.example.survey.exception; +import com.example.survey.enumeration.ResultEnum; +import lombok.Getter; + /** * @author Pope */ -public class RoleException extends RuntimeException{ - public RoleException(String msg){ - super(msg); +@Getter +public class RoleException extends RuntimeException { + private final ResultEnum resultEnum; + + public RoleException(ResultEnum resultEnum) { + super(resultEnum.getMsg()); + this.resultEnum = resultEnum; } } diff --git a/src/main/java/com/example/survey/exception/UserException.java b/src/main/java/com/example/survey/exception/UserException.java index dff6c5b..559660f 100644 --- a/src/main/java/com/example/survey/exception/UserException.java +++ b/src/main/java/com/example/survey/exception/UserException.java @@ -1,10 +1,17 @@ package com.example.survey.exception; +import com.example.survey.enumeration.ResultEnum; +import lombok.Getter; + /** * @author Pope */ -public class UserException extends RuntimeException{ - public UserException(String msg){ - super(msg); +@Getter +public class UserException extends RuntimeException { + private final ResultEnum resultEnum; + + public UserException(ResultEnum resultEnum) { + super(resultEnum.getMsg()); + this.resultEnum = resultEnum; } } diff --git a/src/main/java/com/example/survey/service/InvestigationRecordService.java b/src/main/java/com/example/survey/service/InvestigationRecordService.java deleted file mode 100644 index f84bb17..0000000 --- a/src/main/java/com/example/survey/service/InvestigationRecordService.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.example.survey.service; - -import com.example.survey.entity.InvestigationRecord; -import com.example.survey.vo.InvestigationRecordVo; -import com.example.survey.vo.ReviewVo; - -import javax.servlet.http.HttpServletResponse; -import java.util.List; - -/** - * @author Pope - */ -public interface InvestigationRecordService { - - /** - * 创建新的调查记录 - * - * @param vo 调查记录信息 - * @return 是否创建成功 - */ - boolean addInvestigationRecord(InvestigationRecordVo vo); - - /** - * 根据筛选条件查询调查记录 - * - * @param userPhone 用户电话号码 - * @param currentPage 当前页数 - * @param pageSize 页大小 - * @param state 状态 - * @param idNumber 调查对象身份证号 - * @param version 版本 - * @param questionnaireNumber 问卷编号 - * @param diseased 是否患病 - * @return 调查记录列表 - */ - List listUnderReviewRecordLimit(String userPhone, int currentPage, int pageSize, String state, String idNumber, String version, String questionnaireNumber, Boolean diseased); - - /** - * 根据流调人员电话号码查询待审核记录数量 - * - * @param userPhone 用户电话号码 - * @return 记录数量 - */ - long countUnderReviewRecord(String userPhone); - - /** - * 提交修改后的调查记录,等待审核 - * - * @param vo 调查记录Vo - * @return 修改是否提交成功 - */ - void changeInvestigationRecord(InvestigationRecordVo vo); - - /** - * 审核待调查记录 - * - * @param reviewVo 审核信息 - * @return 是否成功 - */ - boolean reviewRecord(ReviewVo reviewVo); - - /** - * 导出为word - * - * @param idNumber 调查对象身份证号 - * @param response 响应 - */ - void export2Word(String idNumber, HttpServletResponse response); -} diff --git a/src/main/java/com/example/survey/service/MetaDataService.java b/src/main/java/com/example/survey/service/MetaDataService.java new file mode 100644 index 0000000..4bd57f3 --- /dev/null +++ b/src/main/java/com/example/survey/service/MetaDataService.java @@ -0,0 +1,64 @@ +package com.example.survey.service; + +import com.example.survey.dto.metaData.CreateMetaDataDTO; +import com.example.survey.dto.metaData.DeleteMetaDataDTO; +import com.example.survey.dto.metaData.ModifyMetaDataDTO; +import com.example.survey.entity.MetaData; +import com.example.survey.vo.MetaDataVO; + +import java.util.List; + +/** + * @author Pope + */ +public interface MetaDataService { + /** + * 创建元数据 + * + * @param createMetaDataDTO 元数据信息 + */ + void addMetaData(CreateMetaDataDTO createMetaDataDTO); + + /** + * 根据筛选条件模糊查询元数据 + * @param name 元数据名 + * @param currentPage 当前页数 + * @param pageSize 页大小 + * @return 元数据 + */ + List listMetaDataLimit(String name, int currentPage, int pageSize); + + /** + * 根据元数据名查询数量 + * + * @param name 元数据名 + * @return 数量 + */ + long countMetaData(String name); + + /** + * 获取所有元数据名字的列表 + * @return 名字的列表 + */ + List getNameList(); + + /** + * 修改元数据信息 + * + * @param modifyMetaDataDTO 修改信息 + */ + void modifyMetaData(ModifyMetaDataDTO modifyMetaDataDTO); + + /** + * @param name 名字 + * @return 元数据 + */ + MetaData getMetaData(String name); + + /** + * 删除元数据 + * + * @param deleteMetaDataDTO 删除信息 + */ + void deleteMetaData(DeleteMetaDataDTO deleteMetaDataDTO); +} diff --git a/src/main/java/com/example/survey/service/ProjectService.java b/src/main/java/com/example/survey/service/ProjectService.java new file mode 100644 index 0000000..4a654c4 --- /dev/null +++ b/src/main/java/com/example/survey/service/ProjectService.java @@ -0,0 +1,72 @@ +package com.example.survey.service; + +import com.example.survey.dto.project.CreateProjectDTO; +import com.example.survey.dto.project.ModifyProjectDTO; +import com.example.survey.dto.project.ModifyStateDTO; +import com.example.survey.vo.ProjectVO; + +import java.util.List; + +/** + * @author Pope + */ +public interface ProjectService { + + + /** + * 创建新项目 + * + * @param createProjectDTO 创建项目信息 + */ + void createProject(CreateProjectDTO createProjectDTO); + + + /** + * 根据筛选条件分页查询项目 + * + * @param name 项目名 + * @param currentPage 当前页数 + * @param pageSize 页大小 + * @return 项目vo + */ + List listProjectLimit(String name, int currentPage, int pageSize); + + /** + * 根据项目名查询调查对象数量 + * + * @param name 项目名 + * @return 调查对象数量 + */ + long countRespondent(String name); + + /** + * 根据项目名与调查对象状态查询调查对象数量 + * + * @param name 项目名 + * @param respondentState 调查对象状态 + * @return 调查对象数量 + */ + long countRespondent(String name, String respondentState); + + /** + * 修改项目状态 + * + * @param modifyStateDTO 修改信息 + */ + void modifyProjectState(ModifyStateDTO modifyStateDTO); + + /** + * 修改项目数据 + * + * @param modifyProjectDTO 修改信息 + */ + void modifyProject(ModifyProjectDTO modifyProjectDTO); + + /** + * 根据项目吗查询数量 + * + * @param name 项目名 + * @return 数量 + */ + long countProject(String name); +} diff --git a/src/main/java/com/example/survey/service/RecordService.java b/src/main/java/com/example/survey/service/RecordService.java new file mode 100644 index 0000000..b78d14e --- /dev/null +++ b/src/main/java/com/example/survey/service/RecordService.java @@ -0,0 +1,84 @@ +package com.example.survey.service; + +import com.example.survey.dto.record.ModifyRecordDTO; +import com.example.survey.dto.record.ReviewRecordDTO; +import com.example.survey.dto.record.SubmitRecordDTO; +import com.example.survey.vo.RecordVO; + +import java.util.List; +import java.util.Map; + +/** + * @author Pope + */ +public interface RecordService { + + /** + * 根据筛选条件查询流调记录数量 + * + * @param userPhone 用户电话号码 + * @param projectName 项目名 + * @return 符合筛选条件的调查记录数量 + */ + long countRecord(String userPhone, String projectName); + + + /** + * 审核流调记录 + * + * @param reviewRecordDTO 审核信息 + */ + void reviewRecord(ReviewRecordDTO reviewRecordDTO); + + /** + * 修改已审核的流调记录 + * + * @param modifyRecordDTO 修改信息 + */ + void modifyRecord(ModifyRecordDTO modifyRecordDTO); + + /** + * 创建流调记录 + * + * @param submitRecordDTO 流调记录信息 + */ + void createRecord(SubmitRecordDTO submitRecordDTO); + + /** + * 根据筛选条件查询流调记录数量 + * + * @param idNumber 调查对象身份证号 + * @param userPhone 分配的人员电话号码 + * @param projectName 项目名 + * @param state 流调记录状态 + * @param version 流调记录版本 + * @param questionnaireNumber 问卷编号 + * @return 流调记录数量 + */ + long countRecord(String idNumber, String userPhone, String projectName, String state, String version, String questionnaireNumber); + + /** + * 根据筛选条件查询流调记录 + * + * @param idNumber 调查对象身份证号 + * @param userPhone 分配的人员电话号码 + * @param projectName 项目名 + * @param state 流调记录状态 + * @param version 流调记录版本 + * @param questionnaireNumber 问卷编号 + * @param currentPage 当前页数,从0开始 + * @param pageSize 页大小 + * @return 流调记录VO + */ + List listRecordLimit(String idNumber, String userPhone, String projectName, String state, String version, String questionnaireNumber, int currentPage, int pageSize); + + /** + * 根据筛选条件查询流调记录的values + * + * @param projectName 项目名 + * @param idNumber 调查对象身份证号 + * @param version 版本号 + * @return 流调记录的values + */ + Map getRecordValues(String projectName, String idNumber, String version); +} diff --git a/src/main/java/com/example/survey/service/RespondentService.java b/src/main/java/com/example/survey/service/RespondentService.java index 25f5c20..7c74ee6 100644 --- a/src/main/java/com/example/survey/service/RespondentService.java +++ b/src/main/java/com/example/survey/service/RespondentService.java @@ -1,9 +1,7 @@ package com.example.survey.service; -import com.example.survey.entity.Respondent; -import com.example.survey.dto.RespondentDto; -import com.example.survey.entity.inner.AdministrativeArea; -import com.example.survey.vo.CreateRespondentVo; +import com.example.survey.dto.respondent.*; +import com.example.survey.vo.RespondentVO; import java.util.List; @@ -14,30 +12,63 @@ public interface RespondentService { /** * 创建待调查对象 * - * @param createRespondentVo 待调查对象信息 + * @param createRespondentDTO 待调查对象信息 * @return 是否创建成功 */ - boolean addRespondent(CreateRespondentVo createRespondentVo); + void createRespondent(CreateRespondentDTO createRespondentDTO); /** * 根据流调人员电话号码分页查询待调查对象数据 * - * @param userPhone 分配的人员电话号码 - * @param state 状态 - * @param administrativeArea 行政区划 - * @param currentPage 当前页数 - * @param pageSize 页大小 + * @param userPhone 分配的人员电话号码 + * @param state 状态 + * @param idNumber 身份证号 + * @param name 调查对象姓名 + * @param phone 调查对象电话 + * @param province 省份 + * @param city 城市 + * @param county 区县 + * @param projectName 项目名 + * @param currentPage 当前页数 + * @param pageSize 页大小 * @return 页数据 */ - List listRespondentLimit(String userPhone, String state, AdministrativeArea administrativeArea, int currentPage, int pageSize); + List listRespondentLimit(String userPhone, String state, String idNumber, String name, String phone, String province, String city, String county, String projectName, int currentPage, int pageSize); /** * 根据筛选条件查询调查对象数量 * - * @param userPhone 分配的人员电话号码 - * @param state 状态 - * @param administrativeArea 行政区划 + * @param userPhone 分配的人员电话号码 + * @param state 状态 + * @param idNumber 身份证号 + * @param name 调查对象姓名 + * @param phone 调查对象电话 + * @param province 省份 + * @param city 城市 + * @param county 区县 + * @param projectName 项目名 * @return 数量 */ - long countRespondent(String userPhone, String state, AdministrativeArea administrativeArea); + long countRespondent(String userPhone, String state, String idNumber, String name, String phone, String province, String city, String county, String projectName); + + /** + * 修改调查对象信息 + * + * @param modifyRespondentDTO 修改信息 + */ + void modifyRespondent(ModifyRespondentDTO modifyRespondentDTO); + + /** + * 分配人员 + * + * @param modifyRespondentUserDTO 绑定用户信息 + */ + void modifyUser(ModifyRespondentUserDTO modifyRespondentUserDTO); + + /** + * 删除调查对象 + * + * @param deleteRespondentDTO 删除信息 + */ + void deleteRespondent(DeleteRespondentDTO deleteRespondentDTO); } diff --git a/src/main/java/com/example/survey/service/RoleService.java b/src/main/java/com/example/survey/service/RoleService.java index d850c1d..124f20a 100644 --- a/src/main/java/com/example/survey/service/RoleService.java +++ b/src/main/java/com/example/survey/service/RoleService.java @@ -1,7 +1,8 @@ package com.example.survey.service; -import com.example.survey.vo.CreateRoleVo; -import com.example.survey.vo.ModifyRoleVo; +import com.example.survey.dto.role.CreateRoleDTO; +import com.example.survey.dto.role.DeleteRoleDTO; +import com.example.survey.dto.role.ModifyRoleDTO; import java.util.List; @@ -13,33 +14,40 @@ public interface RoleService { /** * 创建角色 * - * @param createRoleVo 角色信息 + * @param createRoleDTO 角色信息 * @return 是否创建成功 */ - boolean addRole(CreateRoleVo createRoleVo); + void addRole(CreateRoleDTO createRoleDTO); /** * 根据权限名分页查询权限 * - * @param roleName 角色名 模糊匹配 + * @param name 角色名 模糊匹配 * @param currentPage 当前页数 * @param pageSize 页大小 * @return 查询结果 */ - List getRole(String roleName, int currentPage, int pageSize); + List listRoleLimit(String name, int currentPage, int pageSize); /** * 删除角色 * - * @param roleName 角色名 - * @return 是否删除成功 + * @param deleteRoleDTO 删除信息 */ - void deleteRole(String roleName); + void deleteRole(DeleteRoleDTO deleteRoleDTO); /** * 修改角色权限 * - * @param modifyRoleVo 修改后角色信息 + * @param modifyRoleDTO 修改信息 */ - void modifyRole(ModifyRoleVo modifyRoleVo); + void modifyRole(ModifyRoleDTO modifyRoleDTO); + + /** + * 根绝角色名模糊查询角色数量 + * + * @param name 角色名 模糊匹配 + * @return 角色数量 + */ + long countRole(String name); } diff --git a/src/main/java/com/example/survey/service/UserService.java b/src/main/java/com/example/survey/service/UserService.java index f1c093a..d095787 100644 --- a/src/main/java/com/example/survey/service/UserService.java +++ b/src/main/java/com/example/survey/service/UserService.java @@ -1,11 +1,8 @@ package com.example.survey.service; -import com.example.survey.dto.LoginDto; -import com.example.survey.dto.UserDto; -import com.example.survey.vo.LoginVo; -import com.example.survey.vo.CreateUserVo; -import com.example.survey.vo.UserInfoVo; -import com.example.survey.vo.UserRoleVo; +import com.example.survey.dto.user.*; +import com.example.survey.vo.LoginVO; +import com.example.survey.vo.UserVO; import java.util.List; @@ -16,25 +13,25 @@ public interface UserService { /** * 根据登录信息判断是否登录 * - * @param loginVo 登录信息 + * @param loginDTO 登录信息 * @return 用户信息 若登录失败则返回null */ - LoginDto matchAuth(LoginVo loginVo); + LoginVO matchAuth(LoginDTO loginDTO); /** * 注册用户 * - * @param createUserVo 注册信息 + * @param createUserDTO 注册信息 * @return 是否注册成功 */ - boolean addUser(CreateUserVo createUserVo); + void addUser(CreateUserDTO createUserDTO); /** * 修改用户权限 * - * @param userRoleVo 新权限信息 + * @param modifyUserRoleDTO 新权限信息 */ - void modifyRole(UserRoleVo userRoleVo); + void modifyRole(ModifyUserRoleDTO modifyUserRoleDTO); /** * 根据筛选条件分页查询用户 @@ -45,27 +42,35 @@ public interface UserService { * @param pageSize 页大小 * @return 用户信息dto */ - List listUserLimit(String username, String phoneNumber, int currentPage, int pageSize); + List listUserLimit(String username, String phoneNumber, int currentPage, int pageSize); /** * 删除用户 * - * @param phoneNumber 电话号码 - * @return 是否删除成功 + * @param deleteUserDTO 删除信息 */ - boolean deleteUser(String phoneNumber); + void deleteUser(DeleteUserDTO deleteUserDTO); /** * 修改用户信息 * - * @param userInfoVo 用户信息 + * @param modifyUserInfoDTO 用户信息 */ - void modifyUserInfo(UserInfoVo userInfoVo); + void modifyUserInfo(ModifyUserInfoDTO modifyUserInfoDTO); /** * 重置密码 * - * @param phoneNumber 电话号码 + * @param resetPwdDTO 用户信息 */ - void resetPwd(String phoneNumber); + void resetPwd(ResetPwdDTO resetPwdDTO); + + /** + * 根据用户名与电话号码查询用户数量 + * + * @param username 用户名 + * @param phone 电话号码 + * @return 用户数量 + */ + long countUser(String username, String phone); } diff --git a/src/main/java/com/example/survey/service/impl/InvestigationRecordServiceImpl.java b/src/main/java/com/example/survey/service/impl/InvestigationRecordServiceImpl.java deleted file mode 100644 index 8d71583..0000000 --- a/src/main/java/com/example/survey/service/impl/InvestigationRecordServiceImpl.java +++ /dev/null @@ -1,163 +0,0 @@ -package com.example.survey.service.impl; - -import com.example.survey.dao.InvestigationRecordDao; -import com.example.survey.dao.RespondentDao; -import com.example.survey.dao.UserDao; -import com.example.survey.entity.InvestigationRecord; -import com.example.survey.entity.inner.OperationInformation; -import com.example.survey.exception.RecordException; -import com.example.survey.exception.RespondentException; -import com.example.survey.exception.UserException; -import com.example.survey.service.InvestigationRecordService; -import com.example.survey.util.WordUtil; -import com.example.survey.vo.InvestigationRecordVo; -import com.example.survey.vo.ReviewVo; -import lombok.extern.log4j.Log4j2; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import javax.servlet.http.HttpServletResponse; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -/** - * @author Pope - */ -@Log4j2 -@Service -public class InvestigationRecordServiceImpl implements InvestigationRecordService { - - - @Autowired - private InvestigationRecordDao investigationRecordDao; - - @Autowired - private RespondentDao respondentDao; - - @Autowired - private UserDao userDao; - - - @Override - public boolean addInvestigationRecord(InvestigationRecordVo vo) { - //如果不存在对应电话号码的调查对象 - if (!respondentDao.existRespondent(vo.getIdNumber())) { - log.error("调查对象不存在"); - throw new RespondentException("调查对象不存在"); - } - //如果已经存在待审核或已审核记录则失败 - if (investigationRecordDao.existInvestigationRecord(vo.getIdNumber(), InvestigationRecord.UNDER_REVIEW, InvestigationRecord.REVIEWED)) { - - log.error("数据库已存在对应调查对象的待审核或已审核记录"); - throw new RecordException("数据库已存在对应调查对象的待审核或已审核记录"); - } - //如果不存在对应电话号码的流调人员 - if(!userDao.existUser(vo.getUserPhone())){ - log.error("用户不存在"); - throw new UserException("用户不存在"); - } - - InvestigationRecord record = new InvestigationRecord(vo); - //生成版本信息 - record.setState(InvestigationRecord.UNDER_REVIEW); - record.setVersion(vo.getUserPhone() + new Date().toString()); - List opList = new ArrayList<>(); - opList.add(OperationInformation.submitOp(vo.getUserPhone(), vo.getMsg())); - record.setOperationInformationList(opList); - - - //TODO 插入消息队列 - - return investigationRecordDao.insertInvestigationRecord(record); - } - - @Override - public List listUnderReviewRecordLimit(String userPhone, int currentPage, int pageSize, String state, String idNumber, String version, String questionnaireNumber, Boolean diseased) { - //TODO 从消息队列进行筛选 - - return investigationRecordDao.listInvestigationRecordLimit(userPhone, pageSize * currentPage, pageSize, state, idNumber, version, questionnaireNumber, diseased); - } - - - @Override - public long countUnderReviewRecord(String userPhone) { - //TODO 从消息队列获取调查记录数量 - - return investigationRecordDao.countInvestigationRecordByUserPhone(userPhone, InvestigationRecord.UNDER_REVIEW); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void changeInvestigationRecord(InvestigationRecordVo vo) { - //创建新记录 - InvestigationRecord oldRecord = investigationRecordDao.selectInvestigationRecord(vo.getIdNumber(), InvestigationRecord.REVIEWED); - if (oldRecord == null) { - oldRecord = investigationRecordDao.selectInvestigationRecord(vo.getIdNumber(), InvestigationRecord.NOT_PASS); - } - - if(oldRecord == null){ - log.error("调查记录不存在"); - throw new RecordException("调查记录不存在"); - } - InvestigationRecord newRecord = new InvestigationRecord(vo); - - //生成版本信息 - newRecord.setState(InvestigationRecord.UNDER_REVIEW); - newRecord.setVersion(vo.getUserPhone() + new Date().toString()); - //生成操作记录 - List opList = oldRecord.getOperationInformationList(); - opList.add(OperationInformation.submitOp(vo.getUserPhone(), vo.getMsg())); - newRecord.setOperationInformationList(opList); - - //存入新纪录 - //原纪录标记为已归档 - investigationRecordDao.updateRecordState(oldRecord.getIdNumber(), InvestigationRecord.REVIEWED, InvestigationRecord.OUT_OF_DATE); - investigationRecordDao.insertInvestigationRecord(newRecord); - - //TODO 将修改请求加入消息队列 - - } - - @Override - public boolean reviewRecord(ReviewVo reviewVo) { - - //如果待审核调查记录表不存在 - if (!investigationRecordDao.existInvestigationRecord(reviewVo.getIdNumber(), InvestigationRecord.UNDER_REVIEW)) { - log.error("未审核记录不存在"); - throw new RecordException("未审核记录不存在"); - } - //如果审核人不存在 - if(!userDao.existUser(reviewVo.getReviewerPhone())){ - log.error("审核人不存在"); - throw new UserException("审核人不存在"); - } - - InvestigationRecord record = investigationRecordDao.selectInvestigationRecord(reviewVo.getIdNumber(), InvestigationRecord.UNDER_REVIEW); - - //审核结果与版本信息 - record.setState(reviewVo.isPass() ? InvestigationRecord.REVIEWED : InvestigationRecord.NOT_PASS); - record.setVersion(reviewVo.getReviewerPhone() + new Date().toString()); - - //生成操作记录 - List opList = record.getOperationInformationList(); - opList.add(OperationInformation.reviewOp(reviewVo.getReviewerPhone(), reviewVo.getMsg(), reviewVo.isPass() ? "审核通过" : "审核不通过")); - record.setOperationInformationList(opList); - - //更新数据库记录 - investigationRecordDao.reviewRecord(record); - - return true; - } - - @Override - public void export2Word(String idNumber, HttpServletResponse response) { - InvestigationRecord record = investigationRecordDao.selectInvestigationRecord(idNumber, InvestigationRecord.REVIEWED); - try { - WordUtil.writeDocx(record, response); - } catch (Exception e) { - log.error(e.getMessage()); - } - } -} diff --git a/src/main/java/com/example/survey/service/impl/MetaDataServiceImpl.java b/src/main/java/com/example/survey/service/impl/MetaDataServiceImpl.java new file mode 100644 index 0000000..898495d --- /dev/null +++ b/src/main/java/com/example/survey/service/impl/MetaDataServiceImpl.java @@ -0,0 +1,96 @@ +package com.example.survey.service.impl; + +import com.example.survey.dao.MetaDataDao; +import com.example.survey.dto.metaData.CreateMetaDataDTO; +import com.example.survey.dto.metaData.DeleteMetaDataDTO; +import com.example.survey.dto.metaData.ModifyMetaDataDTO; +import com.example.survey.entity.MetaData; +import com.example.survey.enumeration.ResultEnum; +import com.example.survey.exception.MetaDataException; +import com.example.survey.service.MetaDataService; +import com.example.survey.vo.MetaDataVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Pope + */ +@Service +public class MetaDataServiceImpl implements MetaDataService { + + @Autowired + MetaDataDao metaDataDao; + + @Override + public void addMetaData(CreateMetaDataDTO createMetaDataDTO) { + if (metaDataDao.existMetaData(createMetaDataDTO.getName())) { + throw new MetaDataException(ResultEnum.ALREADY_EXIST_METADATA); + } + MetaData metaData = new MetaData(); + metaData.setName(createMetaDataDTO.getName()); + metaData.setForm(createMetaDataDTO.getForm()); + metaData.setFieldToNameList(createMetaDataDTO.getFieldToNameList()); + metaData.setConfig(createMetaDataDTO.getConfig()); + metaDataDao.saveMetaData(metaData); + } + + @Override + public List listMetaDataLimit(String name, int currentPage, int pageSize) { + List metaDataList = metaDataDao.listMetaDataLimit(name, currentPage * pageSize, pageSize); + if (metaDataList == null) { + return new ArrayList<>(); + } + return metaDataList.stream() + .map(metaData -> { + MetaDataVO metaDataVO = new MetaDataVO(); + metaDataVO.setName(metaData.getName()); + metaDataVO.setForm(metaData.getForm()); + metaDataVO.setFieldToNameList(metaData.getFieldToNameList()); + metaDataVO.setConfig(metaData.getConfig()); + return metaDataVO; + }) + .collect(Collectors.toList()); + } + + @Override + public long countMetaData(String name) { + return metaDataDao.countMetaData(name); + } + + @Override + public List getNameList() { + return metaDataDao.selectAllMetaData().stream().map(MetaData::getName).collect(Collectors.toList()); + } + + @Override + public void modifyMetaData(ModifyMetaDataDTO modifyMetaDataDTO) { + if (!metaDataDao.existMetaData(modifyMetaDataDTO.getName())) { + throw new MetaDataException(ResultEnum.NOT_EXIST_METADATA); + } + MetaData metaData = metaDataDao.selectMetaData(modifyMetaDataDTO.getName()); + metaData.setForm(modifyMetaDataDTO.getForm()); + metaData.setFieldToNameList(modifyMetaDataDTO.getFieldToNameList()); + metaData.setConfig(modifyMetaDataDTO.getConfig()); + metaDataDao.saveMetaData(metaData); + } + + @Override + public MetaData getMetaData(String name) { + if (!metaDataDao.existMetaData(name)) { + throw new MetaDataException(ResultEnum.ALREADY_EXIST_METADATA); + } + return metaDataDao.selectMetaData(name); + } + + @Override + public void deleteMetaData(DeleteMetaDataDTO deleteMetaDataDTO) { + if (!metaDataDao.existMetaData(deleteMetaDataDTO.getName())) { + throw new MetaDataException(ResultEnum.ALREADY_EXIST_METADATA); + } + metaDataDao.deleteMetaData(deleteMetaDataDTO.getName()); + } +} diff --git a/src/main/java/com/example/survey/service/impl/ProjectServiceImpl.java b/src/main/java/com/example/survey/service/impl/ProjectServiceImpl.java new file mode 100644 index 0000000..9d7ea97 --- /dev/null +++ b/src/main/java/com/example/survey/service/impl/ProjectServiceImpl.java @@ -0,0 +1,139 @@ +package com.example.survey.service.impl; + +import com.example.survey.dao.MetaDataDao; +import com.example.survey.dao.ProjectDao; +import com.example.survey.dao.RespondentDao; +import com.example.survey.dao.UserDao; +import com.example.survey.dto.project.CreateProjectDTO; +import com.example.survey.dto.project.ModifyProjectDTO; +import com.example.survey.dto.project.ModifyStateDTO; +import com.example.survey.entity.MetaData; +import com.example.survey.entity.Project; +import com.example.survey.entity.User; +import com.example.survey.enumeration.ProjectStateEnum; +import com.example.survey.enumeration.ResultEnum; +import com.example.survey.exception.MetaDataException; +import com.example.survey.exception.ProjectException; +import com.example.survey.exception.UserException; +import com.example.survey.service.ProjectService; +import com.example.survey.vo.ProjectVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Pope + */ +@Service +public class ProjectServiceImpl implements ProjectService { + + @Autowired + ProjectDao projectDao; + + @Autowired + RespondentDao respondentDao; + + @Autowired + MetaDataDao metaDataDao; + + @Autowired + UserDao userDao; + + @Override + public void createProject(CreateProjectDTO createProjectDTO) { + if (!userDao.existUser(createProjectDTO.getUserPhone())) { + throw new UserException(ResultEnum.NOT_EXIST_USER); + } + if (!metaDataDao.existMetaData(createProjectDTO.getMetaDataName())) { + throw new MetaDataException(ResultEnum.NOT_EXIST_METADATA); + } + User user = userDao.selectUser(createProjectDTO.getUserPhone()); + MetaData metaData = metaDataDao.selectMetaData(createProjectDTO.getMetaDataName()); + Project project = new Project(); + project.setName(createProjectDTO.getName()); + project.setMetaData(metaData); + project.setStartTime(createProjectDTO.getStartTime()); + project.setEndTime(createProjectDTO.getEndTime()); + project.setDetail(createProjectDTO.getDetail()); + project.setState(ProjectStateEnum.IN_PROGRESS.getValue()); + project.setUser(user); + projectDao.saveProject(project); + } + + @Override + public List listProjectLimit(String name, int currentPage, int pageSize) { + return projectDao.listProjectLimit(name, currentPage * pageSize, pageSize).stream() + .map(project -> { + ProjectVO projectVO = new ProjectVO(); + projectVO.setName(project.getName()); + projectVO.setDetail(project.getDetail()); + projectVO.setStartTime(project.getStartTime()); + projectVO.setEndTime(project.getEndTime()); + if (project.getMetaData() != null) { + projectVO.setMetaDataName(project.getMetaData().getName()); + } + projectVO.setState(project.getState()); + return projectVO; + }).collect(Collectors.toList()); + + } + + @Override + public long countRespondent(String name) { + if (!projectDao.existProject(name)) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + return projectDao.selectProject(name).getRespondentCount(); + } + + @Override + public long countRespondent(String name, String respondentState) { + if (!projectDao.existProject(name)) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + Project project = projectDao.selectProject(name); + return project.getNotInvestigatedRespondentCount(); + } + + @Override + public void modifyProjectState(ModifyStateDTO modifyStateDTO) { + if (!projectDao.existProject(modifyStateDTO.getName())) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + Project project = projectDao.selectProject(modifyStateDTO.getName()); + for (ProjectStateEnum value : ProjectStateEnum.values()) { + if (value.getValue().equals(modifyStateDTO.getState())) { + project.setState(modifyStateDTO.getState()); + projectDao.saveProject(project); + return; + } + } + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT_STATE); + } + + @Override + public void modifyProject(ModifyProjectDTO modifyProjectDTO) { + if (!userDao.existUser(modifyProjectDTO.getUserPhone())) { + throw new UserException(ResultEnum.NOT_EXIST_USER); + } + if (!projectDao.existProject(modifyProjectDTO.getName())) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + User user = userDao.selectUser(modifyProjectDTO.getUserPhone()); + Project project = projectDao.selectProject(modifyProjectDTO.getName()); + project.setDetail(modifyProjectDTO.getDetail()); + project.setStartTime(modifyProjectDTO.getStartTime()); + project.setEndTime(modifyProjectDTO.getEndTime()); + project.setUser(user); + projectDao.saveProject(project); + } + + @Override + public long countProject(String name) { + return projectDao.countProject(name); + + } + +} diff --git a/src/main/java/com/example/survey/service/impl/RecordServiceImpl.java b/src/main/java/com/example/survey/service/impl/RecordServiceImpl.java new file mode 100644 index 0000000..0d175b0 --- /dev/null +++ b/src/main/java/com/example/survey/service/impl/RecordServiceImpl.java @@ -0,0 +1,274 @@ +package com.example.survey.service.impl; + +import com.example.survey.dao.ProjectDao; +import com.example.survey.dao.RecordDao; +import com.example.survey.dao.RespondentDao; +import com.example.survey.dao.UserDao; +import com.example.survey.dto.record.ModifyRecordDTO; +import com.example.survey.dto.record.ReviewRecordDTO; +import com.example.survey.dto.record.SubmitRecordDTO; +import com.example.survey.entity.Project; +import com.example.survey.entity.Record; +import com.example.survey.entity.Respondent; +import com.example.survey.entity.User; +import com.example.survey.entity.inner.Operation; +import com.example.survey.enumeration.RecordStateEnum; +import com.example.survey.enumeration.RespondentStateEnum; +import com.example.survey.enumeration.ResultEnum; +import com.example.survey.exception.ProjectException; +import com.example.survey.exception.RecordException; +import com.example.survey.exception.RespondentException; +import com.example.survey.exception.UserException; +import com.example.survey.service.RecordService; +import com.example.survey.vo.RecordVO; +import com.example.survey.vo.inner.OperationInfo; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author Pope + */ +@Log4j2 +@Service +public class RecordServiceImpl implements RecordService { + + + @Autowired + private RecordDao recordDao; + + @Autowired + private RespondentDao respondentDao; + + @Autowired + private UserDao userDao; + + @Autowired + private ProjectDao projectDao; + + @Override + public long countRecord(String userPhone, String projectName) { + if (userPhone != null && !userDao.existUser(userPhone)) { + throw new UserException(ResultEnum.NOT_EXIST_USER); + } + if (projectName != null && !projectDao.existProject(projectName)) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + User user = userDao.selectUser(userPhone); + Project project = projectDao.selectProject(projectName); + return recordDao.countRecord(null, user, project, RecordStateEnum.UNDER_REVIEW.getValue(), null, null); + } + + @Override + public void reviewRecord(ReviewRecordDTO reviewRecordDTO) { + if (!respondentDao.existRespondent(reviewRecordDTO.getIdNumber(), RespondentStateEnum.NOT_INVESTIGATED.getValue())) { + throw new RespondentException(ResultEnum.NOT_EXIST_RESPONDENT); + } + if (!userDao.existUser(reviewRecordDTO.getReviewerPhone())) { + throw new UserException(ResultEnum.NOT_EXIST_USER); + } + if (!projectDao.existProject(reviewRecordDTO.getProjectName())) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + Project project = projectDao.selectProject(reviewRecordDTO.getProjectName()); + Respondent respondent = respondentDao.selectRespondent(reviewRecordDTO.getIdNumber(), project); + User user = userDao.selectUser(reviewRecordDTO.getReviewerPhone()); + + + if (!recordDao.existRecord(respondent, project, RecordStateEnum.UNDER_REVIEW.getValue())) { + throw new RecordException(ResultEnum.NOT_EXIST_RECORD); + } + Record record = recordDao.getRecord(respondent, project, RecordStateEnum.UNDER_REVIEW.getValue()); + + record.setState(reviewRecordDTO.getPass() ? RecordStateEnum.REVIEWED.getValue() : RecordStateEnum.NOT_PASS.getValue()); + record.setVersion(UUID.randomUUID().toString()); + Operation reviewOp = Operation.reviewOp(user, reviewRecordDTO.getMsg(), record.getVersion(), reviewRecordDTO.getPass()); + List opList = record.getOperationList(); + opList.add(reviewOp); + record.setOperationList(opList); + + recordDao.saveRecord(record); + } + + @Override + public void modifyRecord(ModifyRecordDTO modifyRecordDTO) { + if (!respondentDao.existRespondent(modifyRecordDTO.getIdNumber(), RespondentStateEnum.NOT_INVESTIGATED.getValue())) { + throw new RespondentException(ResultEnum.NOT_EXIST_RESPONDENT); + } + if (!userDao.existUser(modifyRecordDTO.getUserPhone())) { + throw new UserException(ResultEnum.NOT_EXIST_USER); + } + if (!projectDao.existProject(modifyRecordDTO.getProjectName())) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + Project project = projectDao.selectProject(modifyRecordDTO.getProjectName()); + Respondent respondent = respondentDao.selectRespondent(modifyRecordDTO.getIdNumber(), project); + User user = userDao.selectUser(modifyRecordDTO.getUserPhone()); + + + if (!recordDao.existRecord(respondent, project, RecordStateEnum.UNDER_REVIEW.getValue())) { + throw new RecordException(ResultEnum.NOT_EXIST_RECORD); + } + Record record = recordDao.getRecord(respondent, project, RecordStateEnum.REVIEWED.getValue()); + + //将原来的设为已归档 添加覆盖操作 + record.setState(RecordStateEnum.FILED.getValue()); + Operation coverOp = Operation.coverOp(user, record.getVersion()); + List oldOpList = record.getOperationList(); + List newOpList = record.getOperationList(); + oldOpList.add(coverOp); + record.setOperationList(oldOpList); + record.setVersion(UUID.randomUUID().toString()); + recordDao.saveRecord(record); + + //生成新的流调记录 + record.setId(null); + record.setValues(modifyRecordDTO.getValues()); + record.setState(RecordStateEnum.UNDER_REVIEW.getValue()); + Operation modifyOp = Operation.modifyOp(user, modifyRecordDTO.getMsg(), record.getVersion()); + newOpList.add(modifyOp); + record.setOperationList(newOpList); + record.setVersion(UUID.randomUUID().toString()); + recordDao.saveRecord(record); + } + + @Override + public void createRecord(SubmitRecordDTO submitRecordDTO) { + if (!respondentDao.existRespondent(submitRecordDTO.getIdNumber())) { + throw new RespondentException(ResultEnum.NOT_EXIST_RESPONDENT); + } + if (!userDao.existUser(submitRecordDTO.getUserPhone())) { + throw new UserException(ResultEnum.NOT_EXIST_USER); + } + if (!projectDao.existProject(submitRecordDTO.getProjectName())) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + Project project = projectDao.selectProject(submitRecordDTO.getProjectName()); + Respondent respondent = respondentDao.selectRespondent(submitRecordDTO.getIdNumber(), project); + User user = userDao.selectUser(submitRecordDTO.getUserPhone()); + + //设置调查对象为已调查 + respondent.setState(RespondentStateEnum.INVESTIGATED.getValue()); + respondentDao.saveRespondent(respondent); + + Record record = recordDao.getRecord(respondent, project, RecordStateEnum.UNDER_REVIEW.getValue()); + if (record == null) { + record = recordDao.getRecord(respondent, project, RecordStateEnum.REVIEWED.getValue()); + } + if (record != null) { + //存在旧纪录,覆盖 + List oldOpList = record.getOperationList(); + List newOpList = record.getOperationList(); + record.setState(RecordStateEnum.FILED.getValue()); + Operation coverOp = Operation.coverOp(user, record.getVersion()); + oldOpList.add(coverOp); + record.setOperationList(oldOpList); + record.setVersion(UUID.randomUUID().toString()); + recordDao.saveRecord(record); + + //插入新记录 + record.setId(null); + record.setValues(submitRecordDTO.getValues()); + record.setState(RecordStateEnum.UNDER_REVIEW.getValue()); + Operation submitOp = Operation.submitOp(user, submitRecordDTO.getMsg(), record.getVersion()); + newOpList.add(submitOp); + record.setOperationList(newOpList); + record.setVersion(UUID.randomUUID().toString()); + } else { + record = new Record(); + record.setRespondent(respondent); + record.setUser(user); + record.setValues(submitRecordDTO.getValues()); + record.setState(RecordStateEnum.UNDER_REVIEW.getValue()); + record.setVersion(UUID.randomUUID().toString()); + List opList = new ArrayList<>(); + Operation submitOp = Operation.submitOp(user, submitRecordDTO.getMsg(), record.getVersion()); + opList.add(submitOp); + record.setOperationList(opList); + record.setProject(project); + } + recordDao.saveRecord(record); + } + + @Override + public long countRecord(String idNumber, String userPhone, String projectName, String state, String version, String questionnaireNumber) { + if (idNumber != null && !respondentDao.existRespondent(idNumber)) { + throw new RespondentException(ResultEnum.NOT_EXIST_RESPONDENT); + } + if (userPhone != null && !userDao.existUser(userPhone)) { + throw new UserException(ResultEnum.NOT_EXIST_USER); + } + if (projectName != null && !projectDao.existProject(projectName)) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + Project project = projectDao.selectProject(projectName); + Respondent respondent = respondentDao.selectRespondent(idNumber, project); + User user = userDao.selectUser(userPhone); + + + return recordDao.countRecord(respondent, user, project, state, version, questionnaireNumber); + } + + @Override + public List listRecordLimit(String idNumber, String userPhone, String projectName, String state, String version, String questionnaireNumber, int currentPage, int pageSize) { + if (idNumber != null && !respondentDao.existRespondent(idNumber)) { + throw new RespondentException(ResultEnum.NOT_EXIST_RESPONDENT); + } + if (userPhone != null && !userDao.existUser(userPhone)) { + throw new UserException(ResultEnum.NOT_EXIST_USER); + } + if (projectName != null && !projectDao.existProject(projectName)) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + Project project = projectDao.selectProject(projectName); + Respondent respondent = respondentDao.selectRespondent(idNumber, project); + User user = userDao.selectUser(userPhone); + + + List recordList = recordDao.listRecordLimit(respondent, user, project, state, version, questionnaireNumber, currentPage * pageSize, pageSize); + return recordList.stream().map(record -> { + RecordVO recordVO = new RecordVO(); + recordVO.setIdNumber(record.getRespondent().getIdNumber()); + recordVO.setUserPhone(record.getUser().getPhone()); + recordVO.setProjectName(record.getProject().getName()); + recordVO.setOperationInfoList(record.getOperationList().stream().map(op -> { + OperationInfo operationInfo = new OperationInfo(); + operationInfo.setType(op.getType()); + operationInfo.setTime(op.getTime()); + operationInfo.setUserPhone(op.getUser().getPhone()); + operationInfo.setMsg(op.getMsg()); + operationInfo.setResult(op.getResult()); + operationInfo.setVersion(op.getVersion()); + return operationInfo; + }).collect(Collectors.toList())); + recordVO.setVersion(record.getVersion()); + recordVO.setState(record.getState()); + return recordVO; + }).collect(Collectors.toList()); + } + + @Override + public Map getRecordValues(String projectName, String idNumber, String version) { + if (!projectDao.existProject(projectName)) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + if (!respondentDao.existRespondent(idNumber)) { + throw new RespondentException(ResultEnum.NOT_EXIST_RESPONDENT); + } + Project project = projectDao.selectProject(projectName); + Respondent respondent = respondentDao.selectRespondent(idNumber, project); + Record record = recordDao.selectRecord(respondent, project, version); + if (record == null) { + throw new RecordException(ResultEnum.NOT_EXIST_RECORD); + } + return record.getValues(); + } + + +} diff --git a/src/main/java/com/example/survey/service/impl/RespondentServiceImpl.java b/src/main/java/com/example/survey/service/impl/RespondentServiceImpl.java index 72289b1..cbb5d40 100644 --- a/src/main/java/com/example/survey/service/impl/RespondentServiceImpl.java +++ b/src/main/java/com/example/survey/service/impl/RespondentServiceImpl.java @@ -1,19 +1,32 @@ package com.example.survey.service.impl; +import com.example.survey.dao.ProjectDao; import com.example.survey.dao.RespondentDao; import com.example.survey.dao.UserDao; +import com.example.survey.dto.respondent.CreateRespondentDTO; +import com.example.survey.dto.respondent.DeleteRespondentDTO; +import com.example.survey.dto.respondent.ModifyRespondentDTO; +import com.example.survey.dto.respondent.ModifyRespondentUserDTO; +import com.example.survey.entity.Project; import com.example.survey.entity.Respondent; import com.example.survey.entity.User; -import com.example.survey.entity.inner.AdministrativeArea; +import com.example.survey.enumeration.RespondentStateEnum; +import com.example.survey.enumeration.ResultEnum; +import com.example.survey.exception.ProjectException; +import com.example.survey.exception.RespondentException; +import com.example.survey.exception.UserException; import com.example.survey.service.RespondentService; -import com.example.survey.dto.RespondentDto; -import com.example.survey.vo.CreateRespondentVo; +import com.example.survey.vo.RespondentVO; +import com.example.survey.vo.inner.UserInfo; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; /** * @author Pope @@ -25,33 +38,139 @@ public class RespondentServiceImpl implements RespondentService { @Autowired private RespondentDao respondentDao; + @Autowired + private ProjectDao projectDao; + @Autowired private UserDao userDao; @Override - public boolean addRespondent(CreateRespondentVo createRespondentVo) { - if (!userDao.existUser(createRespondentVo.getUserPhone())) { - log.error("不存在对应id的用户"); + public void createRespondent(CreateRespondentDTO createRespondentDTO) { + if (!projectDao.existProject(createRespondentDTO.getProjectName())) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); } - Respondent respondent = new Respondent(createRespondentVo); + if (!userDao.existUser(createRespondentDTO.getUserPhone())) { + throw new UserException(ResultEnum.NOT_EXIST_USER); + } + Project project = projectDao.selectProject(createRespondentDTO.getProjectName()); + User user = userDao.selectUser(createRespondentDTO.getPhone()); - return respondentDao.insertRespondent(respondent); + Respondent respondent = new Respondent(); + respondent.setIdNumber(createRespondentDTO.getIdNumber()); + respondent.setPhone(createRespondentDTO.getPhone()); + respondent.setName(createRespondentDTO.getName()); + respondent.setGender(createRespondentDTO.getGender()); + respondent.setMsg(createRespondentDTO.getMsg()); + respondent.setAdministrativeArea(createRespondentDTO.getAdministrativeArea()); + respondent.setProject(project); + respondent.setUser(user); + respondent.setState(RespondentStateEnum.NOT_INVESTIGATED.getValue()); + respondentDao.saveRespondent(respondent); + + project.setRespondentCount(project.getRespondentCount() + 1); + project.setNotInvestigatedRespondentCount(project.getNotInvestigatedRespondentCount() + 1); + projectDao.saveProject(project); } @Override - public List listRespondentLimit(String userPhone, String state, AdministrativeArea administrativeArea, int currentPage, int pageSize) { - List dtoList = new ArrayList<>(); - List respondentList = respondentDao.listRespondentLimit(userPhone, state, administrativeArea, currentPage * pageSize, pageSize); - for (Respondent respondent : respondentList) { - User user = userDao.selectUser(respondent.getUserPhone()); - dtoList.add(new RespondentDto(respondent, user)); + public List listRespondentLimit(String userPhone, String state, String idNumber, String name, String phone, String province, String city, String county, String projectName, int currentPage, int pageSize) { + if (userPhone != null && !userDao.existUser(userPhone)) { + throw new UserException(ResultEnum.NOT_EXIST_USER); } - return dtoList; + if (projectName != null && !projectDao.existProject(projectName)) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + User tmpUser = userDao.selectUser(userPhone); + Project tmpProject = projectDao.selectProject(projectName); + + List respondentList = respondentDao.listRespondentLimit(tmpUser, state, idNumber, name, phone, province, city, county, tmpProject, currentPage * pageSize, pageSize); + if (respondentList == null) { + return new ArrayList<>(); + } + return respondentList.stream().map(respondent -> { + RespondentVO respondentVO = new RespondentVO(); + respondentVO.setIdNumber(respondent.getIdNumber()); + respondentVO.setPhone(respondent.getPhone()); + respondentVO.setName(respondent.getName()); + respondentVO.setMsg(respondent.getMsg()); + respondentVO.setGender(respondent.getGender()); + respondentVO.setAdministrativeArea(respondent.getAdministrativeArea()); + respondentVO.setProjectName(respondent.getProject().getName()); + respondentVO.setState(respondent.getState()); + User user = respondent.getUser(); + if (user != null) { + UserInfo userInfo = new UserInfo(); + userInfo.setIdNumber(user.getIdNumber()); + userInfo.setUsername(user.getUsername()); + userInfo.setPhone(user.getPhone()); + respondentVO.setUserInfo(userInfo); + } + return respondentVO; + }).collect(Collectors.toList()); } @Override - public long countRespondent(String userPhone, String state, AdministrativeArea administrativeArea) { - return respondentDao.countRespondent(userPhone, state, administrativeArea); + public long countRespondent(String userPhone, String state, String idNumber, String name, String phone, String province, String city, String county, String projectName) { + if (userPhone != null && !userDao.existUser(userPhone)) { + throw new UserException(ResultEnum.NOT_EXIST_USER); + } + if (projectName != null && !projectDao.existProject(projectName)) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + User user = userDao.selectUser(userPhone); + Project project = projectDao.selectProject(projectName); + return respondentDao.countRespondent(user, state, idNumber, name, phone, province, city, county, project); } + @Override + public void modifyRespondent(ModifyRespondentDTO modifyRespondentDTO) { + if (!projectDao.existProject(modifyRespondentDTO.getProjectName())) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + if (!respondentDao.existRespondent(modifyRespondentDTO.getIdNumber())) { + throw new RespondentException(ResultEnum.NOT_EXIST_RESPONDENT); + } + Project project = projectDao.selectProject(modifyRespondentDTO.getProjectName()); + Respondent respondent = respondentDao.selectRespondent(modifyRespondentDTO.getIdNumber(), project); + respondent.setPhone(modifyRespondentDTO.getPhone()); + respondent.setName(modifyRespondentDTO.getName()); + respondent.setMsg(modifyRespondentDTO.getMsg()); + respondent.setGender(modifyRespondentDTO.getGender()); + respondent.setAdministrativeArea(modifyRespondentDTO.getAdministrativeArea()); + respondentDao.saveRespondent(respondent); + } + + + @Override + public void modifyUser(ModifyRespondentUserDTO modifyRespondentUserDTO) { + if (!respondentDao.existRespondent(modifyRespondentUserDTO.getIdNumber())) { + throw new RespondentException(ResultEnum.NOT_EXIST_RESPONDENT); + } + if (!userDao.existUser(modifyRespondentUserDTO.getUserPhone())) { + throw new UserException(ResultEnum.NOT_EXIST_USER); + } + if (!projectDao.existProject(modifyRespondentUserDTO.getProjectName())) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + Project project = projectDao.selectProject(modifyRespondentUserDTO.getProjectName()); + Respondent respondent = respondentDao.selectRespondent(modifyRespondentUserDTO.getIdNumber(), project); + User user = userDao.selectUser(modifyRespondentUserDTO.getUserPhone()); + respondent.setUser(user); + respondentDao.saveRespondent(respondent); + } + + @Override + public void deleteRespondent(DeleteRespondentDTO deleteRespondentDTO) { + if (!respondentDao.existRespondent(deleteRespondentDTO.getIdNumber())) { + throw new RespondentException(ResultEnum.NOT_EXIST_RESPONDENT); + } + if (!projectDao.existProject(deleteRespondentDTO.getProjectName())) { + throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT); + } + Project project = projectDao.selectProject(deleteRespondentDTO.getProjectName()); + Respondent respondent = respondentDao.selectRespondent(deleteRespondentDTO.getIdNumber(), project); + respondent.setState(RespondentStateEnum.FILED.getValue()); + respondentDao.saveRespondent(respondent); + + } } diff --git a/src/main/java/com/example/survey/service/impl/RoleServiceImpl.java b/src/main/java/com/example/survey/service/impl/RoleServiceImpl.java index 7536285..f05fe63 100644 --- a/src/main/java/com/example/survey/service/impl/RoleServiceImpl.java +++ b/src/main/java/com/example/survey/service/impl/RoleServiceImpl.java @@ -2,13 +2,17 @@ package com.example.survey.service.impl; import com.example.survey.dao.RoleDao; import com.example.survey.dao.UserDao; +import com.example.survey.dto.role.CreateRoleDTO; +import com.example.survey.dto.role.DeleteRoleDTO; +import com.example.survey.dto.role.ModifyRoleDTO; import com.example.survey.entity.Role; import com.example.survey.enumeration.AuthEnum; +import com.example.survey.enumeration.ResultEnum; import com.example.survey.exception.AuthException; +import com.example.survey.exception.RoleException; import com.example.survey.service.RoleService; import com.example.survey.util.TokenUtil; -import com.example.survey.vo.CreateRoleVo; -import com.example.survey.vo.ModifyRoleVo; +import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -21,6 +25,7 @@ import java.util.Set; /** * @author Pope */ +@Log4j2 @Service public class RoleServiceImpl implements RoleService { @@ -31,54 +36,72 @@ public class RoleServiceImpl implements RoleService { private UserDao userDao; @Override - public boolean addRole(CreateRoleVo createRoleVo) { + public void addRole(CreateRoleDTO createRoleDTO) { Role role = new Role(); - role.setName(createRoleVo.getRoleName()); + role.setName(createRoleDTO.getName()); Set authoritySet = new HashSet<>(); - for (String name : createRoleVo.getAuthList()) { - authoritySet.add(AuthEnum.getRoleEnum(name)); + for (String name : createRoleDTO.getAuthoritySet()) { + AuthEnum authEnum = AuthEnum.getRoleEnum(name); + if (authEnum == null) { + throw new AuthException(ResultEnum.NOT_EXIST_AUTHORITY); + } + authoritySet.add(authEnum); } role.setAuthoritySet(authoritySet); - - return roleDao.insertRole(role); + roleDao.saveRole(role); } @Override - public List getRole(String roleName, int currentPage, int pageSize) { - List roleList = roleDao.listLimitRole(roleName, currentPage * pageSize, pageSize); - List roleVoList = new LinkedList<>(); + public List listRoleLimit(String name, int currentPage, int pageSize) { + List createRoleDTOList = new LinkedList<>(); + List roleList = roleDao.listRoleLimit(name, currentPage * pageSize, pageSize); + if (roleList == null) { + return createRoleDTOList; + } for (Role role : roleList) { - roleVoList.add(new CreateRoleVo(role)); + createRoleDTOList.add(new CreateRoleDTO(role)); } - return roleVoList; + return createRoleDTOList; } @Override @Transactional(rollbackFor = Exception.class) - public void deleteRole(String roleName) { + public void deleteRole(DeleteRoleDTO deleteRoleDTO) { + if (!roleDao.existRole(deleteRoleDTO.getName())) { + throw new RoleException(ResultEnum.NOT_EXIST_ROLE); + } //将用户数据库中含有该角色的用户更新 - userDao.clearRole(roleDao.selectRole(roleName)); + userDao.clearRole(roleDao.selectRole(deleteRoleDTO.getName())); //从角色数据库删除角色 - roleDao.deleteRole(roleName); - + roleDao.deleteRole(deleteRoleDTO.getName()); //删除redis中的角色 - TokenUtil.expireKey(roleName); + TokenUtil.expireKey(deleteRoleDTO.getName()); } @Override - public void modifyRole(ModifyRoleVo modifyRoleVo) { - Set authEnumList = new HashSet<>(); + public void modifyRole(ModifyRoleDTO modifyRoleDTO) { + if (!roleDao.existRole(modifyRoleDTO.getName())) { + throw new RoleException(ResultEnum.NOT_EXIST_ROLE); + } + Role role = roleDao.selectRole(modifyRoleDTO.getName()); + Set authoritySet = new HashSet<>(); Set routeSet = new HashSet<>(); - for (String authName : modifyRoleVo.getAuthList()) { + for (String authName : modifyRoleDTO.getAuthoritySet()) { AuthEnum authEnum = AuthEnum.getRoleEnum(authName); - if(authEnum == null){ - throw new AuthException("权限不存在"); + if (authEnum == null) { + throw new AuthException(ResultEnum.NOT_EXIST_AUTHORITY); } - authEnumList.add(authEnum); + authoritySet.add(authEnum); routeSet.addAll(authEnum.getRoutes()); } - roleDao.updateRole(modifyRoleVo.getRoleName(), authEnumList); - TokenUtil.setWithoutExpireTime(modifyRoleVo.getRoleName(), routeSet); + role.setAuthoritySet(authoritySet); + roleDao.saveRole(role); + TokenUtil.setWithoutExpireTime(modifyRoleDTO.getName(), routeSet); + } + + @Override + public long countRole(String name) { + return roleDao.countRole(name); } } diff --git a/src/main/java/com/example/survey/service/impl/UserServiceImpl.java b/src/main/java/com/example/survey/service/impl/UserServiceImpl.java index 5b5d7b7..639d84d 100644 --- a/src/main/java/com/example/survey/service/impl/UserServiceImpl.java +++ b/src/main/java/com/example/survey/service/impl/UserServiceImpl.java @@ -1,22 +1,25 @@ package com.example.survey.service.impl; -import com.example.survey.dao.InvestigationRecordDao; import com.example.survey.dao.RoleDao; import com.example.survey.dao.UserDao; -import com.example.survey.dto.LoginDto; -import com.example.survey.dto.UserDto; +import com.example.survey.dto.user.*; import com.example.survey.entity.Role; import com.example.survey.entity.User; import com.example.survey.enumeration.AuthEnum; +import com.example.survey.enumeration.ResultEnum; +import com.example.survey.exception.RoleException; import com.example.survey.exception.UserException; import com.example.survey.service.UserService; import com.example.survey.util.TokenUtil; -import com.example.survey.vo.*; +import com.example.survey.vo.LoginVO; +import com.example.survey.vo.RoleVO; +import com.example.survey.vo.UserVO; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.*; +import java.util.stream.Collectors; /** * @author Pope @@ -29,26 +32,22 @@ public class UserServiceImpl implements UserService { private UserDao userDao; @Autowired private RoleDao roleDao; - @Autowired - private InvestigationRecordDao investigationRecordDao; @Override - public LoginDto matchAuth(LoginVo loginVo) { - User user = userDao.selectUser(loginVo.getPhoneNumber()); - if (user == null) { - log.error("用户不存在"); - throw new UserException("用户不存在"); + public LoginVO matchAuth(LoginDTO loginDTO) { + if (!userDao.existUser(loginDTO.getPhone())) { + throw new UserException(ResultEnum.NOT_EXIST_USER); } - if (!loginVo.getPassword().equals(user.getPassword())) { - log.error("密码错误"); - throw new UserException("密码错误"); + User user = userDao.selectUser(loginDTO.getPhone()); + if (!user.getPassword().equals(loginDTO.getPassword())) { + throw new UserException(ResultEnum.WRONG_PASSWORD); } - LoginDto loginDto = new LoginDto(); + LoginVO loginVO = new LoginVO(); //判断是否已经登录过 - if (TokenUtil.existKey(user.getPhoneNumber())) { - String oldToken = (String) TokenUtil.get(user.getPhoneNumber()); + if (TokenUtil.existKey(user.getPhone())) { + String oldToken = (String) TokenUtil.get(user.getPhone()); if (TokenUtil.existKey(oldToken)) { //已经登录,将旧token过期, TokenUtil.expireKey(oldToken); @@ -57,11 +56,11 @@ public class UserServiceImpl implements UserService { //生成新的token并存入redis String newToken = UUID.randomUUID().toString(); - TokenUtil.set(user.getPhoneNumber(), newToken); + TokenUtil.set(user.getPhone(), newToken); //生成角色列表 Set roleNameSet = new HashSet<>(); - for (Role role : user.getRoleList()) { + for (Role role : user.getRoleSet()) { Set routeSet = new HashSet<>(); for (AuthEnum authEnum : role.getAuthoritySet()) { routeSet.addAll(authEnum.getRoutes()); @@ -71,87 +70,126 @@ public class UserServiceImpl implements UserService { } TokenUtil.set(newToken, roleNameSet); - loginDto.setToken(newToken); - loginDto.setUsername(user.getUsername()); - loginDto.setIdNumber(user.getIdNumber()); - loginDto.setPhoneNumber(user.getPhoneNumber()); - List roleVoList = new ArrayList<>(); - for (Role role : user.getRoleList()) { - roleVoList.add(new RoleVo(role)); + loginVO.setToken(newToken); + loginVO.setUsername(user.getUsername()); + loginVO.setIdNumber(user.getIdNumber()); + loginVO.setPhone(user.getPhone()); + if (user.getRoleSet() != null) { + loginVO.setRoleSet(user.getRoleSet().stream() + .map(role -> { + RoleVO roleVO = new RoleVO(); + roleVO.setName(role.getName()); + roleVO.setAuthoritySet(role.getAuthoritySet().stream() + .map(AuthEnum::getName) + .collect(Collectors.toSet()) + ); + return roleVO; + }) + .collect(Collectors.toSet())); } - loginDto.setRoleList(roleVoList); - loginDto.setDepartmentList(user.getDepartmentList()); - loginDto.setAdministrativeArea(user.getAdministrativeArea()); + loginVO.setDepartmentList(user.getDepartmentList()); + loginVO.setAdministrativeArea(user.getAdministrativeArea()); - return loginDto; + return loginVO; } @Override - public boolean addUser(CreateUserVo createUserVo) { - User user = new User(createUserVo); - - //初始化为流调人员权限 -// Role investigatorRole = roleDao.selectRole("流调人员"); -// List roleList = user.getRoleList(); -// roleList.add(investigatorRole); -// user.setRoleList(roleList); - return userDao.insertUser(user); + public void addUser(CreateUserDTO createUserDTO) { + User user = new User(); + user.setUsername(createUserDTO.getUsername()); + user.setPhone(createUserDTO.getPhone()); + user.setPassword(createUserDTO.getPassword()); + user.setIdNumber(createUserDTO.getIdNumber()); + user.setAdministrativeArea(createUserDTO.getAdministrativeArea()); + userDao.saveUser(user); } @Override - public void modifyRole(UserRoleVo userRoleVo) { - List roleList = new ArrayList<>(); - for (String roleName : userRoleVo.getRoleNameList()) { - roleList.add(roleDao.selectRole(roleName)); + public void modifyRole(ModifyUserRoleDTO modifyUserRoleDTO) { + if (!userDao.existUser(modifyUserRoleDTO.getPhone())) { + throw new UserException(ResultEnum.NOT_EXIST_USER); } - - userDao.updateUserRole(userRoleVo.getPhoneNumber(), roleList); + User user = userDao.selectUser(modifyUserRoleDTO.getPhone()); + Set roleSet = new HashSet<>(); + for (String name : modifyUserRoleDTO.getRoleSet()) { + if (!roleDao.existRole(name)) { + throw new RoleException(ResultEnum.NOT_EXIST_ROLE); + } + roleSet.add(roleDao.selectRole(name)); + } + user.setRoleSet(roleSet); + userDao.saveUser(user); } @Override - public List listUserLimit(String username, String phoneNumber, int currentPage, int pageSize) { + public List listUserLimit(String username, String phoneNumber, int currentPage, int pageSize) { List userList = userDao.listUserLimit(username, phoneNumber, currentPage * pageSize, pageSize); - List userDtoList = new LinkedList<>(); - for (User user : userList) { - userDtoList.add(new UserDto(user)); + if (userList == null) { + return new ArrayList<>(); } - return userDtoList; + return userList.stream().map(user -> { + UserVO userVO = new UserVO(); + userVO.setPhone(user.getPhone()); + userVO.setUsername(user.getUsername()); + userVO.setIdNumber(user.getIdNumber()); + userVO.setAdministrativeArea(user.getAdministrativeArea()); + if (user.getRoleSet() != null) { + userVO.setRoleSet(user.getRoleSet().stream() + .map(role -> { + RoleVO roleVO = new RoleVO(); + roleVO.setName(role.getName()); + roleVO.setAuthoritySet(role.getAuthoritySet().stream() + .map(AuthEnum::getName) + .collect(Collectors.toSet()) + ); + return roleVO; + }) + .collect(Collectors.toSet()) + ); + } + return userVO; + }).collect(Collectors.toList()); } @Override - public boolean deleteUser(String phoneNumber) { - if (!userDao.existUser(phoneNumber)) { - log.error("用户不存在"); - throw new UserException("用户不存在"); + public void deleteUser(DeleteUserDTO deleteUserDTO) { + if (!userDao.existUser(deleteUserDTO.getPhone())) { + throw new UserException(ResultEnum.NOT_EXIST_USER); } - userDao.deleteUser(phoneNumber); - - investigationRecordDao.updateManyRecordUserPhone(phoneNumber, null); - - if (TokenUtil.existKey(phoneNumber)) { - String token = (String) TokenUtil.get(phoneNumber); - TokenUtil.expireKey(phoneNumber); + userDao.deleteUser(deleteUserDTO.getPhone()); + if (TokenUtil.existKey(deleteUserDTO.getPhone())) { + String token = (String) TokenUtil.get(deleteUserDTO.getPhone()); + TokenUtil.expireKey(deleteUserDTO.getPhone()); TokenUtil.expireKey(token); } - return true; } @Override - public void modifyUserInfo(UserInfoVo userInfoVo) { - if (!userDao.existUser(userInfoVo.getPhoneNumber())) { - log.error("用户不存在"); - throw new UserException("用户不存在"); + public void modifyUserInfo(ModifyUserInfoDTO modifyUserInfoDTO) { + if (!userDao.existUser(modifyUserInfoDTO.getPhone())) { + throw new UserException(ResultEnum.NOT_EXIST_USER); } - userDao.modifyUser(userInfoVo); + User user = userDao.selectUser(modifyUserInfoDTO.getPhone()); + user.setUsername(modifyUserInfoDTO.getUsername()); + user.setIdNumber(modifyUserInfoDTO.getIdNumber()); + user.setAdministrativeArea(modifyUserInfoDTO.getAdministrativeArea()); + userDao.saveUser(user); } @Override - public void resetPwd(String phoneNumber) { - if (!userDao.existUser(phoneNumber)) { - log.error("用户不存在"); - throw new UserException("用户不存在"); + public void resetPwd(ResetPwdDTO resetPwdDTO) { + if (!userDao.existUser(resetPwdDTO.getPhone())) { + throw new UserException(ResultEnum.NOT_EXIST_USER); } - userDao.resetPwd(phoneNumber); + User user = userDao.selectUser(resetPwdDTO.getPhone()); + user.setPassword("123456"); + userDao.saveUser(user); + } + + @Override + public long countUser(String username, String phone) { + return userDao.countUser(username, phone); + } diff --git a/src/main/java/com/example/survey/util/WordUtil.java b/src/main/java/com/example/survey/util/WordUtil.java deleted file mode 100644 index 494e779..0000000 --- a/src/main/java/com/example/survey/util/WordUtil.java +++ /dev/null @@ -1,430 +0,0 @@ -package com.example.survey.util; - -import com.example.survey.dao.UserDao; -import com.example.survey.entity.InvestigationRecord; -import com.example.survey.entity.inner.*; -import org.apache.poi.xwpf.usermodel.*; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; -import javax.servlet.http.HttpServletResponse; -import java.math.BigInteger; -import java.util.Calendar; -import java.util.Date; -import java.util.List; - -/** - * @author Pope - */ -@Component -public class WordUtil { - - @Autowired - private UserDao userDao; - - private static WordUtil wordUtil; - - @PostConstruct - public void init() { - wordUtil = this; - wordUtil.userDao = this.userDao; - } - - /** - * 分隔符 - */ - private static final String SEPARATOR = " "; - - private static final String OTHER = "other"; - - public static void writeDocx(InvestigationRecord record, HttpServletResponse response) throws Exception { - XWPFDocument document = new XWPFDocument(); - int index = 1; - - //添加标题 - XWPFParagraph title = document.createParagraph(); - title.setAlignment(ParagraphAlignment.CENTER); - XWPFRun titleRun = title.createRun(); - titleRun.setText("新型冠状病毒肺炎病例个案调查表"); - //设置字体 - setRunFont(titleRun, "宋体", 18, true); - - //换行 - document.createParagraph().createRun().setText("\r"); - - //问卷编号与身份证号 - XWPFParagraph firstPara = document.createParagraph(); - firstPara.setAlignment(ParagraphAlignment.CENTER); - XWPFRun firstParaRun = firstPara.createRun(); - firstParaRun.setText("问卷编号:" + record.getQuestionnaireNumber() + SEPARATOR + "身份证号:" + record.getIdNumber()); - //设置字体 - setRunFont(firstParaRun, "仿宋", 10, false); - - //换行 - document.createParagraph().createRun().setText("\r"); - - //信息表格 - XWPFTable infoTable = document.createTable(); - //列宽自动分割 - CTTblWidth infoTableWidth = infoTable.getCTTbl().addNewTblPr().addNewTblW(); - infoTableWidth.setType(STTblWidth.DXA); - infoTableWidth.setW(BigInteger.valueOf(9072)); - - - //表格第一行 基本信息 - XWPFTableRow infoTableRow1 = infoTable.getRow(0); - XWPFTableCell basicInfoCell = infoTableRow1.getCell(0); - basicInfoCell.removeParagraph(0); - - //基本信息标题 - createParaInCell(basicInfoCell, "一、基本信息", true); - createBreakLine(basicInfoCell); - - //姓名 性别 - createParaInCell(basicInfoCell, index++ + ".姓名:" + record.getName() + SEPARATOR + index++ + ".性别:" + record.getGender(), false); - //是否为境外输入病例 - createParaInCell(basicInfoCell, index++ + ".是否为境外输入病例:" + (record.isOverseasCase() ? "是" : "否"), false); - if (record.isOverseasCase()) { - //如果为境外输入病例,填写入境信息 - EntryExperience entryExperience = record.getEntryExperience(); - createParaInCell(basicInfoCell, SEPARATOR + "入境前居住或旅行的国家或地区:" + entryExperience.getAreaOfResidence(), false); - createParaInCell(basicInfoCell, SEPARATOR + "入境前途经国家和地区:" + entryExperience.getAreaOfAccess(), false); - createParaInCell(basicInfoCell, SEPARATOR + "国籍:" + entryExperience.getNationality() + SEPARATOR + "护照号码:" + entryExperience.getPassportNumber(), false); - createParaInCell(basicInfoCell, SEPARATOR + "入境口岸:" + entryExperience.getEntryPort().getProvince() + "省" + entryExperience.getEntryPort().getPort(), false); - - createParaInCell(basicInfoCell, SEPARATOR + "入境日期:" + formatDate(entryExperience.getEntryDate()), false); - createParaInCell(basicInfoCell, SEPARATOR + "入境交通方式:" + entryExperience.getTransportation(), false); - } - - //病例发现与就诊 - XWPFTableRow infoTableRow2 = infoTable.createRow(); - XWPFTableCell hospInfoCell = infoTableRow2.getCell(0); - hospInfoCell.removeParagraph(0); - - //病例发现与就诊标题 - createParaInCell(hospInfoCell, "二、病例发现与就诊", true); - createBreakLine(hospInfoCell); - - //病例发现途径 - createParaInCell(hospInfoCell, index++ + ".病例发现途径:" + record.getWayOfBeingDiscovered(), false); - //入院日期 - createParaInCell(hospInfoCell, index++ + ".入院日期:" + formatDate(record.getDateOfAdmission()), false); - StringBuilder symptomAndSign = new StringBuilder(); - //入院时症状和体征 - for (String s : record.getSymptomAndSign()) { - symptomAndSign.append(s).append(" "); - } - createParaInCell(hospInfoCell, index++ + ".入院症状和体征:" + symptomAndSign.toString(), false); - //有无并发症 - createParaInCell(hospInfoCell, index++ + ".有无并发症:" + (record.isExistComplication() ? "有" : "无"), false); - if (record.getComplication() != null) { - StringBuilder complication = new StringBuilder("并发症:"); - for (String s : record.getComplication()) { - complication.append(s); - } - createParaInCell(hospInfoCell, complication.toString(), false); - if (record.getComplication().contains("发热")) { - //如果并发症包含发热,则打印最高温度 - createParaInCell(hospInfoCell, SEPARATOR + "发热:最高温度" + record.getMaxTemp() + "°C", false); - } - - } - //胸部X线或CT检测是否有肺炎影像学特征 - createParaInCell(hospInfoCell, index++ + ".胸部X线或CT检测是否有肺炎影像学特征:" + (record.isExistImagingFeatureOfPneumonia() ? "是" : "否"), false); - if (record.isExistImagingFeatureOfPneumonia()) { - //如果存在肺炎影像学特征,打印检测时间 - createParaInCell(hospInfoCell, SEPARATOR + "检测时间:" + formatDate(record.getTestDate()), false); - } - //出院日期 - createParaInCell(hospInfoCell, index++ + ".出院日期:" + formatDate(record.getDateOfDischarge()), false); - //是否为以下特定职业人群 - createParaInCell(hospInfoCell, index++ + ".是否为以下特定职业人群:" + record.getSpecificOccupation(), false); - if (OTHER.equals(record.getSpecificOccupation())) { - //若职业为其他 - createParaInCell(hospInfoCell, SEPARATOR + "职业:" + record.getOtherSpecificOccupation(), false); - } - //如为医务人员,请选择具体工作性质: - createParaInCell(hospInfoCell, SEPARATOR + "如为医务人员,请选择具体工作性质:" + record.getWorkInformation(), false); - if (OTHER.equals(record.getWorkInformation())) { - //若工作性质为其他 - createParaInCell(hospInfoCell, SEPARATOR + "其他工作性质:" + record.getOtherWorkInformation(), false); - } - //是否为孕妇 - createParaInCell(hospInfoCell, index++ + ".是否为孕妇:" + (record.isPregnant() ? "是" : "否"), false); - if (record.isPregnant()) { - //如果是孕妇,打印孕周 - createParaInCell(hospInfoCell, SEPARATOR + "孕周:" + record.getPregnantWeek(), false); - } - //既往病史和基本情况(可多选) - StringBuilder medicalHistory = new StringBuilder(); - for (String s : record.getMedicalHistory()) { - medicalHistory.append(s).append(" "); - } - createParaInCell(hospInfoCell, index++ + ".既往病史与基本情况:" + medicalHistory, false); - //既往病史描述 - createParaInCell(hospInfoCell, SEPARATOR + "既往病史描述:" + record.getMedicalHistoryDetail(), false); - - - //发病或检测阳性前 14 天内是否有以下暴露史或接触史: - XWPFTableRow infoTableRow3 = infoTable.createRow(); - XWPFTableCell contactHistoryCell = infoTableRow3.getCell(0); - contactHistoryCell.removeParagraph(0); - - //病例发现与就诊标题 - createParaInCell(contactHistoryCell, "三、发病或检测阳性前 14 天内是否有以下暴露史或接触史:", true); - createBreakLine(contactHistoryCell); - - //是否有境外疫情严重国家或地区的旅行史或居住史 - createParaInCell(contactHistoryCell, index++ + ".是否有境外疫情严重国家或地区的旅行史或居住史:" + (record.isNearSeriousRegion() ? "是" : "否"), false); - - //是否接触过来自境外疫情严重的国家或地区的发热或有呼吸道症状的患者 - createParaInCell(contactHistoryCell, index++ + ".是否接触过来自境外疫情严重的国家或地区的发热或有呼吸道症状的患者:" + (record.isContactWithSeriousRegionPatients() ? "是" : "否"), false); - - //是否曾有确诊病例或无症状感染者的接触史 - createParaInCell(contactHistoryCell, index++ + ".是否曾有确诊病例或无症状感染者的接触史:" + (record.isContactWithConfirmedCase() ? "是" : "否"), false); - - //患者同一家庭、办公室、学校或托幼机构班级、车间等集体单位是否有聚集性发病 - createParaInCell(contactHistoryCell, index++ + ".患者同一家庭、办公室、学校或托幼机构班级、车间等集体单位是否有聚集性发病:" + (record.isAggregationDisease() ? "是" : "否"), false); - - //体温记录 - XWPFTableRow infoTableRow4 = infoTable.createRow(); - XWPFTableCell tempHistory = infoTableRow4.getCell(0); - tempHistory.removeParagraph(0); - createParaInCell(tempHistory, "四、体温记录", true); - createBreakLine(tempHistory); - - //体温记录表 - XWPFTable tempTable = createTableInCell(tempHistory); - - //创建表头 - XWPFTableRow tempTableHead = tempTable.createRow(); - XWPFTableCell tempDateHead = tempTableHead.createCell(); - tempDateHead.removeParagraph(0); - createParaInCell(tempDateHead, "记录时间", false); - setCellCenter(tempDateHead); - - XWPFTableCell tempHead = tempTableHead.createCell(); - tempHead.removeParagraph(0); - createParaInCell(tempHead, "温度", false); - setCellCenter(tempHead); - //创建数据 - for (TempHistory history : record.getTempHistoryList()) { - XWPFTableRow row = tempTable.createRow(); - - XWPFTableCell temp = row.getCell(0); - temp.removeParagraph(0); - createParaInCell(temp, history.getData(), false); - setCellCenter(temp); - - XWPFTableCell date = row.getCell(1); - date.removeParagraph(0); - createParaInCell(date, formatTime(history.getTime()), false); - setCellCenter(date); - } - - - //居住史 - XWPFTableRow infoTableRow5 = infoTable.createRow(); - XWPFTableCell liveAndTravelHistory = infoTableRow5.getCell(0); - liveAndTravelHistory.removeParagraph(0); - - createParaInCell(liveAndTravelHistory, "五、居旅史", true); - createBreakLine(liveAndTravelHistory); - - List liveHistoryList = record.getLiveHistoryList(); - if (liveHistoryList != null) { - for (int i = 0; i < liveHistoryList.size(); i++) { - createParaInCell(liveAndTravelHistory, "居住史" + (i + 1), false); - createParaInCell(liveAndTravelHistory, SEPARATOR + "开始时间:" + formatDate(liveHistoryList.get(i).getBeginTime()), false); - createParaInCell(liveAndTravelHistory, SEPARATOR + "地点:" + liveHistoryList.get(i).getLocation().getMsg(), false); - createParaInCell(liveAndTravelHistory, SEPARATOR + "结束时间:" + formatDate(liveHistoryList.get(i).getEndTime()), false); - createParaInCell(liveAndTravelHistory, SEPARATOR + "详细信息:" + liveHistoryList.get(i).getDetail(), false); - } - } - List travelHistoryList = record.getTravelHistoryList(); - if (travelHistoryList != null) { - for (int i = 0; i < travelHistoryList.size(); i++) { - createParaInCell(liveAndTravelHistory, "旅行史" + (i + 1), false); - createParaInCell(liveAndTravelHistory, SEPARATOR + "开始时间:" + formatDate(travelHistoryList.get(i).getBeginTime()), false); - createParaInCell(liveAndTravelHistory, SEPARATOR + "开始地点:" + travelHistoryList.get(i).getStartLocation().getMsg(), false); - createParaInCell(liveAndTravelHistory, SEPARATOR + "结束时间:" + formatDate(travelHistoryList.get(i).getEndTime()), false); - createParaInCell(liveAndTravelHistory, SEPARATOR + "结束地点:" + travelHistoryList.get(i).getEndLocation().getMsg(), false); - createParaInCell(liveAndTravelHistory, SEPARATOR + "详细信息:" + travelHistoryList.get(i).getDetail(), false); - } - } - - - //实验室检测单 - XWPFTableRow infoTableRow6 = infoTable.createRow(); - XWPFTableCell detectionList = infoTableRow6.getCell(0); - detectionList.removeParagraph(0); - createParaInCell(detectionList, "六、实验室检测单", true); - createBreakLine(detectionList); - - //实验室检测单表格 - XWPFTable detectionTable = createTableInCell(detectionList); - - //创建表头 - XWPFTableRow detectionTableHead = detectionTable.createRow(); - - XWPFTableCell nameHead = detectionTableHead.createCell(); - nameHead.removeParagraph(0); - createParaInCell(nameHead, "标本类型:", false); - setCellCenter(nameHead); - - XWPFTableCell detectionDate = detectionTableHead.createCell(); - detectionDate.removeParagraph(0); - createParaInCell(detectionDate, "采样时间:", false); - setCellCenter(detectionDate); - - XWPFTableCell detectionResult = detectionTableHead.createCell(); - detectionResult.removeParagraph(0); - createParaInCell(detectionResult, "采样结果:", false); - setCellCenter(detectionResult); - - for (Detection detection : record.getDetectionList()) { - XWPFTableRow row = detectionTable.createRow(); - - XWPFTableCell name = row.getCell(0); - name.removeParagraph(0); - createParaInCell(name, detection.getName(), false); - setCellCenter(name); - - XWPFTableCell date = row.getCell(1); - date.removeParagraph(0); - createParaInCell(date, formatDate(detection.getDate()), false); - setCellCenter(date); - - XWPFTableCell result = row.getCell(2); - result.removeParagraph(0); - createParaInCell(result, detection.getResult(), false); - setCellCenter(result); - } - - - //调查信息 - XWPFParagraph surveyInfo = document.createParagraph(); - XWPFRun surveyInfoRun = surveyInfo.createRun(); - String surveyInfoStr = "调查单位:" + record.getInvestigationCompany() + " " + - "调查者:" + wordUtil.userDao.selectUsername(record.getUserPhone()) + " " + - "调查时间:" + formatDate(record.getInvestigationDate()); - surveyInfoRun.setText(surveyInfoStr); - setRunFont(surveyInfoRun, "仿宋", 11, false); - - - //八进制输出流 - response.setContentType("application/octet-stream"); - - //这后面可以设置导出Excel的名称,此例中名为student.xls - response.setHeader("Content-disposition", "attachment;filename=" + record.getIdNumber() + ".docx"); - document.write(response.getOutputStream()); - } - - - public static XWPFTable createTableInCell(XWPFTableCell cell) { - cell.addParagraph(); - XWPFTable table = cell.insertNewTbl(cell.getParagraphArray(1).getCTP().newCursor()); - table.getCTTbl().addNewTblPr().addNewTblBorders() - .addNewLeft().setVal(STBorder.SINGLE); - table.getCTTbl().addNewTblPr().addNewTblBorders() - .addNewRight().setVal(STBorder.SINGLE); - table.getCTTbl().addNewTblPr().addNewTblBorders() - .addNewTop().setVal(STBorder.SINGLE); - table.getCTTbl().addNewTblPr().addNewTblBorders() - .addNewBottom().setVal(STBorder.SINGLE); - table.getCTTbl().addNewTblPr().addNewTblBorders() - .addNewInsideH().setVal(STBorder.SINGLE); - table.getCTTbl().addNewTblPr().addNewTblBorders() - .addNewInsideV().setVal(STBorder.SINGLE); - - //设置表格水平居中 - table.getCTTbl().getTblPr().addNewJc().setVal(STJc.CENTER); - //设置表格垂直居中 - cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); - table.setWidth(8000); - - return table; - } - - /** - * 设置单元格内容居中 - */ - public static void setCellCenter(XWPFTableCell cell) { - CTTc cttc = cell.getCTTc(); - CTTcPr ctPr = cttc.addNewTcPr(); - ctPr.addNewVAlign().setVal(STVerticalJc.CENTER); - cttc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER); - } - - /** - * 在单元格中创建段落 - */ - public static void createParaInCell(XWPFTableCell cell, String text, boolean title) { - XWPFParagraph paragraph = cell.addParagraph(); - paragraph.setAlignment(ParagraphAlignment.LEFT); - XWPFRun run = paragraph.createRun(); - run.setText(text); - if (title) { - setRunFont(run, "仿宋", 14, true); - } else { - setRunFont(run, "仿宋", 11, false); - } - } - - /** - * 换行 - */ - public static void createBreakLine(XWPFTableCell cell) { - cell.addParagraph().createRun().setText("\r"); - } - - /** - * 设置段落字体 - */ - public static void setRunFont(XWPFRun run, String font, int fontSize, boolean bold) { - run.setFontFamily(font); - run.getCTR().addNewRPr().addNewRFonts().setEastAsia(font); - run.setBold(bold); - run.setFontSize(fontSize); - } - - /** - * 根据日期提取时间 - * - * @param date 日期 - * @return 格式化后的时间字符串 年-月-日 - */ - public static String formatDate(Date date) { - StringBuilder res = new StringBuilder(); - Calendar calendar = Calendar.getInstance(); - calendar.setTime(date); - res.append(calendar.get(Calendar.YEAR)).append("年"); - res.append(calendar.get(Calendar.MONTH) + 1).append("月"); - res.append(calendar.get(Calendar.DAY_OF_MONTH)).append("日"); - - return res.toString(); - } - - /** - * 根据日期提取时间 - * - * @param date 日期 - * @return 格式化后的时间字符串 年-月-日-时-分-秒 - */ - public static String formatTime(Date date) { - StringBuilder res = new StringBuilder(); - Calendar calendar = Calendar.getInstance(); - calendar.setTime(date); - res.append(calendar.get(Calendar.YEAR)).append("年"); - res.append(calendar.get(Calendar.MONTH) + 1).append("月"); - res.append(calendar.get(Calendar.DAY_OF_MONTH)).append("日"); - res.append(calendar.get(Calendar.HOUR_OF_DAY)).append("时"); - res.append(calendar.get(Calendar.MINUTE)).append("分"); - res.append(calendar.get(Calendar.SECOND)).append("秒"); - - return res.toString(); - } - -} diff --git a/src/main/java/com/example/survey/vo/CreateRoleVo.java b/src/main/java/com/example/survey/vo/CreateRoleVo.java deleted file mode 100644 index e063568..0000000 --- a/src/main/java/com/example/survey/vo/CreateRoleVo.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.example.survey.vo; - -import com.example.survey.entity.Role; -import com.example.survey.enumeration.AuthEnum; -import lombok.*; - -import java.util.LinkedList; -import java.util.List; - -/** - * @author Pope - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -public class CreateRoleVo { - private String roleName; - private List authList; - - public CreateRoleVo(Role role) { - roleName = role.getName(); - authList = new LinkedList<>(); - for (AuthEnum authEnum : role.getAuthoritySet()) { - authList.add(authEnum.getName()); - } - } -} diff --git a/src/main/java/com/example/survey/vo/InvestigationRecordVo.java b/src/main/java/com/example/survey/vo/InvestigationRecordVo.java deleted file mode 100644 index 27fac3b..0000000 --- a/src/main/java/com/example/survey/vo/InvestigationRecordVo.java +++ /dev/null @@ -1,228 +0,0 @@ -package com.example.survey.vo; - -import com.example.survey.entity.inner.*; -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.*; - -import java.util.Date; -import java.util.List; -import java.util.Map; - -/** - * @author Pope - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -public class InvestigationRecordVo { - /** - * 问卷编号 - */ - private String questionnaireNumber; - - /** - * 身份证号 - * 唯一索引 - */ - private String idNumber; - - //==================================基本信息================================== - - /** - * 姓名 - */ - private String name; - - /** - * 性别 - * true为男性,false为女性 - */ - private String gender; - - /** - * 是否为境外病例 - */ - private boolean overseasCase; - - /** - * 是否为病例 - * 区分病例与密切接触者 - */ - private boolean diseased; - - /** - * 入境经历 - * 选填 - */ - private EntryExperience entryExperience; - - //==================================病例发现与就诊================================== - - /** - * 病例被发现途径 - */ - private String wayOfBeingDiscovered; - - /** - * 入院时间 - */ - @JsonFormat(pattern = "yyyy-MM-dd") - private Date dateOfAdmission; - - /** - * 入院时症状和体征 - */ - private List symptomAndSign; - - /** - * 有无并发症 - */ - private boolean existComplication; - - /** - * 并发症 - * 选填 - */ - private List complication; - - /** - * 当并发症存在发热时,记录最高体温 - */ - private String maxTemp; - - /** - * 胸部X线或 CT 检测是否有肺炎影像学特征 - */ - private boolean existImagingFeatureOfPneumonia; - - /** - * 如果肺炎影像学特征为是,此处填检测时间 - */ - @JsonFormat(pattern = "yyyy-MM-dd") - private Date testDate; - - /** - * 出院日期 - * 年月日 - */ - @JsonFormat(pattern = "yyyy-MM-dd") - private Date dateOfDischarge; - - //==================================危险因素与暴露史================================== - - /** - * 是否为特定职业人群 - */ - private String specificOccupation; - - /** - * 当specificOccupation为other时起作用 - */ - private String otherSpecificOccupation; - - /** - * 如为医护人员,填写具体工作性质 - */ - private String workInformation; - - /** - * 当workInformation为other时起作用 - */ - private String otherWorkInformation; - - /** - * 是否为孕妇 - */ - private boolean pregnant; - - /** - * 孕周 - */ - private int pregnantWeek; - - /** - * 病史 - */ - private List medicalHistory; - - /** - * 对既往病史的详细描述 - */ - private String medicalHistoryDetail; - - //==================================发病或检测阳性前14天内是否有以下暴露史或接触史================================== - - /** - * 是否有境外疫情严重国家或地区的旅行史或居住史 - */ - private boolean nearSeriousRegion; - - /** - * 是否接触过来自境外疫情严重的国家或地区的发热或有呼吸道症状的患者 - */ - private boolean contactWithSeriousRegionPatients; - - /** - * 是否曾有确诊病例或无症状感染者的接触史 - */ - private boolean contactWithConfirmedCase; - - /** - * 患者同一家庭、办公室、学校或托幼机构班级、车间等集体单位是否有聚集性发病 - */ - private boolean aggregationDisease; - - - //==================================实验室检测================================== - - /** - * 实验室检测结果,未采集则value为null - */ - private List detectionList; - - /** - * 调查单位 - */ - private String investigationCompany; - - /** - * 调查者(身份证) - * 外键 - */ - private String userPhone; - - /** - * 调查日期 - * 年月日 - */ - @JsonFormat(pattern = "yyyy-MM-dd") - private Date investigationDate; - - /** - * 体温历史 - */ - private List tempHistoryList; - - /** - * 居住史 - */ - private List liveHistoryList; - - /** - * 旅行史 - */ - private List travelHistoryList; - - /** - * 备注 - */ - private String msg; - - /** - * 存放一些url - */ - private Map urlMap; - -} diff --git a/src/main/java/com/example/survey/dto/LoginDto.java b/src/main/java/com/example/survey/vo/LoginVO.java similarity index 67% rename from src/main/java/com/example/survey/dto/LoginDto.java rename to src/main/java/com/example/survey/vo/LoginVO.java index f9c407a..7d56fa7 100644 --- a/src/main/java/com/example/survey/dto/LoginDto.java +++ b/src/main/java/com/example/survey/vo/LoginVO.java @@ -1,12 +1,11 @@ -package com.example.survey.dto; +package com.example.survey.vo; import com.example.survey.entity.Department; -import com.example.survey.entity.Role; import com.example.survey.entity.inner.AdministrativeArea; -import com.example.survey.vo.RoleVo; import lombok.*; import java.util.List; +import java.util.Set; /** * @author Pope @@ -16,12 +15,13 @@ import java.util.List; @ToString @NoArgsConstructor @AllArgsConstructor -public class LoginDto { +@EqualsAndHashCode +public class LoginVO { private String token; private String username; private String idNumber; - private String phoneNumber; - private List roleList; + private String phone; + private Set roleSet; private List departmentList; private AdministrativeArea administrativeArea; } diff --git a/src/main/java/com/example/survey/vo/MetaDataVO.java b/src/main/java/com/example/survey/vo/MetaDataVO.java new file mode 100644 index 0000000..5ae48dd --- /dev/null +++ b/src/main/java/com/example/survey/vo/MetaDataVO.java @@ -0,0 +1,18 @@ +package com.example.survey.vo; + +import com.example.survey.entity.inner.FieldToName; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @author Pope + */ +@Data +public class MetaDataVO { + private String name; + private Map form; + private List fieldToNameList; + private Map config; +} diff --git a/src/main/java/com/example/survey/vo/ModifyRoleVo.java b/src/main/java/com/example/survey/vo/ModifyRoleVo.java deleted file mode 100644 index 92ca7f0..0000000 --- a/src/main/java/com/example/survey/vo/ModifyRoleVo.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.example.survey.vo; - -import lombok.*; - -import java.util.List; - -/** - * @author Pope - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -public class ModifyRoleVo { - private String roleName; - private List authList; -} diff --git a/src/main/java/com/example/survey/vo/ProjectVO.java b/src/main/java/com/example/survey/vo/ProjectVO.java new file mode 100644 index 0000000..3462334 --- /dev/null +++ b/src/main/java/com/example/survey/vo/ProjectVO.java @@ -0,0 +1,46 @@ +package com.example.survey.vo; + +import com.example.survey.entity.MetaData; +import com.example.survey.entity.Respondent; +import lombok.Data; +import org.springframework.data.mongodb.core.index.Indexed; +import org.springframework.data.mongodb.core.mapping.DBRef; + +import java.util.Date; +import java.util.Set; + +/** + * @author Pope + */ +@Data +public class ProjectVO { + /** + * 项目名 + */ + private String name; + + /** + * 描述信息 + */ + private String detail; + + /** + * 元数据 + */ + private String metaDataName; + + /** + * 开始时间 + */ + private Date startTime; + + /** + * 结束时间 + */ + private Date endTime; + + /** + * 状态 + */ + private String state; +} diff --git a/src/main/java/com/example/survey/vo/RecordVO.java b/src/main/java/com/example/survey/vo/RecordVO.java new file mode 100644 index 0000000..e9d3661 --- /dev/null +++ b/src/main/java/com/example/survey/vo/RecordVO.java @@ -0,0 +1,28 @@ +package com.example.survey.vo; + +import com.example.survey.vo.inner.OperationInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @author Pope + */ +@Data +public class RecordVO { + + private String idNumber; + + private String userPhone; + + private String projectName; + + private List operationInfoList; + + private String version; + + private String state; + + +} diff --git a/src/main/java/com/example/survey/vo/RespondentVO.java b/src/main/java/com/example/survey/vo/RespondentVO.java new file mode 100644 index 0000000..09bb83d --- /dev/null +++ b/src/main/java/com/example/survey/vo/RespondentVO.java @@ -0,0 +1,57 @@ +package com.example.survey.vo; + +import com.example.survey.entity.inner.AdministrativeArea; +import com.example.survey.vo.inner.UserInfo; +import lombok.Data; + +/** + * @author Pope + */ +@Data +public class RespondentVO { + + /** + * 身份证号 + */ + private String idNumber; + + /** + * 电话 + */ + private String phone; + + /** + * 姓名 + */ + private String name; + + /** + * 备注 + */ + private String msg; + + /** + * 性别 + */ + private String gender; + + /** + * 行政区划 + */ + private AdministrativeArea administrativeArea; + + /** + * 相关项目信息 + */ + private String projectName; + + /** + * 用户信息 + */ + private UserInfo userInfo; + + /** + * 调查对象状态 + */ + private String state; +} diff --git a/src/main/java/com/example/survey/vo/ResultVo.java b/src/main/java/com/example/survey/vo/ResultVO.java similarity index 60% rename from src/main/java/com/example/survey/vo/ResultVo.java rename to src/main/java/com/example/survey/vo/ResultVO.java index c4d0eda..4da7408 100644 --- a/src/main/java/com/example/survey/vo/ResultVo.java +++ b/src/main/java/com/example/survey/vo/ResultVO.java @@ -1,5 +1,6 @@ package com.example.survey.vo; +import com.example.survey.enumeration.ResultEnum; import lombok.*; /** @@ -11,10 +12,7 @@ import lombok.*; @ToString @NoArgsConstructor @AllArgsConstructor -public class ResultVo { - - public static final int SUCCESS = 0; - public static final int FAILED = 1; +public class ResultVO { /** * 状态码 @@ -30,4 +28,9 @@ public class ResultVo { * 数据 */ private Object data; + + public ResultVO(ResultEnum resultEnum) { + this.setCode(resultEnum.getCode()); + this.setMsg(resultEnum.getMsg()); + } } diff --git a/src/main/java/com/example/survey/vo/ReviewVo.java b/src/main/java/com/example/survey/vo/ReviewVo.java deleted file mode 100644 index 0cb8fd5..0000000 --- a/src/main/java/com/example/survey/vo/ReviewVo.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.example.survey.vo; - -import lombok.*; - -/** - * @author Pope - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -public class ReviewVo { - /** - * 调查记录对应的调查对象的身份证号 - */ - private String idNumber; - /** - * 是否审核通过 - */ - private boolean pass; - /** - * 审核信息 - */ - private String msg; - /** - * 审核者id - */ - private String reviewerPhone; -} diff --git a/src/main/java/com/example/survey/vo/RoleVO.java b/src/main/java/com/example/survey/vo/RoleVO.java new file mode 100644 index 0000000..aa39eab --- /dev/null +++ b/src/main/java/com/example/survey/vo/RoleVO.java @@ -0,0 +1,25 @@ +package com.example.survey.vo; + +import com.example.survey.entity.Role; +import com.example.survey.enumeration.AuthEnum; +import lombok.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * @author Pope + */ +@Getter +@Setter +@ToString +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode +public class RoleVO { + + private String name; + private Set authoritySet; + +} diff --git a/src/main/java/com/example/survey/vo/RoleVo.java b/src/main/java/com/example/survey/vo/RoleVo.java deleted file mode 100644 index 972039c..0000000 --- a/src/main/java/com/example/survey/vo/RoleVo.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.example.survey.vo; - -import com.example.survey.entity.Role; -import com.example.survey.enumeration.AuthEnum; -import lombok.*; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Pope - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -public class RoleVo { - - private String roleName; - private List authorityList; - - public RoleVo(Role role) { - roleName = role.getName(); - authorityList = new ArrayList<>(); - for (AuthEnum authEnum : role.getAuthoritySet()) { - authorityList.add(authEnum.getName()); - } - } -} diff --git a/src/main/java/com/example/survey/vo/UserRoleVo.java b/src/main/java/com/example/survey/vo/UserRoleVo.java deleted file mode 100644 index 2390744..0000000 --- a/src/main/java/com/example/survey/vo/UserRoleVo.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.example.survey.vo; - -import lombok.*; - -import java.util.List; - -/** - * @author Pope - */ -@Getter -@Setter -@ToString -@NoArgsConstructor -@AllArgsConstructor -public class UserRoleVo { - private String phoneNumber; - private List roleNameList; -} diff --git a/src/main/java/com/example/survey/vo/UserVO.java b/src/main/java/com/example/survey/vo/UserVO.java new file mode 100644 index 0000000..20b0dc5 --- /dev/null +++ b/src/main/java/com/example/survey/vo/UserVO.java @@ -0,0 +1,25 @@ +package com.example.survey.vo; + +import com.example.survey.entity.Department; +import com.example.survey.entity.inner.AdministrativeArea; +import lombok.*; + +import java.util.Set; + +/** + * @author Pope + */ +@Getter +@Setter +@ToString +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode +public class UserVO { + private String idNumber; + private String username; + private String phone; + private Set roleSet; + private Set departmentSet; + private AdministrativeArea administrativeArea; +} diff --git a/src/main/java/com/example/survey/vo/inner/OperationInfo.java b/src/main/java/com/example/survey/vo/inner/OperationInfo.java new file mode 100644 index 0000000..122712c --- /dev/null +++ b/src/main/java/com/example/survey/vo/inner/OperationInfo.java @@ -0,0 +1,42 @@ +package com.example.survey.vo.inner; + +import lombok.Data; + +import java.util.Date; + +/** + * @author Pope + */ +@Data +public class OperationInfo { + /** + * 操作 + */ + private String type; + + /** + * 时间 + */ + private Date time; + + /** + * 操作者 + */ + private String userPhone; + + /** + * 版本信息 + */ + private String version; + + /** + * 备注 + */ + private String msg; + + /** + * 操作结果 + */ + private String result; + +} diff --git a/src/main/java/com/example/survey/vo/inner/UserInfo.java b/src/main/java/com/example/survey/vo/inner/UserInfo.java new file mode 100644 index 0000000..c42fbee --- /dev/null +++ b/src/main/java/com/example/survey/vo/inner/UserInfo.java @@ -0,0 +1,13 @@ +package com.example.survey.vo.inner; + +import lombok.Data; + +/** + * @author Pope + */ +@Data +public class UserInfo { + private String idNumber; + private String username; + private String phone; +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9f96606..3d7808a 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,3 +1,3 @@ spring: profiles: - active: prod + active: dev diff --git a/src/test/java/com/example/survey/controller/Init.http b/src/test/java/com/example/survey/controller/Init.http deleted file mode 100644 index 9b0f519..0000000 --- a/src/test/java/com/example/survey/controller/Init.http +++ /dev/null @@ -1,58 +0,0 @@ -#创建流调人员权限 -POST http://{{host}}:{{port}}{{prefix}}/role/role -Content-Type: application/json - -{ - "roleName": "流调人员", - "authList": [ - "查询调查记录的权限", - "提交调查记录权限", - "修改调查记录权限", - "删除调查记录权限", - "分析调查记录权限", - "查询流调人员信息的权限", - "增删改调查对象信息的权限", - "查询调查对象信息的权限" - ] -} - -### - -#创建管理员权限 -POST http://{{host}}:{{port}}{{prefix}}/role/role -Content-Type: application/json - -{ - "roleName": "管理员", - "authList": [ - "管理员" - ] -} - -### - -#注册用户 -POST http://{{host}}:{{port}}{{prefix}}/user/signup -Content-Type: application/json - -{ - "username": "cveo", - "phoneNumber": "123456789", - "password": "cveo123456" -} - -### - -#修改用户为管理员权限 -PUT http://{{host}}:{{port}}{{prefix}}/user/userRole -Content-Type:application/json - -{ - "phoneNumber": "123456789", - "roleNameList": [ - "管理员" - ] -} - -### - diff --git a/src/test/java/com/example/survey/controller/InvestigationRecordApi.http b/src/test/java/com/example/survey/controller/InvestigationRecordApi.http deleted file mode 100644 index 6f60c44..0000000 --- a/src/test/java/com/example/survey/controller/InvestigationRecordApi.http +++ /dev/null @@ -1,224 +0,0 @@ - -#提交调查记录 -POST http://localhost:8080/investigationRecord/investigationRecord -Content-Type: application/json -Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd - -{ - "questionnaireNumber": "001", - "idNumber": "420704200002270014", - "name": "Pope0", - "gender": "男", - "overseasCase": false, - "diseased": false, - "entryExperience": { - "areaOfResidence": "武汉市", - "areaOfAccess": "武汉市", - "nationality": "中国", - "passportNumber": "000000", - "entryPort": { - "province": "湖北省", - "port": "天河机场" - }, - "entryDate": "2021-1-28", - "transportation": "航班XXX" - }, - "wayOfBeingDiscovered": "否", - "dateOfAdmission": "2021-1-28", - "symptomAndSign": [ - "症状1", - "症状2" - ], - "existComplication": true, - "complication": [ - "并发症1", - "并发症2" - ], - "maxTemp": "36.5", - "existImagingFeatureOfPneumonia": true, - "testDate": "2021-1-28", - "dateOfDischarge": "2021-1-28", - "specificOccupation": "other", - "otherSpecificOccupation": "学生", - "workInformation": "否", - "otherWorkInformation": "", - "pregnant": false, - "pregnantWeek": 0, - "medicalHistory": [ - "病史1", - "病史2" - ], - "medicalHistoryDetail": "病史描述", - "nearSeriousRegion": false, - "contactWithSeriousRegionPatients": false, - "contactWithConfirmedCase": false, - "aggregationDisease": false, - "detectionList": [ - { - "name": "咽拭子", - "date": "2021-1-28", - "result": "阴性" - }, - { - "name": "鼻拭子", - "date": "2021-1-28", - "result": "阴性" - } - ], - "investigationCompany": "武汉大学", - "userPhone": "cveo", - "investigationDate": "2021-1-28", - "tempHistoryList": [ - { - "time": "2021-1-28:10:07:20", - "data": "36.5" - } - ], - "liveAndTravelHistoryList": [ - { - "type": [ - "居住史", - "旅行史" - ], - "beginTime": "2021-1-28", - "endTime": "2021-1-29", - "location": { - "msg": "鄂州市", - "longitude": 100, - "latitude": 100 - }, - "detail": "详细描述" - } - ], - "msg": "备注信息", - "urlMap":{ - "msg1": "url1", - "msg2": "url2" - } -} - -### -#查询调查记录 -GET http://localhost:8080/investigationRecord/underReviewRecord?currentPage=0&state=待审核 -Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd - -### -#查询未审核记录数量 -GET http://localhost:8080/investigationRecord/underReviewRecordCount?userPhone=cveo -Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd - - -### -PUT http://localhost:8080/investigationRecord/underReviewRecord -Content-Type: application/json -Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd - - -{ - "idNumber": "420704200002270014", - "pass": true, - "passInformation": "经审核通过", - "reviewerPhone": "cveo" -} - -### -#修改记录提交 -PUT http://localhost:8080/investigationRecord/investigationRecord -Content-Type: application/json -Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd - -{ - "questionnaireNumber": "001", - "idNumber": "420704200002270014", - "name": "Pope0", - "gender": "女", - "overseasCase": false, - "diseased": false, - "entryExperience": { - "areaOfResidence": "武汉市", - "areaOfAccess": "武汉市", - "nationality": "中国", - "passportNumber": "000000", - "entryPort": { - "province": "湖北省", - "port": "天河机场" - }, - "entryDate": "2021-1-28", - "transportation": "航班XXX" - }, - "wayOfBeingDiscovered": "否", - "dateOfAdmission": "2021-1-28", - "symptomAndSign": [ - "症状1", - "症状2" - ], - "existComplication": true, - "complication": [ - "并发症1", - "并发症2" - ], - "maxTemp": "36.5", - "existImagingFeatureOfPneumonia": true, - "testDate": "2021-1-28", - "dateOfDischarge": "2021-1-28", - "specificOccupation": "other", - "otherSpecificOccupation": "学生", - "workInformation": "否", - "otherWorkInformation": "", - "pregnant": false, - "pregnantWeek": 0, - "medicalHistory": [ - "病史1", - "病史2" - ], - "medicalHistoryDetail": "病史描述", - "nearSeriousRegion": false, - "contactWithSeriousRegionPatients": false, - "contactWithConfirmedCase": false, - "aggregationDisease": false, - "detectionList": [ - { - "name": "咽拭子", - "date": "2021-1-28", - "result": "阴性" - }, - { - "name": "鼻拭子", - "date": "2021-1-28", - "result": "阴性" - } - ], - "investigationCompany": "武汉大学", - "userPhone": "cveo", - "investigationDate": "2021-1-28", - "tempHistoryList": [ - { - "time": "2021-1-28:10:07:20", - "data": "36.5" - } - ], - "liveAndTravelHistoryList": [ - { - "type": [ - "居住史", - "旅行史" - ], - "beginTime": "2021-1-28", - "endTime": "2021-1-29", - "location": { - "msg": "鄂州市", - "longitude": 100, - "latitude": 100 - }, - "detail": "详细描述" - } - ], - "msg": "备注信息", - "urlMap":{ - "msg1": "url1", - "msg2": "url2" - } -} - -### -GET http://{{host}}:{{port}}{{prefix}}/investigationRecord/record2word?idNumber=420704200002270011 diff --git a/src/test/java/com/example/survey/controller/ProjectApi.http b/src/test/java/com/example/survey/controller/ProjectApi.http new file mode 100644 index 0000000..0def235 --- /dev/null +++ b/src/test/java/com/example/survey/controller/ProjectApi.http @@ -0,0 +1,49 @@ +#创建项目 +POST http://{{host}}:{{port}}{{prefix}}/project/project +Content-Type: application/json +Authorization: 123456 + +{ + "name": "测试项目2", + "detail": "测试项目描述", + "startTime": "2021-3-18 00:01:02", + "endTime": "2021-5-1 00:01:02" +} + +### + +#查询项目 +GET http://{{host}}:{{port}}{{prefix}}/project/project?name=测试项目¤tPage=0 + +### + +#查询调查数量总数与待调查对象数量 +GET http://{{host}}:{{port}}{{prefix}}/project/respondentCount?name=测试项目1 + +### + +#修改项目状态 +PUT http://{{host}}:{{port}}{{prefix}}/project/projectState +Content-Type: application/json +Authorization: xadw + +{ + "name": "测试项目1", + "state": "已完成" +} + +### + +#修改项目信息 +PUT http://{{host}}:{{port}}{{prefix}}/project/project +Content-Type: application/json +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 + +{ + "name": "测试项目1", + "detail": "修改后的描述", + "startTime": "2021-3-18 11:25:00", + "endTime": "2021-3-18 11:25:00" +} + + diff --git a/src/test/java/com/example/survey/controller/RecordApi.http b/src/test/java/com/example/survey/controller/RecordApi.http new file mode 100644 index 0000000..3d9acff --- /dev/null +++ b/src/test/java/com/example/survey/controller/RecordApi.http @@ -0,0 +1,61 @@ +#查询调查记录 +GET http://{{host}}:{{port}}{{prefix}}/record/record +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 + +### + +#提交调查记录 +POST http://{{host}}:{{port}}{{prefix}}/record/record +Content-Type: application/json +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 + +{ + "values": { + "questionnaireNumber": "", + "idNumber": "zzzzzzzzzz", + "name": "zzzzzz", + "gender": "男", + "age": 22, + "height": 180, + "weight": 70, + "address": { + "province": "北京市", + "city": "市辖区", + "county": "东城区" + }, + "工作单位": { + "province": "北京市", + "city": "市辖区", + "county": "东城区" + }, + "msg": "zccccccccccccccccccc", + "currentState": "初次感染", + "lastTime": "", + "lastState": "", + "临床严重程度": "轻型", + "wayOfBeingDiscovered": "", + "infectionTime": null, + "firstMedical": "", + "firstMedicalLevel": "", + "dateOfAdmission": "2021-03-18 17:37:19", + "dateOfDischarge": "2021-03-12 17:37:19", + "dateOfRecovery": null, + "msgOfRecovery": null, + "hasSyndrome": [], + "symptomAndSign": [], + "是否有并发症": false, + "并发症": [], + "是否隔离": false, + "隔离开始时间": false, + "是否到ICU治疗": false, + "example": "", + "血常规检测结果": "", + "胸部X线或CT检查": "", + "project": null, + "investigationCompany": "武汉大学" + }, + "idNumber": "zzzzzzzzzz", + "projectName": "zzzz", + "userPhone": "cveo" +} + diff --git a/src/test/java/com/example/survey/controller/RespondentApi.http b/src/test/java/com/example/survey/controller/RespondentApi.http index 3dd2a07..7575f10 100644 --- a/src/test/java/com/example/survey/controller/RespondentApi.http +++ b/src/test/java/com/example/survey/controller/RespondentApi.http @@ -1,17 +1,44 @@ -### - #创建调查对象 POST http://{{host}}:{{port}}{{prefix}}/respondent/respondent Content-Type: application/json -Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 { - "idNumber": "420704200002270014", - "phoneNumber": "13995833300", - "name": "Pope0", - "msg": "无备注", + "idNumber": "42070420000227000X", + "phone": "1399583330X", + "name": "PopeX", + "msg": "X号对象", + "userPhone": "cveo", + "gender": "男", + "administrativeArea": { + "province": "湖北省", + "city": "鄂州市", + "county": "鄂城区" + }, + "projectNameSet": [ + "111111" + ] +} + +### + +#查询调查对象 +GET http://{{host}}:{{port}}{{prefix}}/respondent/respondent?currentPage=0&city=鄂州市 +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 + +### + +#修改调查对象 +PUT http://{{host}}:{{port}}{{prefix}}/respondent/respondent +Content-Type: application/json +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 + +{ + "idNumber": "420704200002270001", + "phone": "1399583301", + "name": "Pope1", + "msg": "修改调查对象接口测试", "userPhone": "cveo", - "diseased": false, "gender": "男", "administrativeArea": { "province": "湖北省", @@ -22,7 +49,11 @@ Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd ### -#根据流调人员id分页查询待调查对象列表 -GET http://localhost:8080/respondent/respondent?userPhone=cveo&province=湖北省¤tPage=0 -Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd +#删除调查对象 +DELETE http://{{host}}:{{port}}{{prefix}}/respondent/respondent +Content-Type: application/json +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 +{ + "idNumber": "420704200002270001" +} diff --git a/src/test/java/com/example/survey/controller/RoleApi.http b/src/test/java/com/example/survey/controller/RoleApi.http new file mode 100644 index 0000000..fb37019 --- /dev/null +++ b/src/test/java/com/example/survey/controller/RoleApi.http @@ -0,0 +1,51 @@ +#添加角色 +POST http://{{host}}:{{port}}{{prefix}}/role/role +Content-Type: application/json +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 + +{ + "name": "测试角色", + "authoritySet": [ + "管理员", + "查询调查记录的权限", + "提交调查记录权限", + "修改调查记录权限" + ] +} + +### + +#查询角色列表 +GET http://{{host}}:{{port}}{{prefix}}/role/role?currentPage=0&name=测 +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 + +### + +#修改角色权限列表 +PUT http://{{host}}:{{port}}{{prefix}}/role/role +Content-Type: application/json +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 + +{ + "name": "测试角色", + "authoritySet": [ + "管理员" + ] +} + +### + +#删除角色 +DELETE http://{{host}}:{{port}}{{prefix}}/role/role +Content-Type: application/json +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 + +{ + "name": "测试角色" +} + +### + +#查看权限列表 +GET http://{{host}}:{{port}}{{prefix}}/role/authorityList +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 diff --git a/src/test/java/com/example/survey/controller/RoleControllerApi.http b/src/test/java/com/example/survey/controller/RoleControllerApi.http deleted file mode 100644 index 29ebe8a..0000000 --- a/src/test/java/com/example/survey/controller/RoleControllerApi.http +++ /dev/null @@ -1,79 +0,0 @@ - -#添加流调人员角色 -POST http://localhost:8080/role/role -Content-Type: application/json -Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd - -{ - "roleName": "测试角色", - "authList": [ - "查询调查记录的权限", - "提交调查记录权限", - "修改调查记录权限", - "删除调查记录权限", - "分析调查记录权限", - "查询流调人员信息的权限", - "增删改调查对象信息的权限", - "查询调查对象信息的权限" - ] -} - -### -#添加管理员角色 -POST http://localhost:8080/role/role -Content-Type: application/json - -{ - "roleName": "管理员", - "authList": [ - "管理员" - ] -} - -### -#添加测试角色 -POST http://{{host}}:{{port}}{{prefix}}/role/role -Content-Type: application/json -Authorization: 958efa46-44c3-4271-b44a-cc1b7e8e8d2e - -{ - "roleName": "测试角色", - "authList": [ - "管理员" - ] -} - -### -#查询角色 -GET http://{{host}}:{{port}}{{prefix}}/role/role?currentPage=0 -Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd - -### -#删除角色 -DELETE http://{{host}}:{{port}}{{prefix}}/role/role -Content-Type: application/json -Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd - -{ - "roleName": "测试角色" -} - - -### -#修改角色权限 -PUT http://{{host}}:{{port}}{{prefix}}/role/role -Content-Type: application/json -Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd - -{ - "roleName": "测试角色", - "authList": [ - "查询调查记录的权限" - ] -} - - - -### -GET http://{{host}}:{{port}}{{prefix}}/role/authList -Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd diff --git a/src/test/java/com/example/survey/controller/UserApi.http b/src/test/java/com/example/survey/controller/UserApi.http new file mode 100644 index 0000000..ece7c3b --- /dev/null +++ b/src/test/java/com/example/survey/controller/UserApi.http @@ -0,0 +1,86 @@ +#登录 +POST http://{{host}}:{{port}}{{prefix}}/user/login +Content-Type: application/json + +{ + "phone": "cveo", + "password": "cveo123456" +} + +### + +#管理员创建用户 +POST http://{{host}}:{{port}}{{prefix}}/user/user +Content-Type: application/json +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 + +{ + "idNumber": "4207042000227001X", + "username": "Pope10", + "phone": "13995833306", + "password": "13995833308", + "administrativeArea": { + "province": "湖北省", + "city": "鄂州市", + "county": "鄂城区" + } +} + +### + +#管理员修改用户信息 +PUT http://{{host}}:{{port}}{{prefix}}/user/userInfo +Content-Type: application/json +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 + +{ + "phone": "13995833308", + "username": "Pope8", + "idNumber": "4207042000022700118", + "administrativeArea": { + "province": "湖北省", + "city": "鄂州市", + "county": "鄂城区" + } +} + +### + +#管理员重置用户密码 +PUT http://{{host}}:{{port}}{{prefix}}/user/pwd +Content-Type: application/json +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 + +{ + "phone": "1399583330" +} + +### + +#管理员删除用户 +DELETE http://{{host}}:{{port}}{{prefix}}/user/user +Content-Type: application/json +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 + +{ + "phone": "13995833308" +} + +### + +#查询用户列表 +GET http://{{host}}:{{port}}{{prefix}}/user/user?username=Pope¤tPage=0 +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 +### + +#修改用户角色 +PUT http://{{host}}:{{port}}{{prefix}}/user/userRole +Content-Type: application/json +Authorization: 8f6b21a0-fa4b-4241-b5f7-58355048e1f9 + +{ + "phone": "13995833300", + "roleList": [ + "测试角色" + ] +} diff --git a/src/test/java/com/example/survey/controller/UserControllerApi.http b/src/test/java/com/example/survey/controller/UserControllerApi.http deleted file mode 100644 index cd114aa..0000000 --- a/src/test/java/com/example/survey/controller/UserControllerApi.http +++ /dev/null @@ -1,89 +0,0 @@ -#注册用户 -POST http://{{host}}:{{port}}{{prefix}}/user/signup -Content-Type: application/json - -{ - "username": "Pope0", - "phoneNumber": "13995833300", - "password": "13995833308" -} - -### - -#修改用户权限 -PUT http://{{host}}:{{port}}{{prefix}}/user/userRole -Content-Type:application/json -Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd - -{ - "phoneNumber": "13995833308", - "roleNameList": ["测试角色"] -} - -### -POST http://{{host}}:{{port}}{{prefix}}/user/login -Content-Type: application/json - -{ - "phoneNumber": "cveo", - "password": "cveo123456" -} - -### -GET http://{{host}}:{{port}}{{prefix}}/user/user?currentPage=0 -Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd - -### -DELETE http://{{host}}:{{port}}{{prefix}}/user/user -Content-Type: application/json -Authorization: 845a6d23-8d84-4a2d-85db-4f7e99c272bd - -{ - "phoneNumber": "13995833308" -} - -### - -#用户信息修改 -PUT http://{{host}}:{{port}}{{prefix}}/user/userInfo -Content-Type: application/json -Authorization: 8f54a7d3-b82b-4059-ab46-ac9eae545796 - -{ - "phoneNumber": "13995833308", - "username": "Pope", - "idNumber": "420704200002270011", - "administrativeArea": { - "province": "湖北省", - "city": "鄂州市" - } -} - -### - -#用户密码重置 -PUT http://{{host}}:{{port}}{{prefix}}/user/pwd -Content-Type: application/json -Authorization: 8f54a7d3-b82b-4059-ab46-ac9eae545796 - -{ - "phoneNumber": "13995833308" -} - -### - -#添加用户 -POST http://{{host}}:{{port}}{{prefix}}/user/user -Content-Type: application/json -Authorization: 8f54a7d3-b82b-4059-ab46-ac9eae545796 - -{ - "idNumber": "420704200002270010", - "username": "Pope0", - "phoneNumber": "139958333000", - "password": "139958333008", - "administrativeArea": { - "province": "湖北省", - "city": "鄂州市" - } -}