diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java index 3c5aa32..1ddc8a5 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java @@ -17,12 +17,12 @@ @ApiModelProperty(value = "检定环节,实验室名字", dataType = "String") private String measureSegment; @ApiModelProperty(value = "退回人员id", dataType = "Long") - private Long measurePersonId; + private Long sendBackPersonId; @ApiModelProperty(value = "退回人员名字", dataType = "String") - private String measurePerson; + private String sendBackPerson; @ApiModelProperty(value = "退回原因", dataType = "String") private String sendBackReason; @ApiModelProperty(value = "退回时间", dataType = "String") - private String updateTime; + private String sendBackTime; } diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java index 3c5aa32..1ddc8a5 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java @@ -17,12 +17,12 @@ @ApiModelProperty(value = "检定环节,实验室名字", dataType = "String") private String measureSegment; @ApiModelProperty(value = "退回人员id", dataType = "Long") - private Long measurePersonId; + private Long sendBackPersonId; @ApiModelProperty(value = "退回人员名字", dataType = "String") - private String measurePerson; + private String sendBackPerson; @ApiModelProperty(value = "退回原因", dataType = "String") private String sendBackReason; @ApiModelProperty(value = "退回时间", dataType = "String") - private String updateTime; + private String sendBackTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java new file mode 100644 index 0000000..a57ddd9 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java @@ -0,0 +1,24 @@ +package com.casic.missiles.dto.business; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 任务分发详情请求实体 + * @Author: wangpeng + * @Date: 2023/2/11 15:33 + */ +@Data +@ApiModel +public class SampleHandOutDetailRequest { + @NotNull(message = "委托书id不能为空") + @ApiModelProperty(value = "委托书id", dataType = "Long") + private Long orderId; + + @NotNull(message = "样品id不能为空") + @ApiModelProperty(value = "样品id", dataType = "Long") + private Long sampleId; +} diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java index 3c5aa32..1ddc8a5 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java @@ -17,12 +17,12 @@ @ApiModelProperty(value = "检定环节,实验室名字", dataType = "String") private String measureSegment; @ApiModelProperty(value = "退回人员id", dataType = "Long") - private Long measurePersonId; + private Long sendBackPersonId; @ApiModelProperty(value = "退回人员名字", dataType = "String") - private String measurePerson; + private String sendBackPerson; @ApiModelProperty(value = "退回原因", dataType = "String") private String sendBackReason; @ApiModelProperty(value = "退回时间", dataType = "String") - private String updateTime; + private String sendBackTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java new file mode 100644 index 0000000..a57ddd9 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java @@ -0,0 +1,24 @@ +package com.casic.missiles.dto.business; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 任务分发详情请求实体 + * @Author: wangpeng + * @Date: 2023/2/11 15:33 + */ +@Data +@ApiModel +public class SampleHandOutDetailRequest { + @NotNull(message = "委托书id不能为空") + @ApiModelProperty(value = "委托书id", dataType = "Long") + private Long orderId; + + @NotNull(message = "样品id不能为空") + @ApiModelProperty(value = "样品id", dataType = "Long") + private Long sampleId; +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java index 38b80e3..60621f1 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java @@ -48,37 +48,38 @@ private String customerName; @ApiModelProperty(value = "委托方电话", dataType = "String") - private String phone; + private String customerPhone; - @ApiModelProperty(value = "委托方邮编", dataType = "String") - private String postalCode; + //需求中有,建议去掉,否则多关联一张表 +// @ApiModelProperty(value = "委托方邮编", dataType = "String") +// private String postalCode; - @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") - private String addressCountry; - - @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") - private String addressProvince; - - @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") - private String addressCity; - - @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") - private String addressArea; +// @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") +// private String addressCountry; +// +// @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") +// private String addressProvince; +// +// @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") +// private String addressCity; +// +// @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") +// private String addressArea; @ApiModelProperty(value = "委托方公司地址-详细地址", dataType = "String") - private String fullAddress; + private String customerAddress; - @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") - private String addressCountryName; - - @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") - private String addressProvinceName; - - @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") - private String addressCityName; - - @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") - private String addressAreaName; +// @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") +// private String addressCountryName; +// +// @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") +// private String addressProvinceName; +// +// @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") +// private String addressCityName; +// +// @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") +// private String addressAreaName; @ApiModelProperty(value = "委托书id", dataType = "Long") private String orderId; diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java index 3c5aa32..1ddc8a5 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java @@ -17,12 +17,12 @@ @ApiModelProperty(value = "检定环节,实验室名字", dataType = "String") private String measureSegment; @ApiModelProperty(value = "退回人员id", dataType = "Long") - private Long measurePersonId; + private Long sendBackPersonId; @ApiModelProperty(value = "退回人员名字", dataType = "String") - private String measurePerson; + private String sendBackPerson; @ApiModelProperty(value = "退回原因", dataType = "String") private String sendBackReason; @ApiModelProperty(value = "退回时间", dataType = "String") - private String updateTime; + private String sendBackTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java new file mode 100644 index 0000000..a57ddd9 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java @@ -0,0 +1,24 @@ +package com.casic.missiles.dto.business; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 任务分发详情请求实体 + * @Author: wangpeng + * @Date: 2023/2/11 15:33 + */ +@Data +@ApiModel +public class SampleHandOutDetailRequest { + @NotNull(message = "委托书id不能为空") + @ApiModelProperty(value = "委托书id", dataType = "Long") + private Long orderId; + + @NotNull(message = "样品id不能为空") + @ApiModelProperty(value = "样品id", dataType = "Long") + private Long sampleId; +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java index 38b80e3..60621f1 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java @@ -48,37 +48,38 @@ private String customerName; @ApiModelProperty(value = "委托方电话", dataType = "String") - private String phone; + private String customerPhone; - @ApiModelProperty(value = "委托方邮编", dataType = "String") - private String postalCode; + //需求中有,建议去掉,否则多关联一张表 +// @ApiModelProperty(value = "委托方邮编", dataType = "String") +// private String postalCode; - @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") - private String addressCountry; - - @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") - private String addressProvince; - - @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") - private String addressCity; - - @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") - private String addressArea; +// @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") +// private String addressCountry; +// +// @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") +// private String addressProvince; +// +// @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") +// private String addressCity; +// +// @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") +// private String addressArea; @ApiModelProperty(value = "委托方公司地址-详细地址", dataType = "String") - private String fullAddress; + private String customerAddress; - @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") - private String addressCountryName; - - @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") - private String addressProvinceName; - - @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") - private String addressCityName; - - @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") - private String addressAreaName; +// @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") +// private String addressCountryName; +// +// @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") +// private String addressProvinceName; +// +// @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") +// private String addressCityName; +// +// @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") +// private String addressAreaName; @ApiModelProperty(value = "委托书id", dataType = "Long") private String orderId; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java new file mode 100644 index 0000000..7d9a4f5 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java @@ -0,0 +1,31 @@ +package com.casic.missiles.dto.meter; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 培训计划签到请求实体 + * @Author: wangpeng + * @Date: 2023/02/11 17:59 + */ +@ApiModel +@Data +public class TrainPlanSignInRequest { + /** + * 培训计划表id + */ + @NotNull(message = "培训计划表id不能为空") + @ApiModelProperty(value = "培训计划表id", dataType = "Long") + private Long planId; + + /** + * 计量人员表id + */ + @NotNull(message = "培训学员id不能为空") + @ApiModelProperty(value = "计量人员表id", dataType = "Long", required = true) + private Long staffId; + +} diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java index 3c5aa32..1ddc8a5 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java @@ -17,12 +17,12 @@ @ApiModelProperty(value = "检定环节,实验室名字", dataType = "String") private String measureSegment; @ApiModelProperty(value = "退回人员id", dataType = "Long") - private Long measurePersonId; + private Long sendBackPersonId; @ApiModelProperty(value = "退回人员名字", dataType = "String") - private String measurePerson; + private String sendBackPerson; @ApiModelProperty(value = "退回原因", dataType = "String") private String sendBackReason; @ApiModelProperty(value = "退回时间", dataType = "String") - private String updateTime; + private String sendBackTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java new file mode 100644 index 0000000..a57ddd9 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java @@ -0,0 +1,24 @@ +package com.casic.missiles.dto.business; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 任务分发详情请求实体 + * @Author: wangpeng + * @Date: 2023/2/11 15:33 + */ +@Data +@ApiModel +public class SampleHandOutDetailRequest { + @NotNull(message = "委托书id不能为空") + @ApiModelProperty(value = "委托书id", dataType = "Long") + private Long orderId; + + @NotNull(message = "样品id不能为空") + @ApiModelProperty(value = "样品id", dataType = "Long") + private Long sampleId; +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java index 38b80e3..60621f1 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java @@ -48,37 +48,38 @@ private String customerName; @ApiModelProperty(value = "委托方电话", dataType = "String") - private String phone; + private String customerPhone; - @ApiModelProperty(value = "委托方邮编", dataType = "String") - private String postalCode; + //需求中有,建议去掉,否则多关联一张表 +// @ApiModelProperty(value = "委托方邮编", dataType = "String") +// private String postalCode; - @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") - private String addressCountry; - - @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") - private String addressProvince; - - @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") - private String addressCity; - - @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") - private String addressArea; +// @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") +// private String addressCountry; +// +// @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") +// private String addressProvince; +// +// @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") +// private String addressCity; +// +// @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") +// private String addressArea; @ApiModelProperty(value = "委托方公司地址-详细地址", dataType = "String") - private String fullAddress; + private String customerAddress; - @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") - private String addressCountryName; - - @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") - private String addressProvinceName; - - @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") - private String addressCityName; - - @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") - private String addressAreaName; +// @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") +// private String addressCountryName; +// +// @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") +// private String addressProvinceName; +// +// @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") +// private String addressCityName; +// +// @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") +// private String addressAreaName; @ApiModelProperty(value = "委托书id", dataType = "Long") private String orderId; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java new file mode 100644 index 0000000..7d9a4f5 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java @@ -0,0 +1,31 @@ +package com.casic.missiles.dto.meter; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 培训计划签到请求实体 + * @Author: wangpeng + * @Date: 2023/02/11 17:59 + */ +@ApiModel +@Data +public class TrainPlanSignInRequest { + /** + * 培训计划表id + */ + @NotNull(message = "培训计划表id不能为空") + @ApiModelProperty(value = "培训计划表id", dataType = "Long") + private Long planId; + + /** + * 计量人员表id + */ + @NotNull(message = "培训学员id不能为空") + @ApiModelProperty(value = "计量人员表id", dataType = "Long", required = true) + private Long staffId; + +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java index 945baab..cf25b82 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java @@ -54,6 +54,21 @@ @TableField("measure_status") private String measureStatus; + /** + * 操作/退回人员(可能是部门负责人or检定人) + */ + @TableField("operate_person_id") + private Long operatePersonId; + + @TableField("operate_person_name") + private String operatePersonName; + + /** + * 退回原因 + */ + @TableField("operate_reason") + private String operateReason; + @TableField("create_time") private String createTime; diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java index 3c5aa32..1ddc8a5 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java @@ -17,12 +17,12 @@ @ApiModelProperty(value = "检定环节,实验室名字", dataType = "String") private String measureSegment; @ApiModelProperty(value = "退回人员id", dataType = "Long") - private Long measurePersonId; + private Long sendBackPersonId; @ApiModelProperty(value = "退回人员名字", dataType = "String") - private String measurePerson; + private String sendBackPerson; @ApiModelProperty(value = "退回原因", dataType = "String") private String sendBackReason; @ApiModelProperty(value = "退回时间", dataType = "String") - private String updateTime; + private String sendBackTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java new file mode 100644 index 0000000..a57ddd9 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java @@ -0,0 +1,24 @@ +package com.casic.missiles.dto.business; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 任务分发详情请求实体 + * @Author: wangpeng + * @Date: 2023/2/11 15:33 + */ +@Data +@ApiModel +public class SampleHandOutDetailRequest { + @NotNull(message = "委托书id不能为空") + @ApiModelProperty(value = "委托书id", dataType = "Long") + private Long orderId; + + @NotNull(message = "样品id不能为空") + @ApiModelProperty(value = "样品id", dataType = "Long") + private Long sampleId; +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java index 38b80e3..60621f1 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java @@ -48,37 +48,38 @@ private String customerName; @ApiModelProperty(value = "委托方电话", dataType = "String") - private String phone; + private String customerPhone; - @ApiModelProperty(value = "委托方邮编", dataType = "String") - private String postalCode; + //需求中有,建议去掉,否则多关联一张表 +// @ApiModelProperty(value = "委托方邮编", dataType = "String") +// private String postalCode; - @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") - private String addressCountry; - - @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") - private String addressProvince; - - @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") - private String addressCity; - - @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") - private String addressArea; +// @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") +// private String addressCountry; +// +// @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") +// private String addressProvince; +// +// @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") +// private String addressCity; +// +// @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") +// private String addressArea; @ApiModelProperty(value = "委托方公司地址-详细地址", dataType = "String") - private String fullAddress; + private String customerAddress; - @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") - private String addressCountryName; - - @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") - private String addressProvinceName; - - @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") - private String addressCityName; - - @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") - private String addressAreaName; +// @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") +// private String addressCountryName; +// +// @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") +// private String addressProvinceName; +// +// @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") +// private String addressCityName; +// +// @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") +// private String addressAreaName; @ApiModelProperty(value = "委托书id", dataType = "Long") private String orderId; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java new file mode 100644 index 0000000..7d9a4f5 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java @@ -0,0 +1,31 @@ +package com.casic.missiles.dto.meter; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 培训计划签到请求实体 + * @Author: wangpeng + * @Date: 2023/02/11 17:59 + */ +@ApiModel +@Data +public class TrainPlanSignInRequest { + /** + * 培训计划表id + */ + @NotNull(message = "培训计划表id不能为空") + @ApiModelProperty(value = "培训计划表id", dataType = "Long") + private Long planId; + + /** + * 计量人员表id + */ + @NotNull(message = "培训学员id不能为空") + @ApiModelProperty(value = "计量人员表id", dataType = "Long", required = true) + private Long staffId; + +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java index 945baab..cf25b82 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java @@ -54,6 +54,21 @@ @TableField("measure_status") private String measureStatus; + /** + * 操作/退回人员(可能是部门负责人or检定人) + */ + @TableField("operate_person_id") + private Long operatePersonId; + + @TableField("operate_person_name") + private String operatePersonName; + + /** + * 退回原因 + */ + @TableField("operate_reason") + private String operateReason; + @TableField("create_time") private String createTime; diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java index 9add926..09c5074 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java @@ -3,11 +3,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.casic.missiles.dto.IdDTO; -import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; -import com.casic.missiles.dto.business.SampleHandOutDetailResponse; -import com.casic.missiles.dto.business.SampleHandOutListRequest; -import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.*; import com.casic.missiles.enums.CurrentSegmentEnum; import com.casic.missiles.enums.HandOutPropertyEnum; import com.casic.missiles.enums.MeasureStatusEnum; @@ -108,12 +104,15 @@ } @Override - public SampleHandOutDetailResponse handOutListDetail(IdDTO idDTO) { + public SampleHandOutDetailResponse handOutListDetail(SampleHandOutDetailRequest handOutDetailRequest) { //根据样品id和委托书id查询样品、委托书、委托方 - SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetailById(idDTO.getId()); - - //查询检定流程、退回信息 - return null; + SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetail(handOutDetailRequest); + //根据样品id和委托书id查询检定流程、退回信息 + List measureProcessDTOS = labExecutiveInfoMapper.selectExecutiveList(handOutDetailRequest); + List measureSendBackDTOS = labExecutiveOperateLogMapper.selectExecutiveOperateLogList(handOutDetailRequest); + sampleDetail.setMeasureProcessList(measureProcessDTOS); + sampleDetail.setMeasureSendBackList(measureSendBackDTOS); + return sampleDetail; } diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java index 3c5aa32..1ddc8a5 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java @@ -17,12 +17,12 @@ @ApiModelProperty(value = "检定环节,实验室名字", dataType = "String") private String measureSegment; @ApiModelProperty(value = "退回人员id", dataType = "Long") - private Long measurePersonId; + private Long sendBackPersonId; @ApiModelProperty(value = "退回人员名字", dataType = "String") - private String measurePerson; + private String sendBackPerson; @ApiModelProperty(value = "退回原因", dataType = "String") private String sendBackReason; @ApiModelProperty(value = "退回时间", dataType = "String") - private String updateTime; + private String sendBackTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java new file mode 100644 index 0000000..a57ddd9 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java @@ -0,0 +1,24 @@ +package com.casic.missiles.dto.business; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 任务分发详情请求实体 + * @Author: wangpeng + * @Date: 2023/2/11 15:33 + */ +@Data +@ApiModel +public class SampleHandOutDetailRequest { + @NotNull(message = "委托书id不能为空") + @ApiModelProperty(value = "委托书id", dataType = "Long") + private Long orderId; + + @NotNull(message = "样品id不能为空") + @ApiModelProperty(value = "样品id", dataType = "Long") + private Long sampleId; +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java index 38b80e3..60621f1 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java @@ -48,37 +48,38 @@ private String customerName; @ApiModelProperty(value = "委托方电话", dataType = "String") - private String phone; + private String customerPhone; - @ApiModelProperty(value = "委托方邮编", dataType = "String") - private String postalCode; + //需求中有,建议去掉,否则多关联一张表 +// @ApiModelProperty(value = "委托方邮编", dataType = "String") +// private String postalCode; - @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") - private String addressCountry; - - @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") - private String addressProvince; - - @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") - private String addressCity; - - @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") - private String addressArea; +// @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") +// private String addressCountry; +// +// @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") +// private String addressProvince; +// +// @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") +// private String addressCity; +// +// @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") +// private String addressArea; @ApiModelProperty(value = "委托方公司地址-详细地址", dataType = "String") - private String fullAddress; + private String customerAddress; - @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") - private String addressCountryName; - - @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") - private String addressProvinceName; - - @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") - private String addressCityName; - - @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") - private String addressAreaName; +// @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") +// private String addressCountryName; +// +// @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") +// private String addressProvinceName; +// +// @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") +// private String addressCityName; +// +// @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") +// private String addressAreaName; @ApiModelProperty(value = "委托书id", dataType = "Long") private String orderId; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java new file mode 100644 index 0000000..7d9a4f5 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java @@ -0,0 +1,31 @@ +package com.casic.missiles.dto.meter; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 培训计划签到请求实体 + * @Author: wangpeng + * @Date: 2023/02/11 17:59 + */ +@ApiModel +@Data +public class TrainPlanSignInRequest { + /** + * 培训计划表id + */ + @NotNull(message = "培训计划表id不能为空") + @ApiModelProperty(value = "培训计划表id", dataType = "Long") + private Long planId; + + /** + * 计量人员表id + */ + @NotNull(message = "培训学员id不能为空") + @ApiModelProperty(value = "计量人员表id", dataType = "Long", required = true) + private Long staffId; + +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java index 945baab..cf25b82 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java @@ -54,6 +54,21 @@ @TableField("measure_status") private String measureStatus; + /** + * 操作/退回人员(可能是部门负责人or检定人) + */ + @TableField("operate_person_id") + private Long operatePersonId; + + @TableField("operate_person_name") + private String operatePersonName; + + /** + * 退回原因 + */ + @TableField("operate_reason") + private String operateReason; + @TableField("create_time") private String createTime; diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java index 9add926..09c5074 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java @@ -3,11 +3,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.casic.missiles.dto.IdDTO; -import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; -import com.casic.missiles.dto.business.SampleHandOutDetailResponse; -import com.casic.missiles.dto.business.SampleHandOutListRequest; -import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.*; import com.casic.missiles.enums.CurrentSegmentEnum; import com.casic.missiles.enums.HandOutPropertyEnum; import com.casic.missiles.enums.MeasureStatusEnum; @@ -108,12 +104,15 @@ } @Override - public SampleHandOutDetailResponse handOutListDetail(IdDTO idDTO) { + public SampleHandOutDetailResponse handOutListDetail(SampleHandOutDetailRequest handOutDetailRequest) { //根据样品id和委托书id查询样品、委托书、委托方 - SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetailById(idDTO.getId()); - - //查询检定流程、退回信息 - return null; + SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetail(handOutDetailRequest); + //根据样品id和委托书id查询检定流程、退回信息 + List measureProcessDTOS = labExecutiveInfoMapper.selectExecutiveList(handOutDetailRequest); + List measureSendBackDTOS = labExecutiveOperateLogMapper.selectExecutiveOperateLogList(handOutDetailRequest); + sampleDetail.setMeasureProcessList(measureProcessDTOS); + sampleDetail.setMeasureSendBackList(measureSendBackDTOS); + return sampleDetail; } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java index 57bb3a9..59b2809 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java @@ -121,7 +121,6 @@ equipmentApply.setApprovalStatus(ApprovalStatusEnum.FAILED_REJECT); } } - // todo 如果查全部,怎么设置审批状态 if(ApprovalStatusEnum.TO_BE_APPROVED.equals(status)){ equipmentApply.setTaskId(taskMap.get(equipmentApply.getId().toString())); } diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java index 3c5aa32..1ddc8a5 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java @@ -17,12 +17,12 @@ @ApiModelProperty(value = "检定环节,实验室名字", dataType = "String") private String measureSegment; @ApiModelProperty(value = "退回人员id", dataType = "Long") - private Long measurePersonId; + private Long sendBackPersonId; @ApiModelProperty(value = "退回人员名字", dataType = "String") - private String measurePerson; + private String sendBackPerson; @ApiModelProperty(value = "退回原因", dataType = "String") private String sendBackReason; @ApiModelProperty(value = "退回时间", dataType = "String") - private String updateTime; + private String sendBackTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java new file mode 100644 index 0000000..a57ddd9 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java @@ -0,0 +1,24 @@ +package com.casic.missiles.dto.business; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 任务分发详情请求实体 + * @Author: wangpeng + * @Date: 2023/2/11 15:33 + */ +@Data +@ApiModel +public class SampleHandOutDetailRequest { + @NotNull(message = "委托书id不能为空") + @ApiModelProperty(value = "委托书id", dataType = "Long") + private Long orderId; + + @NotNull(message = "样品id不能为空") + @ApiModelProperty(value = "样品id", dataType = "Long") + private Long sampleId; +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java index 38b80e3..60621f1 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java @@ -48,37 +48,38 @@ private String customerName; @ApiModelProperty(value = "委托方电话", dataType = "String") - private String phone; + private String customerPhone; - @ApiModelProperty(value = "委托方邮编", dataType = "String") - private String postalCode; + //需求中有,建议去掉,否则多关联一张表 +// @ApiModelProperty(value = "委托方邮编", dataType = "String") +// private String postalCode; - @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") - private String addressCountry; - - @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") - private String addressProvince; - - @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") - private String addressCity; - - @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") - private String addressArea; +// @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") +// private String addressCountry; +// +// @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") +// private String addressProvince; +// +// @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") +// private String addressCity; +// +// @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") +// private String addressArea; @ApiModelProperty(value = "委托方公司地址-详细地址", dataType = "String") - private String fullAddress; + private String customerAddress; - @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") - private String addressCountryName; - - @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") - private String addressProvinceName; - - @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") - private String addressCityName; - - @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") - private String addressAreaName; +// @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") +// private String addressCountryName; +// +// @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") +// private String addressProvinceName; +// +// @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") +// private String addressCityName; +// +// @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") +// private String addressAreaName; @ApiModelProperty(value = "委托书id", dataType = "Long") private String orderId; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java new file mode 100644 index 0000000..7d9a4f5 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java @@ -0,0 +1,31 @@ +package com.casic.missiles.dto.meter; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 培训计划签到请求实体 + * @Author: wangpeng + * @Date: 2023/02/11 17:59 + */ +@ApiModel +@Data +public class TrainPlanSignInRequest { + /** + * 培训计划表id + */ + @NotNull(message = "培训计划表id不能为空") + @ApiModelProperty(value = "培训计划表id", dataType = "Long") + private Long planId; + + /** + * 计量人员表id + */ + @NotNull(message = "培训学员id不能为空") + @ApiModelProperty(value = "计量人员表id", dataType = "Long", required = true) + private Long staffId; + +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java index 945baab..cf25b82 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java @@ -54,6 +54,21 @@ @TableField("measure_status") private String measureStatus; + /** + * 操作/退回人员(可能是部门负责人or检定人) + */ + @TableField("operate_person_id") + private Long operatePersonId; + + @TableField("operate_person_name") + private String operatePersonName; + + /** + * 退回原因 + */ + @TableField("operate_reason") + private String operateReason; + @TableField("create_time") private String createTime; diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java index 9add926..09c5074 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java @@ -3,11 +3,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.casic.missiles.dto.IdDTO; -import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; -import com.casic.missiles.dto.business.SampleHandOutDetailResponse; -import com.casic.missiles.dto.business.SampleHandOutListRequest; -import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.*; import com.casic.missiles.enums.CurrentSegmentEnum; import com.casic.missiles.enums.HandOutPropertyEnum; import com.casic.missiles.enums.MeasureStatusEnum; @@ -108,12 +104,15 @@ } @Override - public SampleHandOutDetailResponse handOutListDetail(IdDTO idDTO) { + public SampleHandOutDetailResponse handOutListDetail(SampleHandOutDetailRequest handOutDetailRequest) { //根据样品id和委托书id查询样品、委托书、委托方 - SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetailById(idDTO.getId()); - - //查询检定流程、退回信息 - return null; + SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetail(handOutDetailRequest); + //根据样品id和委托书id查询检定流程、退回信息 + List measureProcessDTOS = labExecutiveInfoMapper.selectExecutiveList(handOutDetailRequest); + List measureSendBackDTOS = labExecutiveOperateLogMapper.selectExecutiveOperateLogList(handOutDetailRequest); + sampleDetail.setMeasureProcessList(measureProcessDTOS); + sampleDetail.setMeasureSendBackList(measureSendBackDTOS); + return sampleDetail; } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java index 57bb3a9..59b2809 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java @@ -121,7 +121,6 @@ equipmentApply.setApprovalStatus(ApprovalStatusEnum.FAILED_REJECT); } } - // todo 如果查全部,怎么设置审批状态 if(ApprovalStatusEnum.TO_BE_APPROVED.equals(status)){ equipmentApply.setTaskId(taskMap.get(equipmentApply.getId().toString())); } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java index 9159410..82cae83 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java @@ -18,6 +18,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterCertificateExpireMessageMapper; import com.casic.missiles.mapper.meter.MeterCertificateMapper; import com.casic.missiles.mapper.meter.MeterStaffMapper; @@ -149,7 +150,7 @@ if(messageMapper.update(null, updateWrapper)>0){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java index 3c5aa32..1ddc8a5 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java @@ -17,12 +17,12 @@ @ApiModelProperty(value = "检定环节,实验室名字", dataType = "String") private String measureSegment; @ApiModelProperty(value = "退回人员id", dataType = "Long") - private Long measurePersonId; + private Long sendBackPersonId; @ApiModelProperty(value = "退回人员名字", dataType = "String") - private String measurePerson; + private String sendBackPerson; @ApiModelProperty(value = "退回原因", dataType = "String") private String sendBackReason; @ApiModelProperty(value = "退回时间", dataType = "String") - private String updateTime; + private String sendBackTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java new file mode 100644 index 0000000..a57ddd9 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java @@ -0,0 +1,24 @@ +package com.casic.missiles.dto.business; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 任务分发详情请求实体 + * @Author: wangpeng + * @Date: 2023/2/11 15:33 + */ +@Data +@ApiModel +public class SampleHandOutDetailRequest { + @NotNull(message = "委托书id不能为空") + @ApiModelProperty(value = "委托书id", dataType = "Long") + private Long orderId; + + @NotNull(message = "样品id不能为空") + @ApiModelProperty(value = "样品id", dataType = "Long") + private Long sampleId; +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java index 38b80e3..60621f1 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java @@ -48,37 +48,38 @@ private String customerName; @ApiModelProperty(value = "委托方电话", dataType = "String") - private String phone; + private String customerPhone; - @ApiModelProperty(value = "委托方邮编", dataType = "String") - private String postalCode; + //需求中有,建议去掉,否则多关联一张表 +// @ApiModelProperty(value = "委托方邮编", dataType = "String") +// private String postalCode; - @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") - private String addressCountry; - - @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") - private String addressProvince; - - @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") - private String addressCity; - - @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") - private String addressArea; +// @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") +// private String addressCountry; +// +// @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") +// private String addressProvince; +// +// @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") +// private String addressCity; +// +// @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") +// private String addressArea; @ApiModelProperty(value = "委托方公司地址-详细地址", dataType = "String") - private String fullAddress; + private String customerAddress; - @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") - private String addressCountryName; - - @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") - private String addressProvinceName; - - @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") - private String addressCityName; - - @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") - private String addressAreaName; +// @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") +// private String addressCountryName; +// +// @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") +// private String addressProvinceName; +// +// @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") +// private String addressCityName; +// +// @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") +// private String addressAreaName; @ApiModelProperty(value = "委托书id", dataType = "Long") private String orderId; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java new file mode 100644 index 0000000..7d9a4f5 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java @@ -0,0 +1,31 @@ +package com.casic.missiles.dto.meter; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 培训计划签到请求实体 + * @Author: wangpeng + * @Date: 2023/02/11 17:59 + */ +@ApiModel +@Data +public class TrainPlanSignInRequest { + /** + * 培训计划表id + */ + @NotNull(message = "培训计划表id不能为空") + @ApiModelProperty(value = "培训计划表id", dataType = "Long") + private Long planId; + + /** + * 计量人员表id + */ + @NotNull(message = "培训学员id不能为空") + @ApiModelProperty(value = "计量人员表id", dataType = "Long", required = true) + private Long staffId; + +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java index 945baab..cf25b82 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java @@ -54,6 +54,21 @@ @TableField("measure_status") private String measureStatus; + /** + * 操作/退回人员(可能是部门负责人or检定人) + */ + @TableField("operate_person_id") + private Long operatePersonId; + + @TableField("operate_person_name") + private String operatePersonName; + + /** + * 退回原因 + */ + @TableField("operate_reason") + private String operateReason; + @TableField("create_time") private String createTime; diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java index 9add926..09c5074 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java @@ -3,11 +3,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.casic.missiles.dto.IdDTO; -import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; -import com.casic.missiles.dto.business.SampleHandOutDetailResponse; -import com.casic.missiles.dto.business.SampleHandOutListRequest; -import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.*; import com.casic.missiles.enums.CurrentSegmentEnum; import com.casic.missiles.enums.HandOutPropertyEnum; import com.casic.missiles.enums.MeasureStatusEnum; @@ -108,12 +104,15 @@ } @Override - public SampleHandOutDetailResponse handOutListDetail(IdDTO idDTO) { + public SampleHandOutDetailResponse handOutListDetail(SampleHandOutDetailRequest handOutDetailRequest) { //根据样品id和委托书id查询样品、委托书、委托方 - SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetailById(idDTO.getId()); - - //查询检定流程、退回信息 - return null; + SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetail(handOutDetailRequest); + //根据样品id和委托书id查询检定流程、退回信息 + List measureProcessDTOS = labExecutiveInfoMapper.selectExecutiveList(handOutDetailRequest); + List measureSendBackDTOS = labExecutiveOperateLogMapper.selectExecutiveOperateLogList(handOutDetailRequest); + sampleDetail.setMeasureProcessList(measureProcessDTOS); + sampleDetail.setMeasureSendBackList(measureSendBackDTOS); + return sampleDetail; } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java index 57bb3a9..59b2809 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java @@ -121,7 +121,6 @@ equipmentApply.setApprovalStatus(ApprovalStatusEnum.FAILED_REJECT); } } - // todo 如果查全部,怎么设置审批状态 if(ApprovalStatusEnum.TO_BE_APPROVED.equals(status)){ equipmentApply.setTaskId(taskMap.get(equipmentApply.getId().toString())); } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java index 9159410..82cae83 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java @@ -18,6 +18,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterCertificateExpireMessageMapper; import com.casic.missiles.mapper.meter.MeterCertificateMapper; import com.casic.missiles.mapper.meter.MeterStaffMapper; @@ -149,7 +150,7 @@ if(messageMapper.update(null, updateWrapper)>0){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java index 34c92ea..33611bd 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java @@ -10,8 +10,10 @@ import com.casic.missiles.dto.meter.OrganizeListRequest; import com.casic.missiles.dto.meter.ParentDeptRequest; import com.casic.missiles.dto.meter.ParentDeptResponse; +import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.MeterDeptTypeEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterOrganizeMapper; import com.casic.missiles.model.meter.MeterOrganize; import com.casic.missiles.modular.system.model.Dept; @@ -147,7 +149,7 @@ if(organizeMapper.updateById(meterOrganize) > 0 && success){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } private QueryWrapper getWrapper(OrganizeListRequest request) { diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java index 3c5aa32..1ddc8a5 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java @@ -17,12 +17,12 @@ @ApiModelProperty(value = "检定环节,实验室名字", dataType = "String") private String measureSegment; @ApiModelProperty(value = "退回人员id", dataType = "Long") - private Long measurePersonId; + private Long sendBackPersonId; @ApiModelProperty(value = "退回人员名字", dataType = "String") - private String measurePerson; + private String sendBackPerson; @ApiModelProperty(value = "退回原因", dataType = "String") private String sendBackReason; @ApiModelProperty(value = "退回时间", dataType = "String") - private String updateTime; + private String sendBackTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java new file mode 100644 index 0000000..a57ddd9 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java @@ -0,0 +1,24 @@ +package com.casic.missiles.dto.business; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 任务分发详情请求实体 + * @Author: wangpeng + * @Date: 2023/2/11 15:33 + */ +@Data +@ApiModel +public class SampleHandOutDetailRequest { + @NotNull(message = "委托书id不能为空") + @ApiModelProperty(value = "委托书id", dataType = "Long") + private Long orderId; + + @NotNull(message = "样品id不能为空") + @ApiModelProperty(value = "样品id", dataType = "Long") + private Long sampleId; +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java index 38b80e3..60621f1 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java @@ -48,37 +48,38 @@ private String customerName; @ApiModelProperty(value = "委托方电话", dataType = "String") - private String phone; + private String customerPhone; - @ApiModelProperty(value = "委托方邮编", dataType = "String") - private String postalCode; + //需求中有,建议去掉,否则多关联一张表 +// @ApiModelProperty(value = "委托方邮编", dataType = "String") +// private String postalCode; - @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") - private String addressCountry; - - @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") - private String addressProvince; - - @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") - private String addressCity; - - @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") - private String addressArea; +// @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") +// private String addressCountry; +// +// @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") +// private String addressProvince; +// +// @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") +// private String addressCity; +// +// @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") +// private String addressArea; @ApiModelProperty(value = "委托方公司地址-详细地址", dataType = "String") - private String fullAddress; + private String customerAddress; - @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") - private String addressCountryName; - - @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") - private String addressProvinceName; - - @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") - private String addressCityName; - - @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") - private String addressAreaName; +// @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") +// private String addressCountryName; +// +// @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") +// private String addressProvinceName; +// +// @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") +// private String addressCityName; +// +// @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") +// private String addressAreaName; @ApiModelProperty(value = "委托书id", dataType = "Long") private String orderId; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java new file mode 100644 index 0000000..7d9a4f5 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java @@ -0,0 +1,31 @@ +package com.casic.missiles.dto.meter; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 培训计划签到请求实体 + * @Author: wangpeng + * @Date: 2023/02/11 17:59 + */ +@ApiModel +@Data +public class TrainPlanSignInRequest { + /** + * 培训计划表id + */ + @NotNull(message = "培训计划表id不能为空") + @ApiModelProperty(value = "培训计划表id", dataType = "Long") + private Long planId; + + /** + * 计量人员表id + */ + @NotNull(message = "培训学员id不能为空") + @ApiModelProperty(value = "计量人员表id", dataType = "Long", required = true) + private Long staffId; + +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java index 945baab..cf25b82 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java @@ -54,6 +54,21 @@ @TableField("measure_status") private String measureStatus; + /** + * 操作/退回人员(可能是部门负责人or检定人) + */ + @TableField("operate_person_id") + private Long operatePersonId; + + @TableField("operate_person_name") + private String operatePersonName; + + /** + * 退回原因 + */ + @TableField("operate_reason") + private String operateReason; + @TableField("create_time") private String createTime; diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java index 9add926..09c5074 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java @@ -3,11 +3,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.casic.missiles.dto.IdDTO; -import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; -import com.casic.missiles.dto.business.SampleHandOutDetailResponse; -import com.casic.missiles.dto.business.SampleHandOutListRequest; -import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.*; import com.casic.missiles.enums.CurrentSegmentEnum; import com.casic.missiles.enums.HandOutPropertyEnum; import com.casic.missiles.enums.MeasureStatusEnum; @@ -108,12 +104,15 @@ } @Override - public SampleHandOutDetailResponse handOutListDetail(IdDTO idDTO) { + public SampleHandOutDetailResponse handOutListDetail(SampleHandOutDetailRequest handOutDetailRequest) { //根据样品id和委托书id查询样品、委托书、委托方 - SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetailById(idDTO.getId()); - - //查询检定流程、退回信息 - return null; + SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetail(handOutDetailRequest); + //根据样品id和委托书id查询检定流程、退回信息 + List measureProcessDTOS = labExecutiveInfoMapper.selectExecutiveList(handOutDetailRequest); + List measureSendBackDTOS = labExecutiveOperateLogMapper.selectExecutiveOperateLogList(handOutDetailRequest); + sampleDetail.setMeasureProcessList(measureProcessDTOS); + sampleDetail.setMeasureSendBackList(measureSendBackDTOS); + return sampleDetail; } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java index 57bb3a9..59b2809 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java @@ -121,7 +121,6 @@ equipmentApply.setApprovalStatus(ApprovalStatusEnum.FAILED_REJECT); } } - // todo 如果查全部,怎么设置审批状态 if(ApprovalStatusEnum.TO_BE_APPROVED.equals(status)){ equipmentApply.setTaskId(taskMap.get(equipmentApply.getId().toString())); } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java index 9159410..82cae83 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java @@ -18,6 +18,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterCertificateExpireMessageMapper; import com.casic.missiles.mapper.meter.MeterCertificateMapper; import com.casic.missiles.mapper.meter.MeterStaffMapper; @@ -149,7 +150,7 @@ if(messageMapper.update(null, updateWrapper)>0){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java index 34c92ea..33611bd 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java @@ -10,8 +10,10 @@ import com.casic.missiles.dto.meter.OrganizeListRequest; import com.casic.missiles.dto.meter.ParentDeptRequest; import com.casic.missiles.dto.meter.ParentDeptResponse; +import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.MeterDeptTypeEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterOrganizeMapper; import com.casic.missiles.model.meter.MeterOrganize; import com.casic.missiles.modular.system.model.Dept; @@ -147,7 +149,7 @@ if(organizeMapper.updateById(meterOrganize) > 0 && success){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } private QueryWrapper getWrapper(OrganizeListRequest request) { diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java index 393696e..48096c1 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java @@ -14,6 +14,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterPriceCategoryMapper; import com.casic.missiles.mapper.meter.MeterPriceItemMapper; import com.casic.missiles.mapper.meter.MeterPriceMapper; @@ -87,7 +88,7 @@ if(meterPriceMapper.insert(meterPrice)>0){ return ReturnUtil.success(); }else{ - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } } return ReturnUtil.failed("价格库新增失败"); diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java index 3c5aa32..1ddc8a5 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java @@ -17,12 +17,12 @@ @ApiModelProperty(value = "检定环节,实验室名字", dataType = "String") private String measureSegment; @ApiModelProperty(value = "退回人员id", dataType = "Long") - private Long measurePersonId; + private Long sendBackPersonId; @ApiModelProperty(value = "退回人员名字", dataType = "String") - private String measurePerson; + private String sendBackPerson; @ApiModelProperty(value = "退回原因", dataType = "String") private String sendBackReason; @ApiModelProperty(value = "退回时间", dataType = "String") - private String updateTime; + private String sendBackTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java new file mode 100644 index 0000000..a57ddd9 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java @@ -0,0 +1,24 @@ +package com.casic.missiles.dto.business; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 任务分发详情请求实体 + * @Author: wangpeng + * @Date: 2023/2/11 15:33 + */ +@Data +@ApiModel +public class SampleHandOutDetailRequest { + @NotNull(message = "委托书id不能为空") + @ApiModelProperty(value = "委托书id", dataType = "Long") + private Long orderId; + + @NotNull(message = "样品id不能为空") + @ApiModelProperty(value = "样品id", dataType = "Long") + private Long sampleId; +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java index 38b80e3..60621f1 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java @@ -48,37 +48,38 @@ private String customerName; @ApiModelProperty(value = "委托方电话", dataType = "String") - private String phone; + private String customerPhone; - @ApiModelProperty(value = "委托方邮编", dataType = "String") - private String postalCode; + //需求中有,建议去掉,否则多关联一张表 +// @ApiModelProperty(value = "委托方邮编", dataType = "String") +// private String postalCode; - @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") - private String addressCountry; - - @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") - private String addressProvince; - - @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") - private String addressCity; - - @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") - private String addressArea; +// @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") +// private String addressCountry; +// +// @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") +// private String addressProvince; +// +// @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") +// private String addressCity; +// +// @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") +// private String addressArea; @ApiModelProperty(value = "委托方公司地址-详细地址", dataType = "String") - private String fullAddress; + private String customerAddress; - @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") - private String addressCountryName; - - @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") - private String addressProvinceName; - - @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") - private String addressCityName; - - @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") - private String addressAreaName; +// @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") +// private String addressCountryName; +// +// @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") +// private String addressProvinceName; +// +// @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") +// private String addressCityName; +// +// @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") +// private String addressAreaName; @ApiModelProperty(value = "委托书id", dataType = "Long") private String orderId; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java new file mode 100644 index 0000000..7d9a4f5 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java @@ -0,0 +1,31 @@ +package com.casic.missiles.dto.meter; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 培训计划签到请求实体 + * @Author: wangpeng + * @Date: 2023/02/11 17:59 + */ +@ApiModel +@Data +public class TrainPlanSignInRequest { + /** + * 培训计划表id + */ + @NotNull(message = "培训计划表id不能为空") + @ApiModelProperty(value = "培训计划表id", dataType = "Long") + private Long planId; + + /** + * 计量人员表id + */ + @NotNull(message = "培训学员id不能为空") + @ApiModelProperty(value = "计量人员表id", dataType = "Long", required = true) + private Long staffId; + +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java index 945baab..cf25b82 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java @@ -54,6 +54,21 @@ @TableField("measure_status") private String measureStatus; + /** + * 操作/退回人员(可能是部门负责人or检定人) + */ + @TableField("operate_person_id") + private Long operatePersonId; + + @TableField("operate_person_name") + private String operatePersonName; + + /** + * 退回原因 + */ + @TableField("operate_reason") + private String operateReason; + @TableField("create_time") private String createTime; diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java index 9add926..09c5074 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java @@ -3,11 +3,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.casic.missiles.dto.IdDTO; -import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; -import com.casic.missiles.dto.business.SampleHandOutDetailResponse; -import com.casic.missiles.dto.business.SampleHandOutListRequest; -import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.*; import com.casic.missiles.enums.CurrentSegmentEnum; import com.casic.missiles.enums.HandOutPropertyEnum; import com.casic.missiles.enums.MeasureStatusEnum; @@ -108,12 +104,15 @@ } @Override - public SampleHandOutDetailResponse handOutListDetail(IdDTO idDTO) { + public SampleHandOutDetailResponse handOutListDetail(SampleHandOutDetailRequest handOutDetailRequest) { //根据样品id和委托书id查询样品、委托书、委托方 - SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetailById(idDTO.getId()); - - //查询检定流程、退回信息 - return null; + SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetail(handOutDetailRequest); + //根据样品id和委托书id查询检定流程、退回信息 + List measureProcessDTOS = labExecutiveInfoMapper.selectExecutiveList(handOutDetailRequest); + List measureSendBackDTOS = labExecutiveOperateLogMapper.selectExecutiveOperateLogList(handOutDetailRequest); + sampleDetail.setMeasureProcessList(measureProcessDTOS); + sampleDetail.setMeasureSendBackList(measureSendBackDTOS); + return sampleDetail; } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java index 57bb3a9..59b2809 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java @@ -121,7 +121,6 @@ equipmentApply.setApprovalStatus(ApprovalStatusEnum.FAILED_REJECT); } } - // todo 如果查全部,怎么设置审批状态 if(ApprovalStatusEnum.TO_BE_APPROVED.equals(status)){ equipmentApply.setTaskId(taskMap.get(equipmentApply.getId().toString())); } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java index 9159410..82cae83 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java @@ -18,6 +18,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterCertificateExpireMessageMapper; import com.casic.missiles.mapper.meter.MeterCertificateMapper; import com.casic.missiles.mapper.meter.MeterStaffMapper; @@ -149,7 +150,7 @@ if(messageMapper.update(null, updateWrapper)>0){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java index 34c92ea..33611bd 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java @@ -10,8 +10,10 @@ import com.casic.missiles.dto.meter.OrganizeListRequest; import com.casic.missiles.dto.meter.ParentDeptRequest; import com.casic.missiles.dto.meter.ParentDeptResponse; +import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.MeterDeptTypeEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterOrganizeMapper; import com.casic.missiles.model.meter.MeterOrganize; import com.casic.missiles.modular.system.model.Dept; @@ -147,7 +149,7 @@ if(organizeMapper.updateById(meterOrganize) > 0 && success){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } private QueryWrapper getWrapper(OrganizeListRequest request) { diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java index 393696e..48096c1 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java @@ -14,6 +14,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterPriceCategoryMapper; import com.casic.missiles.mapper.meter.MeterPriceItemMapper; import com.casic.missiles.mapper.meter.MeterPriceMapper; @@ -87,7 +88,7 @@ if(meterPriceMapper.insert(meterPrice)>0){ return ReturnUtil.success(); }else{ - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } } return ReturnUtil.failed("价格库新增失败"); diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java index e4d5cb9..664d965 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java @@ -16,6 +16,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterCertificateMapper; import com.casic.missiles.mapper.meter.MeterStaffMapper; import com.casic.missiles.mapper.sys.UserInfoMapper; @@ -185,7 +186,7 @@ }else{ return ReturnUtil.failed("人员信息编辑失败"); } } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java index 3c5aa32..1ddc8a5 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java @@ -17,12 +17,12 @@ @ApiModelProperty(value = "检定环节,实验室名字", dataType = "String") private String measureSegment; @ApiModelProperty(value = "退回人员id", dataType = "Long") - private Long measurePersonId; + private Long sendBackPersonId; @ApiModelProperty(value = "退回人员名字", dataType = "String") - private String measurePerson; + private String sendBackPerson; @ApiModelProperty(value = "退回原因", dataType = "String") private String sendBackReason; @ApiModelProperty(value = "退回时间", dataType = "String") - private String updateTime; + private String sendBackTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java new file mode 100644 index 0000000..a57ddd9 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java @@ -0,0 +1,24 @@ +package com.casic.missiles.dto.business; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 任务分发详情请求实体 + * @Author: wangpeng + * @Date: 2023/2/11 15:33 + */ +@Data +@ApiModel +public class SampleHandOutDetailRequest { + @NotNull(message = "委托书id不能为空") + @ApiModelProperty(value = "委托书id", dataType = "Long") + private Long orderId; + + @NotNull(message = "样品id不能为空") + @ApiModelProperty(value = "样品id", dataType = "Long") + private Long sampleId; +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java index 38b80e3..60621f1 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java @@ -48,37 +48,38 @@ private String customerName; @ApiModelProperty(value = "委托方电话", dataType = "String") - private String phone; + private String customerPhone; - @ApiModelProperty(value = "委托方邮编", dataType = "String") - private String postalCode; + //需求中有,建议去掉,否则多关联一张表 +// @ApiModelProperty(value = "委托方邮编", dataType = "String") +// private String postalCode; - @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") - private String addressCountry; - - @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") - private String addressProvince; - - @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") - private String addressCity; - - @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") - private String addressArea; +// @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") +// private String addressCountry; +// +// @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") +// private String addressProvince; +// +// @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") +// private String addressCity; +// +// @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") +// private String addressArea; @ApiModelProperty(value = "委托方公司地址-详细地址", dataType = "String") - private String fullAddress; + private String customerAddress; - @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") - private String addressCountryName; - - @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") - private String addressProvinceName; - - @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") - private String addressCityName; - - @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") - private String addressAreaName; +// @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") +// private String addressCountryName; +// +// @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") +// private String addressProvinceName; +// +// @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") +// private String addressCityName; +// +// @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") +// private String addressAreaName; @ApiModelProperty(value = "委托书id", dataType = "Long") private String orderId; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java new file mode 100644 index 0000000..7d9a4f5 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java @@ -0,0 +1,31 @@ +package com.casic.missiles.dto.meter; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 培训计划签到请求实体 + * @Author: wangpeng + * @Date: 2023/02/11 17:59 + */ +@ApiModel +@Data +public class TrainPlanSignInRequest { + /** + * 培训计划表id + */ + @NotNull(message = "培训计划表id不能为空") + @ApiModelProperty(value = "培训计划表id", dataType = "Long") + private Long planId; + + /** + * 计量人员表id + */ + @NotNull(message = "培训学员id不能为空") + @ApiModelProperty(value = "计量人员表id", dataType = "Long", required = true) + private Long staffId; + +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java index 945baab..cf25b82 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java @@ -54,6 +54,21 @@ @TableField("measure_status") private String measureStatus; + /** + * 操作/退回人员(可能是部门负责人or检定人) + */ + @TableField("operate_person_id") + private Long operatePersonId; + + @TableField("operate_person_name") + private String operatePersonName; + + /** + * 退回原因 + */ + @TableField("operate_reason") + private String operateReason; + @TableField("create_time") private String createTime; diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java index 9add926..09c5074 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java @@ -3,11 +3,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.casic.missiles.dto.IdDTO; -import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; -import com.casic.missiles.dto.business.SampleHandOutDetailResponse; -import com.casic.missiles.dto.business.SampleHandOutListRequest; -import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.*; import com.casic.missiles.enums.CurrentSegmentEnum; import com.casic.missiles.enums.HandOutPropertyEnum; import com.casic.missiles.enums.MeasureStatusEnum; @@ -108,12 +104,15 @@ } @Override - public SampleHandOutDetailResponse handOutListDetail(IdDTO idDTO) { + public SampleHandOutDetailResponse handOutListDetail(SampleHandOutDetailRequest handOutDetailRequest) { //根据样品id和委托书id查询样品、委托书、委托方 - SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetailById(idDTO.getId()); - - //查询检定流程、退回信息 - return null; + SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetail(handOutDetailRequest); + //根据样品id和委托书id查询检定流程、退回信息 + List measureProcessDTOS = labExecutiveInfoMapper.selectExecutiveList(handOutDetailRequest); + List measureSendBackDTOS = labExecutiveOperateLogMapper.selectExecutiveOperateLogList(handOutDetailRequest); + sampleDetail.setMeasureProcessList(measureProcessDTOS); + sampleDetail.setMeasureSendBackList(measureSendBackDTOS); + return sampleDetail; } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java index 57bb3a9..59b2809 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java @@ -121,7 +121,6 @@ equipmentApply.setApprovalStatus(ApprovalStatusEnum.FAILED_REJECT); } } - // todo 如果查全部,怎么设置审批状态 if(ApprovalStatusEnum.TO_BE_APPROVED.equals(status)){ equipmentApply.setTaskId(taskMap.get(equipmentApply.getId().toString())); } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java index 9159410..82cae83 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java @@ -18,6 +18,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterCertificateExpireMessageMapper; import com.casic.missiles.mapper.meter.MeterCertificateMapper; import com.casic.missiles.mapper.meter.MeterStaffMapper; @@ -149,7 +150,7 @@ if(messageMapper.update(null, updateWrapper)>0){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java index 34c92ea..33611bd 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java @@ -10,8 +10,10 @@ import com.casic.missiles.dto.meter.OrganizeListRequest; import com.casic.missiles.dto.meter.ParentDeptRequest; import com.casic.missiles.dto.meter.ParentDeptResponse; +import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.MeterDeptTypeEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterOrganizeMapper; import com.casic.missiles.model.meter.MeterOrganize; import com.casic.missiles.modular.system.model.Dept; @@ -147,7 +149,7 @@ if(organizeMapper.updateById(meterOrganize) > 0 && success){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } private QueryWrapper getWrapper(OrganizeListRequest request) { diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java index 393696e..48096c1 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java @@ -14,6 +14,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterPriceCategoryMapper; import com.casic.missiles.mapper.meter.MeterPriceItemMapper; import com.casic.missiles.mapper.meter.MeterPriceMapper; @@ -87,7 +88,7 @@ if(meterPriceMapper.insert(meterPrice)>0){ return ReturnUtil.success(); }else{ - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } } return ReturnUtil.failed("价格库新增失败"); diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java index e4d5cb9..664d965 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java @@ -16,6 +16,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterCertificateMapper; import com.casic.missiles.mapper.meter.MeterStaffMapper; import com.casic.missiles.mapper.sys.UserInfoMapper; @@ -185,7 +186,7 @@ }else{ return ReturnUtil.failed("人员信息编辑失败"); } } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java index 2a79b51..0fd9403 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java @@ -9,6 +9,8 @@ import com.casic.missiles.dto.meter.TrainLogDetailResponse; import com.casic.missiles.dto.meter.TrainLogListRequest; import com.casic.missiles.dto.meter.TrainLogUpdateRequest; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterTrainLogMapper; import com.casic.missiles.mapper.meter.MeterTrainStaffMapper; import com.casic.missiles.model.meter.MeterTrainLog; @@ -79,7 +81,7 @@ if(insertFlag > 0 && updateFlag > 0){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java index 3c5aa32..1ddc8a5 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java @@ -17,12 +17,12 @@ @ApiModelProperty(value = "检定环节,实验室名字", dataType = "String") private String measureSegment; @ApiModelProperty(value = "退回人员id", dataType = "Long") - private Long measurePersonId; + private Long sendBackPersonId; @ApiModelProperty(value = "退回人员名字", dataType = "String") - private String measurePerson; + private String sendBackPerson; @ApiModelProperty(value = "退回原因", dataType = "String") private String sendBackReason; @ApiModelProperty(value = "退回时间", dataType = "String") - private String updateTime; + private String sendBackTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java new file mode 100644 index 0000000..a57ddd9 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java @@ -0,0 +1,24 @@ +package com.casic.missiles.dto.business; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 任务分发详情请求实体 + * @Author: wangpeng + * @Date: 2023/2/11 15:33 + */ +@Data +@ApiModel +public class SampleHandOutDetailRequest { + @NotNull(message = "委托书id不能为空") + @ApiModelProperty(value = "委托书id", dataType = "Long") + private Long orderId; + + @NotNull(message = "样品id不能为空") + @ApiModelProperty(value = "样品id", dataType = "Long") + private Long sampleId; +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java index 38b80e3..60621f1 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java @@ -48,37 +48,38 @@ private String customerName; @ApiModelProperty(value = "委托方电话", dataType = "String") - private String phone; + private String customerPhone; - @ApiModelProperty(value = "委托方邮编", dataType = "String") - private String postalCode; + //需求中有,建议去掉,否则多关联一张表 +// @ApiModelProperty(value = "委托方邮编", dataType = "String") +// private String postalCode; - @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") - private String addressCountry; - - @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") - private String addressProvince; - - @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") - private String addressCity; - - @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") - private String addressArea; +// @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") +// private String addressCountry; +// +// @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") +// private String addressProvince; +// +// @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") +// private String addressCity; +// +// @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") +// private String addressArea; @ApiModelProperty(value = "委托方公司地址-详细地址", dataType = "String") - private String fullAddress; + private String customerAddress; - @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") - private String addressCountryName; - - @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") - private String addressProvinceName; - - @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") - private String addressCityName; - - @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") - private String addressAreaName; +// @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") +// private String addressCountryName; +// +// @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") +// private String addressProvinceName; +// +// @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") +// private String addressCityName; +// +// @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") +// private String addressAreaName; @ApiModelProperty(value = "委托书id", dataType = "Long") private String orderId; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java new file mode 100644 index 0000000..7d9a4f5 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java @@ -0,0 +1,31 @@ +package com.casic.missiles.dto.meter; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 培训计划签到请求实体 + * @Author: wangpeng + * @Date: 2023/02/11 17:59 + */ +@ApiModel +@Data +public class TrainPlanSignInRequest { + /** + * 培训计划表id + */ + @NotNull(message = "培训计划表id不能为空") + @ApiModelProperty(value = "培训计划表id", dataType = "Long") + private Long planId; + + /** + * 计量人员表id + */ + @NotNull(message = "培训学员id不能为空") + @ApiModelProperty(value = "计量人员表id", dataType = "Long", required = true) + private Long staffId; + +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java index 945baab..cf25b82 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java @@ -54,6 +54,21 @@ @TableField("measure_status") private String measureStatus; + /** + * 操作/退回人员(可能是部门负责人or检定人) + */ + @TableField("operate_person_id") + private Long operatePersonId; + + @TableField("operate_person_name") + private String operatePersonName; + + /** + * 退回原因 + */ + @TableField("operate_reason") + private String operateReason; + @TableField("create_time") private String createTime; diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java index 9add926..09c5074 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java @@ -3,11 +3,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.casic.missiles.dto.IdDTO; -import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; -import com.casic.missiles.dto.business.SampleHandOutDetailResponse; -import com.casic.missiles.dto.business.SampleHandOutListRequest; -import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.*; import com.casic.missiles.enums.CurrentSegmentEnum; import com.casic.missiles.enums.HandOutPropertyEnum; import com.casic.missiles.enums.MeasureStatusEnum; @@ -108,12 +104,15 @@ } @Override - public SampleHandOutDetailResponse handOutListDetail(IdDTO idDTO) { + public SampleHandOutDetailResponse handOutListDetail(SampleHandOutDetailRequest handOutDetailRequest) { //根据样品id和委托书id查询样品、委托书、委托方 - SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetailById(idDTO.getId()); - - //查询检定流程、退回信息 - return null; + SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetail(handOutDetailRequest); + //根据样品id和委托书id查询检定流程、退回信息 + List measureProcessDTOS = labExecutiveInfoMapper.selectExecutiveList(handOutDetailRequest); + List measureSendBackDTOS = labExecutiveOperateLogMapper.selectExecutiveOperateLogList(handOutDetailRequest); + sampleDetail.setMeasureProcessList(measureProcessDTOS); + sampleDetail.setMeasureSendBackList(measureSendBackDTOS); + return sampleDetail; } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java index 57bb3a9..59b2809 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java @@ -121,7 +121,6 @@ equipmentApply.setApprovalStatus(ApprovalStatusEnum.FAILED_REJECT); } } - // todo 如果查全部,怎么设置审批状态 if(ApprovalStatusEnum.TO_BE_APPROVED.equals(status)){ equipmentApply.setTaskId(taskMap.get(equipmentApply.getId().toString())); } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java index 9159410..82cae83 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java @@ -18,6 +18,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterCertificateExpireMessageMapper; import com.casic.missiles.mapper.meter.MeterCertificateMapper; import com.casic.missiles.mapper.meter.MeterStaffMapper; @@ -149,7 +150,7 @@ if(messageMapper.update(null, updateWrapper)>0){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java index 34c92ea..33611bd 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java @@ -10,8 +10,10 @@ import com.casic.missiles.dto.meter.OrganizeListRequest; import com.casic.missiles.dto.meter.ParentDeptRequest; import com.casic.missiles.dto.meter.ParentDeptResponse; +import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.MeterDeptTypeEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterOrganizeMapper; import com.casic.missiles.model.meter.MeterOrganize; import com.casic.missiles.modular.system.model.Dept; @@ -147,7 +149,7 @@ if(organizeMapper.updateById(meterOrganize) > 0 && success){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } private QueryWrapper getWrapper(OrganizeListRequest request) { diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java index 393696e..48096c1 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java @@ -14,6 +14,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterPriceCategoryMapper; import com.casic.missiles.mapper.meter.MeterPriceItemMapper; import com.casic.missiles.mapper.meter.MeterPriceMapper; @@ -87,7 +88,7 @@ if(meterPriceMapper.insert(meterPrice)>0){ return ReturnUtil.success(); }else{ - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } } return ReturnUtil.failed("价格库新增失败"); diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java index e4d5cb9..664d965 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java @@ -16,6 +16,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterCertificateMapper; import com.casic.missiles.mapper.meter.MeterStaffMapper; import com.casic.missiles.mapper.sys.UserInfoMapper; @@ -185,7 +186,7 @@ }else{ return ReturnUtil.failed("人员信息编辑失败"); } } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java index 2a79b51..0fd9403 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java @@ -9,6 +9,8 @@ import com.casic.missiles.dto.meter.TrainLogDetailResponse; import com.casic.missiles.dto.meter.TrainLogListRequest; import com.casic.missiles.dto.meter.TrainLogUpdateRequest; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterTrainLogMapper; import com.casic.missiles.mapper.meter.MeterTrainStaffMapper; import com.casic.missiles.model.meter.MeterTrainLog; @@ -79,7 +81,7 @@ if(insertFlag > 0 && updateFlag > 0){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainPlanServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainPlanServiceImpl.java index 3dbecc0..35a7098 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainPlanServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainPlanServiceImpl.java @@ -19,6 +19,7 @@ import com.casic.missiles.enums.MeterDictEnum; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterTrainPlanMapper; +import com.casic.missiles.mapper.meter.MeterTrainStaffMapper; import com.casic.missiles.model.meter.MeterTrainPlan; import com.casic.missiles.model.meter.MeterTrainStaff; import com.casic.missiles.model.response.ResponseData; @@ -30,6 +31,7 @@ import com.casic.missiles.service.meter.IMeterTrainStaffService; import com.casic.missiles.utils.ConvertUtils; import com.casic.missiles.utils.NumberGeneratorUtil; +import com.casic.missiles.utils.QRCodeUtil; import org.apache.commons.lang3.StringUtils; import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; @@ -57,6 +59,8 @@ @Autowired private MeterTrainPlanMapper trainPlanMapper; @Autowired + private MeterTrainStaffMapper trainStaffMapper; + @Autowired private IMeterTrainStaffService trainStaffService; @Resource private AbstractDictService dictService; @@ -244,6 +248,22 @@ return ReturnUtil.success(planResponse); } + @Override + public ReturnDTO planQrCode(Long id) { + String base64QRCode = QRCodeUtil.getBase64QRCode(String.valueOf(id)); + return ReturnUtil.success(base64QRCode); + } + + @Override + public ReturnDTO signIn(TrainPlanSignInRequest request) { + //更新培训计划员工考核结果 + int updateFlag = trainStaffMapper.updateStaffForSignIn(request); + if(updateFlag > 0){ + return ReturnUtil.success(); + } + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); + } + private List handleApprovalStatus(Page page, TrainPlanApprovalListRequest request) { List approvalList = new ArrayList<>(); List businessKeys = new ArrayList<>(); diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java index 3c5aa32..1ddc8a5 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java @@ -17,12 +17,12 @@ @ApiModelProperty(value = "检定环节,实验室名字", dataType = "String") private String measureSegment; @ApiModelProperty(value = "退回人员id", dataType = "Long") - private Long measurePersonId; + private Long sendBackPersonId; @ApiModelProperty(value = "退回人员名字", dataType = "String") - private String measurePerson; + private String sendBackPerson; @ApiModelProperty(value = "退回原因", dataType = "String") private String sendBackReason; @ApiModelProperty(value = "退回时间", dataType = "String") - private String updateTime; + private String sendBackTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java new file mode 100644 index 0000000..a57ddd9 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java @@ -0,0 +1,24 @@ +package com.casic.missiles.dto.business; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 任务分发详情请求实体 + * @Author: wangpeng + * @Date: 2023/2/11 15:33 + */ +@Data +@ApiModel +public class SampleHandOutDetailRequest { + @NotNull(message = "委托书id不能为空") + @ApiModelProperty(value = "委托书id", dataType = "Long") + private Long orderId; + + @NotNull(message = "样品id不能为空") + @ApiModelProperty(value = "样品id", dataType = "Long") + private Long sampleId; +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java index 38b80e3..60621f1 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java @@ -48,37 +48,38 @@ private String customerName; @ApiModelProperty(value = "委托方电话", dataType = "String") - private String phone; + private String customerPhone; - @ApiModelProperty(value = "委托方邮编", dataType = "String") - private String postalCode; + //需求中有,建议去掉,否则多关联一张表 +// @ApiModelProperty(value = "委托方邮编", dataType = "String") +// private String postalCode; - @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") - private String addressCountry; - - @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") - private String addressProvince; - - @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") - private String addressCity; - - @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") - private String addressArea; +// @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") +// private String addressCountry; +// +// @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") +// private String addressProvince; +// +// @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") +// private String addressCity; +// +// @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") +// private String addressArea; @ApiModelProperty(value = "委托方公司地址-详细地址", dataType = "String") - private String fullAddress; + private String customerAddress; - @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") - private String addressCountryName; - - @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") - private String addressProvinceName; - - @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") - private String addressCityName; - - @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") - private String addressAreaName; +// @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") +// private String addressCountryName; +// +// @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") +// private String addressProvinceName; +// +// @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") +// private String addressCityName; +// +// @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") +// private String addressAreaName; @ApiModelProperty(value = "委托书id", dataType = "Long") private String orderId; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java new file mode 100644 index 0000000..7d9a4f5 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java @@ -0,0 +1,31 @@ +package com.casic.missiles.dto.meter; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 培训计划签到请求实体 + * @Author: wangpeng + * @Date: 2023/02/11 17:59 + */ +@ApiModel +@Data +public class TrainPlanSignInRequest { + /** + * 培训计划表id + */ + @NotNull(message = "培训计划表id不能为空") + @ApiModelProperty(value = "培训计划表id", dataType = "Long") + private Long planId; + + /** + * 计量人员表id + */ + @NotNull(message = "培训学员id不能为空") + @ApiModelProperty(value = "计量人员表id", dataType = "Long", required = true) + private Long staffId; + +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java index 945baab..cf25b82 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java @@ -54,6 +54,21 @@ @TableField("measure_status") private String measureStatus; + /** + * 操作/退回人员(可能是部门负责人or检定人) + */ + @TableField("operate_person_id") + private Long operatePersonId; + + @TableField("operate_person_name") + private String operatePersonName; + + /** + * 退回原因 + */ + @TableField("operate_reason") + private String operateReason; + @TableField("create_time") private String createTime; diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java index 9add926..09c5074 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java @@ -3,11 +3,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.casic.missiles.dto.IdDTO; -import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; -import com.casic.missiles.dto.business.SampleHandOutDetailResponse; -import com.casic.missiles.dto.business.SampleHandOutListRequest; -import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.*; import com.casic.missiles.enums.CurrentSegmentEnum; import com.casic.missiles.enums.HandOutPropertyEnum; import com.casic.missiles.enums.MeasureStatusEnum; @@ -108,12 +104,15 @@ } @Override - public SampleHandOutDetailResponse handOutListDetail(IdDTO idDTO) { + public SampleHandOutDetailResponse handOutListDetail(SampleHandOutDetailRequest handOutDetailRequest) { //根据样品id和委托书id查询样品、委托书、委托方 - SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetailById(idDTO.getId()); - - //查询检定流程、退回信息 - return null; + SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetail(handOutDetailRequest); + //根据样品id和委托书id查询检定流程、退回信息 + List measureProcessDTOS = labExecutiveInfoMapper.selectExecutiveList(handOutDetailRequest); + List measureSendBackDTOS = labExecutiveOperateLogMapper.selectExecutiveOperateLogList(handOutDetailRequest); + sampleDetail.setMeasureProcessList(measureProcessDTOS); + sampleDetail.setMeasureSendBackList(measureSendBackDTOS); + return sampleDetail; } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java index 57bb3a9..59b2809 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java @@ -121,7 +121,6 @@ equipmentApply.setApprovalStatus(ApprovalStatusEnum.FAILED_REJECT); } } - // todo 如果查全部,怎么设置审批状态 if(ApprovalStatusEnum.TO_BE_APPROVED.equals(status)){ equipmentApply.setTaskId(taskMap.get(equipmentApply.getId().toString())); } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java index 9159410..82cae83 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java @@ -18,6 +18,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterCertificateExpireMessageMapper; import com.casic.missiles.mapper.meter.MeterCertificateMapper; import com.casic.missiles.mapper.meter.MeterStaffMapper; @@ -149,7 +150,7 @@ if(messageMapper.update(null, updateWrapper)>0){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java index 34c92ea..33611bd 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java @@ -10,8 +10,10 @@ import com.casic.missiles.dto.meter.OrganizeListRequest; import com.casic.missiles.dto.meter.ParentDeptRequest; import com.casic.missiles.dto.meter.ParentDeptResponse; +import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.MeterDeptTypeEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterOrganizeMapper; import com.casic.missiles.model.meter.MeterOrganize; import com.casic.missiles.modular.system.model.Dept; @@ -147,7 +149,7 @@ if(organizeMapper.updateById(meterOrganize) > 0 && success){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } private QueryWrapper getWrapper(OrganizeListRequest request) { diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java index 393696e..48096c1 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java @@ -14,6 +14,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterPriceCategoryMapper; import com.casic.missiles.mapper.meter.MeterPriceItemMapper; import com.casic.missiles.mapper.meter.MeterPriceMapper; @@ -87,7 +88,7 @@ if(meterPriceMapper.insert(meterPrice)>0){ return ReturnUtil.success(); }else{ - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } } return ReturnUtil.failed("价格库新增失败"); diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java index e4d5cb9..664d965 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java @@ -16,6 +16,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterCertificateMapper; import com.casic.missiles.mapper.meter.MeterStaffMapper; import com.casic.missiles.mapper.sys.UserInfoMapper; @@ -185,7 +186,7 @@ }else{ return ReturnUtil.failed("人员信息编辑失败"); } } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java index 2a79b51..0fd9403 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java @@ -9,6 +9,8 @@ import com.casic.missiles.dto.meter.TrainLogDetailResponse; import com.casic.missiles.dto.meter.TrainLogListRequest; import com.casic.missiles.dto.meter.TrainLogUpdateRequest; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterTrainLogMapper; import com.casic.missiles.mapper.meter.MeterTrainStaffMapper; import com.casic.missiles.model.meter.MeterTrainLog; @@ -79,7 +81,7 @@ if(insertFlag > 0 && updateFlag > 0){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainPlanServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainPlanServiceImpl.java index 3dbecc0..35a7098 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainPlanServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainPlanServiceImpl.java @@ -19,6 +19,7 @@ import com.casic.missiles.enums.MeterDictEnum; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterTrainPlanMapper; +import com.casic.missiles.mapper.meter.MeterTrainStaffMapper; import com.casic.missiles.model.meter.MeterTrainPlan; import com.casic.missiles.model.meter.MeterTrainStaff; import com.casic.missiles.model.response.ResponseData; @@ -30,6 +31,7 @@ import com.casic.missiles.service.meter.IMeterTrainStaffService; import com.casic.missiles.utils.ConvertUtils; import com.casic.missiles.utils.NumberGeneratorUtil; +import com.casic.missiles.utils.QRCodeUtil; import org.apache.commons.lang3.StringUtils; import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; @@ -57,6 +59,8 @@ @Autowired private MeterTrainPlanMapper trainPlanMapper; @Autowired + private MeterTrainStaffMapper trainStaffMapper; + @Autowired private IMeterTrainStaffService trainStaffService; @Resource private AbstractDictService dictService; @@ -244,6 +248,22 @@ return ReturnUtil.success(planResponse); } + @Override + public ReturnDTO planQrCode(Long id) { + String base64QRCode = QRCodeUtil.getBase64QRCode(String.valueOf(id)); + return ReturnUtil.success(base64QRCode); + } + + @Override + public ReturnDTO signIn(TrainPlanSignInRequest request) { + //更新培训计划员工考核结果 + int updateFlag = trainStaffMapper.updateStaffForSignIn(request); + if(updateFlag > 0){ + return ReturnUtil.success(); + } + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); + } + private List handleApprovalStatus(Page page, TrainPlanApprovalListRequest request) { List approvalList = new ArrayList<>(); List businessKeys = new ArrayList<>(); diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/business/IBusinessLabExecutiveInfoService.java b/casic-metering-service/src/main/java/com/casic/missiles/service/business/IBusinessLabExecutiveInfoService.java index 570127e..c286be6 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/business/IBusinessLabExecutiveInfoService.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/business/IBusinessLabExecutiveInfoService.java @@ -2,10 +2,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; /** @@ -20,5 +20,5 @@ Page handOutListPage(Page page, SampleHandOutListRequest handOutListRequest) throws Exception; - SampleHandOutDetailResponse handOutListDetail(IdDTO idDTO); + SampleHandOutDetailResponse handOutListDetail(SampleHandOutDetailRequest SampleHandOutDetailRequest); } diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java index 72c5208..c3420c5 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/business/BusinessLabExecutiveInfoController.java @@ -4,12 +4,12 @@ import com.casic.missiles.core.base.controller.ExportController; import com.casic.missiles.core.page.PageFactory; import com.casic.missiles.core.page.PageInfoBT; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.ReturnDTO; import com.casic.missiles.dto.ReturnUtil; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.model.exception.enums.CoreExceptionEnum; import com.casic.missiles.service.business.IBusinessLabExecutiveInfoService; @@ -64,8 +64,11 @@ @ApiOperation("任务分发-详情") @PostMapping("/handOutDetail") @ResponseBody - public ReturnDTO queryHandOutDetail(@RequestBody IdDTO idDTO) { - return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(idDTO)); + public ReturnDTO queryHandOutDetail(@RequestBody @Valid SampleHandOutDetailRequest handOutDetailRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return ReturnUtil.success(labExecutiveInfoService.handOutListDetail(handOutDetailRequest)); } /** diff --git a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java index a543546..afdfda8 100644 --- a/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java +++ b/casic-metering-api/src/main/java/com/casic/missiles/controller/meter/MeterTrainController.java @@ -162,6 +162,27 @@ return trainPlanService.trainPlanDetail(idDTO.getId()); } + //APP扫码后从培训计划详情中选择签到人员,扫码后提交调用签到接口,更新培训计划员工签到时间 + @ApiOperation("培训计划二维码") + @PostMapping("/plan/qrCode") + @ResponseBody + public ReturnDTO planQrCode(@RequestBody @Valid IdDTO idDTO) { + Assert.isFalse(Objects.isNull(idDTO.getId()), () -> { + throw new BusinessException(BusinessExceptionEnum.ID_NULL); + }); + return trainPlanService.planQrCode(idDTO.getId()); + } + + @ApiOperation("签到(更新培训计划员工签到时间)") + @PostMapping("/plan/signIn") + @ResponseBody + public ReturnDTO signIn(@RequestBody @Valid TrainPlanSignInRequest trainPlanSignInRequest, BindingResult bindingResult) { + if(bindingResult.hasErrors()){ + throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage()); + } + return trainPlanService.signIn(trainPlanSignInRequest); + } + @ApiOperation("培训计划审批列表及详情中基础信息(分页),培训学员情况可用培训计划详情接口") @PostMapping("/plan/approval/listPage") @ResponseBody diff --git a/casic-metering-common/pom.xml b/casic-metering-common/pom.xml index 19b75b5..142b343 100644 --- a/casic-metering-common/pom.xml +++ b/casic-metering-common/pom.xml @@ -160,7 +160,6 @@ - org.apache.poi poi @@ -171,11 +170,18 @@ poi-ooxml 4.1.2 - - - - - + + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + org.springframework.boot diff --git a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java index 098dfbc..c5c4bb0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/enums/BusinessExceptionEnum.java @@ -50,7 +50,8 @@ TRAIN_PLAN_SUBMIT_FAILED(2406, "培训计划提交处理失败"), FILE_SUBMIT_FAILED(2407, "文件提交处理失败"), FLOW_NO_JOIN_FLOWABLE(2408, "该流程暂未接入Flowable,请重试"), - HANDLE_FAILED(500, "操作失败"); + HANDLE_FAILED(500, "操作失败"), + QRCODE_FAILED(2409, "二维码生成失败"); private Integer code; private String message; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java index 18ab69f..e838f36 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/listeners/flowable/CounterSignListener.java @@ -131,7 +131,7 @@ String id = String.valueOf(idMap.get("id")); assigneeList.add(id); } else if (AssigneeSetTypeEnum.SELF_SELECT == settype) { - // TODO: 2022/12/27 发起人自选审批人(需求暂无此功能) + //发起人自选审批人(需求暂无此功能) } else if (AssigneeSetTypeEnum.SELF == settype) { //启动流程时设置的发起人全局变量 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java new file mode 100644 index 0000000..9af3fb8 --- /dev/null +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package com.casic.missiles.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.HashMap; + +/** + * @Description: 二维码工具 + * @Author: wangpeng + * @Date: 2023/2/11 13:59 + */ +@Slf4j +@UtilityClass +public class QRCodeUtil { + /** + * 默认宽度 + */ + private static final Integer WIDTH = 140; + /** + * 默认高度 + */ + private static final Integer HEIGHT = 140; + + /** + * LOGO 默认宽度 + */ + private static final Integer LOGO_WIDTH = 22; + /** + * LOGO 默认高度 + */ + private static final Integer LOGO_HEIGHT = 22; + + /** + * 图片格式 + */ + private static final String IMAGE_FORMAT = "png"; + private static final String CHARSET = "utf-8"; + /** + * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析 + */ + private static final String BASE64_IMAGE = "data:image/png;base64,%s"; + + /** + * 生成二维码,使用默认尺寸 + * + * @param content 内容 + * @return + */ + public String getBase64QRCode(String content) { + return getBase64Image(content, WIDTH, HEIGHT, null, null, null); + } + + /** + * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo + * + * @param content 内容 + * @param logoUrl logo地址 + * @return + */ + public String getBase64QRCode(String content, String logoUrl) { + return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); + } + + private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); + try { + ImageIO.write(bufferedImage, IMAGE_FORMAT, os); + } catch (IOException e) { + log.error("[生成二维码,错误{}]", e); + throw new BusinessException(BusinessExceptionEnum.QRCODE_FAILED); + } + // 转出即可直接使用 + return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray())); + } + + + /** + * 生成二维码 + * + * @param content 内容 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @return + */ + private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { + if (StrUtil.isNotBlank(content)) { + ServletOutputStream stream = null; + HashMap hints = new HashMap<>(4); + // 指定字符编码为utf-8 + hints.put(EncodeHintType.CHARACTER_SET, CHARSET); + // 指定二维码的纠错等级为中级 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + // 设置图片的边距 + hints.put(EncodeHintType.MARGIN, 2); + try { + QRCodeWriter writer = new QRCodeWriter(); + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StrUtil.isNotBlank(logoUrl)) { + insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight); + } + return bufferedImage; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.flush(); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + /** + * 二维码插入logo + * + * @param source 二维码 + * @param width 二维码宽度 + * @param height 二维码高度 + * @param logoUrl logo 在线地址 + * @param logoWidth logo 宽度 + * @param logoHeight logo 高度 + * @throws Exception + */ + private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception { + // logo 源可为 File/InputStream/URL + Image src = ImageIO.read(new URL(logoUrl)); + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + graph.drawImage(src, x, y, logoWidth, logoHeight, null); + Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 获取二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws IOException + */ + public void getQRCode(String content, OutputStream output) throws IOException { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null); + ImageIO.write(image, IMAGE_FORMAT, output); + } + + /** + * 获取二维码 + * + * @param content 内容 + * @param logoUrl logo资源 + * @param output 输出流 + * @throws Exception + */ + public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception { + BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT); + ImageIO.write(image, IMAGE_FORMAT, output); + } + +} \ No newline at end of file diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java index f614231..07da262 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveInfoMapper.java @@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; +import com.casic.missiles.dto.business.MeasureProcessDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; import org.apache.ibatis.annotations.Param; @@ -18,4 +20,6 @@ public interface BusinessLabExecutiveInfoMapper extends BaseMapper { List selectListByInMeasureStatus(@Param("orderId") Long orderId, @Param("sampleId") Long sampleId); + + List selectExecutiveList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java index 190058c..ed6f4a1 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessLabExecutiveOperateLogMapper.java @@ -1,7 +1,12 @@ package com.casic.missiles.mapper.business; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.business.MeasureSendBackDTO; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveOperateLog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** @@ -14,4 +19,5 @@ */ public interface BusinessLabExecutiveOperateLogMapper extends BaseMapper { + List selectExecutiveOperateLogList(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java index 4eb24af..dad016b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/business/BusinessOrderSampleRelationMapper.java @@ -5,6 +5,7 @@ import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessOrderSampleRelation; import org.apache.ibatis.annotations.Param; @@ -20,7 +21,5 @@ Page selectSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - Page getSampleListByStatus(Page page, @Param("request") SampleHandOutListRequest request); - - SampleHandOutDetailResponse selectSampleDetailById(@Param("id") Long id); + SampleHandOutDetailResponse selectSampleDetail(@Param("request") SampleHandOutDetailRequest request); } diff --git a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java index c4186f7..c094c3b 100644 --- a/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java +++ b/casic-metering-dao/src/main/java/com/casic/missiles/mapper/meter/MeterTrainStaffMapper.java @@ -1,6 +1,7 @@ package com.casic.missiles.mapper.meter; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.missiles.dto.meter.TrainPlanSignInRequest; import com.casic.missiles.dto.meter.TrainStaffExamDTO; import com.casic.missiles.model.meter.MeterTrainStaff; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,6 @@ public interface MeterTrainStaffMapper extends BaseMapper { int updateForStaff(@Param("trainStaffList") List trainStaffList); + + int updateStaffForSignIn(@Param("request") TrainPlanSignInRequest request); } diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml index cacf676..0c4e748 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveInfoMapper.xml @@ -39,4 +39,15 @@ AND blei.sample_id = #{sampleId} AND (blei.measure_status = 1 OR blei.measure_status = 2) + + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml index 792510e..d3e2b05 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessLabExecutiveOperateLogMapper.xml @@ -19,4 +19,12 @@ id, order_id, sample_id, measure_dept_id, measure_person_id, measure_status, create_time, update_time + diff --git a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml index 05914b4..c385826 100644 --- a/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/business/BusinessOrderSampleRelationMapper.xml @@ -23,8 +23,10 @@ - csi.id AS sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, bo.order_code AS orderNo, bo.id AS orderId, - bo.customer_id, bo.customer_name, bo.deliverer, bo.is_urgent, csi.sample_belong, bo.require_over_time, bosr.sample_status + bosr.sample_id, csi.sample_no, csi.sample_name, csi.sample_model, csi.manufacturing_no, csi.manufacturer, csi.manufacturer_country, + csi.manufacturing_date, csi.ABC, bo.customer_id, bo.customer_name, bo.customer_phone, bo.customer_address, bo.id AS orderId, + bo.order_code, bo.deliverer, bo.deliverer_tel, bo.plan_deliver_time, bo.require_over_time, bosr.mesure_content, csi.measure_period, + csi.measure_last_time, csi.valid_deadline, bosr.remark, csi.minio_file_name, csi.measure_type, csi.label_bind - - - SELECT - FROM customer_sample_info csi - LEFT JOIN business_order bo - LEFT JOIN business_order_sample_relation bosr ON bo.id = bosr.order_id - JOIN customer_sample_info csi ON csi.id = bosr.sample_id - WHERE bo.is_del = 0 + FROM business_order_sample_relation bosr + JOIN customer_sample_info csi ON bosr.sample_id = csi.id + JOIN business_order bo ON bosr.order_id = bo.id + WHERE bo.is_del = 0 AND csi.is_del = 0 + AND bosr.order_id = #{request.orderId} + AND bosr.sample_id = #{request.sampleId} diff --git a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml index 2aadf6f..f3083a8 100644 --- a/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml +++ b/casic-metering-dao/src/main/resources/mapper/meter/MeterTrainStaffMapper.xml @@ -9,4 +9,10 @@ WHERE staff_id = #{item.staffId} AND plan_id = #{item.planId} + + + UPDATE meter_train_staff + SET sign_time = NOW() + WHERE staff_id = #{request.staffId} AND plan_id = #{request.planId} + diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java index a1b096b..c80d42e 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureProcessDTO.java @@ -26,6 +26,7 @@ private String measureStatusName; @ApiModelProperty(value = "应出具证书总数", dataType = "Integer") private Integer requireCertifications; + //更新时间使用business_lab_executive_info表更新时间,因为只有操作和修改应出具证书个数才会更新 @ApiModelProperty(value = "更新时间", dataType = "String") private String updateTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java index 3c5aa32..1ddc8a5 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/MeasureSendBackDTO.java @@ -17,12 +17,12 @@ @ApiModelProperty(value = "检定环节,实验室名字", dataType = "String") private String measureSegment; @ApiModelProperty(value = "退回人员id", dataType = "Long") - private Long measurePersonId; + private Long sendBackPersonId; @ApiModelProperty(value = "退回人员名字", dataType = "String") - private String measurePerson; + private String sendBackPerson; @ApiModelProperty(value = "退回原因", dataType = "String") private String sendBackReason; @ApiModelProperty(value = "退回时间", dataType = "String") - private String updateTime; + private String sendBackTime; } diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java new file mode 100644 index 0000000..a57ddd9 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailRequest.java @@ -0,0 +1,24 @@ +package com.casic.missiles.dto.business; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 任务分发详情请求实体 + * @Author: wangpeng + * @Date: 2023/2/11 15:33 + */ +@Data +@ApiModel +public class SampleHandOutDetailRequest { + @NotNull(message = "委托书id不能为空") + @ApiModelProperty(value = "委托书id", dataType = "Long") + private Long orderId; + + @NotNull(message = "样品id不能为空") + @ApiModelProperty(value = "样品id", dataType = "Long") + private Long sampleId; +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java index 38b80e3..60621f1 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/SampleHandOutDetailResponse.java @@ -48,37 +48,38 @@ private String customerName; @ApiModelProperty(value = "委托方电话", dataType = "String") - private String phone; + private String customerPhone; - @ApiModelProperty(value = "委托方邮编", dataType = "String") - private String postalCode; + //需求中有,建议去掉,否则多关联一张表 +// @ApiModelProperty(value = "委托方邮编", dataType = "String") +// private String postalCode; - @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") - private String addressCountry; - - @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") - private String addressProvince; - - @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") - private String addressCity; - - @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") - private String addressArea; +// @ApiModelProperty(value = "委托方公司地址-国家", dataType = "String") +// private String addressCountry; +// +// @ApiModelProperty(value = "委托方公司地址-省", dataType = "String") +// private String addressProvince; +// +// @ApiModelProperty(value = "委托方公司地址-市", dataType = "String") +// private String addressCity; +// +// @ApiModelProperty(value = "委托方公司地址-区", dataType = "String") +// private String addressArea; @ApiModelProperty(value = "委托方公司地址-详细地址", dataType = "String") - private String fullAddress; + private String customerAddress; - @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") - private String addressCountryName; - - @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") - private String addressProvinceName; - - @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") - private String addressCityName; - - @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") - private String addressAreaName; +// @ApiModelProperty(value = "委托方公司地址-国家名字", dataType = "String") +// private String addressCountryName; +// +// @ApiModelProperty(value = "委托方公司地址-省名字", dataType = "String") +// private String addressProvinceName; +// +// @ApiModelProperty(value = "委托方公司地址-市名字", dataType = "String") +// private String addressCityName; +// +// @ApiModelProperty(value = "委托方公司地址-区名字", dataType = "String") +// private String addressAreaName; @ApiModelProperty(value = "委托书id", dataType = "Long") private String orderId; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java new file mode 100644 index 0000000..7d9a4f5 --- /dev/null +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/meter/TrainPlanSignInRequest.java @@ -0,0 +1,31 @@ +package com.casic.missiles.dto.meter; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Description: 培训计划签到请求实体 + * @Author: wangpeng + * @Date: 2023/02/11 17:59 + */ +@ApiModel +@Data +public class TrainPlanSignInRequest { + /** + * 培训计划表id + */ + @NotNull(message = "培训计划表id不能为空") + @ApiModelProperty(value = "培训计划表id", dataType = "Long") + private Long planId; + + /** + * 计量人员表id + */ + @NotNull(message = "培训学员id不能为空") + @ApiModelProperty(value = "计量人员表id", dataType = "Long", required = true) + private Long staffId; + +} diff --git a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java index 945baab..cf25b82 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/model/business/BusinessLabExecutiveOperateLog.java @@ -54,6 +54,21 @@ @TableField("measure_status") private String measureStatus; + /** + * 操作/退回人员(可能是部门负责人or检定人) + */ + @TableField("operate_person_id") + private Long operatePersonId; + + @TableField("operate_person_name") + private String operatePersonName; + + /** + * 退回原因 + */ + @TableField("operate_reason") + private String operateReason; + @TableField("create_time") private String createTime; diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java index 9add926..09c5074 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/business/BusinessLabExecutiveInfoServiceImpl.java @@ -3,11 +3,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.casic.missiles.dto.IdDTO; -import com.casic.missiles.dto.business.HandOutLabExecutiveDTO; -import com.casic.missiles.dto.business.SampleHandOutDetailResponse; -import com.casic.missiles.dto.business.SampleHandOutListRequest; -import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.*; import com.casic.missiles.enums.CurrentSegmentEnum; import com.casic.missiles.enums.HandOutPropertyEnum; import com.casic.missiles.enums.MeasureStatusEnum; @@ -108,12 +104,15 @@ } @Override - public SampleHandOutDetailResponse handOutListDetail(IdDTO idDTO) { + public SampleHandOutDetailResponse handOutListDetail(SampleHandOutDetailRequest handOutDetailRequest) { //根据样品id和委托书id查询样品、委托书、委托方 - SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetailById(idDTO.getId()); - - //查询检定流程、退回信息 - return null; + SampleHandOutDetailResponse sampleDetail = orderSampleRelationMapper.selectSampleDetail(handOutDetailRequest); + //根据样品id和委托书id查询检定流程、退回信息 + List measureProcessDTOS = labExecutiveInfoMapper.selectExecutiveList(handOutDetailRequest); + List measureSendBackDTOS = labExecutiveOperateLogMapper.selectExecutiveOperateLogList(handOutDetailRequest); + sampleDetail.setMeasureProcessList(measureProcessDTOS); + sampleDetail.setMeasureSendBackList(measureSendBackDTOS); + return sampleDetail; } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java index 57bb3a9..59b2809 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/equipment/EquipmentApplyServiceImpl.java @@ -121,7 +121,6 @@ equipmentApply.setApprovalStatus(ApprovalStatusEnum.FAILED_REJECT); } } - // todo 如果查全部,怎么设置审批状态 if(ApprovalStatusEnum.TO_BE_APPROVED.equals(status)){ equipmentApply.setTaskId(taskMap.get(equipmentApply.getId().toString())); } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java index 9159410..82cae83 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterCertificateServiceImpl.java @@ -18,6 +18,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterCertificateExpireMessageMapper; import com.casic.missiles.mapper.meter.MeterCertificateMapper; import com.casic.missiles.mapper.meter.MeterStaffMapper; @@ -149,7 +150,7 @@ if(messageMapper.update(null, updateWrapper)>0){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java index 34c92ea..33611bd 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterOrganizeServiceImpl.java @@ -10,8 +10,10 @@ import com.casic.missiles.dto.meter.OrganizeListRequest; import com.casic.missiles.dto.meter.ParentDeptRequest; import com.casic.missiles.dto.meter.ParentDeptResponse; +import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.MeterDeptTypeEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterOrganizeMapper; import com.casic.missiles.model.meter.MeterOrganize; import com.casic.missiles.modular.system.model.Dept; @@ -147,7 +149,7 @@ if(organizeMapper.updateById(meterOrganize) > 0 && success){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } private QueryWrapper getWrapper(OrganizeListRequest request) { diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java index 393696e..48096c1 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterPriceServiceImpl.java @@ -14,6 +14,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterPriceCategoryMapper; import com.casic.missiles.mapper.meter.MeterPriceItemMapper; import com.casic.missiles.mapper.meter.MeterPriceMapper; @@ -87,7 +88,7 @@ if(meterPriceMapper.insert(meterPrice)>0){ return ReturnUtil.success(); }else{ - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } } return ReturnUtil.failed("价格库新增失败"); diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java index e4d5cb9..664d965 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterStaffServiceImpl.java @@ -16,6 +16,7 @@ import com.casic.missiles.enums.BusinessExceptionEnum; import com.casic.missiles.enums.ExportEnum; import com.casic.missiles.enums.MeterDictEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterCertificateMapper; import com.casic.missiles.mapper.meter.MeterStaffMapper; import com.casic.missiles.mapper.sys.UserInfoMapper; @@ -185,7 +186,7 @@ }else{ return ReturnUtil.failed("人员信息编辑失败"); } } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java index 2a79b51..0fd9403 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainLogServiceImpl.java @@ -9,6 +9,8 @@ import com.casic.missiles.dto.meter.TrainLogDetailResponse; import com.casic.missiles.dto.meter.TrainLogListRequest; import com.casic.missiles.dto.meter.TrainLogUpdateRequest; +import com.casic.missiles.enums.BusinessExceptionEnum; +import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterTrainLogMapper; import com.casic.missiles.mapper.meter.MeterTrainStaffMapper; import com.casic.missiles.model.meter.MeterTrainLog; @@ -79,7 +81,7 @@ if(insertFlag > 0 && updateFlag > 0){ return ReturnUtil.success(); } - return ReturnUtil.failed("操作失败"); + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); } @Override diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainPlanServiceImpl.java b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainPlanServiceImpl.java index 3dbecc0..35a7098 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainPlanServiceImpl.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/Impl/meter/MeterTrainPlanServiceImpl.java @@ -19,6 +19,7 @@ import com.casic.missiles.enums.MeterDictEnum; import com.casic.missiles.exception.BusinessException; import com.casic.missiles.mapper.meter.MeterTrainPlanMapper; +import com.casic.missiles.mapper.meter.MeterTrainStaffMapper; import com.casic.missiles.model.meter.MeterTrainPlan; import com.casic.missiles.model.meter.MeterTrainStaff; import com.casic.missiles.model.response.ResponseData; @@ -30,6 +31,7 @@ import com.casic.missiles.service.meter.IMeterTrainStaffService; import com.casic.missiles.utils.ConvertUtils; import com.casic.missiles.utils.NumberGeneratorUtil; +import com.casic.missiles.utils.QRCodeUtil; import org.apache.commons.lang3.StringUtils; import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; @@ -57,6 +59,8 @@ @Autowired private MeterTrainPlanMapper trainPlanMapper; @Autowired + private MeterTrainStaffMapper trainStaffMapper; + @Autowired private IMeterTrainStaffService trainStaffService; @Resource private AbstractDictService dictService; @@ -244,6 +248,22 @@ return ReturnUtil.success(planResponse); } + @Override + public ReturnDTO planQrCode(Long id) { + String base64QRCode = QRCodeUtil.getBase64QRCode(String.valueOf(id)); + return ReturnUtil.success(base64QRCode); + } + + @Override + public ReturnDTO signIn(TrainPlanSignInRequest request) { + //更新培训计划员工考核结果 + int updateFlag = trainStaffMapper.updateStaffForSignIn(request); + if(updateFlag > 0){ + return ReturnUtil.success(); + } + throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED); + } + private List handleApprovalStatus(Page page, TrainPlanApprovalListRequest request) { List approvalList = new ArrayList<>(); List businessKeys = new ArrayList<>(); diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/business/IBusinessLabExecutiveInfoService.java b/casic-metering-service/src/main/java/com/casic/missiles/service/business/IBusinessLabExecutiveInfoService.java index 570127e..c286be6 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/business/IBusinessLabExecutiveInfoService.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/business/IBusinessLabExecutiveInfoService.java @@ -2,10 +2,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.missiles.dto.IdDTO; import com.casic.missiles.dto.business.SampleHandOutDetailResponse; import com.casic.missiles.dto.business.SampleHandOutListRequest; import com.casic.missiles.dto.business.SampleHandOutListResponse; +import com.casic.missiles.dto.business.SampleHandOutDetailRequest; import com.casic.missiles.model.business.BusinessLabExecutiveInfo; /** @@ -20,5 +20,5 @@ Page handOutListPage(Page page, SampleHandOutListRequest handOutListRequest) throws Exception; - SampleHandOutDetailResponse handOutListDetail(IdDTO idDTO); + SampleHandOutDetailResponse handOutListDetail(SampleHandOutDetailRequest SampleHandOutDetailRequest); } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/meter/IMeterTrainPlanService.java b/casic-metering-service/src/main/java/com/casic/missiles/service/meter/IMeterTrainPlanService.java index 74dae78..7375f3e 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/meter/IMeterTrainPlanService.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/meter/IMeterTrainPlanService.java @@ -34,6 +34,10 @@ ReturnDTO trainPlanDetail(Long id); + ReturnDTO planQrCode(Long id); + + ReturnDTO signIn(TrainPlanSignInRequest trainPlanSignInRequest); + List planList(TrainPlanListRequest request); ReturnDTO draftUpdate(MeterTrainPlan trainPlan);