From 13702d08258abb92f147c9757def159eb2c83739 Mon Sep 17 00:00:00 2001 From: jkj Date: Thu, 9 Nov 2023 14:39:34 +0800 Subject: [PATCH] init --- .gitignore | 47 + LICENSE | 20 + README.md | 97 + bin/clean.bat | 12 + bin/package.bat | 12 + bin/run.bat | 14 + cmcc_gm/pom.xml | 37 + .../cmcc_gm/common/enums/OrderStatus.java | 59 + .../ruoyi/cmcc_gm/common/enums/OrderType.java | 83 + .../cmcc_gm/domain/YwMaterialsBatch.java | 54 + .../cmcc_gm/domain/YwMaterialsClasses.java | 52 + .../cmcc_gm/domain/YwMaterialsInform.java | 99 + .../cmcc_gm/domain/YwMaterialsOrderLog.java | 114 + .../cmcc_gm/domain/YwMaterialsSnList.java | 50 + .../cmcc_gm/domain/YwMaterialsStock.java | 65 + .../com/ruoyi/cmcc_gm/domain/dto/BaseDTO.java | 12 + .../TransformJsonArrayToMaterialsXlsDTO.java | 12 + .../domain/dto/YmMaterialsClassesParam.java | 22 + .../domain/dto/YwMaterialsBatchDTO.java | 30 + .../cmcc_gm/domain/dto/YwMaterialsDTO.java | 23 + .../domain/dto/YwMaterialsInformDTO.java | 62 + .../domain/dto/YwMaterialsOrderLogDTO.java | 103 + .../domain/dto/YwMaterialsSearchDTO.java | 74 + .../domain/dto/YwMaterialsSnListDTO.java | 32 + .../domain/dto/YwMaterialsStockImportDTO.java | 84 + .../domain/qo/YwMaterialsSnListQO.java | 26 + .../domain/vo/MaterialsXlsToJsonArrayVo.java | 36 + .../cmcc_gm/domain/vo/YwMaterialsBatchVo.java | 49 + .../domain/vo/YwMaterialsClassesVo.java | 35 + .../domain/vo/YwMaterialsExportVo.java | 105 + .../domain/vo/YwMaterialsInformRedisVo.java | 53 + .../domain/vo/YwMaterialsInformVo.java | 74 + .../domain/vo/YwMaterialsOrderLogVo.java | 160 ++ .../domain/vo/YwMaterialsSnListVo.java | 31 + .../cmcc_gm/domain/vo/YwMaterialsVo.java | 68 + .../importer/ImporterMaterialsBatch.java | 133 ++ .../importer/ImporterMaterialsInform.java | 174 ++ .../importer/ImporterMaterialsReturnList.java | 158 ++ .../importer/ImporterMaterialsStock.java | 187 ++ .../mapper/YwMaterialsBatchMapper.java | 34 + .../mapper/YwMaterialsClassesMapper.java | 31 + .../mapper/YwMaterialsInformMapper.java | 37 + .../mapper/YwMaterialsOrderLogMapper.java | 30 + .../mapper/YwMaterialsSnListMapper.java | 32 + .../mapper/YwMaterialsStockMapper.java | 44 + .../cmcc_gm/service/GMCommonService.java | 7 + .../service/YwMaterialsBatchService.java | 33 + .../service/YwMaterialsClassesService.java | 38 + .../service/YwMaterialsInformService.java | 52 + .../service/YwMaterialsOrderLogService.java | 33 + .../service/YwMaterialsSnListService.java | 32 + .../service/YwMaterialsStockService.java | 71 + .../service/impl/GMCommonServiceImpl.java | 50 + .../impl/YwMaterialsBatchServiceImpl.java | 314 +++ .../impl/YwMaterialsClassesServiceImpl.java | 182 ++ .../impl/YwMaterialsInformServiceImpl.java | 333 +++ .../impl/YwMaterialsOrderLogServiceImpl.java | 300 +++ .../impl/YwMaterialsSnListServiceImpl.java | 208 ++ .../impl/YwMaterialsStockServiceImpl.java | 1087 ++++++++++ .../mapper/cmcc_gm/YwMaterialsBatchMapper.xml | 72 + .../cmcc_gm/YwMaterialsClassesMapper.xml | 41 + .../cmcc_gm/YwMaterialsInformMapper.xml | 100 + .../cmcc_gm/YwMaterialsOrderLogMapper.xml | 140 ++ .../cmcc_gm/YwMaterialsSnListMapper.xml | 32 + .../mapper/cmcc_gm/YwMaterialsStockMapper.xml | 135 ++ ...\347\224\250\346\211\213\345\206\214.docx" | Bin 0 -> 428430 bytes eastcom_yw/pom.xml | 85 + .../common/constant/AlarmConstants.java | 9 + .../common/constant/CacheConstants.java | 8 + .../common/constant/KpiConstants.java | 53 + .../common/constant/NetElementConstants.java | 15 + .../common/enums/FlowDealStatus.java | 59 + .../eastcom_yw/common/enums/InRedLine.java | 45 + .../common/enums/WireTaskSubType.java | 58 + .../eastcom_yw/common/enums/WireTaskType.java | 58 + .../eastcom_yw/domain/AppVersionConfig.java | 39 + .../eastcom_yw/domain/Dp2AgisLink5mi.java | 133 ++ .../ruoyi/eastcom_yw/domain/Dp2MmlList.java | 107 + .../eastcom_yw/domain/Dp2PnNetVenue5mi.java | 137 ++ .../ruoyi/eastcom_yw/domain/Dp2SpotCell.java | 231 ++ .../eastcom_yw/domain/Dp2SpotConfig.java | 54 + .../eastcom_yw/domain/Dp2ViewPowerAlarm.java | 81 + .../domain/Dp2ViewWirelessAlarm.java | 89 + .../eastcom_yw/domain/DpSceneConfig.java | 74 + .../eastcom_yw/domain/HmAlarmDerive.java | 84 + .../ruoyi/eastcom_yw/domain/PmKpi4gCell.java | 200 ++ .../ruoyi/eastcom_yw/domain/PmKpi4gMin.java | 126 ++ .../ruoyi/eastcom_yw/domain/PmKpi4gVenue.java | 86 + .../ruoyi/eastcom_yw/domain/PmKpi5gCell.java | 183 ++ .../ruoyi/eastcom_yw/domain/PmKpi5gMin.java | 109 + .../ruoyi/eastcom_yw/domain/PmKpi5gVenue.java | 99 + .../eastcom_yw/domain/PmKpiMaxEntity.java | 21 + .../eastcom_yw/domain/PmKpiMonitorEntity.java | 75 + .../ruoyi/eastcom_yw/domain/SysNotice.java | 144 ++ .../ruoyi/eastcom_yw/domain/SysUserImp.java | 45 + .../com/ruoyi/eastcom_yw/domain/YwAlarm.java | 55 + .../ruoyi/eastcom_yw/domain/YwAlarmCS.java | 55 + .../eastcom_yw/domain/YwAlarmConfig.java | 31 + .../ruoyi/eastcom_yw/domain/YwAlarmDH.java | 55 + .../eastcom_yw/domain/YwAlarmHangupLog.java | 77 + .../domain/YwAlarmHangupReover.java | 26 + .../eastcom_yw/domain/YwAlarmOprateLog.java | 49 + .../eastcom_yw/domain/YwAlarmRecover.java | 44 + .../ruoyi/eastcom_yw/domain/YwAlarmView.java | 56 + .../ruoyi/eastcom_yw/domain/YwAlarmWX.java | 55 + .../ruoyi/eastcom_yw/domain/YwDrsConfig.java | 67 + .../eastcom_yw/domain/YwDrsTempTask.java | 93 + .../ruoyi/eastcom_yw/domain/YwKpiConfig.java | 84 + .../eastcom_yw/domain/YwNoticeBriefing.java | 108 + .../eastcom_yw/domain/YwNoticeHandwork.java | 96 + .../domain/YwNoticeHandworkdetail.java | 55 + .../ruoyi/eastcom_yw/domain/YwNoticeList.java | 100 + .../eastcom_yw/domain/YwNoticeModel.java | 84 + .../eastcom_yw/domain/YwNoticeObject.java | 103 + .../ruoyi/eastcom_yw/domain/YwNoticeUser.java | 33 + .../domain/YwRoutInspectConfig.java | 49 + .../eastcom_yw/domain/YwRoutInspectLog.java | 41 + .../eastcom_yw/domain/YwRoutInspectPlan.java | 66 + .../domain/YwRoutInspectQuestionConfig.java | 44 + .../com/ruoyi/eastcom_yw/domain/YwScene.java | 169 ++ .../ruoyi/eastcom_yw/domain/YwSceneAlarm.java | 33 + .../eastcom_yw/domain/YwSceneBigConfig.java | 45 + .../eastcom_yw/domain/YwSceneCalendar.java | 62 + .../ruoyi/eastcom_yw/domain/YwSceneFile.java | 47 + .../eastcom_yw/domain/YwSceneNetelement.java | 78 + .../eastcom_yw/domain/YwSceneTestData.java | 22 + .../ruoyi/eastcom_yw/domain/YwSceneUser.java | 61 + .../ruoyi/eastcom_yw/domain/YwSceneView.java | 42 + .../ruoyi/eastcom_yw/domain/YwSignLog.java | 39 + .../eastcom_yw/domain/YwSignLogView.java | 78 + .../ruoyi/eastcom_yw/domain/YwSignPlan.java | 47 + .../eastcom_yw/domain/YwSignPlanRemind.java | 25 + .../eastcom_yw/domain/YwSignPlanView.java | 37 + .../ruoyi/eastcom_yw/domain/YwSpareParts.java | 105 + .../eastcom_yw/domain/YwWireTaskLog.java | 103 + .../eastcom_yw/domain/dto/CommonDTO.java | 16 + .../eastcom_yw/domain/dto/Dp2SpotCellDTO.java | 135 ++ .../domain/dto/Dp2SpotConfigDTO.java | 49 + .../domain/dto/Dp2ViewPowerAlarmDTO.java | 83 + .../domain/dto/Dp2ViewWirelessAlarmDTO.java | 89 + .../domain/dto/DpSceneConfigDTO.java | 75 + .../eastcom_yw/domain/dto/MmlObjectDTO.java | 19 + .../eastcom_yw/domain/dto/PageNumsDTO.java | 16 + .../eastcom_yw/domain/dto/PageSizesDTO.java | 16 + .../eastcom_yw/domain/dto/PmKpi4gCellDTO.java | 185 ++ .../eastcom_yw/domain/dto/PmKpi4gMinDTO.java | 102 + .../domain/dto/PmKpi4gVenueDTO.java | 75 + .../eastcom_yw/domain/dto/PmKpi5gCellDTO.java | 170 ++ .../eastcom_yw/domain/dto/PmKpi5gMinDTO.java | 88 + .../domain/dto/PmKpi5gVenueDTO.java | 88 + .../eastcom_yw/domain/dto/SysNoticeDTO.java | 131 ++ .../eastcom_yw/domain/dto/WorkFlowDTO.java | 11 + .../eastcom_yw/domain/dto/YwAlarmDTO.java | 103 + .../domain/dto/YwAlarmDTONoPage.java | 104 + .../domain/dto/YwAlarmHangupLogDTO.java | 66 + .../eastcom_yw/domain/dto/YwDataDTO.java | 32 + .../eastcom_yw/domain/dto/YwDrsConfigDTO.java | 71 + .../domain/dto/YwDrsTempTaskDTO.java | 100 + .../domain/dto/YwDrsTempTaskTimeDTO.java | 35 + .../domain/dto/YwInspectPlanDTO.java | 65 + .../domain/dto/YwInspectPlanExportDTO.java | 41 + .../domain/dto/YwInspectStatDTO.java | 41 + .../domain/dto/YwInspectTaskDTO.java | 19 + .../domain/dto/YwInspectTaskExportDTO.java | 50 + .../eastcom_yw/domain/dto/YwKpiConfigDTO.java | 84 + .../domain/dto/YwNoticeBriefingDTO.java | 101 + .../domain/dto/YwNoticeHandworkDTO.java | 90 + .../domain/dto/YwNoticeHandworkdetailDTO.java | 55 + .../domain/dto/YwNoticeListDTO.java | 98 + .../domain/dto/YwNoticeModelDTO.java | 77 + .../domain/dto/YwNoticeObjectDTO.java | 97 + .../domain/dto/YwSceneCalendarDTO.java | 29 + .../eastcom_yw/domain/dto/YwSceneDTO.java | 106 + .../dto/YwSceneNoticeinfoSearchDTO.java | 14 + .../eastcom_yw/domain/dto/YwSearchDTO.java | 31 + .../eastcom_yw/domain/dto/YwSignDTO.java | 23 + .../eastcom_yw/domain/dto/YwSignInDTO.java | 22 + .../eastcom_yw/domain/dto/YwSignLogDTO.java | 41 + .../eastcom_yw/domain/dto/YwSignPlanDTO.java | 67 + .../domain/dto/YwSignPlanImportDTO.java | 26 + .../domain/dto/YwSignPlanUserDTO.java | 15 + .../domain/dto/YwSparePartsDTO.java | 124 ++ .../domain/dto/YwWireTaskLogDTO.java | 71 + .../domain/enums/TaskNameWithRoleEnum.java | 47 + .../domain/enums/WireTaskStatus.java | 67 + .../eastcom_yw/domain/model/AppEntity.java | 19 + .../eastcom_yw/domain/model/StepInfo.java | 9 + .../eastcom_yw/domain/param/SysUserParam.java | 12 + .../param/YwInspectQuestionConfigParam.java | 17 + .../param/YwRoutInspectConfigParam.java | 33 + .../domain/param/YwRoutInspectPlanParam.java | 38 + .../domain/param/YwRoutInspectStatParam.java | 46 + .../domain/param/YwSceneAlarmParam.java | 18 + .../domain/param/YwSceneCalendarParam.java | 24 + .../domain/param/YwSceneMatchParam.java | 7 + .../param/YwSceneNetelementAgisParam.java | 15 + .../param/YwSceneNetelementCsParam.java | 15 + .../param/YwSceneNetelementDhParam.java | 18 + .../domain/param/YwSceneNetelementParam.java | 18 + .../param/YwSceneNetelementWxParam.java | 16 + .../eastcom_yw/domain/param/YwSceneParam.java | 26 + .../domain/param/YwSceneUserParam.java | 24 + .../domain/param/YwSignPlanParam.java | 63 + .../eastcom_yw/domain/qo/Dp2MmlListQO.java | 32 + .../eastcom_yw/domain/qo/Dp2SpotCellQO.java | 137 ++ .../eastcom_yw/domain/qo/Dp2SpotConfigQO.java | 38 + .../domain/qo/Dp2ViewPowerAlarmQO.java | 37 + .../domain/qo/Dp2ViewWirelessAlarmQO.java | 100 + .../eastcom_yw/domain/qo/DpKpiMonitorQO.java | 58 + .../eastcom_yw/domain/qo/DpSceneConfigQO.java | 80 + .../eastcom_yw/domain/qo/PmKpi4gMinQO.java | 103 + .../eastcom_yw/domain/qo/PmKpi5gCellQO.java | 169 ++ .../eastcom_yw/domain/qo/PmKpi5gMinQO.java | 88 + .../domain/qo/PmKpiCellMonitorQO.java | 96 + .../eastcom_yw/domain/qo/PmKpiCellQO.java | 90 + .../eastcom_yw/domain/qo/PmKpiColorQo.java | 44 + .../eastcom_yw/domain/qo/PmKpiMinQO.java | 73 + .../eastcom_yw/domain/qo/PmKpiVenueQO.java | 56 + .../eastcom_yw/domain/qo/SysNoticeQO.java | 138 ++ .../eastcom_yw/domain/qo/YwDrsConfigQO.java | 71 + .../eastcom_yw/domain/qo/YwDrsTempTaskQO.java | 106 + .../eastcom_yw/domain/qo/YwKpiConfigQO.java | 84 + .../domain/qo/YwNoticeBriefingQO.java | 112 + .../domain/qo/YwNoticeHandworkQO.java | 89 + .../domain/qo/YwNoticeHandworkdetailQO.java | 55 + .../eastcom_yw/domain/qo/YwNoticeListQO.java | 96 + .../eastcom_yw/domain/qo/YwNoticeModelQO.java | 80 + .../domain/qo/YwNoticeObjectQO.java | 103 + .../eastcom_yw/domain/qo/YwSparePartsQO.java | 59 + .../domain/vo/AlarmStaticListVo.java | 17 + .../domain/vo/AlarmStatisticsListVo.java | 10 + .../eastcom_yw/domain/vo/AlarmTopListVo.java | 18 + .../eastcom_yw/domain/vo/DictTreeVO.java | 17 + .../domain/vo/Dp2AgisLink5miVO.java | 140 ++ .../domain/vo/Dp2PnNetVenue5miVO.java | 138 ++ .../eastcom_yw/domain/vo/Dp2SpotCellVO.java | 167 ++ .../eastcom_yw/domain/vo/Dp2SpotConfigVO.java | 48 + .../domain/vo/Dp2ViewPowerAlarmVO.java | 95 + .../domain/vo/Dp2ViewWirelessAlarmVO.java | 110 + .../eastcom_yw/domain/vo/DpSceneConfigVO.java | 94 + .../domain/vo/DpcSeneControlVo.java | 32 + .../eastcom_yw/domain/vo/FlowContentVo.java | 17 + .../eastcom_yw/domain/vo/HmAlarmDeriveVo.java | 56 + .../eastcom_yw/domain/vo/KpiLinkTrendVo.java | 31 + .../eastcom_yw/domain/vo/KpiReport4gVo.java | 69 + .../eastcom_yw/domain/vo/KpiReport5gVo.java | 80 + .../eastcom_yw/domain/vo/KpiTrendVo.java | 32 + .../domain/vo/KpiVenueReportVo.java | 123 ++ .../eastcom_yw/domain/vo/MatchListVo.java | 15 + .../eastcom_yw/domain/vo/MedalListVo.java | 12 + .../eastcom_yw/domain/vo/MonitorCellVo.java | 71 + .../eastcom_yw/domain/vo/NewsListVo.java | 14 + .../domain/vo/PmKpi15CellMonitorVO.java | 108 + .../domain/vo/PmKpi15MinCellVO.java | 102 + .../eastcom_yw/domain/vo/PmKpi4gCellVO.java | 224 ++ .../eastcom_yw/domain/vo/PmKpi4gMinVO.java | 138 ++ .../domain/vo/PmKpi4gVenueConvertVO.java | 43 + .../eastcom_yw/domain/vo/PmKpi4gVenueVO.java | 77 + .../eastcom_yw/domain/vo/PmKpi5gCellVO.java | 206 ++ .../eastcom_yw/domain/vo/PmKpi5gMinVO.java | 116 + .../eastcom_yw/domain/vo/PmKpi5gVenueVO.java | 90 + .../eastcom_yw/domain/vo/PmKpiOneMinVO.java | 85 + .../ruoyi/eastcom_yw/domain/vo/PmKpiVO.java | 52 + .../domain/vo/RaceScheduleListVo.java | 18 + .../ruoyi/eastcom_yw/domain/vo/RecordVo.java | 27 + .../domain/vo/SceneBaseStation.java | 98 + .../eastcom_yw/domain/vo/SysNoticeVO.java | 185 ++ .../ruoyi/eastcom_yw/domain/vo/SysUserVo.java | 203 ++ .../eastcom_yw/domain/vo/TaskMangeListVo.java | 13 + .../domain/vo/WholeAreaAssureCellSheet.java | 35 + .../eastcom_yw/domain/vo/YwAlarmAGISVo.java | 45 + .../eastcom_yw/domain/vo/YwAlarmAppVo.java | 12 + .../eastcom_yw/domain/vo/YwAlarmCSVo.java | 45 + .../vo/YwAlarmClassificationDetail.java | 13 + .../eastcom_yw/domain/vo/YwAlarmDHVo.java | 45 + .../eastcom_yw/domain/vo/YwAlarmInfoVo.java | 40 + .../eastcom_yw/domain/vo/YwAlarmLastVo.java | 31 + .../eastcom_yw/domain/vo/YwAlarmNewNumVo.java | 18 + .../eastcom_yw/domain/vo/YwAlarmNoticeVo.java | 13 + .../domain/vo/YwAlarmQuestionVo.java | 23 + .../domain/vo/YwAlarmStatistics.java | 31 + .../eastcom_yw/domain/vo/YwAlarmViewVo.java | 57 + .../ruoyi/eastcom_yw/domain/vo/YwAlarmVo.java | 58 + .../eastcom_yw/domain/vo/YwAlarmWXVo.java | 45 + .../domain/vo/YwConstrucTeamVo.java | 14 + .../eastcom_yw/domain/vo/YwDrsConfigVO.java | 76 + .../eastcom_yw/domain/vo/YwDrsTempTaskVO.java | 129 ++ .../eastcom_yw/domain/vo/YwErrorAlarmVO.java | 18 + .../eastcom_yw/domain/vo/YwInspectLogVo.java | 102 + .../domain/vo/YwInspectPlanStaticVo.java | 30 + .../eastcom_yw/domain/vo/YwInspectPlanVo.java | 28 + .../eastcom_yw/domain/vo/YwKpiConfigVO.java | 84 + .../domain/vo/YwNoticeBriefingPlanVO.java | 135 ++ .../domain/vo/YwNoticeBriefingVO.java | 183 ++ .../domain/vo/YwNoticeHandworkVO.java | 134 ++ .../domain/vo/YwNoticeHandworkdetailVO.java | 61 + .../eastcom_yw/domain/vo/YwNoticeListVO.java | 136 ++ .../eastcom_yw/domain/vo/YwNoticeModelVO.java | 104 + .../domain/vo/YwNoticeObjectVO.java | 158 ++ .../domain/vo/YwNoticeObjectaVO.java | 158 ++ .../eastcom_yw/domain/vo/YwSceneAlarmVo.java | 41 + .../domain/vo/YwSceneBaseInfoVo.java | 9 + .../domain/vo/YwSceneCalendar2Vo.java | 58 + .../domain/vo/YwSceneCalendarVo.java | 45 + .../eastcom_yw/domain/vo/YwSceneExportVo.java | 57 + .../domain/vo/YwSceneKPIStatisticsVo.java | 38 + .../eastcom_yw/domain/vo/YwSceneMatchVo.java | 54 + .../domain/vo/YwSceneNetAgixStaVo.java | 71 + .../domain/vo/YwSceneNetFixtelRegSuccVo.java | 14 + .../domain/vo/YwSceneNetFixtelStaVo.java | 25 + .../eastcom_yw/domain/vo/YwSceneNetStaVo.java | 54 + .../domain/vo/YwSceneNetVelocityStaVo.java | 17 + .../domain/vo/YwSceneNetWifiStaVo.java | 50 + .../domain/vo/YwSceneNetelementAgis.java | 46 + .../domain/vo/YwSceneNetelementCs.java | 45 + .../domain/vo/YwSceneNetelementDh.java | 39 + .../domain/vo/YwSceneNetelementWx.java | 125 ++ .../domain/vo/YwSceneNoticeinfo.java | 187 ++ .../eastcom_yw/domain/vo/YwSceneRedisVO.java | 12 + .../domain/vo/YwSceneTestDataInterface.java | 23 + .../domain/vo/YwSceneTransGbStaVo.java | 16 + .../vo/YwSceneTransOpticalpowerStaVo.java | 20 + .../domain/vo/YwSceneTransStaVo.java | 20 + .../eastcom_yw/domain/vo/YwSceneUserVo.java | 50 + .../ruoyi/eastcom_yw/domain/vo/YwSceneVo.java | 93 + .../domain/vo/YwSignLogStaticVo.java | 27 + .../eastcom_yw/domain/vo/YwSignLogVo.java | 93 + .../eastcom_yw/domain/vo/YwSignPlanVo.java | 73 + .../eastcom_yw/domain/vo/YwSignUserVo.java | 12 + .../ruoyi/eastcom_yw/domain/vo/YwSignVo.java | 21 + .../eastcom_yw/domain/vo/YwSparePartsVO.java | 122 ++ .../eastcom_yw/domain/vo/YwWireTaskLogVo.java | 112 + .../eastcom_yw/domain/yw_alarm_deal_log.java | 59 + .../eastcom_yw/domain/yw_alarm_deal_res.java | 34 + .../eastcom_yw/importer/ImportSpareParts.java | 149 ++ .../eastcom_yw/importer/ImporterAgis.java | 168 ++ .../eastcom_yw/importer/ImporterCalendar.java | 223 ++ .../ruoyi/eastcom_yw/importer/ImporterCs.java | 184 ++ .../ruoyi/eastcom_yw/importer/ImporterDh.java | 176 ++ .../eastcom_yw/importer/ImporterMatch.java | 198 ++ .../eastcom_yw/importer/ImporterScene.java | 172 ++ .../importer/ImporterSceneNoticeinfo.java | 176 ++ .../importer/ImporterSceneUser.java | 377 ++++ .../eastcom_yw/importer/ImporterSignPlan.java | 183 ++ .../ruoyi/eastcom_yw/importer/ImporterWx.java | 233 ++ .../ruoyi/eastcom_yw/mapper/AppMapper.java | 44 + .../mapper/AppVersionConfigMapper.java | 10 + .../mapper/Dp2AgisLink5miMapper.java | 27 + .../eastcom_yw/mapper/Dp2MmlListMapper.java | 21 + .../mapper/Dp2PnNetVenue5miMapper.java | 34 + .../eastcom_yw/mapper/Dp2SpotCellMapper.java | 24 + .../mapper/Dp2SpotConfigMapper.java | 22 + .../mapper/Dp2ViewPowerAlarmMapper.java | 23 + .../mapper/Dp2ViewWirelessAlarmMapper.java | 22 + .../mapper/DpSceneConfigMapper.java | 58 + .../mapper/HmAlarmDeriveMapper.java | 18 + .../eastcom_yw/mapper/LargeScreenMapper.java | 24 + .../eastcom_yw/mapper/PmKpi4gCellMapper.java | 74 + .../eastcom_yw/mapper/PmKpi4gMinMapper.java | 34 + .../eastcom_yw/mapper/PmKpi4gVenueMapper.java | 35 + .../eastcom_yw/mapper/PmKpi5gCellMapper.java | 66 + .../eastcom_yw/mapper/PmKpi5gMinMapper.java | 35 + .../eastcom_yw/mapper/PmKpi5gVenueMapper.java | 37 + .../eastcom_yw/mapper/SysNoticeMapper.java | 40 + .../eastcom_yw/mapper/YwAlarmCSMapper.java | 28 + .../eastcom_yw/mapper/YwAlarmDHMapper.java | 27 + .../mapper/YwAlarmHangupLogMapper.java | 25 + .../eastcom_yw/mapper/YwAlarmMapper.java | 49 + .../mapper/YwAlarmOprateLogMapper.java | 16 + .../mapper/YwAlarmStatisticsMapper.java | 33 + .../eastcom_yw/mapper/YwAlarmViewMapper.java | 63 + .../eastcom_yw/mapper/YwAlarmWXMapper.java | 26 + .../mapper/YwConstrucTeamMapper.java | 15 + .../eastcom_yw/mapper/YwDrsConfigMapper.java | 22 + .../mapper/YwDrsTempTaskMapper.java | 26 + .../eastcom_yw/mapper/YwKpiConfigMapper.java | 17 + .../mapper/YwNoticeBriefingMapper.java | 26 + .../mapper/YwNoticeHandworkMapper.java | 23 + .../mapper/YwNoticeHandworkdetailMapper.java | 16 + .../eastcom_yw/mapper/YwNoticeListMapper.java | 17 + .../mapper/YwNoticeModelMapper.java | 17 + .../mapper/YwNoticeObjectMapper.java | 20 + .../eastcom_yw/mapper/YwNoticeUserMapper.java | 25 + .../mapper/YwRoutInspectConfigMapper.java | 19 + .../mapper/YwRoutInspectLogMapper.java | 21 + .../mapper/YwRoutInspectPlanMapper.java | 77 + .../YwRoutInspectQuestionConfigMapper.java | 23 + .../eastcom_yw/mapper/YwSceneAlarmMapper.java | 27 + .../mapper/YwSceneBigConfigMapper.java | 20 + .../mapper/YwSceneCalendarMapper.java | 86 + .../eastcom_yw/mapper/YwSceneMapper.java | 69 + .../eastcom_yw/mapper/YwSceneMatchMapper.java | 20 + .../mapper/YwSceneNetelementAgisMapper.java | 24 + .../mapper/YwSceneNetelementCsMapper.java | 26 + .../mapper/YwSceneNetelementDhMapper.java | 26 + .../mapper/YwSceneNetelementMapper.java | 30 + .../mapper/YwSceneNetelementWxMapper.java | 31 + .../mapper/YwSceneNoticeinfoMapper.java | 51 + .../mapper/YwScenePictureMapper.java | 88 + .../YwSceneTestDataInterfaceMapper.java | 15 + .../mapper/YwSceneTestDataMapper.java | 38 + .../eastcom_yw/mapper/YwSceneUserMapper.java | 50 + .../eastcom_yw/mapper/YwSceneViewMapper.java | 29 + .../eastcom_yw/mapper/YwSignLogMapper.java | 32 + .../mapper/YwSignLogViewMapper.java | 21 + .../eastcom_yw/mapper/YwSignPlanMapper.java | 27 + .../eastcom_yw/mapper/YwSparePartsMapper.java | 28 + .../mapper/YwWireTaskLogMapper.java | 27 + .../mapper/yw_alarm_deal_logMapper.java | 25 + .../mapper/yw_alarm_deal_resMapper.java | 7 + .../eastcom_yw/service/AppVersionService.java | 8 + .../eastcom_yw/service/CommonService.java | 35 + .../eastcom_yw/service/Dp2MmlListService.java | 77 + .../service/Dp2SpotCellService.java | 85 + .../service/Dp2SpotConfigService.java | 88 + .../service/Dp2ViewPowerAlarmService.java | 56 + .../service/Dp2ViewWirelessAlarmService.java | 82 + .../service/DpSceneConfigService.java | 86 + .../service/HmAlarmDeriveService.java | 23 + .../service/LargeScreenService.java | 25 + .../eastcom_yw/service/OpenApiService.java | 15 + .../service/PmKpi4gCellService.java | 42 + .../eastcom_yw/service/PmKpi4gMinService.java | 90 + .../service/PmKpi4gVenueService.java | 30 + .../service/PmKpi5gCellService.java | 42 + .../eastcom_yw/service/PmKpi5gMinService.java | 84 + .../service/PmKpi5gVenueService.java | 36 + .../service/PmKpiMonitorCellService.java | 38 + .../eastcom_yw/service/SysNoticeService.java | 106 + .../eastcom_yw/service/WeatherService.java | 11 + .../eastcom_yw/service/YwAlarmCSService.java | 21 + .../eastcom_yw/service/YwAlarmDHService.java | 25 + .../service/YwAlarmHangupLogService.java | 20 + .../service/YwAlarmOprateLogService.java | 16 + .../eastcom_yw/service/YwAlarmService.java | 32 + .../service/YwAlarmViewService.java | 55 + .../eastcom_yw/service/YwAlarmWXService.java | 21 + .../service/YwDrsConfigService.java | 86 + .../service/YwDrsTempTaskService.java | 89 + .../service/YwKpiConfigService.java | 82 + .../service/YwNoticeBriefingService.java | 152 ++ .../service/YwNoticeHandworkService.java | 92 + .../YwNoticeHandworkdetailService.java | 87 + .../service/YwNoticeListService.java | 87 + .../service/YwNoticeModelService.java | 88 + .../service/YwNoticeObjectService.java | 95 + .../service/YwNoticeUserService.java | 22 + .../service/YwRoutInspectConfigService.java | 17 + .../service/YwRoutInspectLogService.java | 12 + .../service/YwRoutInspectPlanService.java | 93 + .../YwRoutInspectQuestionConfigService.java | 26 + .../service/YwSceneAlarmService.java | 30 + .../service/YwSceneCalendarService.java | 35 + .../service/YwSceneMatchService.java | 33 + .../service/YwSceneNetelementAgisService.java | 34 + .../service/YwSceneNetelementCsService.java | 32 + .../service/YwSceneNetelementDhService.java | 32 + .../service/YwSceneNetelementService.java | 30 + .../service/YwSceneNetelementWxService.java | 39 + .../service/YwSceneNoticeinfoService.java | 39 + .../service/YwScenePictureService.java | 71 + .../eastcom_yw/service/YwSceneService.java | 78 + .../service/YwSceneTestDataService.java | 13 + .../service/YwSceneUserService.java | 44 + .../eastcom_yw/service/YwSignLogService.java | 15 + .../service/YwSignLogViewService.java | 24 + .../eastcom_yw/service/YwSignPlanService.java | 30 + .../service/YwSparePartsService.java | 88 + .../service/YwWireTaskLogService.java | 30 + .../service/convert/Dp2SpotCellConvert.java | 25 + .../service/convert/Dp2SpotConfigConvert.java | 25 + .../convert/Dp2ViewPowerAlarmConvert.java | 25 + .../convert/Dp2ViewWirelessAlarmConvert.java | 25 + .../service/convert/DpSceneConfigConvert.java | 26 + .../service/convert/PmKpi4gCellConvert.java | 25 + .../service/convert/PmKpi4gMinConvert.java | 26 + .../service/convert/PmKpi4gVenueConvert.java | 27 + .../service/convert/PmKpi5gCellConvert.java | 26 + .../service/convert/PmKpi5gMinConvert.java | 26 + .../service/convert/PmKpi5gVenueConvert.java | 26 + .../service/convert/SysNoticeConvert.java | 25 + .../service/convert/YwDrsConfigConvert.java | 25 + .../service/convert/YwDrsTempTaskConvert.java | 25 + .../service/convert/YwKpiConfigConvert.java | 26 + .../convert/YwNoticeBriefingConvert.java | 30 + .../convert/YwNoticeHandworkConvert.java | 30 + .../YwNoticeHandworkdetailConvert.java | 26 + .../service/convert/YwNoticeListConvert.java | 25 + .../service/convert/YwNoticeModelConvert.java | 26 + .../convert/YwNoticeObjectConvert.java | 27 + .../service/convert/YwSparePartsConvert.java | 26 + .../service/impl/AppVersionServiceImpl.java | 11 + .../service/impl/CommonServiceImpl.java | 348 +++ .../service/impl/Dp2MmlListServiceImpl.java | 115 + .../service/impl/Dp2SpotCellServiceImpl.java | 312 +++ .../impl/Dp2SpotConfigServiceImpl.java | 130 ++ .../impl/Dp2ViewPowerAlarmServiceImpl.java | 86 + .../impl/Dp2ViewWirelessAlarmServiceImpl.java | 129 ++ .../impl/DpSceneConfigServiceImpl.java | 166 ++ .../impl/HmAlarmDeriveServiceImpl.java | 192 ++ .../service/impl/LargeScreenServiceImpl.java | 62 + .../service/impl/OpenApiServiceImpl.java | 41 + .../service/impl/PmKpi4gCellServiceImpl.java | 208 ++ .../service/impl/PmKpi4gMinServiceImpl.java | 269 +++ .../service/impl/PmKpi4gVenueServiceImpl.java | 117 + .../service/impl/PmKpi5gCellServiceImpl.java | 229 ++ .../service/impl/PmKpi5gMinServiceImpl.java | 271 +++ .../service/impl/PmKpi5gVenueServiceImpl.java | 127 ++ .../impl/PmKpiMonitorCellServiceImpl.java | 747 +++++++ .../service/impl/SysNoticeServiceImpl.java | 341 +++ .../service/impl/WeatherServiceImpl.java | 102 + .../service/impl/YwAlarmCSServiceImpl.java | 225 ++ .../service/impl/YwAlarmDHServiceImpl.java | 216 ++ .../impl/YwAlarmHangupLogServiceImpl.java | 161 ++ .../impl/YwAlarmOprateLogServiceImpl.java | 20 + .../service/impl/YwAlarmServiceImpl.java | 402 ++++ .../service/impl/YwAlarmViewServiceImpl.java | 819 +++++++ .../service/impl/YwAlarmWXServiceImpl.java | 216 ++ .../service/impl/YwDrsConfigServiceImpl.java | 119 + .../impl/YwDrsTempTaskServiceImpl.java | 410 ++++ .../service/impl/YwKpiConfigServiceImpl.java | 149 ++ .../impl/YwNoticeBriefingServiceImpl.java | 1598 ++++++++++++++ .../impl/YwNoticeHandworkServiceImpl.java | 382 ++++ .../YwNoticeHandworkdetailServiceImpl.java | 153 ++ .../service/impl/YwNoticeListServiceImpl.java | 238 ++ .../impl/YwNoticeModelServiceImpl.java | 237 ++ .../impl/YwNoticeObjectServiceImpl.java | 607 ++++++ .../service/impl/YwNoticeUserServiceImpl.java | 262 +++ .../impl/YwRoutInspectConfigServiceImpl.java | 28 + .../impl/YwRoutInspectLogServiceImpl.java | 30 + .../impl/YwRoutInspectPlanServiceImpl.java | 661 ++++++ ...wRoutInspectQuestionConfigServiceImpl.java | 73 + .../service/impl/YwSceneAlarmServiceImpl.java | 74 + .../impl/YwSceneCalendarServiceImpl.java | 94 + .../service/impl/YwSceneMatchServiceImpl.java | 49 + .../YwSceneNetelementAgisServiceImpl.java | 77 + .../impl/YwSceneNetelementCsServiceImpl.java | 78 + .../impl/YwSceneNetelementDhServiceImpl.java | 70 + .../impl/YwSceneNetelementServiceImpl.java | 86 + .../impl/YwSceneNetelementWxServiceImpl.java | 151 ++ .../impl/YwSceneNoticeinfoServiceImpl.java | 272 +++ .../impl/YwScenePictureServiceImpl.java | 724 +++++++ .../service/impl/YwSceneServiceImpl.java | 706 ++++++ .../impl/YwSceneTestDataServiceImpl.java | 186 ++ .../service/impl/YwSceneUserServiceImpl.java | 208 ++ .../service/impl/YwSignLogServiceImpl.java | 284 +++ .../impl/YwSignLogViewServiceImpl.java | 257 +++ .../service/impl/YwSignPlanServiceImpl.java | 769 +++++++ .../service/impl/YwSparePartsServiceImpl.java | 162 ++ .../impl/YwWireTaskLogServiceImpl.java | 533 +++++ .../impl/yw_alarm_deal_logServiceImpl.java | 63 + .../impl/yw_alarm_deal_resServiceImpl.java | 20 + .../service/yw_alarm_deal_logService.java | 17 + .../service/yw_alarm_deal_resService.java | 16 + .../eastcom_yw/Dp2AgisLink5miMapper.xml | 23 + .../mapper/eastcom_yw/Dp2MmlListMapper.xml | 17 + .../eastcom_yw/Dp2PnNetVenue5miMapper.xml | 35 + .../mapper/eastcom_yw/Dp2SpotCellMapper.xml | 16 + .../mapper/eastcom_yw/Dp2SpotConfigMapper.xml | 12 + .../eastcom_yw/Dp2ViewPowerAlarmMapper.xml | 20 + .../eastcom_yw/Dp2ViewWirelessAlarmMapper.xml | 23 + .../mapper/eastcom_yw/DpSceneConfigMapper.xml | 63 + .../mapper/eastcom_yw/LargeScreenMapper.xml | 202 ++ .../mapper/eastcom_yw/PmKpi4gCellMapper.xml | 421 ++++ .../mapper/eastcom_yw/PmKpi4gMinMapper.xml | 184 ++ .../mapper/eastcom_yw/PmKpi4gVenueMapper.xml | 95 + .../mapper/eastcom_yw/PmKpi5gCellMapper.xml | 397 ++++ .../mapper/eastcom_yw/PmKpi5gMinMapper.xml | 178 ++ .../mapper/eastcom_yw/PmKpi5gVenueMapper.xml | 99 + .../mapper/eastcom_yw/SysNoticeMapper.xml | 130 ++ .../eastcom_yw/YwAlarmHangupLogMapper.xml | 11 + .../mapper/eastcom_yw/YwAlarmMapper.xml | 218 ++ .../eastcom_yw/YwAlarmStatisticsMapper.xml | 59 + .../mapper/eastcom_yw/YwAlarmViewMapper.xml | 510 +++++ .../eastcom_yw/YwConstrucTeamMapper.xml | 12 + .../mapper/eastcom_yw/YwDrsConfigMapper.xml | 15 + .../mapper/eastcom_yw/YwDrsTempTaskMapper.xml | 31 + .../mapper/eastcom_yw/YwKpiConfigMapper.xml | 5 + .../eastcom_yw/YwNoticeBriefingMapper.xml | 41 + .../eastcom_yw/YwNoticeHandworkMapper.xml | 16 + .../mapper/eastcom_yw/YwNoticeModelMapper.xml | 5 + .../eastcom_yw/YwNoticeObjectMapper.xml | 14 + .../mapper/eastcom_yw/YwNoticeUserMapper.xml | 63 + .../eastcom_yw/YwRoutInspectConfigMapper.xml | 102 + .../eastcom_yw/YwRoutInspectLogMapper.xml | 90 + .../eastcom_yw/YwRoutInspectPlanMapper.xml | 574 +++++ .../YwRoutInspectQuestionConfigMapper.xml | 77 + .../mapper/eastcom_yw/YwSceneAlarmMapper.xml | 122 ++ .../eastcom_yw/YwSceneBigConfigMapper.xml | 11 + .../eastcom_yw/YwSceneCalendarMapper.xml | 194 ++ .../mapper/eastcom_yw/YwSceneMapper.xml | 748 +++++++ .../mapper/eastcom_yw/YwSceneMatchMapper.xml | 30 + .../YwSceneNetelementAgisMapper.xml | 69 + .../eastcom_yw/YwSceneNetelementCsMapper.xml | 158 ++ .../eastcom_yw/YwSceneNetelementDhMapper.xml | 145 ++ .../eastcom_yw/YwSceneNetelementMapper.xml | 222 ++ .../eastcom_yw/YwSceneNetelementWxMapper.xml | 206 ++ .../eastcom_yw/YwSceneNoticeinfoMapper.xml | 175 ++ .../eastcom_yw/YwScenePictureMapper.xml | 186 ++ .../YwSceneTestDataInterfaceMapper.xml | 7 + .../eastcom_yw/YwSceneTestDataMapper.xml | 32 + .../mapper/eastcom_yw/YwSceneUserMapper.xml | 225 ++ .../mapper/eastcom_yw/YwSignLogMapper.xml | 89 + .../mapper/eastcom_yw/YwSignLogViewMapper.xml | 286 +++ .../mapper/eastcom_yw/YwSignPlanMapper.xml | 115 + .../mapper/eastcom_yw/YwSparePartsMapper.xml | 21 + .../mapper/eastcom_yw/YwWireTaskLogMapper.xml | 76 + .../eastcom_yw/yw_alarm_deal_logMapper.xml | 18 + pom.xml | 339 +++ ruoyi-admin/pom.xml | 140 ++ .../main/java/com/ruoyi/RuoYiApplication.java | 42 + .../com/ruoyi/RuoYiServletInitializer.java | 18 + .../cmcc_gm/YwMaterialsClassesController.java | 197 ++ .../cmcc_gm/YwMaterialsController.java | 967 +++++++++ .../cmcc_gm/YwMaterialsInformController.java | 234 ++ .../YwMaterialsOrderLogController.java | 238 ++ .../cmcc_gm/YwMaterialsStockController.java | 124 ++ .../controller/common/CaptchaController.java | 94 + .../controller/common/CommonController.java | 262 +++ .../eastcom_yw/Dp2MmlListController.java | 116 + .../eastcom_yw/Dp2SpotCellController.java | 117 + .../eastcom_yw/Dp2SpotConfigController.java | 120 ++ .../Dp2ViewPowerAlarmController.java | 81 + .../Dp2ViewWirelessAlarmController.java | 84 + .../eastcom_yw/DpSceneConfigController.java | 154 ++ .../eastcom_yw/LargeScreenController.java | 101 + .../eastcom_yw/WeatherController.java | 29 + .../eastcom_yw/YwAlarmController.java | 1068 +++++++++ .../eastcom_yw/YwDrsConfigController.java | 124 ++ .../eastcom_yw/YwDrsTempTaskController.java | 142 ++ .../eastcom_yw/YwKpiConfigController.java | 135 ++ .../eastcom_yw/YwKpiController.java | 366 ++++ .../YwMaterialsBatchController.java | 142 ++ .../YwNoticeBriefingController.java | 189 ++ .../YwNoticeHandworkController.java | 124 ++ .../YwNoticeHandworkdetailController.java | 124 ++ .../eastcom_yw/YwNoticeListController.java | 124 ++ .../eastcom_yw/YwNoticeModelController.java | 192 ++ .../eastcom_yw/YwNoticeObjectController.java | 138 ++ .../eastcom_yw/YwNoticeUserController.java | 272 +++ .../YwRoutInspectLogController.java | 39 + .../YwRoutInspectPlanController.java | 297 +++ ...YwRoutInspectQuestionConfigController.java | 86 + .../eastcom_yw/YwSceneAlarmController.java | 80 + .../eastcom_yw/YwSceneCalendarController.java | 93 + .../eastcom_yw/YwSceneController.java | 254 +++ .../eastcom_yw/YwSceneMatchController.java | 40 + .../YwSceneNetelementAgisController.java | 93 + .../YwSceneNetelementController.java | 84 + .../YwSceneNetelementCsController.java | 88 + .../YwSceneNetelementDhController.java | 89 + .../YwSceneNetelementWxController.java | 140 ++ .../YwSceneNoticeinfoController.java | 190 ++ .../eastcom_yw/YwScenePictureController.java | 118 + .../eastcom_yw/YwSceneTestDataController.java | 40 + .../eastcom_yw/YwSceneUserController.java | 135 ++ .../eastcom_yw/YwSignController.java | 312 +++ .../eastcom_yw/YwSparePartsController.java | 125 ++ .../eastcom_yw/YwWireTaskLogController.java | 418 ++++ .../controller/monitor/CacheController.java | 122 ++ .../controller/monitor/ServerController.java | 27 + .../monitor/SysLogininforController.java | 82 + .../monitor/SysOperlogController.java | 69 + .../monitor/SysUserOnlineController.java | 145 ++ .../web/controller/sunlm/DpApiController.java | 53 + .../controller/sunlm/dpConfigController.java | 983 +++++++++ .../sunlm/dpNewYayun1Controller.java | 593 +++++ .../sunlm/dpNewYayunController.java | 1909 +++++++++++++++++ .../controller/sunlm/dpYayunController.java | 422 ++++ .../system/SysAppMenuController.java | 118 + .../system/SysConfigController.java | 136 ++ .../controller/system/SysDeptController.java | 132 ++ .../system/SysDictDataController.java | 124 ++ .../system/SysDictTypeController.java | 132 ++ .../controller/system/SysIndexController.java | 29 + .../controller/system/SysLoginController.java | 226 ++ .../controller/system/SysMenuController.java | 142 ++ .../system/SysNoticeController.java | 140 ++ .../controller/system/SysPostController.java | 130 ++ .../system/SysProfileController.java | 183 ++ .../system/SysRegisterController.java | 38 + .../controller/system/SysRoleController.java | 282 +++ .../controller/system/SysUserController.java | 542 +++++ .../web/controller/tool/TestController.java | 183 ++ .../ruoyi/web/core/config/SwaggerConfig.java | 127 ++ .../META-INF/spring-devtools.properties | 1 + .../src/main/resources/application-bak1.yml | 154 ++ .../src/main/resources/application-bak2.yml | 151 ++ .../src/main/resources/application-druid.yml | 152 ++ .../src/main/resources/application-local.yml | 156 ++ .../src/main/resources/application-ser.yml | 137 ++ .../src/main/resources/application-test.yml | 154 ++ .../src/main/resources/application.properties | 5 + .../src/main/resources/application.yml | 151 ++ ruoyi-admin/src/main/resources/banner.txt | 24 + .../main/resources/i18n/messages.properties | 41 + ruoyi-admin/src/main/resources/logback.xml | 93 + .../main/resources/mybatis/mybatis-config.xml | 20 + .../src/main/resources/rebel-remote.xml | 4 + .../templates/wireReportTemplate.ftl | 3 + .../templates/wireReportTemplate1.ftl | 3 + .../src/test/java/com/ruoyi/wl_test.java | 1000 +++++++++ ruoyi-app/pom.xml | 134 ++ .../java/com/ruoyi/RuoYiAPPApplication.java | 39 + .../com/ruoyi/RuoYiServletInitializer.java | 16 + .../cmcc_gm/YwMaterialsClassesController.java | 113 + .../cmcc_gm/YwMaterialsController.java | 611 ++++++ .../cmcc_gm/YwMaterialsInformController.java | 164 ++ .../YwMaterialsOrderLogController.java | 176 ++ .../controller/common/CaptchaController.java | 94 + .../controller/common/CommonController.java | 229 ++ .../eastcom_yw/AppBaseStationController.java | 58 + .../eastcom_yw/AppKpiController.java | 200 ++ .../eastcom_yw/AppVersionController.java | 30 + .../eastcom_yw/PersonalCenterController.java | 142 ++ .../eastcom_yw/SysNoticeController.java | 124 ++ .../eastcom_yw/WeatherController.java | 29 + .../eastcom_yw/YwAlarmController.java | 704 ++++++ .../eastcom_yw/YwContactBookController.java | 115 + .../eastcom_yw/YwDrsTempTaskController.java | 135 ++ .../YwRoutInspectLogController.java | 45 + .../YwRoutInspectPlanController.java | 173 ++ ...YwRoutInspectQuestionConfigController.java | 93 + .../eastcom_yw/YwSceneController.java | 133 ++ .../eastcom_yw/YwScenePictureController.java | 108 + .../eastcom_yw/YwSignController.java | 368 ++++ .../eastcom_yw/YwWireTaskLogController.java | 167 ++ .../eastcom_yw/dpConfigController.java | 102 + .../controller/monitor/CacheController.java | 120 ++ .../controller/monitor/ServerController.java | 27 + .../monitor/SysLogininforController.java | 82 + .../monitor/SysOperlogController.java | 69 + .../monitor/SysUserOnlineController.java | 92 + .../system/SysAppMenuController.java | 118 + .../system/SysConfigController.java | 134 ++ .../controller/system/SysDeptController.java | 132 ++ .../system/SysDictDataController.java | 135 ++ .../system/SysDictTypeController.java | 132 ++ .../controller/system/SysIndexController.java | 29 + .../controller/system/SysLoginController.java | 167 ++ .../controller/system/SysPostController.java | 130 ++ .../system/SysProfileController.java | 145 ++ .../system/SysRegisterController.java | 38 + .../controller/system/SysRoleController.java | 264 +++ .../controller/system/SysUserController.java | 561 +++++ .../app/controller/tool/TestController.java | 183 ++ .../ruoyi/app/core/config/SwaggerConfig.java | 125 ++ .../META-INF/spring-devtools.properties | 1 + .../src/main/resources/application-bak1.yml | 145 ++ .../src/main/resources/application-bak2.yml | 145 ++ .../src/main/resources/application-druid.yml | 138 ++ .../src/main/resources/application-test.yml | 145 ++ .../src/main/resources/application.properties | 5 + ruoyi-app/src/main/resources/application.yml | 124 ++ ruoyi-app/src/main/resources/banner.txt | 24 + .../main/resources/i18n/messages.properties | 41 + ruoyi-app/src/main/resources/logback.xml | 93 + .../main/resources/mybatis/mybatis-config.xml | 20 + ruoyi-app/src/main/resources/rebel-remote.xml | 4 + ruoyi-common/pom.xml | 230 ++ .../ruoyi/common/annotation/Anonymous.java | 19 + .../com/ruoyi/common/annotation/BindDict.java | 20 + .../ruoyi/common/annotation/DataScope.java | 33 + .../ruoyi/common/annotation/DataSource.java | 28 + .../com/ruoyi/common/annotation/Excel.java | 187 ++ .../com/ruoyi/common/annotation/Excels.java | 18 + .../java/com/ruoyi/common/annotation/Log.java | 46 + .../ruoyi/common/annotation/RateLimiter.java | 40 + .../ruoyi/common/annotation/RepeatSubmit.java | 35 + .../com/ruoyi/common/config/MinioConfig.java | 82 + .../com/ruoyi/common/config/RuoYiConfig.java | 135 ++ .../ruoyi/common/constant/AlarmConstants.java | 13 + .../ruoyi/common/constant/CacheConstants.java | 104 + .../com/ruoyi/common/constant/Constants.java | 150 ++ .../ruoyi/common/constant/GenConstants.java | 117 + .../com/ruoyi/common/constant/HttpStatus.java | 94 + .../common/constant/ScheduleConstants.java | 50 + .../ruoyi/common/constant/TaskConstants.java | 13 + .../ruoyi/common/constant/UserConstants.java | 82 + .../ruoyi/common/constant/WordConstants.java | 13 + .../core/controller/BaseController.java | 216 ++ .../ruoyi/common/core/domain/AjaxResult.java | 185 ++ .../ruoyi/common/core/domain/BaseEntity.java | 129 ++ .../java/com/ruoyi/common/core/domain/R.java | 115 + .../ruoyi/common/core/domain/TreeEntity.java | 79 + .../ruoyi/common/core/domain/TreeSelect.java | 85 + .../common/core/domain/dto/HandleDataDTO.java | 46 + .../common/core/domain/dto/SearchInfo.java | 26 + .../domain/dto/StartProcessInstanceDTO.java | 20 + .../ruoyi/common/core/domain/dto/TaskDTO.java | 27 + .../common/core/domain/dto/json/UserInfo.java | 22 + .../common/core/domain/entity/SysAppMenu.java | 298 +++ .../common/core/domain/entity/SysDept.java | 215 ++ .../core/domain/entity/SysDictData.java | 189 ++ .../core/domain/entity/SysDictType.java | 104 + .../common/core/domain/entity/SysMenu.java | 271 +++ .../common/core/domain/entity/SysRole.java | 286 +++ .../common/core/domain/entity/SysUser.java | 575 +++++ .../core/domain/model/ExcelSelector.java | 41 + .../common/core/domain/model/LoginBody.java | 94 + .../common/core/domain/model/LoginUser.java | 310 +++ .../core/domain/model/RegisterBody.java | 11 + .../ruoyi/common/core/page/PageDomain.java | 101 + .../ruoyi/common/core/page/TableDataInfo.java | 96 + .../ruoyi/common/core/page/TableSupport.java | 56 + .../ruoyi/common/core/redis/RedisCache.java | 268 +++ .../ruoyi/common/core/text/CharsetKit.java | 86 + .../com/ruoyi/common/core/text/Convert.java | 1000 +++++++++ .../ruoyi/common/core/text/StrFormatter.java | 92 + .../ruoyi/common/enums/BusinessStatus.java | 20 + .../com/ruoyi/common/enums/BusinessType.java | 59 + .../ruoyi/common/enums/DataSourceType.java | 19 + .../ruoyi/common/enums/FlowDealStatus.java | 59 + .../com/ruoyi/common/enums/HttpMethod.java | 36 + .../com/ruoyi/common/enums/LimitType.java | 20 + .../com/ruoyi/common/enums/NoticeType.java | 47 + .../com/ruoyi/common/enums/OperatorType.java | 24 + .../com/ruoyi/common/enums/UserStatus.java | 30 + .../common/exception/DemoModeException.java | 15 + .../common/exception/GlobalException.java | 58 + .../common/exception/ServiceException.java | 80 + .../ruoyi/common/exception/UtilException.java | 26 + .../common/exception/base/BaseException.java | 97 + .../common/exception/file/FileException.java | 19 + .../FileNameLengthLimitExceededException.java | 16 + .../file/FileSizeLimitExceededException.java | 16 + .../file/InvalidExtensionException.java | 81 + .../common/exception/job/TaskException.java | 34 + .../exception/user/CaptchaException.java | 16 + .../user/CaptchaExpireException.java | 16 + .../common/exception/user/UserException.java | 18 + .../user/UserPasswordNotMatchException.java | 16 + ...UserPasswordRetryLimitExceedException.java | 16 + .../user/UserSmsNotMatchException.java | 16 + .../UserSmsRetryLimitExceedException.java | 16 + .../filter/PropertyPreExcludeFilter.java | 24 + .../ruoyi/common/filter/RepeatableFilter.java | 52 + .../filter/RepeatedlyRequestWrapper.java | 76 + .../com/ruoyi/common/filter/XssFilter.java | 75 + .../filter/XssHttpServletRequestWrapper.java | 111 + .../ruoyi/common/importer/ImporterBase.java | 527 +++++ .../common/importer/beans/CellFormatBean.java | 79 + .../common/importer/beans/ResultBean.java | 17 + .../beans/enums/ImportResultType.java | 39 + .../importer/service/YwBatchAddService.java | 47 + .../mybatis/JsonListLongTypeHandler.java | 62 + .../java/com/ruoyi/common/utils/AppUtils.java | 85 + .../java/com/ruoyi/common/utils/Arith.java | 114 + .../utils/CoordinateConversionUtils.java | 168 ++ .../com/ruoyi/common/utils/DateUtils.java | 193 ++ .../com/ruoyi/common/utils/DictUtils.java | 188 ++ .../com/ruoyi/common/utils/ExceptionUtil.java | 39 + .../java/com/ruoyi/common/utils/GeoUtils.java | 18 + .../java/com/ruoyi/common/utils/LogUtils.java | 18 + .../com/ruoyi/common/utils/MessageUtils.java | 26 + .../com/ruoyi/common/utils/PageUtils.java | 62 + .../com/ruoyi/common/utils/PasswordUtil.java | 963 +++++++++ .../ruoyi/common/utils/RestTemplateUtils.java | 664 ++++++ .../java/com/ruoyi/common/utils/RsaUtils.java | 148 ++ .../com/ruoyi/common/utils/SecurityUtils.java | 120 ++ .../com/ruoyi/common/utils/ServletUtils.java | 218 ++ .../com/ruoyi/common/utils/StringUtils.java | 633 ++++++ .../java/com/ruoyi/common/utils/Threads.java | 99 + .../java/com/ruoyi/common/utils/ZipUtils.java | 84 + .../ruoyi/common/utils/bean/BeanUtils.java | 110 + .../common/utils/bean/BeanValidators.java | 24 + .../common/utils/file/FileTypeUtils.java | 76 + .../common/utils/file/FileUploadUtils.java | 319 +++ .../ruoyi/common/utils/file/FileUtils.java | 293 +++ .../ruoyi/common/utils/file/ImageUtils.java | 98 + .../common/utils/file/MimeTypeUtils.java | 59 + .../ruoyi/common/utils/file/MinioUtil.java | 43 + .../common/utils/file/XmlDocToDocxUtil.java | 41 + .../ruoyi/common/utils/html/EscapeUtil.java | 167 ++ .../ruoyi/common/utils/html/HTMLFilter.java | 570 +++++ .../ruoyi/common/utils/http/HttpHelper.java | 55 + .../ruoyi/common/utils/http/HttpUtils.java | 328 +++ .../ruoyi/common/utils/ip/AddressUtils.java | 56 + .../com/ruoyi/common/utils/ip/IpUtils.java | 264 +++ .../common/utils/poi/EasyPoiExcelUtil.java | 104 + .../common/utils/poi/ExcelHandlerAdapter.java | 19 + .../com/ruoyi/common/utils/poi/ExcelUtil.java | 1721 +++++++++++++++ .../poi/LocalDateExcelHandlerAdapter.java | 13 + .../poi/LocalDateTimeExcelHandlerAdapter.java | 14 + .../com/ruoyi/common/utils/poi/WordUtil.java | 47 + .../common/utils/reflect/ReflectUtils.java | 489 +++++ .../com/ruoyi/common/utils/sign/Base64.java | 291 +++ .../com/ruoyi/common/utils/sign/Md5Utils.java | 67 + .../common/utils/spring/SpringUtils.java | 158 ++ .../com/ruoyi/common/utils/sql/SqlUtil.java | 61 + .../com/ruoyi/common/utils/uuid/IdUtils.java | 49 + .../java/com/ruoyi/common/utils/uuid/Seq.java | 86 + .../com/ruoyi/common/utils/uuid/UUID.java | 484 +++++ .../main/java/com/ruoyi/common/xss/Xss.java | 27 + .../com/ruoyi/common/xss/XssValidator.java | 34 + ruoyi-framework/pom.xml | 76 + .../framework/aspectj/BindDictAspect.java | 161 ++ .../framework/aspectj/DataScopeAspect.java | 168 ++ .../framework/aspectj/DataSourceAspect.java | 72 + .../ruoyi/framework/aspectj/LogAspect.java | 227 ++ .../framework/aspectj/RateLimiterAspect.java | 90 + .../framework/config/ApplicationConfig.java | 30 + .../ruoyi/framework/config/CaptchaConfig.java | 83 + .../ruoyi/framework/config/DruidConfig.java | 126 ++ .../config/FastJson2JsonRedisSerializer.java | 48 + .../ruoyi/framework/config/FilterConfig.java | 58 + .../framework/config/KaptchaTextCreator.java | 68 + .../ruoyi/framework/config/MyBatisConfig.zip | Bin 0 -> 1713 bytes .../framework/config/MybatisPlusConfig.java | 80 + .../ruoyi/framework/config/RedisConfig.java | 81 + .../framework/config/RedissonConfig.java | 27 + .../framework/config/ResourcesConfig.java | 126 ++ .../framework/config/SecurityConfig.java | 158 ++ .../ruoyi/framework/config/ServerConfig.java | 32 + .../framework/config/ThreadPoolConfig.java | 63 + .../config/properties/DruidProperties.java | 77 + .../properties/PermitAllUrlProperties.java | 72 + .../datasource/DynamicDataSource.java | 26 + .../DynamicDataSourceContextHolder.java | 45 + .../handler/MyMetaObjectHandler.java | 68 + .../interceptor/RepeatSubmitInterceptor.java | 72 + .../impl/SameUrlDataInterceptor.java | 213 ++ .../listener/RedisKeyExpirationListener.java | 61 + .../ruoyi/framework/manager/AsyncManager.java | 55 + .../framework/manager/ShutdownManager.java | 39 + .../manager/factory/AsyncFactory.java | 102 + .../context/AuthenticationContextHolder.java | 28 + .../context/PermissionContextHolder.java | 27 + .../filter/JwtAuthenticationTokenFilter.java | 44 + .../handle/AuthenticationEntryPointImpl.java | 34 + .../handle/LogoutSuccessHandlerImpl.java | 58 + .../sms/SmsCodeAuthenticationProvider.java | 52 + .../sms/SmsCodeAuthenticationToken.java | 73 + .../ruoyi/framework/web/domain/Server.java | 240 +++ .../framework/web/domain/SysNoticeEntity.java | 125 ++ .../web/domain/dto/MobileOfficesDTO.java | 47 + .../framework/web/domain/server/Cpu.java | 101 + .../framework/web/domain/server/Jvm.java | 130 ++ .../framework/web/domain/server/Mem.java | 61 + .../framework/web/domain/server/Sys.java | 84 + .../framework/web/domain/server/SysFile.java | 114 + .../web/exception/ErrorInfoBuilder.java | 138 ++ .../web/exception/GlobalExceptionHandler.java | 188 ++ .../framework/web/mapper/SysLoginMapper.java | 11 + .../web/service/AppPermissionService.java | 169 ++ .../web/service/PermissionService.java | 168 ++ .../web/service/SysLoginService.java | 438 ++++ .../web/service/SysPasswordService.java | 94 + .../web/service/SysPermissionService.java | 122 ++ .../web/service/SysRegisterService.java | 115 + .../framework/web/service/SysSmsService.java | 119 + .../framework/web/service/TokenService.java | 289 +++ .../UserDetailsByTelephoneServiceImpl.java | 101 + .../web/service/UserDetailsServiceImpl.java | 65 + .../web/service/sms/MessageService.java | 54 + .../web/service/sms/MessageServiceImpl.java | 361 ++++ .../web/service/sms/SmsRsponseVo.java | 16 + ruoyi-generator/pom.xml | 69 + .../ruoyi/generator/MyBatisPlusGenerator.java | 75 + .../com/ruoyi/generator/config/GenConfig.java | 73 + .../generator/controller/GenController.java | 214 ++ .../com/ruoyi/generator/domain/GenTable.java | 372 ++++ .../generator/domain/GenTableColumn.java | 373 ++++ .../mapper/GenTableColumnMapper.java | 60 + .../generator/mapper/GenTableMapper.java | 83 + .../service/GenTableColumnServiceImpl.java | 68 + .../service/GenTableServiceImpl.java | 521 +++++ .../service/IGenTableColumnService.java | 44 + .../generator/service/IGenTableService.java | 121 ++ .../com/ruoyi/generator/util/GenUtils.java | 257 +++ .../generator/util/VelocityInitializer.java | 34 + .../ruoyi/generator/util/VelocityUtils.java | 402 ++++ .../src/main/resources/generator.yml | 10 + .../mapper/generator/GenTableColumnMapper.xml | 127 ++ .../mapper/generator/GenTableMapper.xml | 204 ++ .../resources/templates/controller.java.ftl | 137 ++ .../resources/templates/controller.java.vm | 44 + .../main/resources/templates/convert.java.ftl | 22 + .../src/main/resources/templates/dto.java.ftl | 117 + .../main/resources/templates/entity.java.ftl | 136 ++ .../main/resources/templates/entity.java.vm | 165 ++ .../main/resources/templates/mapper.xml.ftl | 39 + .../main/resources/templates/mapper.xml.vm | 39 + .../src/main/resources/templates/qo.java.ftl | 116 + .../main/resources/templates/service.java.ftl | 80 + .../main/resources/templates/service.java.vm | 20 + .../resources/templates/serviceImpl.java.ftl | 175 ++ .../resources/templates/serviceImpl.java.vm | 26 + .../src/main/resources/templates/vo.java.ftl | 116 + .../main/resources/vm/java/controller.java.vm | 115 + .../src/main/resources/vm/java/domain.java.vm | 105 + .../src/main/resources/vm/java/mapper.java.vm | 91 + .../main/resources/vm/java/service.java.vm | 61 + .../resources/vm/java/serviceImpl.java.vm | 169 ++ .../main/resources/vm/java/sub-domain.java.vm | 76 + .../src/main/resources/vm/js/api.js.vm | 44 + .../src/main/resources/vm/sql/sql.vm | 22 + .../main/resources/vm/vue/index-tree.vue.vm | 505 +++++ .../src/main/resources/vm/vue/index.vue.vm | 602 ++++++ .../resources/vm/vue/v3/index-tree.vue.vm | 475 ++++ .../src/main/resources/vm/vue/v3/index.vue.vm | 590 +++++ .../src/main/resources/vm/vue/v3/readme.txt | 1 + .../src/main/resources/vm/xml/mapper.xml.vm | 135 ++ ruoyi-quartz/pom.xml | 58 + .../ruoyi/quartz/config/ScheduleConfig.java | 57 + .../quartz/controller/SysJobController.java | 185 ++ .../controller/SysJobLogController.java | 92 + .../java/com/ruoyi/quartz/domain/SysJob.java | 171 ++ .../com/ruoyi/quartz/domain/SysJobLog.java | 155 ++ .../ruoyi/quartz/mapper/SysJobLogMapper.java | 67 + .../com/ruoyi/quartz/mapper/SysJobMapper.java | 67 + .../quartz/service/ISysJobLogService.java | 56 + .../ruoyi/quartz/service/ISysJobService.java | 102 + .../service/impl/SysJobLogServiceImpl.java | 87 + .../service/impl/SysJobServiceImpl.java | 266 +++ .../java/com/ruoyi/quartz/task/RyTask.java | 223 ++ .../ruoyi/quartz/util/AbstractQuartzJob.java | 145 ++ .../java/com/ruoyi/quartz/util/CronUtils.java | 63 + .../com/ruoyi/quartz/util/JobInvokeUtil.java | 182 ++ .../QuartzDisallowConcurrentExecution.java | 21 + .../ruoyi/quartz/util/QuartzJobExecution.java | 19 + .../com/ruoyi/quartz/util/ScheduleUtils.java | 139 ++ .../mapper/quartz/SysJobLogMapper.xml | 99 + .../resources/mapper/quartz/SysJobMapper.xml | 111 + ruoyi-sunlm/pom.xml | 44 + .../sunlm/daping/class_dp_1_cache_config.java | 9 + .../class_dp_1_device_alarm_counts.java | 9 + .../class_dp_1_device_alarms_counts_ext.java | 15 + .../daping/class_dp_1_gbflow_wireless.java | 47 + .../class_dp_1_gbflow_wireless_compare.java | 10 + .../daping/class_dp_1_manage_counts.java | 13 + .../sunlm/daping/class_dp_1_maps_alarms.java | 31 + .../class_dp_1_outservice_wireless.java | 11 + .../class_dp_2_bts_wireless_alarms.java | 14 + .../daping/class_dp_2_code_net_alarms.java | 17 + .../daping/class_dp_2_freq_statistics.java | 9 + .../sunlm/daping/class_dp_2_kpi_spot.java | 15 + .../daping/class_dp_2_kpi_spot_cell.java | 15 + .../class_dp_2_kpi_spot_celldetail.java | 27 + .../sunlm/daping/class_dp_2_kpi_spot_kpi.java | 10 + .../class_dp_2_out_wireless_alarms.java | 15 + .../sunlm/daping/class_dp_2_power_alarm.java | 15 + .../daping/class_dp_2_scene_control.java | 17 + .../daping/class_dp_2_scene_seat_detail.java | 13 + .../daping/class_dp_2_scene_seat_info.java | 14 + .../daping/class_dp_2_scene_test_data.java | 21 + .../sunlm/daping/class_dp_2_scenelist.java | 12 + .../daping/class_dp_2_seat_chinesename.java | 10 + .../class_dp_2_seat_wireless_alarms.java | 12 + .../daping/class_dp_2_site_cell_info.java | 16 + .../sunlm/daping/class_dp_2_spotdetail.java | 15 + .../sunlm/daping/class_dp_2_spotlist.java | 11 + .../ruoyi/sunlm/daping/class_dp_2_top5.java | 41 + .../sunlm/daping/class_dp_2_top5_allspot.java | 11 + .../sunlm/daping/class_dp_2_top5_spot.java | 11 + .../sunlm/daping/class_dp_2_usercounts.java | 13 + .../daping/class_dp_2_usercounts_compare.java | 10 + .../daping/class_dp_2_wireless_alarm.java | 19 + .../daping/class_dp_2_wireless_highload.java | 17 + .../sunlm/daping/class_dp_3_gb_top5.java | 15 + .../sunlm/daping/class_dp_3_maps_alarms.java | 23 + .../sunlm/daping/class_dp_3_net_alarm.java | 22 + .../sunlm/daping/class_dp_3_opticalpower.java | 18 + .../sunlm/daping/class_dp_3_trans_alarm.java | 17 + .../sunlm/daping/class_dp_4_maps_alarms.java | 22 + .../daping/class_dp_5_scenecontacts.java | 17 + .../sunlm/daping/class_dp_5_scenesta.java | 30 + .../sunlm/daping/class_dp_6_dict_alarm.java | 13 + .../daping/class_dp_6_dict_alarm_monitor.java | 11 + .../daping/class_dp_6_dict_kpi_monitor.java | 14 + .../daping/class_dp_6_dict_link_alarm.java | 16 + .../sunlm/daping/class_dp_6_dict_links.java | 13 + .../sunlm/daping/class_dp_6_dict_maps.java | 14 + .../sunlm/daping/class_dp_6_dict_project.java | 14 + .../class_dp_6_dict_project_statis.java | 11 + .../daping/class_dp_map_agis_dev_15mi.java | 20 + .../daping/class_dp_map_agis_link_5mi.java | 21 + .../sunlm/daping/class_dp_map_alarms.java | 22 + .../ruoyi/sunlm/daping/dp3d/NewCommonDTO.java | 16 + .../sunlm/daping/dp3d/NewDpKpiMonitorQO.java | 59 + .../sunlm/daping/dp3d/NewDpSceneConfig.java | 74 + .../sunlm/daping/dp3d/NewDpSceneConfigQO.java | 80 + .../sunlm/daping/dp3d/NewKpiConstants.java | 45 + .../sunlm/daping/dp3d/NewMonitorCellVo.java | 79 + .../ruoyi/sunlm/daping/dp3d/NewPageDTO.java | 16 + .../daping/dp3d/NewPmKpi15CellMonitorVO.java | 109 + .../sunlm/daping/dp3d/NewPmKpi4gCell.java | 200 ++ .../sunlm/daping/dp3d/NewPmKpi4gMin.java | 126 ++ .../sunlm/daping/dp3d/NewPmKpi5gCell.java | 183 ++ .../sunlm/daping/dp3d/NewPmKpi5gMin.java | 109 + .../daping/dp3d/NewPmKpiCellMonitorQO.java | 92 + .../sunlm/daping/dp3d/NewPmKpiCellQO.java | 82 + .../sunlm/daping/dp3d/NewPmKpiColorQo.java | 44 + .../sunlm/daping/dp3d/NewPmKpiMinQO.java | 70 + .../daping/dp3d/NewPmKpiMonitorEntity.java | 81 + .../ruoyi/sunlm/daping/dp3d/NewPmKpiVO.java | 52 + .../ruoyi/sunlm/daping/dp3d/NewRecordVo.java | 27 + .../ruoyi/sunlm/domain/class_dp_btsinfo.java | 36 + .../ruoyi/sunlm/domain/class_dp_compare.java | 10 + .../ruoyi/sunlm/domain/class_dp_left_1.java | 47 + .../ruoyi/sunlm/domain/class_dp_left_2.java | 45 + .../com/ruoyi/sunlm/domain/class_dp_maps.java | 34 + .../sunlm/domain/class_dp_maps_topinfo.java | 71 + .../sunlm/domain/class_dp_scene_control.java | 14 + .../domain/class_dp_scene_seat_detail.java | 13 + .../domain/class_dp_scene_seat_info.java | 14 + .../sunlm/domain/class_dp_scenelist.java | 9 + .../com/ruoyi/sunlm/domain/class_dp_top5.java | 41 + .../ruoyi/sunlm/domain/class_dp_topinfo.java | 19 + .../ruoyi/sunlm/domain/class_medal_stand.java | 43 + .../ruoyi/sunlm/domain/class_public_news.java | 33 + .../sunlm/domain/class_scene_big_config.java | 41 + .../sunlm/domain/class_scene_calendar.java | 44 + .../ruoyi/sunlm/domain/class_scene_match.java | 44 + .../ruoyi/sunlm/domain/class_scene_team.java | 51 + .../sunlm/domain/class_scene_team_scene.java | 11 + .../sunlm/domain/class_scene_team_user.java | 11 + .../sunlm/entity/class_medal_stand_list.java | 9 + .../sunlm/entity/class_medal_stand_new.java | 14 + .../sunlm/entity/class_medal_stand_upt.java | 15 + .../sunlm/entity/class_public_news_list.java | 12 + .../sunlm/entity/class_public_news_new.java | 14 + .../sunlm/entity/class_public_news_upt.java | 13 + .../sunlm/entity/class_scene_team_list.java | 16 + .../sunlm/entity/class_scene_team_new.java | 18 + .../sunlm/entity/class_scene_team_upt.java | 19 + .../com/ruoyi/sunlm/entity/publicEntity.java | 13 + .../sunlm/entity/scene_big_entity_list.java | 15 + .../sunlm/entity/scene_big_entity_new.java | 13 + .../sunlm/entity/scene_big_entity_upt.java | 13 + .../entity/scene_calendar_entity_list.java | 17 + .../entity/scene_calendar_entity_new.java | 17 + .../entity/scene_calendar_entity_upt.java | 17 + .../sunlm/entity/scene_match_entity_list.java | 19 + .../sunlm/entity/scene_match_entity_new.java | 15 + .../sunlm/entity/scene_match_entity_upt.java | 15 + .../com/ruoyi/sunlm/mapper/DpApiMapper.java | 65 + .../ruoyi/sunlm/mapper/NewDpApiMapper.java | 68 + .../sunlm/mapper/NewDpSceneConfigMapper.java | 56 + .../sunlm/mapper/NewPmKpi4gCellMapper.java | 28 + .../sunlm/mapper/NewPmKpi4gMinMapper.java | 28 + .../sunlm/mapper/NewPmKpi5gCellMapper.java | 27 + .../sunlm/mapper/NewPmKpi5gMinMapper.java | 26 + .../ruoyi/sunlm/mapper/dpConfigMapper.java | 1031 +++++++++ .../mapper/dpNewYayun_ChuanDong_Mapper.java | 172 ++ .../sunlm/mapper/dpNewYayun_Dict_Mapper.java | 99 + .../mapper/dpNewYayun_Gailan_Mapper.java | 260 +++ .../mapper/dpNewYayun_Wuxian_Mapper.java | 1394 ++++++++++++ .../mapper/dpNewYayun_ZhuanWang_Mapper.java | 358 ++++ .../mapper/dpNewYayun_ZongHe_Mapper.java | 79 + .../com/ruoyi/sunlm/mapper/dpYayunMapper.java | 1089 ++++++++++ .../sunlm/mapper/dpYayunReplayMapper.java | 618 ++++++ .../service/NewPmKpiMonitorCellService.java | 15 + .../sunlm/service/YwDpNewYayunService.java | 14 + .../ruoyi/sunlm/service/dpAllMyServices.java | 27 + .../impl/NewPmKpiMonitorCellServiceImpl.java | 505 +++++ .../service/impl/YwDpNewYayunServiceImpl.java | 291 +++ .../service/impl/dpAllMyServicesImpl.java | 218 ++ .../mapper/sunlm/NewDpSceneConfigMapper.xml | 63 + .../mapper/sunlm/NewPmKpi4gCellMapper.xml | 131 ++ .../mapper/sunlm/NewPmKpi4gMinMapper.xml | 120 ++ .../mapper/sunlm/NewPmKpi5gCellMapper.xml | 120 ++ .../mapper/sunlm/NewPmKpi5gMinMapper.xml | 120 ++ ruoyi-system/pom.xml | 28 + .../ruoyi/system/domain/SysAppRoleMenu.java | 51 + .../ruoyi/system/domain/SysAppUserMenu.java | 51 + .../com/ruoyi/system/domain/SysCache.java | 81 + .../com/ruoyi/system/domain/SysConfig.java | 121 ++ .../ruoyi/system/domain/SysLogininfor.java | 156 ++ .../com/ruoyi/system/domain/SysOperLog.java | 273 +++ .../java/com/ruoyi/system/domain/SysPost.java | 133 ++ .../com/ruoyi/system/domain/SysRoleDept.java | 48 + .../com/ruoyi/system/domain/SysRoleMenu.java | 51 + .../ruoyi/system/domain/SysUserOnline.java | 123 ++ .../com/ruoyi/system/domain/SysUserPost.java | 51 + .../com/ruoyi/system/domain/SysUserRole.java | 62 + .../com/ruoyi/system/domain/YwUserVenue.java | 12 + .../com/ruoyi/system/domain/vo/MetaVo.java | 106 + .../com/ruoyi/system/domain/vo/RouterVo.java | 148 ++ .../ruoyi/system/domain/vo/SysUserInfoVo.java | 10 + .../system/domain/vo/UserTypeInfoVO.java | 11 + .../ruoyi/system/mapper/SysAppMenuMapper.java | 127 ++ .../system/mapper/SysAppRoleMenuMapper.java | 47 + .../system/mapper/SysAppUserMenuMapper.java | 50 + .../ruoyi/system/mapper/SysConfigMapper.java | 68 + .../ruoyi/system/mapper/SysDeptMapper.java | 118 + .../system/mapper/SysDictDataMapper.java | 116 + .../system/mapper/SysDictTypeMapper.java | 83 + .../system/mapper/SysLogininforMapper.java | 46 + .../ruoyi/system/mapper/SysMenuMapper.java | 127 ++ .../ruoyi/system/mapper/SysOperLogMapper.java | 52 + .../ruoyi/system/mapper/SysPostMapper.java | 99 + .../system/mapper/SysRoleDeptMapper.java | 44 + .../ruoyi/system/mapper/SysRoleMapper.java | 114 + .../system/mapper/SysRoleMenuMapper.java | 45 + .../ruoyi/system/mapper/SysUserMapper.java | 191 ++ .../system/mapper/SysUserPostMapper.java | 44 + .../system/mapper/SysUserRoleMapper.java | 77 + .../system/mapper/SysUserVenueMapper.java | 17 + .../system/service/ISysAppMenuService.java | 154 ++ .../system/service/ISysConfigService.java | 92 + .../ruoyi/system/service/ISysDeptService.java | 124 ++ .../system/service/ISysDictDataService.java | 78 + .../system/service/ISysDictTypeService.java | 106 + .../system/service/ISysLogininforService.java | 40 + .../ruoyi/system/service/ISysMenuService.java | 146 ++ .../system/service/ISysOperLogService.java | 48 + .../ruoyi/system/service/ISysPostService.java | 99 + .../ruoyi/system/service/ISysRoleService.java | 195 ++ .../system/service/ISysUserOnlineService.java | 48 + .../ruoyi/system/service/ISysUserService.java | 267 +++ .../service/impl/SysAppMenuServiceImpl.java | 549 +++++ .../service/impl/SysConfigServiceImpl.java | 236 ++ .../service/impl/SysDeptServiceImpl.java | 338 +++ .../service/impl/SysDictDataServiceImpl.java | 123 ++ .../service/impl/SysDictTypeServiceImpl.java | 234 ++ .../impl/SysLogininforServiceImpl.java | 65 + .../service/impl/SysMenuServiceImpl.java | 536 +++++ .../service/impl/SysOperLogServiceImpl.java | 76 + .../service/impl/SysPostServiceImpl.java | 178 ++ .../service/impl/SysRoleServiceImpl.java | 508 +++++ .../impl/SysUserOnlineServiceImpl.java | 97 + .../service/impl/SysUserServiceImpl.java | 780 +++++++ .../mapper/system/SysAppMenuMapper.xml | 207 ++ .../mapper/system/SysAppRoleMenuMapper.xml | 34 + .../mapper/system/SysAppUserMenuMapper.xml | 40 + .../mapper/system/SysConfigMapper.xml | 112 + .../resources/mapper/system/SysDeptMapper.xml | 160 ++ .../mapper/system/SysDictDataMapper.xml | 150 ++ .../mapper/system/SysDictTypeMapper.xml | 105 + .../mapper/system/SysLogininforMapper.xml | 62 + .../resources/mapper/system/SysMenuMapper.xml | 210 ++ .../mapper/system/SysOperLogMapper.xml | 87 + .../resources/mapper/system/SysPostMapper.xml | 122 ++ .../mapper/system/SysRoleDeptMapper.xml | 34 + .../resources/mapper/system/SysRoleMapper.xml | 180 ++ .../mapper/system/SysRoleMenuMapper.xml | 34 + .../resources/mapper/system/SysUserMapper.xml | 539 +++++ .../mapper/system/SysUserPostMapper.xml | 34 + .../mapper/system/SysUserRoleMapper.xml | 69 + .../mapper/system/SysUserVenueMapper.xml | 16 + ry.bat | 67 + ry.sh | 86 + sql/quartz.sql | 174 ++ sql/ry_20220822.sql | 692 ++++++ 1245 files changed, 137422 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 bin/clean.bat create mode 100644 bin/package.bat create mode 100644 bin/run.bat create mode 100644 cmcc_gm/pom.xml create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/common/enums/OrderStatus.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/common/enums/OrderType.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsBatch.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsClasses.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsInform.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsOrderLog.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsSnList.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsStock.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/BaseDTO.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/TransformJsonArrayToMaterialsXlsDTO.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YmMaterialsClassesParam.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsBatchDTO.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsDTO.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsInformDTO.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsOrderLogDTO.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsSearchDTO.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsSnListDTO.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsStockImportDTO.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/qo/YwMaterialsSnListQO.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/MaterialsXlsToJsonArrayVo.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsBatchVo.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsClassesVo.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsExportVo.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsInformRedisVo.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsInformVo.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsOrderLogVo.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsSnListVo.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsVo.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsBatch.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsInform.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsReturnList.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsStock.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsBatchMapper.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsClassesMapper.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsInformMapper.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsOrderLogMapper.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsSnListMapper.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsStockMapper.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/GMCommonService.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsBatchService.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsClassesService.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsInformService.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsOrderLogService.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsSnListService.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsStockService.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/GMCommonServiceImpl.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsBatchServiceImpl.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsClassesServiceImpl.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsInformServiceImpl.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsOrderLogServiceImpl.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsSnListServiceImpl.java create mode 100644 cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsStockServiceImpl.java create mode 100644 cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsBatchMapper.xml create mode 100644 cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsClassesMapper.xml create mode 100644 cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsInformMapper.xml create mode 100644 cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsOrderLogMapper.xml create mode 100644 cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsSnListMapper.xml create mode 100644 cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsStockMapper.xml create mode 100644 "doc/\350\213\245\344\276\235\347\216\257\345\242\203\344\275\277\347\224\250\346\211\213\345\206\214.docx" create mode 100644 eastcom_yw/pom.xml create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/AlarmConstants.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/CacheConstants.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/KpiConstants.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/NetElementConstants.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/FlowDealStatus.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/InRedLine.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/WireTaskSubType.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/WireTaskType.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/AppVersionConfig.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2AgisLink5mi.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2MmlList.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2PnNetVenue5mi.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2SpotCell.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2SpotConfig.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2ViewPowerAlarm.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2ViewWirelessAlarm.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/DpSceneConfig.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/HmAlarmDerive.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi4gCell.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi4gMin.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi4gVenue.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi5gCell.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi5gMin.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi5gVenue.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpiMaxEntity.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpiMonitorEntity.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/SysNotice.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/SysUserImp.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarm.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmCS.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmConfig.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmDH.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmHangupLog.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmHangupReover.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmOprateLog.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmRecover.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmView.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmWX.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwDrsConfig.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwDrsTempTask.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwKpiConfig.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeBriefing.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeHandwork.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeHandworkdetail.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeList.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeModel.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeObject.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeUser.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectConfig.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectLog.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectPlan.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectQuestionConfig.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwScene.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneAlarm.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneBigConfig.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneCalendar.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneFile.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneNetelement.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneTestData.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneUser.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneView.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignLog.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignLogView.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignPlan.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignPlanRemind.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignPlanView.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSpareParts.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwWireTaskLog.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/CommonDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2SpotCellDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2SpotConfigDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2ViewPowerAlarmDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2ViewWirelessAlarmDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/DpSceneConfigDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/MmlObjectDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PageNumsDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PageSizesDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi4gCellDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi4gMinDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi4gVenueDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi5gCellDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi5gMinDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi5gVenueDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/SysNoticeDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/WorkFlowDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwAlarmDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwAlarmDTONoPage.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwAlarmHangupLogDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDataDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDrsConfigDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDrsTempTaskDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDrsTempTaskTimeDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectPlanDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectPlanExportDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectStatDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectTaskDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectTaskExportDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwKpiConfigDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeBriefingDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeHandworkDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeHandworkdetailDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeListDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeModelDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeObjectDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSceneCalendarDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSceneDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSceneNoticeinfoSearchDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSearchDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignInDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignLogDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignPlanDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignPlanImportDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignPlanUserDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSparePartsDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwWireTaskLogDTO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/enums/TaskNameWithRoleEnum.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/enums/WireTaskStatus.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/model/AppEntity.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/model/StepInfo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/SysUserParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwInspectQuestionConfigParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwRoutInspectConfigParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwRoutInspectPlanParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwRoutInspectStatParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneAlarmParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneCalendarParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneMatchParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementAgisParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementCsParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementDhParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementWxParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneUserParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSignPlanParam.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2MmlListQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2SpotCellQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2SpotConfigQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2ViewPowerAlarmQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2ViewWirelessAlarmQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/DpKpiMonitorQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/DpSceneConfigQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpi4gMinQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpi5gCellQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpi5gMinQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiCellMonitorQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiCellQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiColorQo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiMinQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiVenueQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/SysNoticeQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwDrsConfigQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwDrsTempTaskQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwKpiConfigQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeBriefingQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeHandworkQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeHandworkdetailQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeListQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeModelQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeObjectQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwSparePartsQO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/AlarmStaticListVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/AlarmStatisticsListVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/AlarmTopListVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/DictTreeVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2AgisLink5miVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2PnNetVenue5miVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2SpotCellVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2SpotConfigVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2ViewPowerAlarmVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2ViewWirelessAlarmVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/DpSceneConfigVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/DpcSeneControlVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/FlowContentVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/HmAlarmDeriveVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiLinkTrendVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiReport4gVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiReport5gVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiTrendVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiVenueReportVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/MatchListVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/MedalListVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/MonitorCellVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/NewsListVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi15CellMonitorVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi15MinCellVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gCellVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gMinVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gVenueConvertVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gVenueVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi5gCellVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi5gMinVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi5gVenueVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpiOneMinVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpiVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/RaceScheduleListVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/RecordVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/SceneBaseStation.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/SysNoticeVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/SysUserVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/TaskMangeListVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/WholeAreaAssureCellSheet.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmAGISVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmAppVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmCSVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmClassificationDetail.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmDHVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmInfoVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmLastVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmNewNumVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmNoticeVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmQuestionVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmStatistics.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmViewVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmWXVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwConstrucTeamVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwDrsConfigVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwDrsTempTaskVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwErrorAlarmVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwInspectLogVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwInspectPlanStaticVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwInspectPlanVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwKpiConfigVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeBriefingPlanVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeBriefingVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeHandworkVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeHandworkdetailVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeListVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeModelVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeObjectVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeObjectaVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneAlarmVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneBaseInfoVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneCalendar2Vo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneCalendarVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneExportVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneKPIStatisticsVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneMatchVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetAgixStaVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetFixtelRegSuccVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetFixtelStaVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetStaVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetVelocityStaVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetWifiStaVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementAgis.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementCs.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementDh.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementWx.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNoticeinfo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneRedisVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTestDataInterface.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTransGbStaVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTransOpticalpowerStaVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTransStaVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneUserVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignLogStaticVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignLogVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignPlanVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignUserVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSparePartsVO.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwWireTaskLogVo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/yw_alarm_deal_log.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/yw_alarm_deal_res.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImportSpareParts.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterAgis.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterCalendar.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterCs.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterDh.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterMatch.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterScene.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterSceneNoticeinfo.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterSceneUser.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterSignPlan.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterWx.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/AppMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/AppVersionConfigMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2AgisLink5miMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2MmlListMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2PnNetVenue5miMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2SpotCellMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2SpotConfigMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2ViewPowerAlarmMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2ViewWirelessAlarmMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/DpSceneConfigMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/HmAlarmDeriveMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/LargeScreenMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi4gCellMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi4gMinMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi4gVenueMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi5gCellMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi5gMinMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi5gVenueMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/SysNoticeMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmCSMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmDHMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmHangupLogMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmOprateLogMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmStatisticsMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmViewMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmWXMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwConstrucTeamMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwDrsConfigMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwDrsTempTaskMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwKpiConfigMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeBriefingMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeHandworkMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeHandworkdetailMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeListMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeModelMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeObjectMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeUserMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectConfigMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectLogMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectPlanMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectQuestionConfigMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneAlarmMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneBigConfigMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneCalendarMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneMatchMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementAgisMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementCsMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementDhMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementWxMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNoticeinfoMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwScenePictureMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneTestDataInterfaceMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneTestDataMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneUserMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneViewMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSignLogMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSignLogViewMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSignPlanMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSparePartsMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwWireTaskLogMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/yw_alarm_deal_logMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/yw_alarm_deal_resMapper.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/AppVersionService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/CommonService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2MmlListService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2SpotCellService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2SpotConfigService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2ViewPowerAlarmService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2ViewWirelessAlarmService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/DpSceneConfigService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/HmAlarmDeriveService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/LargeScreenService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/OpenApiService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi4gCellService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi4gMinService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi4gVenueService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi5gCellService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi5gMinService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi5gVenueService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpiMonitorCellService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/SysNoticeService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/WeatherService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmCSService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmDHService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmHangupLogService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmOprateLogService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmViewService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmWXService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwDrsConfigService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwDrsTempTaskService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwKpiConfigService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeBriefingService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeHandworkService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeHandworkdetailService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeListService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeModelService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeObjectService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeUserService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectConfigService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectLogService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectPlanService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectQuestionConfigService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneAlarmService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneCalendarService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneMatchService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementAgisService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementCsService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementDhService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementWxService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNoticeinfoService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwScenePictureService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneTestDataService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneUserService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSignLogService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSignLogViewService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSignPlanService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSparePartsService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwWireTaskLogService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2SpotCellConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2SpotConfigConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2ViewPowerAlarmConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2ViewWirelessAlarmConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/DpSceneConfigConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi4gCellConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi4gMinConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi4gVenueConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi5gCellConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi5gMinConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi5gVenueConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/SysNoticeConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwDrsConfigConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwDrsTempTaskConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwKpiConfigConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeBriefingConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeHandworkConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeHandworkdetailConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeListConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeModelConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeObjectConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwSparePartsConvert.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/AppVersionServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/CommonServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2MmlListServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2SpotCellServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2SpotConfigServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2ViewPowerAlarmServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2ViewWirelessAlarmServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/DpSceneConfigServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/HmAlarmDeriveServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/LargeScreenServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/OpenApiServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi4gCellServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi4gMinServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi4gVenueServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi5gCellServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi5gMinServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi5gVenueServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpiMonitorCellServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/SysNoticeServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/WeatherServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmCSServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmDHServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmHangupLogServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmOprateLogServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmViewServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmWXServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwDrsConfigServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwDrsTempTaskServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwKpiConfigServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeBriefingServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeHandworkServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeHandworkdetailServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeListServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeModelServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeObjectServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeUserServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectConfigServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectLogServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectPlanServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectQuestionConfigServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneAlarmServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneCalendarServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneMatchServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementAgisServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementCsServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementDhServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementWxServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNoticeinfoServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwScenePictureServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneTestDataServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneUserServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSignLogServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSignLogViewServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSignPlanServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSparePartsServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwWireTaskLogServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/yw_alarm_deal_logServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/yw_alarm_deal_resServiceImpl.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/yw_alarm_deal_logService.java create mode 100644 eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/yw_alarm_deal_resService.java create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2AgisLink5miMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2MmlListMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2PnNetVenue5miMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2SpotCellMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2SpotConfigMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2ViewPowerAlarmMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2ViewWirelessAlarmMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/DpSceneConfigMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/LargeScreenMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi4gCellMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi4gMinMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi4gVenueMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi5gCellMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi5gMinMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi5gVenueMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/SysNoticeMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmHangupLogMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmStatisticsMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmViewMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwConstrucTeamMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwDrsConfigMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwDrsTempTaskMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwKpiConfigMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeBriefingMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeHandworkMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeModelMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeObjectMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeUserMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectConfigMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectLogMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectPlanMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectQuestionConfigMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneAlarmMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneBigConfigMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneCalendarMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneMatchMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementAgisMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementCsMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementDhMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementWxMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNoticeinfoMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwScenePictureMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneTestDataInterfaceMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneTestDataMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneUserMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSignLogMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSignLogViewMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSignPlanMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSparePartsMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/YwWireTaskLogMapper.xml create mode 100644 eastcom_yw/src/main/resources/mapper/eastcom_yw/yw_alarm_deal_logMapper.xml create mode 100644 pom.xml create mode 100644 ruoyi-admin/pom.xml create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/RuoYiServletInitializer.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsClassesController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsInformController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsOrderLogController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsStockController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2MmlListController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2SpotCellController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2SpotConfigController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2ViewPowerAlarmController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2ViewWirelessAlarmController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/DpSceneConfigController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/LargeScreenController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/WeatherController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwAlarmController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwDrsConfigController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwDrsTempTaskController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwKpiConfigController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwKpiController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwMaterialsBatchController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeBriefingController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeHandworkController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeHandworkdetailController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeListController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeModelController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeObjectController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeUserController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwRoutInspectLogController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwRoutInspectPlanController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwRoutInspectQuestionConfigController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneAlarmController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneCalendarController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneMatchController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementAgisController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementCsController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementDhController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementWxController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNoticeinfoController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwScenePictureController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneTestDataController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneUserController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSignController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSparePartsController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwWireTaskLogController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ServerController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/DpApiController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/dpConfigController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/dpNewYayun1Controller.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/dpNewYayunController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/dpYayunController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysAppMenuController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysIndexController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java create mode 100644 ruoyi-admin/src/main/resources/META-INF/spring-devtools.properties create mode 100644 ruoyi-admin/src/main/resources/application-bak1.yml create mode 100644 ruoyi-admin/src/main/resources/application-bak2.yml create mode 100644 ruoyi-admin/src/main/resources/application-druid.yml create mode 100644 ruoyi-admin/src/main/resources/application-local.yml create mode 100644 ruoyi-admin/src/main/resources/application-ser.yml create mode 100644 ruoyi-admin/src/main/resources/application-test.yml create mode 100644 ruoyi-admin/src/main/resources/application.properties create mode 100644 ruoyi-admin/src/main/resources/application.yml create mode 100644 ruoyi-admin/src/main/resources/banner.txt create mode 100644 ruoyi-admin/src/main/resources/i18n/messages.properties create mode 100644 ruoyi-admin/src/main/resources/logback.xml create mode 100644 ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml create mode 100644 ruoyi-admin/src/main/resources/rebel-remote.xml create mode 100644 ruoyi-admin/src/main/resources/templates/wireReportTemplate.ftl create mode 100644 ruoyi-admin/src/main/resources/templates/wireReportTemplate1.ftl create mode 100644 ruoyi-admin/src/test/java/com/ruoyi/wl_test.java create mode 100644 ruoyi-app/pom.xml create mode 100644 ruoyi-app/src/main/java/com/ruoyi/RuoYiAPPApplication.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/RuoYiServletInitializer.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsClassesController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsInformController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsOrderLogController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/common/CaptchaController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/common/CommonController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/AppBaseStationController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/AppKpiController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/AppVersionController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/PersonalCenterController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/SysNoticeController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/WeatherController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwAlarmController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwContactBookController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwDrsTempTaskController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwRoutInspectLogController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwRoutInspectPlanController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwRoutInspectQuestionConfigController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwSceneController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwScenePictureController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwSignController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwWireTaskLogController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/dpConfigController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/CacheController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/ServerController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/SysLogininforController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/SysOperlogController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/SysUserOnlineController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysAppMenuController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysConfigController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysDeptController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysDictDataController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysDictTypeController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysIndexController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysLoginController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysPostController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysProfileController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysRegisterController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysRoleController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysUserController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/controller/tool/TestController.java create mode 100644 ruoyi-app/src/main/java/com/ruoyi/app/core/config/SwaggerConfig.java create mode 100644 ruoyi-app/src/main/resources/META-INF/spring-devtools.properties create mode 100644 ruoyi-app/src/main/resources/application-bak1.yml create mode 100644 ruoyi-app/src/main/resources/application-bak2.yml create mode 100644 ruoyi-app/src/main/resources/application-druid.yml create mode 100644 ruoyi-app/src/main/resources/application-test.yml create mode 100644 ruoyi-app/src/main/resources/application.properties create mode 100644 ruoyi-app/src/main/resources/application.yml create mode 100644 ruoyi-app/src/main/resources/banner.txt create mode 100644 ruoyi-app/src/main/resources/i18n/messages.properties create mode 100644 ruoyi-app/src/main/resources/logback.xml create mode 100644 ruoyi-app/src/main/resources/mybatis/mybatis-config.xml create mode 100644 ruoyi-app/src/main/resources/rebel-remote.xml create mode 100644 ruoyi-common/pom.xml create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/annotation/Anonymous.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/annotation/BindDict.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataScope.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataSource.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excels.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/annotation/Log.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/annotation/RateLimiter.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/config/MinioConfig.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/constant/AlarmConstants.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/constant/GenConstants.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/constant/HttpStatus.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/constant/TaskConstants.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/constant/UserConstants.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/constant/WordConstants.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AjaxResult.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/R.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeEntity.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/HandleDataDTO.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/SearchInfo.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/StartProcessInstanceDTO.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/TaskDTO.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/json/UserInfo.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysAppMenu.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictData.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictType.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/ExcelSelector.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/RegisterBody.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/page/PageDomain.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableDataInfo.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableSupport.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/text/CharsetKit.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/text/Convert.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/text/StrFormatter.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/enums/BusinessStatus.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/enums/BusinessType.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/enums/DataSourceType.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/enums/FlowDealStatus.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/enums/HttpMethod.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/enums/LimitType.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/enums/NoticeType.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/enums/OperatorType.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/enums/UserStatus.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/DemoModeException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/GlobalException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/ServiceException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/UtilException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/base/BaseException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileNameLengthLimitExceededException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileSizeLimitExceededException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/job/TaskException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/user/CaptchaException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/user/CaptchaExpireException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserPasswordNotMatchException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserPasswordRetryLimitExceedException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserSmsNotMatchException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserSmsRetryLimitExceedException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/filter/PropertyPreExcludeFilter.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatableFilter.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/filter/XssFilter.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/importer/ImporterBase.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/importer/beans/CellFormatBean.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/importer/beans/ResultBean.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/importer/beans/enums/ImportResultType.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/importer/service/YwBatchAddService.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/mybatis/JsonListLongTypeHandler.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/AppUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/Arith.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/CoordinateConversionUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/ExceptionUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/GeoUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/LogUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/MessageUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/PasswordUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/RestTemplateUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/RsaUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/StringUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/Threads.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/ZipUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanValidators.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileTypeUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/file/ImageUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MinioUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/file/XmlDocToDocxUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpHelper.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/EasyPoiExcelUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelHandlerAdapter.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/LocalDateExcelHandlerAdapter.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/LocalDateTimeExcelHandlerAdapter.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/WordUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/sign/Base64.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/sign/Md5Utils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/IdUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/Seq.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/UUID.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/xss/Xss.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/xss/XssValidator.java create mode 100644 ruoyi-framework/pom.xml create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/BindDictAspect.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/CaptchaConfig.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/KaptchaTextCreator.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.zip create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/MybatisPlusConfig.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedissonConfig.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/ServerConfig.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/DruidProperties.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/PermitAllUrlProperties.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSource.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSourceContextHolder.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/handler/MyMetaObjectHandler.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/listener/RedisKeyExpirationListener.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/manager/AsyncManager.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/security/context/AuthenticationContextHolder.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/security/context/PermissionContextHolder.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/security/sms/SmsCodeAuthenticationProvider.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/security/sms/SmsCodeAuthenticationToken.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/Server.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/SysNoticeEntity.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/dto/MobileOfficesDTO.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Cpu.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Mem.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Sys.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/SysFile.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/ErrorInfoBuilder.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/mapper/SysLoginMapper.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/AppPermissionService.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysPasswordService.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysPermissionService.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysSmsService.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsByTelephoneServiceImpl.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/sms/MessageService.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/sms/MessageServiceImpl.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/sms/SmsRsponseVo.java create mode 100644 ruoyi-generator/pom.xml create mode 100644 ruoyi-generator/src/main/java/com/ruoyi/generator/MyBatisPlusGenerator.java create mode 100644 ruoyi-generator/src/main/java/com/ruoyi/generator/config/GenConfig.java create mode 100644 ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java create mode 100644 ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java create mode 100644 ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java create mode 100644 ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java create mode 100644 ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java create mode 100644 ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableColumnServiceImpl.java create mode 100644 ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java create mode 100644 ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableColumnService.java create mode 100644 ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java create mode 100644 ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java create mode 100644 ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java create mode 100644 ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java create mode 100644 ruoyi-generator/src/main/resources/generator.yml create mode 100644 ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml create mode 100644 ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml create mode 100644 ruoyi-generator/src/main/resources/templates/controller.java.ftl create mode 100644 ruoyi-generator/src/main/resources/templates/controller.java.vm create mode 100644 ruoyi-generator/src/main/resources/templates/convert.java.ftl create mode 100644 ruoyi-generator/src/main/resources/templates/dto.java.ftl create mode 100644 ruoyi-generator/src/main/resources/templates/entity.java.ftl create mode 100644 ruoyi-generator/src/main/resources/templates/entity.java.vm create mode 100644 ruoyi-generator/src/main/resources/templates/mapper.xml.ftl create mode 100644 ruoyi-generator/src/main/resources/templates/mapper.xml.vm create mode 100644 ruoyi-generator/src/main/resources/templates/qo.java.ftl create mode 100644 ruoyi-generator/src/main/resources/templates/service.java.ftl create mode 100644 ruoyi-generator/src/main/resources/templates/service.java.vm create mode 100644 ruoyi-generator/src/main/resources/templates/serviceImpl.java.ftl create mode 100644 ruoyi-generator/src/main/resources/templates/serviceImpl.java.vm create mode 100644 ruoyi-generator/src/main/resources/templates/vo.java.ftl create mode 100644 ruoyi-generator/src/main/resources/vm/java/controller.java.vm create mode 100644 ruoyi-generator/src/main/resources/vm/java/domain.java.vm create mode 100644 ruoyi-generator/src/main/resources/vm/java/mapper.java.vm create mode 100644 ruoyi-generator/src/main/resources/vm/java/service.java.vm create mode 100644 ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm create mode 100644 ruoyi-generator/src/main/resources/vm/java/sub-domain.java.vm create mode 100644 ruoyi-generator/src/main/resources/vm/js/api.js.vm create mode 100644 ruoyi-generator/src/main/resources/vm/sql/sql.vm create mode 100644 ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm create mode 100644 ruoyi-generator/src/main/resources/vm/vue/index.vue.vm create mode 100644 ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm create mode 100644 ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm create mode 100644 ruoyi-generator/src/main/resources/vm/vue/v3/readme.txt create mode 100644 ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm create mode 100644 ruoyi-quartz/pom.xml create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJobLog.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java create mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java create mode 100644 ruoyi-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml create mode 100644 ruoyi-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml create mode 100644 ruoyi-sunlm/pom.xml create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_cache_config.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_device_alarm_counts.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_device_alarms_counts_ext.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_gbflow_wireless.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_gbflow_wireless_compare.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_manage_counts.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_maps_alarms.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_outservice_wireless.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_bts_wireless_alarms.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_code_net_alarms.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_freq_statistics.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot_cell.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot_celldetail.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot_kpi.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_out_wireless_alarms.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_power_alarm.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_control.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_seat_detail.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_seat_info.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_test_data.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scenelist.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_seat_chinesename.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_seat_wireless_alarms.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_site_cell_info.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_spotdetail.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_spotlist.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_top5.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_top5_allspot.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_top5_spot.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_usercounts.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_usercounts_compare.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_wireless_alarm.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_wireless_highload.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_gb_top5.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_maps_alarms.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_net_alarm.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_opticalpower.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_trans_alarm.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_4_maps_alarms.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_5_scenecontacts.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_5_scenesta.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_alarm.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_alarm_monitor.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_kpi_monitor.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_link_alarm.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_links.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_maps.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_project.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_project_statis.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_map_agis_dev_15mi.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_map_agis_link_5mi.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_map_alarms.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewCommonDTO.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewDpKpiMonitorQO.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewDpSceneConfig.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewDpSceneConfigQO.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewKpiConstants.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewMonitorCellVo.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPageDTO.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi15CellMonitorVO.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi4gCell.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi4gMin.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi5gCell.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi5gMin.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiCellMonitorQO.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiCellQO.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiColorQo.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiMinQO.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiMonitorEntity.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiVO.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewRecordVo.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_btsinfo.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_compare.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_left_1.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_left_2.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_maps.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_maps_topinfo.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scene_control.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scene_seat_detail.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scene_seat_info.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scenelist.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_top5.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_topinfo.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_medal_stand.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_public_news.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_big_config.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_calendar.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_match.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_team.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_team_scene.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_team_user.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_medal_stand_list.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_medal_stand_new.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_medal_stand_upt.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_public_news_list.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_public_news_new.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_public_news_upt.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_scene_team_list.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_scene_team_new.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_scene_team_upt.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/publicEntity.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_big_entity_list.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_big_entity_new.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_big_entity_upt.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_calendar_entity_list.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_calendar_entity_new.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_calendar_entity_upt.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_match_entity_list.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_match_entity_new.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_match_entity_upt.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/DpApiMapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewDpApiMapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewDpSceneConfigMapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi4gCellMapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi4gMinMapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi5gCellMapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi5gMinMapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpConfigMapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_ChuanDong_Mapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_Dict_Mapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_Gailan_Mapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_Wuxian_Mapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_ZhuanWang_Mapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_ZongHe_Mapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpYayunMapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpYayunReplayMapper.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/NewPmKpiMonitorCellService.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/YwDpNewYayunService.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/dpAllMyServices.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/impl/NewPmKpiMonitorCellServiceImpl.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/impl/YwDpNewYayunServiceImpl.java create mode 100644 ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/impl/dpAllMyServicesImpl.java create mode 100644 ruoyi-sunlm/src/main/resources/mapper/sunlm/NewDpSceneConfigMapper.xml create mode 100644 ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi4gCellMapper.xml create mode 100644 ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi4gMinMapper.xml create mode 100644 ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi5gCellMapper.xml create mode 100644 ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi5gMinMapper.xml create mode 100644 ruoyi-system/pom.xml create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysAppRoleMenu.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysAppUserMenu.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfig.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysLogininfor.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOperLog.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleDept.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserPost.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserRole.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/YwUserVenue.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MetaVo.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/RouterVo.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserInfoVo.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/UserTypeInfoVO.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysAppMenuMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysAppRoleMenuMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysAppUserMenuMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserVenueMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysAppMenuService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysAppMenuServiceImpl.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysAppMenuMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysAppRoleMenuMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysAppUserMenuMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysUserVenueMapper.xml create mode 100644 ry.bat create mode 100644 ry.sh create mode 100644 sql/quartz.sql create mode 100644 sql/ry_20220822.sql diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed8368a --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ +###################################################################### +# Build Tools + +.gradle +/build/ +!gradle/wrapper/gradle-wrapper.jar + +target/ +!.mvn/wrapper/maven-wrapper.jar + +###################################################################### +# IDE + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### JRebel ### +rebel.xml + +### NetBeans ### +nbproject/private/ +build/* +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +###################################################################### +# Others +*.log +*.xml.versionsBackup +*.swp + +!*/build/*.java +!*/build/*.html +!*/build/*.xml diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8564f29 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2018 RuoYi + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d438bf5 --- /dev/null +++ b/README.md @@ -0,0 +1,97 @@ +

+ logo +

+

RuoYi v3.8.4

+

基于SpringBoot+Vue前后端分离的Java快速开发框架

+

+ + + +

+ +## 平台简介 + +若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。 + +* 前端采用Vue、Element UI。 +* 后端采用Spring Boot、Spring Security、Redis & Jwt。 +* 权限认证使用Jwt,支持多终端认证系统。 +* 支持加载动态权限菜单,多方式轻松权限控制。 +* 高效率开发,使用代码生成器可以一键生成前后端代码。 +* 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Vue3](https://github.com/yangzongzhuan/RuoYi-Vue3),保持同步更新。 +* 提供了单应用版本[RuoYi-Vue-fast](https://github.com/yangzongzhuan/RuoYi-Vue-fast),Oracle版本[RuoYi-Vue-Oracle](https://github.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。 +* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud) +* 特别鸣谢:[element](https://github.com/ElemeFE/element),[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin),[eladmin-web](https://github.com/elunez/eladmin-web)。 +* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)   +* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)   + +## 内置功能 + +1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。 +2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。 +3. 岗位管理:配置系统用户所属担任职务。 +4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。 +5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。 +6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。 +7. 参数管理:对系统动态配置常用参数。 +8. 通知公告:系统通知公告信息发布维护。 +9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 +10. 登录日志:系统登录日志记录查询包含登录异常。 +11. 在线用户:当前系统中活跃用户状态监控。 +12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 +13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。 +14. 系统接口:根据业务代码自动生成相关的api接口文档。 +15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。 +16. 缓存监控:对系统的缓存信息查询,命令统计等。 +17. 在线构建器:拖动表单元素生成相应的HTML代码。 +18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。 + +## 在线体验 + +- admin/admin123 +- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。 + +演示地址:http://vue.ruoyi.vip +文档地址:http://doc.ruoyi.vip + +## 演示图 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +## 若依前后端分离交流群 + +QQ群: [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/已满-104748341-blue.svg)](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [![加入QQ群](https://img.shields.io/badge/已满-160110482-blue.svg)](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [![加入QQ群](https://img.shields.io/badge/170801498-blue.svg)](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) 点击按钮入群。 \ No newline at end of file diff --git a/bin/clean.bat b/bin/clean.bat new file mode 100644 index 0000000..24c0974 --- /dev/null +++ b/bin/clean.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] target· +echo. + +%~d0 +cd %~dp0 + +cd .. +call mvn clean + +pause \ No newline at end of file diff --git a/bin/package.bat b/bin/package.bat new file mode 100644 index 0000000..c693ec0 --- /dev/null +++ b/bin/package.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] Weḅwar/jarļ +echo. + +%~d0 +cd %~dp0 + +cd .. +call mvn clean package -Dmaven.test.skip=true + +pause \ No newline at end of file diff --git a/bin/run.bat b/bin/run.bat new file mode 100644 index 0000000..41efbd0 --- /dev/null +++ b/bin/run.bat @@ -0,0 +1,14 @@ +@echo off +echo. +echo [Ϣ] ʹJarWeb̡ +echo. + +cd %~dp0 +cd ../ruoyi-admin/target + +set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m + +java -jar %JAVA_OPTS% ruoyi-admin.jar + +cd bin +pause \ No newline at end of file diff --git a/cmcc_gm/pom.xml b/cmcc_gm/pom.xml new file mode 100644 index 0000000..4bae25d --- /dev/null +++ b/cmcc_gm/pom.xml @@ -0,0 +1,37 @@ + + + + ruoyi + com.ruoyi + 3.8.4 + + 4.0.0 + + cmcc_gm + + + 移动的物资管理模块 + + + + + com.ruoyi + ruoyi-common + + + + com.baomidou + mybatis-plus-boot-starter + + + + + + 8 + 8 + UTF-8 + + + \ No newline at end of file diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/common/enums/OrderStatus.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/common/enums/OrderStatus.java new file mode 100644 index 0000000..207c738 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/common/enums/OrderStatus.java @@ -0,0 +1,59 @@ +package com.ruoyi.cmcc_gm.common.enums; + +public enum OrderStatus { + + DSQ("0", "待申请") ,DSH("1", "待审核") ,YSH("2","已审核") ,YCK("3","已出库") ,YRK("4","已入库"), + CX("5","撤销"); + + /** code */ + private String code; + + /** 显示标签 */ + private String label; + + OrderStatus(String code, String label){ + + this.code = code; + + this.label = label; + } + + public static String getLabelByCode (String code) { + + for (OrderStatus enuma : OrderStatus.values()) { + + if (enuma.getCode().equals(code)) { + + return enuma.getLabel(); + + } + + } + + return ""; + + } + + + @Override + public String toString(){ + + return label; + + } + + public String getLabel() { + + return label; + + } + + + public String getCode(){ + + return this.code; + + } + + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/common/enums/OrderType.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/common/enums/OrderType.java new file mode 100644 index 0000000..1624e8b --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/common/enums/OrderType.java @@ -0,0 +1,83 @@ +package com.ruoyi.cmcc_gm.common.enums; + +public enum OrderType { + + ZXK((Integer)1, "ZXK","中心库更新") ,SL((Integer)2,"SL" ,"物资申领") ,TK((Integer) 3,"TK" ,"物资退库") ,CK((Integer) 4,"CK" ,"工程出库") ,RK((Integer) 5,"RK" ,"折旧入库"),DB((Integer) 6,"DB" ,"调拨"); + + /** code */ + private Integer code; + + /** 英文标签 */ + private String abbLabel; + + /** 显示标签 */ + private String label; + + OrderType(Integer code,String abbLabel, String label){ + + this.code = code; + this.abbLabel = abbLabel; + this.label = label; + } + + public static String getLabelByCode (Integer code) { + + for (OrderType enuma : OrderType.values()) { + + if (enuma.getCode().compareTo(code) == 0) { + + return enuma.getLabel(); + + } + + } + + return ""; + + } + + public static String getAbbLabelByCode (Integer code) { + + for (OrderType enuma : OrderType.values()) { + + if (enuma.getCode().compareTo(code) == 0) { + + return enuma.getAbbLabel(); + + } + + } + + return ""; + + } + + + @Override + public String toString(){ + + return label; + + } + + public String getLabel() { + + return label; + + } + + + public String getAbbLabel() { + + return abbLabel; + + } + + public Integer getCode(){ + + return this.code; + + } + + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsBatch.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsBatch.java new file mode 100644 index 0000000..f827163 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsBatch.java @@ -0,0 +1,54 @@ +package com.ruoyi.cmcc_gm.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * 物资批次表 + *

+ * + * @author jkj + * @since 2023-04-10 + */ +@Getter +@Setter +@TableName("yw_materials_batch") +public class YwMaterialsBatch implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 序号 + */ + private Long id; + + /** + * 工单号 + */ + private String orderid; + + /** + * 物资编码 + */ + private String materialCode; + + /** + * 数量 + */ + private Integer sum; + + /** + * 实际入库数量 + */ + private Integer inSum; + + /** + * 实际出库数量 + */ + private Integer outSum; + + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsClasses.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsClasses.java new file mode 100644 index 0000000..12425d9 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsClasses.java @@ -0,0 +1,52 @@ +package com.ruoyi.cmcc_gm.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.annotation.Excel; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +/** + *

+ * + *

+ * + * @author jkj + * @since 2023-04-07 + */ +@Getter +@Setter +@TableName("yw_materials_classes") +public class YwMaterialsClasses implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 序号 + */ + @TableId(type = IdType.AUTO) + @Excel(name = "ID",type= Excel.Type.EXPORT, sort = 1) + private Long id; + + /** + * 物资大类 + */ + @Excel(name = "物资大类",type= Excel.Type.ALL, sort = 1) + private String bigClass; + + /** + * 物资小类 + */ + @Excel(name = "物资大类",type= Excel.Type.ALL, sort = 2) + private String smallClass; + + + @Excel(name = "失败原因", type = Excel.Type.EXPORT,sort = 3) + @TableField(exist = false) + private String reason; + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsInform.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsInform.java new file mode 100644 index 0000000..6fdf7dc --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsInform.java @@ -0,0 +1,99 @@ +package com.ruoyi.cmcc_gm.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.importer.beans.ResultBean; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * 物资信息表 + *

+ * + * @author jkj + * @since 2023-04-06 + */ +@Getter +@Setter +@TableName("yw_materials_inform") +public class YwMaterialsInform extends ResultBean implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 序号 + */ + @TableId(type = IdType.AUTO) + private Long id; + + @TableField(exist = false) + private String rowId; + + @TableField(exist = false) + private String special; + + /** + * 物资名称 + */ + @Excel(name = "物资名称", sort = 3) + private String materialName; + + /** + * 物资编码 + */ + @Excel(name = "物资编号", sort = 2) + private String materialCode; + + private String factory; + + /** + * 规格 + */ + @Excel(name = "规格型号", sort = 4) + private String materialStand; + + @TableField(exist = false) + private String detail; + + /** + * 单位 + */ + @Excel(name = "单位", sort = 7) + private String materialUnit; + + @TableField(exist = false) + private String ifStringCode; + + /** + * 物资大类id + */ + @Excel(name = "大类", sort = 5) + private String materialBigClass; + + /** + * 物资小类id + */ + @Excel(name = "小类", sort = 6) + private String materialSmallClass; + + /** + * SN绑定 + */ + @Excel(name = "SN绑定", sort = 8) + private String snCode; + + /** + * 物资数量 + */ + @Excel(name = "申请数量", sort = 9) + @TableField(exist = false) + private String sum; + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsOrderLog.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsOrderLog.java new file mode 100644 index 0000000..e244d9b --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsOrderLog.java @@ -0,0 +1,114 @@ +package com.ruoyi.cmcc_gm.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * 物资工单日志表 + *

+ * + * @author jkj + * @since 2023-04-07 + */ +@Data +@TableName("yw_materials_order_log") +public class YwMaterialsOrderLog implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 序号 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 工单号 + */ + private String orderId; + + /** + * 工单类型(更新中心库=1,申领=2,退库=3,工程出库=4,折旧入库=5,物资调拨=6) + */ + private Integer orderType; + + /** + * 工作流id + */ + private String flwProcessid; + + /** + * 申请人 + */ + private String applyName; + + /** + * 审核人 + */ + private String checkName; + + /** + * 入库人 + */ + private String inStoreName; + + /** + * 任务状态 + */ + private String taskStatus; + + /** + * 任务发起时间 + */ + private LocalDateTime taskStartTime; + + /** + * 入库场馆 + */ + private Long inStoreVenue; + + /** + * 出库场馆 + */ + private Long outStoreVenue; + + /** + * 拆布线工单号 + */ + private String wireTaskId; + + /** + * 上传文件路径 + */ + private String fileUrl; + + /** + * 上传文件名称 + */ + private String fileName; + + /** + * 申请人ID + */ + private Long applyId; + + /** + * 审核人ID + */ + private Long checkId; + + /** + * 入库人ID + */ + private Long inStoreId; + + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsSnList.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsSnList.java new file mode 100644 index 0000000..82697c5 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsSnList.java @@ -0,0 +1,50 @@ +package com.ruoyi.cmcc_gm.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +/** + *

+ * 物资编码串码对应表 + *

+ * + * @author jkj + * @since 2023-04-10 + */ +@Getter +@Setter +@TableName("yw_materials_list") +public class YwMaterialsSnList implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 序号 + */ + private Long id; + + /** + * 工单号 + */ + private String orderid; + + /** + * 物资编码 + */ + private String materialCode; + + /** + * 串码 + */ + private String materialStrCode; + + + /** + * 操作类型 + */ + private Integer opType; + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsStock.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsStock.java new file mode 100644 index 0000000..e66fc42 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/YwMaterialsStock.java @@ -0,0 +1,65 @@ +package com.ruoyi.cmcc_gm.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * 物资库存表 + *

+ * + * @author jkj + * @since 2023-04-06 + */ + +@Data +@TableName("yw_materials_stock") +public class YwMaterialsStock implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 序号 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 物资库ID(场馆库对应venue_id,中心库对应一个特殊id比如-1 + */ + + private Long materialStoreId; + + /** + * 物资编码 + */ + private String materialCode; + + /** + * 可用数 + */ + private Integer availSum; + + /** + * 出库在途数 + */ + private Integer outWaySum; + + /** + * 入库在途数 + */ + private Integer inWaySum; + + /** + * 大场景id + */ + private Long sceneBigId; + + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/BaseDTO.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/BaseDTO.java new file mode 100644 index 0000000..d829cf6 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/BaseDTO.java @@ -0,0 +1,12 @@ +package com.ruoyi.cmcc_gm.domain.dto; + +import lombok.Data; + +@Data +public class BaseDTO { + + private Integer pageNum; + + private Integer pageSize; + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/TransformJsonArrayToMaterialsXlsDTO.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/TransformJsonArrayToMaterialsXlsDTO.java new file mode 100644 index 0000000..6fe3a6e --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/TransformJsonArrayToMaterialsXlsDTO.java @@ -0,0 +1,12 @@ +package com.ruoyi.cmcc_gm.domain.dto; + +import com.ruoyi.cmcc_gm.domain.vo.MaterialsXlsToJsonArrayVo; +import lombok.Data; + +import java.util.List; + +@Data +public class TransformJsonArrayToMaterialsXlsDTO { + private List data; + private Long taskType; +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YmMaterialsClassesParam.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YmMaterialsClassesParam.java new file mode 100644 index 0000000..abc124f --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YmMaterialsClassesParam.java @@ -0,0 +1,22 @@ +package com.ruoyi.cmcc_gm.domain.dto; + +import lombok.Data; + +@Data +public class YmMaterialsClassesParam extends BaseDTO { + /** + * 序号 + */ + private Long id; + + /** + * 物资大类 + */ + private String bigClass; + + /** + * 物资小类 + */ + private String smallClass; + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsBatchDTO.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsBatchDTO.java new file mode 100644 index 0000000..3cc8067 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsBatchDTO.java @@ -0,0 +1,30 @@ +package com.ruoyi.cmcc_gm.domain.dto; + +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import lombok.Data; + +import java.util.List; + +@Data +public class YwMaterialsBatchDTO { + + /** + * 工单号 + */ + private String orderId; + + /** + * 仓库号 + */ + private Long storeId; + + + /** + * 是否需要冻结 + */ + private Integer needfrozen; + + private List data; + + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsDTO.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsDTO.java new file mode 100644 index 0000000..811e002 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsDTO.java @@ -0,0 +1,23 @@ +package com.ruoyi.cmcc_gm.domain.dto; + +import lombok.Data; + +@Data +public class YwMaterialsDTO { + + + //工单号 + private String orderId; + + //工单类型 + private Integer orderType; + + //操作步骤 1.提交申请 2.审核任务 3.出库确认 4.入库确认 + private String opType; + + //当前审核人 + private String auditor; + + + private String isBack; +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsInformDTO.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsInformDTO.java new file mode 100644 index 0000000..40e6e82 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsInformDTO.java @@ -0,0 +1,62 @@ +package com.ruoyi.cmcc_gm.domain.dto; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +/** + *

+ * 物资信息表 + *

+ * + * @author jkj + * @since 2023-04-06 + */ +@Data +public class YwMaterialsInformDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + + /** + * 物资名称 + */ + private String materialName; + + /** + * 物资编码 + */ + private String materialCode; + + + /** + * 规格 + */ + private String materialStand; + + /** + * 单位 + */ + private String materialUnit; + + /** + * 物资大类id + */ + private String materialBigClass; + + /** + * 物资小类id + */ + private String materialSmallClass; + + /** + * SN绑定 + */ + private String snBand; + + + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsOrderLogDTO.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsOrderLogDTO.java new file mode 100644 index 0000000..2faa51f --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsOrderLogDTO.java @@ -0,0 +1,103 @@ +package com.ruoyi.cmcc_gm.domain.dto; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 物资工单日志表 + *

+ * + * @author jkj + * @since 2023-04-07 + */ +@Data +public class YwMaterialsOrderLogDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 工单号 + */ + private String orderId; + + /** + * 工单类型(更新中心库=1,申领=2,退库=3,工程出库=4,折旧入库=5,物资调拨=6) + */ + private Integer orderType; + + /** + * 工作流id + */ + private String flwProcessid; + + /** + * 申请人 + */ + private String applyName; + + /** + * 审核人 + */ + private String checkName; + + /** + * 入库人 + */ + private String inStoreName; + + /** + * 任务状态 + */ + private String taskStatus; + + + /** + * 入库场馆 + */ + private Long inStoreVenue; + + /** + * 出库场馆 + */ + private Long outStoreVenue; + + /** + * 拆布线工单号 + */ + private String wireTaskId; + + + /** + * 上传文件路径 + */ + private String fileUrl; + + + /** + * 上传文件名称 + */ + private String fileName; + + /** + * 申请人ID + */ + private Long applyId; + + /** + * 审核人ID + */ + private Long checkId; + + /** + * 入库人ID + */ + private Long inStoreId; + + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsSearchDTO.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsSearchDTO.java new file mode 100644 index 0000000..d27d5cc --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsSearchDTO.java @@ -0,0 +1,74 @@ +package com.ruoyi.cmcc_gm.domain.dto; + +import lombok.Data; + +@Data +public class YwMaterialsSearchDTO extends BaseDTO { + + + //工单号 + private String orderId; + + //工单类型 + private Integer orderType; + + //任务状态 + private String taskStatus; + + //查询日期 + private String searchDate; + + //查询某个仓库 + private Long storeId; + + //查询入库仓库 + private Long inStoreId; + + //查询出库仓库 + private Long outStoreId; + + //查询入库仓库 + private Long [] inStoreIds; + + //查询出库仓库 + private Long [] outStoreIds; + + //查询多个仓库 + private Long [] storeIds; + + private String flwId; + + /** + * 物资编码 + */ + private String materialCode; + + /** + * 物资名称 + */ + private String materialName; + + + /** + * 规格 + */ + private String materialStand; + + + /** + * 物资大类id + */ + private String materialBigClass; + + + /** + * SN绑定 + */ + private String snCode; + + /** + * 物资小类id + */ + private String materialSmallClass; + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsSnListDTO.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsSnListDTO.java new file mode 100644 index 0000000..db0443b --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsSnListDTO.java @@ -0,0 +1,32 @@ +package com.ruoyi.cmcc_gm.domain.dto; + +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import com.ruoyi.cmcc_gm.domain.YwMaterialsSnList; +import lombok.Data; + +import java.util.List; + +@Data +public class YwMaterialsSnListDTO { + + /** + * 工单号 + */ + private String orderId; + + /** + * 物资编码 + */ + private String materialCode; + + /** + * 操作类型 + */ + private Integer opType; + + + private List data; + + + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsStockImportDTO.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsStockImportDTO.java new file mode 100644 index 0000000..43664ac --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/dto/YwMaterialsStockImportDTO.java @@ -0,0 +1,84 @@ +package com.ruoyi.cmcc_gm.domain.dto; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.importer.beans.ResultBean; +import lombok.Data; + +/** + * @author los + */ +@Data +public class YwMaterialsStockImportDTO extends ResultBean { + + /** + * rowId + */ + @TableField(exist = false) + private String rowId; + + /** + * 物资编码 + */ + @Excel(name = "物资编号", sort = 2) + private String materialCode; + + /** + * 专业 + */ + @TableField(exist = false) + private String special; + + /** + * 物资大类id + */ + @Excel(name = "大类", sort = 5) + private String materialBigClass; + + /** + * 物资小类id + */ + @Excel(name = "小类", sort = 6) + private String materialSmallClass; + + /** + * 厂家 + */ + private String factory; + + /** + * 物资名称 + */ + @Excel(name = "物资名称", sort = 3) + private String materialName; + + /** + * 规格 + */ + @Excel(name = "规格型号", sort = 4) + private String materialStand; + + /** + * 详情 + */ + @TableField(exist = false) + private String detail; + + /** + * 单位 + */ + @Excel(name = "单位", sort = 7) + private String materialUnit; + + /** + * SN绑定 + */ + private String snCode; + + /** + * 物资数量 + */ + @Excel(name = "申请数量", sort = 8) + @TableField(exist = false) + private String availSum; +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/qo/YwMaterialsSnListQO.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/qo/YwMaterialsSnListQO.java new file mode 100644 index 0000000..896a59f --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/qo/YwMaterialsSnListQO.java @@ -0,0 +1,26 @@ +package com.ruoyi.cmcc_gm.domain.qo; + +import com.ruoyi.cmcc_gm.domain.YwMaterialsSnList; +import lombok.Data; + +import java.util.List; + +@Data +public class YwMaterialsSnListQO { + + /** + * 工单号 + */ + private String orderId; + + /** + * 物资编码 + */ + private String materialCode; + + /** + * 操作类型 + */ + private Integer opType; + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/MaterialsXlsToJsonArrayVo.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/MaterialsXlsToJsonArrayVo.java new file mode 100644 index 0000000..c445c21 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/MaterialsXlsToJsonArrayVo.java @@ -0,0 +1,36 @@ +package com.ruoyi.cmcc_gm.domain.vo; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.importer.beans.ResultBean; +import lombok.Data; + +/** + * @author los + */ +@Data +public class MaterialsXlsToJsonArrayVo extends ResultBean { + @Excel(name = "序号", sort = 1) + private String id; + @Excel(name = "物资名称", sort = 3) + private String materialName; + @Excel(name = "规格型号", sort = 4) + private String materialStand; + @Excel(name = "物资编号", sort = 2) + private String materialCode; + @Excel(name = "SN绑定", sort = 8) + private String snCode; + @Excel(name = "大类", sort = 6) + private String materialBigClass; + @Excel(name = "小类", sort = 7) + private String materialSmallClass; + @Excel(name = "可领数量", sort = 9) + private String availSum; + @Excel(name = "申请数量", sort = 10) + private String sum; + @Excel(name = "出库数量", sort = 10) + private String outSum; + @Excel(name = "入库数量", sort = 11) + private String inSum; + @Excel(name = "操作", sort = 12) + private String operation; +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsBatchVo.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsBatchVo.java new file mode 100644 index 0000000..7930f4f --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsBatchVo.java @@ -0,0 +1,49 @@ +package com.ruoyi.cmcc_gm.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +/** + *

+ * 物资批次表 + *

+ * + * @author jkj + * @since 2023-04-10 + */ +@Data +public class YwMaterialsBatchVo extends YwMaterialsInformVo implements Serializable { + + private static final long serialVersionUID = 1L; + + + /** + * 工单号 + */ + private String orderid; + + /** + * 可用数量 + */ + private Integer availSum; + + /** + * 申领数量 + */ + private Integer sum; + + /** + * 出库数量 + */ + private Integer outSum; + + /** + * 出库数量 + */ + private Integer inSum; + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsClassesVo.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsClassesVo.java new file mode 100644 index 0000000..60db76c --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsClassesVo.java @@ -0,0 +1,35 @@ +package com.ruoyi.cmcc_gm.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +/** + *

+ * + *

+ * + * @author jkj + * @since 2023-04-07 + */ +@Data +public class YwMaterialsClassesVo implements Serializable { + + private static final long serialVersionUID = 1L; + + + /** + * 物资大类 + */ + private String bigClass; + + /** + * 物资小类 + */ + private String smallClass; + + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsExportVo.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsExportVo.java new file mode 100644 index 0000000..4bbb1b6 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsExportVo.java @@ -0,0 +1,105 @@ +package com.ruoyi.cmcc_gm.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +/** + * @author los + */ +@Data +public class YwMaterialsExportVo { + /** + * 物资库ID(场馆库对应venue_id,中心库对应一个特殊id比如0 + */ + private Long materialStoreId; + /** + * 仓库名称 + */ + @Excel(name = "仓库名称", type = Excel.Type.EXPORT, sort = 1) + private String materialStoreName; + /** + * 物资编码 + */ + @Excel(name = "物资编号", type = Excel.Type.EXPORT, sort = 2) + private String materialCode; + /** + * 可用数 + */ + @Excel(name = "可领取数", type = Excel.Type.EXPORT, sort = 10) + private Integer availSum; + + /** + * 出库在途数 + */ + @Excel(name = "冻结数", type = Excel.Type.EXPORT, sort = 11) + private Integer outWaySum; + + /** + * 入库在途数 + */ + @Excel(name = "在途数", type = Excel.Type.EXPORT, sort = 12) + private Integer inWaySum; + /** + * 物资名称 + */ + @Excel(name = "物资名称", type = Excel.Type.EXPORT, sort = 3) + private String materialName; + /** + * 规格 + */ + @Excel(name = "规格型号", type = Excel.Type.EXPORT, sort = 4) + private String materialStand; + + /** + * 单位 + */ + @Excel(name = "单位", type = Excel.Type.EXPORT, sort = 8) + private String materialUnit; + + /** + * SN绑定 + */ + @Excel(name = "SN绑定", type = Excel.Type.EXPORT, sort = 9) + private String snCode; + + /** + * 库存数 + */ + @Excel(name = "库存数", type = Excel.Type.EXPORT, sort = 13) + @TableField(exist = false) + private Integer storeSum; + + + /** + * 中心库入库数量 + */ + @Excel(name = "中心库导入数", type = Excel.Type.EXPORT, sort = 14) + private Integer zxkInSum; + + /** + * 申领数量 + */ + @Excel(name = "申领数", type = Excel.Type.EXPORT, sort = 15) + private Integer slSum; + + /** + * 退库数量 + */ + @Excel(name = "退库数", type = Excel.Type.EXPORT, sort = 16) + private Integer tkSum; + + + /** + * 物资大类id + */ + @Excel(name = "大类", type = Excel.Type.EXPORT, sort = 5) + private String materialBigClass; + + /** + * 物资小类id + */ + @Excel(name = "小类", type = Excel.Type.EXPORT, sort = 6) + private String materialSmallClass; + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsInformRedisVo.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsInformRedisVo.java new file mode 100644 index 0000000..cb67301 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsInformRedisVo.java @@ -0,0 +1,53 @@ +package com.ruoyi.cmcc_gm.domain.vo; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +/** + *

+ * 物资信息表 + *

+ * + * @author jkj + * @since 2023-04-06 + */ +@Data +public class YwMaterialsInformRedisVo implements Serializable { + + /** + * 物资编号 + */ + private String wzbh; + + /** + * 物资名称 + */ + private String wzmc; + + /** + * 规格 + */ + private String ggxh; + + /** + * 物资单位 + */ + private String wzdw; + + /** + * 物资大类id + */ + private String dl; + + /** + * 物资小类id + */ + private String xl; + + + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsInformVo.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsInformVo.java new file mode 100644 index 0000000..c938def --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsInformVo.java @@ -0,0 +1,74 @@ +package com.ruoyi.cmcc_gm.domain.vo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.annotation.Excel; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +/** + *

+ * 物资信息表 + *

+ * + * @author jkj + * @since 2023-04-06 + */ +@Data +public class YwMaterialsInformVo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 序号 + */ + private Long id; + + /** + * 物资名称 + */ + @Excel(name = "物资名称") + private String materialName; + + /** + * 物资编码 + */ + private String materialCode; + + /** + * 规格 + */ + @Excel(name = "规格") + private String materialStand; + + /** + * 单位 + */ + @Excel(name = "单位") + private String materialUnit; + + /** + * 物资大类id + */ + @Excel(name = "物资大类") + private String materialBigClass; + + /** + * 物资小类id + */ + @Excel(name = "物资小类") + private String materialSmallClass; + + /** + * SN绑定 + */ + @Excel(name = "SN绑定") + private String snCode; + + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsOrderLogVo.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsOrderLogVo.java new file mode 100644 index 0000000..eb522e1 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsOrderLogVo.java @@ -0,0 +1,160 @@ +package com.ruoyi.cmcc_gm.domain.vo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 物资工单日志表 + *

+ * + * @author jkj + * @since 2023-04-07 + */ +@Data +public class YwMaterialsOrderLogVo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 序号 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 工单号 + */ + @Excel(name = "工单号", type = Excel.Type.EXPORT) + private String orderId; + + /** + * 入库场馆名称 + */ + @Excel(name = "场馆", type = Excel.Type.EXPORT) + private String inVenueName; + + /** + * 出库场馆名称 + */ + @Excel(name = "场馆", type = Excel.Type.EXPORT) + private String outVenueName; + + /** + * 出库场馆名称 + */ + @Excel(name = "调出库", type = Excel.Type.EXPORT) + private String outVenue2Name; + + /** + * 入库场馆名称 + */ + @Excel(name = "调入库", type = Excel.Type.EXPORT) + private String inVenue2Name; + + /** + * 拆布线工单号 + */ + @Excel(name = "布线项目号", type = Excel.Type.EXPORT) + private String wireTaskId; + + /** + * 任务发起时间 + */ + @Excel(name = "申请时间", type = Excel.Type.EXPORT, dateFormat = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime taskStartTime; + + /** + * 申请人 + */ + @Excel(name = "申请人", type = Excel.Type.EXPORT) + private String applyName; + + /** + * 审核人 + */ + @Excel(name = "审核人", type = Excel.Type.EXPORT) + private String checkName; + + /** + * 入库人 + */ + @Excel(name = "入库人", type = Excel.Type.EXPORT) + private String inStoreName; + + /** + * 出库人 + */ + @Excel(name = "出库人", type = Excel.Type.EXPORT) + @TableField(exist = false) + private String outStoreName; + + /** + * 任务状态 + */ + @Excel(name = "工单状态", type = Excel.Type.EXPORT) + private String taskStatus; + + private String dealStatus; + + /** + * 工单类型(更新中心库=1,申领=2,退库=3,工程出库=4,折旧入库=5,物资调拨=6) + */ + private Integer orderType; + private String orderTypeName; + + /** + * 工作流id + */ + private String flwProcessid; + + /** + * 工作流任务id + */ + private String taskId; + + /** + * 入库场馆 + */ + private Long inStoreVenue; + + /** + * 出库场馆 + */ + private Long outStoreVenue; + + /** + * 申请人ID + */ + private Long applyId; + + /** + * 审核人ID + */ + private Long checkId; + + /** + * 入库人ID + */ + private Long inStoreId; + + /** + * 上传文件路径 + */ + private String fileUrl; + + /** + * 上传文件名称 + */ + private String fileName; + + + private Integer materialNum; + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsSnListVo.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsSnListVo.java new file mode 100644 index 0000000..bcde038 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsSnListVo.java @@ -0,0 +1,31 @@ +package com.ruoyi.cmcc_gm.domain.vo; + +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 物资编码串码对应表 + *

+ * + * @author jkj + * @since 2023-04-10 + */ +@Data +public class YwMaterialsSnListVo extends YwMaterialsInformVo implements Serializable { + + private static final long serialVersionUID = 1L; + + + /** + * 工单号 + */ + private String orderid; + + /** + * 串码 + */ + private String materialStrCode; + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsVo.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsVo.java new file mode 100644 index 0000000..776b5e7 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/domain/vo/YwMaterialsVo.java @@ -0,0 +1,68 @@ +package com.ruoyi.cmcc_gm.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 物资库存表 + *

+ * + * @author jkj + * @since 2023-04-06 + */ + +@Data +public class YwMaterialsVo extends YwMaterialsInformVo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 物资库ID(场馆库对应venue_id,中心库对应一个特殊id比如0 + */ + private Long materialStoreId; + + /** + * 仓库名称 + */ + private String materialStoreName; + + /** + * 可用数 + */ + private Integer availSum; + + /** + * 出库在途数 + */ + private Integer outWaySum; + + /** + * 入库在途数 + */ + private Integer inWaySum; + + /** + * 出入库统计数 + */ + private Integer statisSum; + + /** + * 中心库入库数量 + */ + private Integer zxkInSum; + + /** + * 申领数量 + */ + private Integer slSum; + + /** + * 退库数量 + */ + private Integer tkSum; + + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsBatch.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsBatch.java new file mode 100644 index 0000000..62d43d3 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsBatch.java @@ -0,0 +1,133 @@ +package com.ruoyi.cmcc_gm.importer; + +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import com.ruoyi.cmcc_gm.domain.YwMaterialsInform; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsBatchMapper; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsInformMapper; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.importer.service.YwBatchAddService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@RequiredArgsConstructor +public class ImporterMaterialsBatch extends ImporterBase implements YwBatchAddService { + + private final YwMaterialsBatchMapper ywMaterialsBatchMapper; + + private final YwMaterialsInformMapper ywMaterialsInformMapper; + + private String materialCode; + private String materialName; + private String materialStand; + + { + cellFormatBeans.add(new CellFormatBean("物资编号", "materialCode", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("物资名称", "materialName", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("规格型号", "materialStand", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("大类", "materialBigClass", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("小类", "materialSmallClass", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("单位", "materialUnit", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("SN绑定", "snCode", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("数量", "sum", "false", "", "true", "nonNegative", "", "", "", "")); + } + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception { + + } + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i + * @throws Exception 异常 + */ + @Override + protected void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception { + List ywMaterialsInforms = ywMaterialsInformMapper.selectByMaterialNameAndMaterialStandAndMaterialCode(materialName, materialStand, materialCode); + if (CollectionUtils.isEmpty(ywMaterialsInforms)) { + reasonL.append("物资编号&物资名称&规格型号不存在于物资配置表。"); + } + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i + * @param j + * @throws Exception 异常 + */ + @Override + protected void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) throws Exception { + if ("materialCode".equals(format.getColumnEn())) { + materialCode = s; + } else if ("materialName".equals(format.getColumnEn())) { + materialName = s; + } else if ("materialStand".equals(format.getColumnEn())) { + materialStand = s; + } + } + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) throws Exception { + //导入 + List ywMaterialsBatchList = new ArrayList<>(); + for (YwMaterialsInform ywMaterialsInform : datas) { + YwMaterialsBatch ywMaterialsBatch = new YwMaterialsBatch(); + ywMaterialsBatch.setMaterialCode(ywMaterialsInform.getMaterialCode()); + ywMaterialsBatch.setOrderid((String) args[0]); + ywMaterialsBatch.setSum(Integer.parseInt(ywMaterialsInform.getSum())); + ywMaterialsBatchList.add(ywMaterialsBatch); + } + ywMaterialsBatchMapper.deleteByOrderid((String) args[0]); + add(ywMaterialsBatchList); + } + + /** + * 实现类提供具体插入方法 + * + * @param collect + */ + @Override + public void insertB(List collect) { + ywMaterialsBatchMapper.insertBatch(collect); + } +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsInform.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsInform.java new file mode 100644 index 0000000..364f3fb --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsInform.java @@ -0,0 +1,174 @@ +package com.ruoyi.cmcc_gm.importer; + +import com.ruoyi.cmcc_gm.domain.YwMaterialsClasses; +import com.ruoyi.cmcc_gm.domain.YwMaterialsInform; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSearchDTO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsInformVo; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsClassesMapper; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsInformMapper; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RequiredArgsConstructor +@Slf4j +public class ImporterMaterialsInform extends ImporterBase { + + private final YwMaterialsClassesMapper ywMaterialsClassesMapper; + + private final YwMaterialsInformMapper ywMaterialsInformMapper; + + private String bigClass; + private String smallClass; + + private String materialCode; + + private List> materialCodeList = new ArrayList<>(); + + private String materialName; + + private String materialStand; + + { + cellFormatBeans.add(new CellFormatBean("物资编号", "materialCode", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("物资名称", "materialName", "false", "", "", "", "", "", "true")); + cellFormatBeans.add(new CellFormatBean("规格型号", "materialStand", "false", "", "", "", "", "", "true")); + cellFormatBeans.add(new CellFormatBean("大类", "materialBigClass", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("小类", "materialSmallClass", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("单位", "materialUnit", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("SN绑定", "snCode", "", "", "", "", "", "是,否", "")); + + this.setHiddenResultColumns(new String[]{"sum"}); + } + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception { + + } + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i + * @throws Exception 异常 + */ + @Override + protected void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception { + if (isNotEmpty(bigClass) && isNotEmpty(smallClass)) { + List list = ywMaterialsClassesMapper.selectByBigClassAndSmallClass(bigClass, smallClass); + if (CollectionUtils.isEmpty(list)) { + reasonL.append("大类+小类的组合不在类型配置表中。"); + } + } + for (Map stringObjectMap : materialCodeList) { + if (materialCode.equals(stringObjectMap.get("materialCode")) && i != (Integer) stringObjectMap.get("row")) { + reasonL.append("物资编号重复。"); + } + } + if (isNotEmpty(materialName) && isNotEmpty(materialStand)) { + List ywMaterialsInforms = ywMaterialsInformMapper.selectByMaterialNameAndMaterialStand(materialName, materialStand); + if (!CollectionUtils.isEmpty(ywMaterialsInforms)) { + if (ywMaterialsInforms.size() > 1) { + reasonL.append("物资名称和规格型号已存在物资配置表中。"); + } else { + YwMaterialsInform ywMaterialsInform = ywMaterialsInforms.get(0); + if (!materialCode.equals(ywMaterialsInform.getMaterialCode())) { + reasonL.append("物资名称和规格型号已存在物资配置表中。"); + } + } + } + } + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i + * @param j + * @throws Exception 异常 + */ + @Override + protected void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) throws Exception { + if ("materialBigClass".equals(format.getColumnEn())) { + bigClass = s; + } else if ("materialSmallClass".equals(format.getColumnEn())) { + smallClass = s; + } else if ("materialName".equals(format.getColumnEn())) { + materialName = s; + } else if ("materialStand".equals(format.getColumnEn())) { + materialStand = s; + } else if ("materialCode".equals(format.getColumnEn())) { + materialCode = s; + Map map = new HashMap<>(); + map.put("row", i); + map.put("materialCode", materialCode); + materialCodeList.add(map); + } + } + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + @Transactional + protected void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) throws Exception { + + + if(args.length>0) + { + if((boolean)args[0]==true) + { + ywMaterialsInformMapper.deleteNotExistsStock(); + } + } + + for (YwMaterialsInform data : datas) { + YwMaterialsSearchDTO ywMaterialsSearchDTO = new YwMaterialsSearchDTO(); + ywMaterialsSearchDTO.setMaterialCode(data.getMaterialCode()); + List ywMaterialsInformVos = ywMaterialsInformMapper.selectMaterialsInfo(ywMaterialsSearchDTO); + if (CollectionUtils.isEmpty(ywMaterialsInformVos)) { + ywMaterialsInformMapper.insert(data); + } else { + data.setId(ywMaterialsInformVos.get(0).getId()); + ywMaterialsInformMapper.updateById(data); + } + } + } +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsReturnList.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsReturnList.java new file mode 100644 index 0000000..963e3f4 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsReturnList.java @@ -0,0 +1,158 @@ +package com.ruoyi.cmcc_gm.importer; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.cmcc_gm.domain.YwMaterialsClasses; +import com.ruoyi.cmcc_gm.domain.YwMaterialsInform; +import com.ruoyi.cmcc_gm.domain.YwMaterialsStock; +import com.ruoyi.cmcc_gm.domain.vo.MaterialsXlsToJsonArrayVo; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsClassesMapper; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsInformMapper; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsStockMapper; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.CollectionUtils; + +import java.util.List; + +@Slf4j +@RequiredArgsConstructor +public class ImporterMaterialsReturnList extends ImporterBase { + + private final YwMaterialsClassesMapper ywMaterialsClassesMapper; + private final YwMaterialsStockMapper ywMaterialsStockMapper; + private final YwMaterialsInformMapper ywMaterialsInformMapper; + + private String bigClass; + private String smallClass; + + private String materialCode; + private String materialName; + private String materialStand; + + private String sum; + + { + setHiddenResultColumns(new String[]{"id", "availSum", "outSum", "inSum", "operation"}); + cellFormatBeans.add(new CellFormatBean("物资编号", "materialCode", "false", "", "", "", "", "", "true")); + cellFormatBeans.add(new CellFormatBean("物资名称", "materialName", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("规格型号", "materialStand", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("大类", "materialBigClass", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("小类", "materialSmallClass", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("SN绑定", "snCode", "false", "", "", "", "", "是,否", "")); + cellFormatBeans.add(new CellFormatBean("申请数量", "sum", "false", "", "true", "nonNegative", "", "", "", "")); + } + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception { + + } + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i + * @throws Exception 异常 + */ + @Override + protected void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception { + if (isNotEmpty(bigClass) && isNotEmpty(smallClass)) { + List list = ywMaterialsClassesMapper.selectByBigClassAndSmallClass(bigClass, smallClass); + if (CollectionUtils.isEmpty(list)) { + reasonL.append("大类+小类的组合不在类型配置表中。"); + } + } + if (isNotEmpty(sum) && isNotEmpty(materialCode)) { + String name; + Long materialId = (Long) args[0]; + // 物资折旧入库不需要判断物资是否存在和库存数 + if (materialId != -1L) { + if (materialId == 0L) { + name = "中心库"; + } else { + name = "场馆库"; + } + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(YwMaterialsStock::getMaterialStoreId, materialId).eq(YwMaterialsStock::getMaterialCode, materialCode); + List list = ywMaterialsStockMapper.selectList(wrapper); + if (CollectionUtils.isEmpty(list)) { + reasonL.append(name).append("中不存在该物资。"); + } else { + wrapper.ge(YwMaterialsStock::getAvailSum, Integer.parseInt(sum)); + List list1 = ywMaterialsStockMapper.selectList(wrapper); + if (CollectionUtils.isEmpty(list1)) { + reasonL.append(name).append("中该物资库存数量不足。"); + } + } + } + } + if (isNotEmpty(materialName) && isNotEmpty(materialStand) && isNotEmpty(materialCode)) { + List ywMaterialsInforms = ywMaterialsInformMapper.selectByMaterialNameAndMaterialStandAndMaterialCode(materialName, materialStand, materialCode); + if (CollectionUtils.isEmpty(ywMaterialsInforms)) { + reasonL.append("物资编号+物资名称+规格型号不存在于物资配置表。"); + } + } + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i + * @param j + * @throws Exception 异常 + */ + @Override + protected void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) throws Exception { + if ("materialBigClass".equals(format.getColumnEn())) { + bigClass = s; + } else if ("materialSmallClass".equals(format.getColumnEn())) { + smallClass = s; + } else if ("materialCode".equals(format.getColumnEn())) { + materialCode = s; + } else if ("sum".equals(format.getColumnEn())) { + sum = s; + } else if ("materialName".equals(format.getColumnEn())) { + materialName = s; + } else if ("materialStand".equals(format.getColumnEn())) { + materialStand = s; + } + } + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) throws Exception { + + } +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsStock.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsStock.java new file mode 100644 index 0000000..530eaf4 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/importer/ImporterMaterialsStock.java @@ -0,0 +1,187 @@ +package com.ruoyi.cmcc_gm.importer; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.cmcc_gm.domain.YwMaterialsClasses; +import com.ruoyi.cmcc_gm.domain.YwMaterialsInform; +import com.ruoyi.cmcc_gm.domain.YwMaterialsStock; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsStockImportDTO; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsClassesMapper; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsInformMapper; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsStockMapper; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.importer.service.YwBatchAddService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@RequiredArgsConstructor +public class ImporterMaterialsStock extends ImporterBase implements YwBatchAddService { + + private final YwMaterialsStockMapper ywMaterialsStockMapper; + + private final YwMaterialsClassesMapper ywMaterialsClassesMapper; + + private final YwMaterialsInformMapper ywMaterialsInformMapper; + + private String bigClass; + private String smallClass; + private String materialCode; + private String materialName; + private String materialStand; + + { + cellFormatBeans.add(new CellFormatBean("物资编号", "materialCode", "false", "", "", "", "", "", "true")); + cellFormatBeans.add(new CellFormatBean("物资名称", "materialName", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("规格型号", "materialStand", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("大类", "materialBigClass", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("小类", "materialSmallClass", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("单位", "materialUnit", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("数量", "availSum", "false", "", "true", "nonNegative", "", "", "", "")); + } + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception { + + } + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i + * @throws Exception 异常 + */ + @Override + protected void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception { + if (isNotEmpty(bigClass) && isNotEmpty(smallClass)) { + List list = ywMaterialsClassesMapper.selectByBigClassAndSmallClass(bigClass, smallClass); + if (CollectionUtils.isEmpty(list)) { + reasonL.append("大类+小类的组合不在类型配置表中。"); + } + } + if (isNotEmpty(materialCode) && isNotEmpty(materialName) && isNotEmpty(materialStand)) { + List ywMaterialsInforms = ywMaterialsInformMapper.selectByMaterialNameAndMaterialStandAndMaterialCode(materialName, materialStand, materialCode); + if (CollectionUtils.isEmpty(ywMaterialsInforms)) { + reasonL.append("物资编号+物资名称+规格型号的组合不在物资配置表中。"); + } + } + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i + * @param j + * @throws Exception 异常 + */ + @Override + protected void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) throws Exception { + if ("materialBigClass".equals(format.getColumnEn())) { + bigClass = s; + } else if ("materialSmallClass".equals(format.getColumnEn())) { + smallClass = s; + } else if ("materialCode".equals(format.getColumnEn())) { + materialCode = s; + } else if ("materialName".equals(format.getColumnEn())) { + materialName = s; + } else if ("materialStand".equals(format.getColumnEn())) { + materialStand = s; + } + } + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) throws Exception { + if ("0".equals(importType)) { + ywMaterialsStockMapper.deleteByMaterialStoreId((Long) args[0]); + List list = new ArrayList<>(); + for (YwMaterialsStockImportDTO data : datas) { + YwMaterialsStock ywMaterialsStock = new YwMaterialsStock(); + ywMaterialsStock.setMaterialCode(data.getMaterialCode()); + ywMaterialsStock.setMaterialStoreId((Long) args[0]); + ywMaterialsStock.setAvailSum(Integer.parseInt(data.getAvailSum())); + ywMaterialsStock.setInWaySum(0); + ywMaterialsStock.setOutWaySum(0); + ywMaterialsStock.setSceneBigId(sceneBigId); + list.add(ywMaterialsStock); + } + add(list); + } else if ("1".equals(importType)) { + for (YwMaterialsStockImportDTO data : datas) { + // 1 新增 2 修改 + Integer opType; + Integer availSumOld = null; + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(YwMaterialsStock::getMaterialCode, data.getMaterialCode()).eq(YwMaterialsStock::getMaterialStoreId, args[0]); + YwMaterialsStock ywMaterialsStock = ywMaterialsStockMapper.selectOne(queryWrapper); + if (ObjectUtils.isNotEmpty(ywMaterialsStock)) { + availSumOld = ywMaterialsStock.getAvailSum(); + opType = 2; + } else { + opType = 1; + } + YwMaterialsStock y = new YwMaterialsStock(); + if (opType == 1) { + y.setMaterialCode(data.getMaterialCode()); + y.setMaterialStoreId((Long) args[0]); + y.setAvailSum(Integer.parseInt(data.getAvailSum())); + y.setInWaySum(0); + y.setOutWaySum(0); + y.setSceneBigId(sceneBigId); + ywMaterialsStockMapper.insert(y); + } else if (opType == 2) { + y.setAvailSum(Integer.parseInt(data.getAvailSum()) + availSumOld); + LambdaQueryWrapper queryWrapper1 = new LambdaQueryWrapper<>(); + queryWrapper1.eq(YwMaterialsStock::getMaterialStoreId, args[0]).eq(YwMaterialsStock::getMaterialCode, data.getMaterialCode()); + ywMaterialsStockMapper.update(y, queryWrapper1); + } + } + } + } + + /** + * 实现类提供具体插入方法 + * + * @param collect + */ + @Override + public void insertB(List collect) { + ywMaterialsStockMapper.insertBatch(collect); + } +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsBatchMapper.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsBatchMapper.java new file mode 100644 index 0000000..39f5b3d --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsBatchMapper.java @@ -0,0 +1,34 @@ +package com.ruoyi.cmcc_gm.mapper; + +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsBatchVo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 物资批次表 Mapper 接口 + *

+ * + * @author jkj + * @since 2023-04-10 + */ +public interface YwMaterialsBatchMapper extends BaseMapper { + + /** + * 批量新增数据(MyBatis原生foreach方法) + * + * @param entities List 实例对象列表 + * @return 影响行数 + */ + int insertBatch(@Param("entities") List entities); + + int updateBatch(@Param("orderId") String orderId,@Param("entities") List entities); + + List selectBatch(@Param("orderid") String orderid); + + int deleteByOrderid(@Param("orderid") String orderid); + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsClassesMapper.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsClassesMapper.java new file mode 100644 index 0000000..3d0ed2b --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsClassesMapper.java @@ -0,0 +1,31 @@ +package com.ruoyi.cmcc_gm.mapper; +import org.apache.ibatis.annotations.Param; + +import com.ruoyi.cmcc_gm.domain.YwMaterialsClasses; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsClassesVo; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsVo; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jkj + * @since 2023-04-07 + */ +@Mapper +public interface YwMaterialsClassesMapper extends BaseMapper { + + List selectMaterialClass(); + + List selectByBigClassAndSmallClass(@Param("bigClass") String bigClass, @Param("smallClass") String smallClass); + + List listAllByBigClassAndSmallClass(@Param("bigClass") String bigClass, @Param("smallClass") String smallClass); + + public void cleanMaterialClass(); + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsInformMapper.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsInformMapper.java new file mode 100644 index 0000000..4fac268 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsInformMapper.java @@ -0,0 +1,37 @@ +package com.ruoyi.cmcc_gm.mapper; +import java.util.Collection; + +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; +import com.ruoyi.cmcc_gm.domain.YwMaterialsInform; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSearchDTO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsInformVo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 物资信息表 Mapper 接口 + *

+ * + * @author jkj + * @since 2023-04-06 + */ +public interface YwMaterialsInformMapper extends BaseMapper { + + List selectByMaterialNameAndMaterialStand(@Param("materialName") String materialName, @Param("materialStand") String materialStand); + + List selectByMaterialNameAndMaterialStandAndMaterialCode(@Param("materialName") String materialName, @Param("materialStand") String materialStand, @Param("materialCode") String materialCode); + + List selectMaterialsInfo(YwMaterialsSearchDTO ywMaterialsSearchDTO); + + @InterceptorIgnore(blockAttack = "true") + int delete(); + + int insertBatch(@Param("ywMaterialsInformCollection") Collection ywMaterialsInformCollection); + + List listAll(YwMaterialsSearchDTO ywMaterialsSearchDTO); + + int deleteNotExistsStock(); +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsOrderLogMapper.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsOrderLogMapper.java new file mode 100644 index 0000000..85543b5 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsOrderLogMapper.java @@ -0,0 +1,30 @@ +package com.ruoyi.cmcc_gm.mapper; + +import com.ruoyi.cmcc_gm.domain.YwMaterialsOrderLog; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSearchDTO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsOrderLogVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 物资工单日志表 Mapper 接口 + *

+ * + * @author jkj + * @since 2023-04-07 + */ + +public interface YwMaterialsOrderLogMapper extends BaseMapper { + + List selectMaterialsOrderLog(YwMaterialsSearchDTO ywMaterialsSearchDTO); + + List selectOrderMaterialsNumLog(@Param("materialStoreId") Long storeId,@Param("materialCode") String materialCode); + + + Long selectCheckUserIdByFlwId(@Param("flwId") String flwId); + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsSnListMapper.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsSnListMapper.java new file mode 100644 index 0000000..b2b96d5 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsSnListMapper.java @@ -0,0 +1,32 @@ +package com.ruoyi.cmcc_gm.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import com.ruoyi.cmcc_gm.domain.YwMaterialsSnList; +import com.ruoyi.cmcc_gm.domain.qo.YwMaterialsSnListQO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsBatchVo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 物资批次表 Mapper 接口 + *

+ * + * @author jkj + * @since 2023-04-10 + */ +public interface YwMaterialsSnListMapper extends BaseMapper { + + /** + * 批量新增数据(MyBatis原生foreach方法) + * + * @param entities List 实例对象列表 + * @return 影响行数 + */ + int insertSnList(@Param("entities") List entities); + + List selectSnList(YwMaterialsSnListQO ywMaterialsSnListQO); + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsStockMapper.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsStockMapper.java new file mode 100644 index 0000000..904a128 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/mapper/YwMaterialsStockMapper.java @@ -0,0 +1,44 @@ +package com.ruoyi.cmcc_gm.mapper; +import org.apache.ibatis.annotations.Param; +import java.util.Collection; + +import com.ruoyi.cmcc_gm.domain.YwMaterialsStock; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSearchDTO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsVo; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + *

+ * 物资库存表 Mapper 接口 + *

+ * + * @author jkj + * @since 2023-04-06 + */ +@Mapper +public interface YwMaterialsStockMapper extends BaseMapper { + + + public List getYwMaterial(YwMaterialsSearchDTO ywMaterialsSearchDTO); + + /** + * 批量插入 + * + * @param ywMaterialsStockCollection + * @return + */ + int insertBatch(@Param("ywMaterialsStockCollection") Collection ywMaterialsStockCollection); + + /** + * 根据大场景id和materialStoreId删除 + * + * @param materialStoreId + * @return + */ + int deleteByMaterialStoreId(@Param("materialStoreId") Long materialStoreId); + + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/GMCommonService.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/GMCommonService.java new file mode 100644 index 0000000..e5a4097 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/GMCommonService.java @@ -0,0 +1,7 @@ +package com.ruoyi.cmcc_gm.service; + +public interface GMCommonService { + + String getJobNo(String type); + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsBatchService.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsBatchService.java new file mode 100644 index 0000000..fa77cf4 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsBatchService.java @@ -0,0 +1,33 @@ +package com.ruoyi.cmcc_gm.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import com.ruoyi.cmcc_gm.domain.YwMaterialsInform; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsBatchDTO; +import com.ruoyi.common.core.domain.AjaxResult; + +import java.io.File; +import java.util.List; + +/** + * 物资批次表(YwMaterialsBatch)表服务接口 + * + * @author makejava + * @since 2023-04-10 15:39:19 + */ +public interface YwMaterialsBatchService extends IService { + + AjaxResult importExcel(String orderId, List y, File file) throws Exception; + + Boolean deleteBatch(YwMaterialsBatchDTO ywMaterialsBatchDTO); + + Boolean deleteBatchALL(YwMaterialsBatchDTO ywMaterialsBatchDTO); + + Boolean insertBatch(YwMaterialsBatchDTO ywMaterialsBatchDTO); + + Boolean updateBatch(YwMaterialsBatch ywMaterialsBatch); + + Boolean updateBatchInner(YwMaterialsBatch ywMaterialsBatch); + +} + diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsClassesService.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsClassesService.java new file mode 100644 index 0000000..fd08610 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsClassesService.java @@ -0,0 +1,38 @@ +package com.ruoyi.cmcc_gm.service; + +import com.ruoyi.cmcc_gm.domain.YwMaterialsClasses; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.cmcc_gm.domain.dto.YmMaterialsClassesParam; +import com.ruoyi.common.core.domain.AjaxResult; + +import java.util.List; +import java.util.Map; + +/** + *

+ * 服务类 + *

+ * + * @author jkj + * @since 2023-04-07 + */ +public interface YwMaterialsClassesService extends IService { + + public void loadingMaterialsClassesCache(); + + Map GetMaterialsClasses(); + + List getMaterialsBySearch(YmMaterialsClassesParam ywMaterialsClasses); + + /** + * 核查大小类是否在物资信息中已经使用 + * + * @param ywMaterialsClasses 大小类 + * @return 是否 + */ + boolean checkClassesInUse(YwMaterialsClasses ywMaterialsClasses); + + + AjaxResult importMaterialsClasses(List ywMaterialsClasses, Boolean updateSupport); + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsInformService.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsInformService.java new file mode 100644 index 0000000..c64aa75 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsInformService.java @@ -0,0 +1,52 @@ +package com.ruoyi.cmcc_gm.service; + +import com.ruoyi.cmcc_gm.domain.YwMaterialsInform; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsInformDTO; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSearchDTO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsInformRedisVo; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsInformVo; +import com.ruoyi.common.core.domain.AjaxResult; + +import java.util.List; + + +/** + *

+ * 物资信息表 服务类 + *

+ * + * @author jkj + * @since 2023-04-06 + */ +public interface YwMaterialsInformService extends IService { + + + void loadingMaterialsInfoCache(); + + List getMaterials(YwMaterialsSearchDTO ywMaterialsSearchDTO); + + List selectMaterials(YwMaterialsSearchDTO ywMaterialsSearchDTO); + + List getMaterials(); + + Boolean insertMaterials(YwMaterialsInformDTO ywMaterialsInformDTO); + + Boolean updateMaterials(YwMaterialsInformDTO ywMaterialsInformDTO); + + Boolean deleteMaterials(YwMaterialsInformDTO ywMaterialsInformDTO); + + int deleteNotExistsMaterials(); + + /** + * 导入 + * + * @param informs 数据 + * @return + */ + AjaxResult doImport(List informs) throws Exception; + + AjaxResult doImport(List informs,boolean delNotUse) throws Exception; + + List getMaterialsBySearch(YwMaterialsSearchDTO ywMaterialsInform); +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsOrderLogService.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsOrderLogService.java new file mode 100644 index 0000000..a90d9bf --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsOrderLogService.java @@ -0,0 +1,33 @@ +package com.ruoyi.cmcc_gm.service; + +import com.ruoyi.cmcc_gm.domain.YwMaterialsOrderLog; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsOrderLogDTO; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSearchDTO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsOrderLogVo; +import com.ruoyi.common.core.page.TableDataInfo; + +import java.util.List; + +/** + *

+ * 物资工单日志表 服务类 + *

+ * + * @author jkj + * @since 2023-04-07 + */ +public interface YwMaterialsOrderLogService extends IService { + + String insertMaterialsOrderLog(YwMaterialsOrderLogDTO ywMaterialsOrderLogDTO); + + Boolean updateMaterialsOrderLog(YwMaterialsOrderLogDTO ywMaterialsOrderLogDTO); + + Boolean updateMaterialsOrderLogInner(YwMaterialsOrderLogDTO ywMaterialsOrderLogDTO); + + Boolean deleteMaterialsOrderLog(YwMaterialsOrderLogDTO ywMaterialsOrderLogDTO); + + TableDataInfo getMaterialsOrderLog(YwMaterialsSearchDTO ywMaterialsSearchDTO); + + List selectMaterialsOrderLog(YwMaterialsSearchDTO ywMaterialsSearchDTO); +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsSnListService.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsSnListService.java new file mode 100644 index 0000000..1aa900f --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsSnListService.java @@ -0,0 +1,32 @@ +package com.ruoyi.cmcc_gm.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import com.ruoyi.cmcc_gm.domain.YwMaterialsInform; +import com.ruoyi.cmcc_gm.domain.YwMaterialsSnList; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsBatchDTO; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSnListDTO; +import com.ruoyi.cmcc_gm.domain.qo.YwMaterialsSnListQO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsBatchVo; +import com.ruoyi.common.core.domain.AjaxResult; + +import java.io.File; +import java.util.List; + +/** + * 出入库串码(YwMaterialsSnList)表服务接口 + * + * @author makejava + * @since 2023-04-10 15:39:19 + */ +public interface YwMaterialsSnListService extends IService { + + + Boolean deleteSnListALL(String orderId); + + Boolean insertSnList(YwMaterialsSnListDTO ywMaterialsSnListDTO); + + List selectSnList(YwMaterialsSnListQO ywMaterialsSnListQO); + +} + diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsStockService.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsStockService.java new file mode 100644 index 0000000..b856aec --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/YwMaterialsStockService.java @@ -0,0 +1,71 @@ +package com.ruoyi.cmcc_gm.service; + +import com.ruoyi.cmcc_gm.domain.YwMaterialsOrderLog; +import com.ruoyi.cmcc_gm.domain.YwMaterialsStock; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.cmcc_gm.domain.dto.*; +import com.ruoyi.cmcc_gm.domain.vo.MaterialsXlsToJsonArrayVo; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsVo; +import com.ruoyi.common.core.domain.AjaxResult; + +import java.util.List; + +/** + *

+ * 物资库存表 服务类 + *

+ * + * @author jkj + * @since 2023-04-06 + */ +public interface YwMaterialsStockService extends IService { + + List getMaterialsStock(YwMaterialsSearchDTO ywMaterialsSearchDTO); + + Boolean freezeOutWayMaterialsStock(YwMaterialsDTO ywMaterialsDTO, YwMaterialsOrderLog ywMaterialsOrderLog); + + Boolean freezeOutWayMaterialsStock(YwMaterialsBatchDTO ywMaterialsBatchDTO); + + Boolean freezeOutWayMaterialsStockBack(YwMaterialsBatchDTO ywMaterialsBatchDTO); + + Boolean freezeOutWayMaterialsStockBack(YwMaterialsDTO ywMaterialsDTO, YwMaterialsOrderLog ywMaterialsOrderLog); + + Boolean updateInWayMaterialsStock(YwMaterialsDTO ywMaterialsDTO); + + Boolean updateInWayMaterialsStockBack(YwMaterialsDTO ywMaterialsDTO); + + Boolean updateMaterialsStock(YwMaterialsDTO ywMaterialsDTO); + + Boolean updateMaterialsStockBack(YwMaterialsDTO ywMaterialsDTO); + + Boolean updateFreezeOutWayMaterialsStock(YwMaterialsDTO ywMaterialsDTO); + + Boolean updateFreezeOutWayMaterialsStockBack(YwMaterialsDTO ywMaterialsDTO); + + YwMaterialsOrderLog Validate(YwMaterialsDTO ywMaterialsDTO); + + int insertMaterialsStock(YwMaterialsStock ywMaterialsStock); + + int updateMaterialsStock(YwMaterialsStock ywMaterialsStock); + + /** + * 导入 + * + * @param beans 数据 + * @param sceneBigId 大场景id + * @param importType 导入方式 + * @param materialStoreId materialStoreId + * @return 导入结果 + */ + AjaxResult importXls(List beans, Long sceneBigId, String importType, Long materialStoreId) throws Exception; + + /** + * 导入,返回List + * + * @param xls 数据 + * @param sceneId + * @return 导入的数据 + * @throws Exception 异常 + */ + AjaxResult importXlsReturnList(List xls, Long sceneId) throws Exception; +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/GMCommonServiceImpl.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/GMCommonServiceImpl.java new file mode 100644 index 0000000..9f64f39 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/GMCommonServiceImpl.java @@ -0,0 +1,50 @@ +package com.ruoyi.cmcc_gm.service.impl; + +import com.ruoyi.cmcc_gm.service.GMCommonService; +import com.ruoyi.common.core.redis.RedisCache; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +@Component +public class GMCommonServiceImpl implements GMCommonService { + + @Autowired + private RedisCache redisCache; + + @Override + public String getJobNo(String type) { + String date = new SimpleDateFormat("yyyyMMdd").format(new Date()); + String key = type + date; + + if (redisCache.hasKey(key)) { + String value = redisCache.getCacheObject(key).toString(); + String[] split = value.split("-"); + if (split.length == 3) { + int i = Integer.parseInt(split[2]) + 1; + String num = String.format("%04d", i); + if(type.equals("ZXK")) + { + num = String.format("%02d", i); + } + String v = split[0] + "-" + split[1] + "-" + num; + redisCache.setCacheObject(key,v,1, TimeUnit.DAYS); + return v; + } + } + String value = ""; + if(type.equals("ZXK")) + { + value = type + "-" + date + "-" + "01"; + } + if(!type.equals("ZXK")) + { + value = type + "-" + date + "-" + "0001"; + } + redisCache.setCacheObject(key,value,1, TimeUnit.DAYS); + return value; + } +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsBatchServiceImpl.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsBatchServiceImpl.java new file mode 100644 index 0000000..597802d --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsBatchServiceImpl.java @@ -0,0 +1,314 @@ +package com.ruoyi.cmcc_gm.service.impl; + +import cn.hutool.core.io.FileUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.cmcc_gm.common.enums.OrderStatus; +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import com.ruoyi.cmcc_gm.domain.YwMaterialsInform; +import com.ruoyi.cmcc_gm.domain.YwMaterialsOrderLog; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsBatchDTO; +import com.ruoyi.cmcc_gm.importer.ImporterMaterialsBatch; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsBatchMapper; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsInformMapper; +import com.ruoyi.cmcc_gm.service.YwMaterialsBatchService; +import com.ruoyi.cmcc_gm.service.YwMaterialsOrderLogService; +import com.ruoyi.cmcc_gm.service.YwMaterialsStockService; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.utils.StringUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * 物资批次表(YwMaterialsBatch)表服务实现类 + * + * @author makejava + * @since 2023-04-10 15:39:20 + */ +@Service("ywMaterialsBatchService") +@RequiredArgsConstructor +public class YwMaterialsBatchServiceImpl extends ServiceImpl implements YwMaterialsBatchService { + + private final YwMaterialsInformMapper ywMaterialsInformMapper; + private final YwMaterialsBatchMapper ywMaterialsBatchMapper; + + @Autowired + private YwMaterialsOrderLogService ywMaterialsOrderLogService; + + @Autowired + private YwMaterialsStockService ywMaterialsStockService; + + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult importExcel(String orderId, List y, File file) throws Exception { + + ImporterBase importer = new ImporterMaterialsBatch(ywMaterialsBatchMapper, ywMaterialsInformMapper); + AjaxResult ajaxResult = importer.doAdd(y, null, "", orderId); + if (HttpStatus.ACCEPTED == (int) ajaxResult.get(AjaxResult.CODE_TAG)) { + String s = (String) ajaxResult.get(AjaxResult.DATA_TAG); + File src = new File(RuoYiConfig.getDownloadPath() + s); + if (src.exists()) { + FileUtil.copy(src, file, true); + } + return new AjaxResult(HttpStatus.ACCEPTED, "导入失败"); + } else { + return ajaxResult; + } + } + + @Override + @Transactional + public Boolean deleteBatch(YwMaterialsBatchDTO ywMaterialsBatchDTO) { + + if (StringUtils.isEmpty(ywMaterialsBatchDTO.getOrderId())) { + throw new ServiceException("物资订单号不能为空"); + } + + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(YwMaterialsOrderLog::getOrderId, ywMaterialsBatchDTO.getOrderId()); + + List listOrder = ywMaterialsOrderLogService.list(query); + + if (listOrder.isEmpty()) { + throw new ServiceException("物资订单不存在"); + } + + YwMaterialsOrderLog orderLog = listOrder.get(0); + + if (!orderLog.getTaskStatus().equals("0")) { + throw new ServiceException("当前物资订单状态不允许删除申领数据"); + } + + LambdaQueryWrapper queryBatch = new LambdaQueryWrapper<>(); + queryBatch.eq(YwMaterialsBatch::getOrderid, ywMaterialsBatchDTO.getOrderId()); + + if (ywMaterialsBatchDTO.getData().size() > 0) { + + List listBatch = ywMaterialsBatchMapper.selectList(queryBatch); + + if (listBatch.isEmpty()) { + return true; + } + + List backBatchs = new ArrayList<>(); + + for (YwMaterialsBatch delBatch : ywMaterialsBatchDTO.getData()) { + for (YwMaterialsBatch existsBatch : listBatch) { + if (delBatch.getMaterialCode().equals(existsBatch.getMaterialCode())) { + + backBatchs.add(existsBatch); + + } + } + } + + ywMaterialsBatchDTO.setData(backBatchs); + + //释放库存数 + ywMaterialsStockService.freezeOutWayMaterialsStockBack(ywMaterialsBatchDTO); + } + + int res = 0; + + if (!ywMaterialsBatchDTO.getData().isEmpty()) { + + for (YwMaterialsBatch batch : ywMaterialsBatchDTO.getData()) { + LambdaQueryWrapper deleteBatch = new LambdaQueryWrapper<>(); + + deleteBatch.eq(YwMaterialsBatch::getOrderid, ywMaterialsBatchDTO.getOrderId()); + deleteBatch.eq(YwMaterialsBatch::getMaterialCode, batch.getMaterialCode()); + + res = ywMaterialsBatchMapper.delete(deleteBatch); + + if (res == 0) { + throw new ServiceException("删除申领数据失败"); + } + } + } + + if (res > 0) { + return true; + } + + return false; + + } + + @Override + @Transactional + public Boolean deleteBatchALL(YwMaterialsBatchDTO ywMaterialsBatchDTO) { + + LambdaQueryWrapper queryBatch = new LambdaQueryWrapper<>(); + queryBatch.eq(YwMaterialsBatch::getOrderid, ywMaterialsBatchDTO.getOrderId()); + + YwMaterialsBatchDTO dto = new YwMaterialsBatchDTO(); + + dto.setStoreId(ywMaterialsBatchDTO.getStoreId()); + dto.setOrderId(ywMaterialsBatchDTO.getOrderId()); + + List listBatch = ywMaterialsBatchMapper.selectList(queryBatch); + dto.setData(listBatch); + + if (dto.getData().isEmpty()) { + return true; + } + +//驳回的同时,释放了库存,这里就不需要再次释放库存 +// if (ywMaterialsBatchDTO.getStoreId() >= 0) +// { +// if (dto.getData().size() > 0) { +// //释放库存数 +// Boolean r = ywMaterialsStockService.freezeOutWayMaterialsStockBack(dto); +// } +// } + + int res = ywMaterialsBatchMapper.delete(queryBatch); + + if (res > 0) { + return true; + } + + return false; + } + + @Override + @Transactional + public Boolean insertBatch(YwMaterialsBatchDTO ywMaterialsBatchDTO) { + + if (StringUtils.isEmpty(ywMaterialsBatchDTO.getOrderId())) { + throw new ServiceException("物资订单号不能为空"); + } + + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(YwMaterialsOrderLog::getOrderId, ywMaterialsBatchDTO.getOrderId()); + + List listOrder = ywMaterialsOrderLogService.list(query); + + if (listOrder.isEmpty()) { + throw new ServiceException("物资订单不存在"); + } + + YwMaterialsOrderLog order = listOrder.get(0); + + if (!order.getTaskStatus().equals(OrderStatus.DSQ.getCode())) { + throw new ServiceException("物资订单状态不是待申请"); + } + + Long outStore = order.getOutStoreVenue(); + + //设置出库仓库的仓库号 + ywMaterialsBatchDTO.setStoreId(outStore); + + List ywMaterialsBatchList = new ArrayList<>(); + + for (YwMaterialsBatch stockDTO : ywMaterialsBatchDTO.getData()) { + + if (StringUtils.isEmpty(stockDTO.getMaterialCode())) { + throw new ServiceException("物资编号不能为空"); + } + + if (outStore >= 0) { + + if (ObjectUtils.isEmpty(stockDTO.getSum())) { + + throw new ServiceException("申领数量不能为空"); + } + + if (stockDTO.getSum() <= 0) { + throw new ServiceException("申领数量必须大于0"); + } + } + + YwMaterialsBatch ywMaterialsBatch = new YwMaterialsBatch(); + ywMaterialsBatch.setMaterialCode(stockDTO.getMaterialCode()); + ywMaterialsBatch.setOrderid(ywMaterialsBatchDTO.getOrderId()); + ywMaterialsBatch.setSum(stockDTO.getSum()); + ywMaterialsBatchList.add(ywMaterialsBatch); + + } + + //回滚冻结数和删除旧的批量数据 + this.deleteBatchALL(ywMaterialsBatchDTO); + + //默认是1 暂存传0 + if(ObjectUtils.isEmpty(ywMaterialsBatchDTO.getNeedfrozen())) + { + if (outStore >= 0) { + //冻结库存数,最后讨论还是放在这,把更新库存表的冻结去掉 + ywMaterialsStockService.freezeOutWayMaterialsStock(ywMaterialsBatchDTO); + } + } + + if(ObjectUtils.isNotEmpty(ywMaterialsBatchDTO.getNeedfrozen())) + { + if(ywMaterialsBatchDTO.getNeedfrozen() == 1) + { + if (outStore >= 0) { + //冻结库存数,最后讨论还是放在这,把更新库存表的冻结去掉 + ywMaterialsStockService.freezeOutWayMaterialsStock(ywMaterialsBatchDTO); + } + } + } + + int res = ywMaterialsBatchMapper.insertBatch(ywMaterialsBatchList); + + if (res > 0) { + return true; + } + + return false; + + } + + // 存一下出入库的数据量,用于显示 + @Override + public Boolean updateBatch(YwMaterialsBatch ywMaterialsBatch) { + + if (StringUtils.isEmpty(ywMaterialsBatch.getOrderid())) { + throw new ServiceException("物资订单号不能为空"); + } + + if (StringUtils.isEmpty(ywMaterialsBatch.getMaterialCode())) { + throw new ServiceException("物资编号不能为空"); + } + + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(YwMaterialsOrderLog::getOrderId, ywMaterialsBatch.getOrderid()); + List listOrder = ywMaterialsOrderLogService.list(query); + + if (listOrder.isEmpty()) { + throw new ServiceException("物资订单不存在"); + } + + return this.updateBatchInner(ywMaterialsBatch); + + } + + @Override + public Boolean updateBatchInner(YwMaterialsBatch ywMaterialsBatch) { + + LambdaQueryWrapper condition = new LambdaQueryWrapper<>(); + condition.eq(YwMaterialsBatch::getOrderid, ywMaterialsBatch.getOrderid()); + condition.eq(YwMaterialsBatch::getMaterialCode, ywMaterialsBatch.getMaterialCode()); + int res = ywMaterialsBatchMapper.update(ywMaterialsBatch, condition); + + if (res > 0) { + return true; + } + + return false; + } + +} + diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsClassesServiceImpl.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsClassesServiceImpl.java new file mode 100644 index 0000000..31a7c4c --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsClassesServiceImpl.java @@ -0,0 +1,182 @@ +package com.ruoyi.cmcc_gm.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ArrayUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.cmcc_gm.domain.YwMaterialsClasses; +import com.ruoyi.cmcc_gm.domain.YwMaterialsInform; +import com.ruoyi.cmcc_gm.domain.dto.YmMaterialsClassesParam; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsClassesVo; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsClassesMapper; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsInformMapper; +import com.ruoyi.cmcc_gm.service.YwMaterialsClassesService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.utils.spring.SpringUtils; +import org.apache.commons.collections4.ListUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.PostConstruct; +import java.util.*; + +/** + *

+ * 服务实现类 + *

+ * + * @author jkj + * @since 2023-04-07 + */ +@Service +public class YwMaterialsClassesServiceImpl extends ServiceImpl implements YwMaterialsClassesService { + + @Autowired + private YwMaterialsClassesMapper ywMaterialsClassesMapper; + + @Autowired + private YwMaterialsInformMapper ywMaterialsInformMapper; + + @Autowired + private RedisCache redisCache; + + + private String key = CacheConstants.YW_MATERIALS_CLASS; + + /** + * 项目启动时,初始化参数到缓存 + */ + @PostConstruct + public void init() { + loadingMaterialsClassesCache(); + } + + @Override + public void loadingMaterialsClassesCache() { + + List list = ywMaterialsClassesMapper.selectMaterialClass(); + + Map dictDataMap = new HashMap<>(); + + for (YwMaterialsClassesVo ywMaterialsClassesVo : list) { + String[] smallClasses = ywMaterialsClassesVo.getSmallClass().split(","); + dictDataMap.put(ywMaterialsClassesVo.getBigClass(), smallClasses); + } + + redisCache.setCacheObject(key, dictDataMap); + + } + + @Override + public Map GetMaterialsClasses() { + + if (redisCache.hasKey(key)) { + try { + Map res = redisCache.getCacheObject(key); + if (ObjectUtils.isEmpty(res)) { + throw new Exception(); + } + return res; + } catch (Exception ex) { + + List list = ywMaterialsClassesMapper.selectMaterialClass(); + + Map dictDataMap = new HashMap<>(); + + for (YwMaterialsClassesVo ywMaterialsClassesVo : list) { + String[] smallClasses = ywMaterialsClassesVo.getSmallClass().split(","); + dictDataMap.put(ywMaterialsClassesVo.getBigClass(), smallClasses); + } + + redisCache.setCacheObject(key, dictDataMap); + + return dictDataMap; + + } + } + + List list = ywMaterialsClassesMapper.selectMaterialClass(); + + Map dictDataMap = new HashMap<>(); + + for (YwMaterialsClassesVo ywMaterialsClassesVo : list) { + String[] smallClasses = ywMaterialsClassesVo.getSmallClass().split(","); + dictDataMap.put(ywMaterialsClassesVo.getBigClass(), smallClasses); + } + + redisCache.setCacheObject(key, dictDataMap); + + return dictDataMap; + + } + + @Override + public List getMaterialsBySearch(YmMaterialsClassesParam ywMaterialsClasses) { + return ywMaterialsClassesMapper.listAllByBigClassAndSmallClass(ywMaterialsClasses.getBigClass(), ywMaterialsClasses.getSmallClass()); + } + + /** + * 核查大小类是否在物资信息中已经使用 + * + * @param ywMaterialsClasses 大小类 + * @return 是否 + */ + @Override + public boolean checkClassesInUse(YwMaterialsClasses ywMaterialsClasses) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(YwMaterialsInform::getMaterialBigClass, ywMaterialsClasses.getBigClass()) + .eq(YwMaterialsInform::getMaterialSmallClass, ywMaterialsClasses.getSmallClass()); + Long aLong = ywMaterialsInformMapper.selectCount(wrapper); + return aLong > 0; + } + + @Override + @Transactional + public AjaxResult importMaterialsClasses(List lstMaterialsClasses, Boolean updateSupport) { + if (StringUtils.isNull(lstMaterialsClasses) || lstMaterialsClasses.size() == 0) { + throw new ServiceException("导入数据不能为空!"); + } + + // 核查数据 + boolean checkFlag = true; + + for (int i = 0; i < lstMaterialsClasses.size() - 1; i++) { + for (int j = i + 1; j < lstMaterialsClasses.size(); j++) { + if (lstMaterialsClasses.get(i).getBigClass().equals(lstMaterialsClasses.get(j).getBigClass()) && + lstMaterialsClasses.get(i).getSmallClass().equals(lstMaterialsClasses.get(j).getSmallClass()) + ) { + lstMaterialsClasses.get(i).setReason("存在重复"); + lstMaterialsClasses.get(j).setReason("存在重复"); + checkFlag = false; + break; + } + } + } + + if (!checkFlag) { + ExcelUtil util = new ExcelUtil<>(YwMaterialsClasses.class); + String fileName = (String) util.exportExcel(lstMaterialsClasses, "签到导入结果").get(AjaxResult.MSG_TAG); + return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + } + + try { + ywMaterialsClassesMapper.cleanMaterialClass(); + for (YwMaterialsClasses materialsClasses : lstMaterialsClasses) { + ywMaterialsClassesMapper.insert(materialsClasses); + } + } catch (Exception ex) { + throw new ServiceException(ex.getMessage()); + } + + return AjaxResult.success(); + + } + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsInformServiceImpl.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsInformServiceImpl.java new file mode 100644 index 0000000..ae5eb0d --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsInformServiceImpl.java @@ -0,0 +1,333 @@ +package com.ruoyi.cmcc_gm.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.cmcc_gm.domain.YwMaterialsInform; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsInformDTO; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSearchDTO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsInformRedisVo; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsInformVo; +import com.ruoyi.cmcc_gm.importer.ImporterMaterialsInform; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsClassesMapper; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsInformMapper; +import com.ruoyi.cmcc_gm.service.YwMaterialsInformService; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.PostConstruct; +import java.util.ArrayList; +import java.util.List; + +/** + *

+ * 物资信息表 服务实现类 + *

+ * + * @author jkj + * @since 2023-04-06 + */ +@Service +public class YwMaterialsInformServiceImpl extends ServiceImpl implements YwMaterialsInformService { + + + @Autowired + private YwMaterialsInformMapper ywMaterialsInformMapper; + + @Autowired + private YwMaterialsClassesMapper ywMaterialsClassesMapper; + + @Autowired + private RedisCache redisCache; + + private String key = CacheConstants.YW_MATERIALS_INFO; + + @PostConstruct + public void init() { + loadingMaterialsInfoCache(); + } + + @Override + public void loadingMaterialsInfoCache() { + + List list = ywMaterialsInformMapper.selectList(null); + + List listVo = new ArrayList<>(); + + for (YwMaterialsInform inform : list) { + YwMaterialsInformRedisVo ywMaterialsRedis = new YwMaterialsInformRedisVo(); + ywMaterialsRedis.setWzmc(inform.getMaterialName()); + ywMaterialsRedis.setGgxh(inform.getMaterialStand()); + ywMaterialsRedis.setDl(inform.getMaterialBigClass()); + ywMaterialsRedis.setXl(inform.getMaterialSmallClass()); + ywMaterialsRedis.setWzbh(inform.getMaterialCode()); + ywMaterialsRedis.setWzdw(inform.getMaterialUnit()); + listVo.add(ywMaterialsRedis); + } + + + redisCache.setCacheObject(key, listVo); + + } + + @Override + public List getMaterials(YwMaterialsSearchDTO ywMaterialsSearchDTO) { + + YwMaterialsInform ywMaterialsInform = new YwMaterialsInform(); + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + //物资编号 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywMaterialsSearchDTO.getMaterialCode()), YwMaterialsInform::getMaterialCode, ywMaterialsSearchDTO.getMaterialCode()); + + //物资名称 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywMaterialsSearchDTO.getMaterialName()), YwMaterialsInform::getMaterialName, ywMaterialsSearchDTO.getMaterialName()); + + //规格型号 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywMaterialsSearchDTO.getMaterialStand()), YwMaterialsInform::getMaterialStand, ywMaterialsSearchDTO.getMaterialStand()); + + //是否绑定SN + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywMaterialsSearchDTO.getSnCode()), YwMaterialsInform::getSnCode, ywMaterialsSearchDTO.getSnCode()); + + List list = ywMaterialsInformMapper.selectList(lambdaQueryWrapper); + + List listVo = new ArrayList<>(); + + for (YwMaterialsInform inform : list) { + YwMaterialsInformVo ywMaterialsInformVo = new YwMaterialsInformVo(); + BeanUtils.copyBeanProp(ywMaterialsInformVo, inform); + listVo.add(ywMaterialsInformVo); + } + + return listVo; + + } + + @Override + public List selectMaterials(YwMaterialsSearchDTO ywMaterialsSearchDTO) { + return ywMaterialsInformMapper.selectMaterialsInfo(ywMaterialsSearchDTO); + } + + @Override + public List getMaterials() { + + if (redisCache.hasKey(key)) { + try { + List res = redisCache.getCacheObject(key); + if (ObjectUtils.isEmpty(res)) { + throw new Exception(); + } + return res; + } catch (Exception ex) { + + List list = ywMaterialsInformMapper.selectList(null); + + List listVo = new ArrayList<>(); + + for (YwMaterialsInform inform : list) { + YwMaterialsInformRedisVo ywMaterialsRedis = new YwMaterialsInformRedisVo(); + + ywMaterialsRedis.setWzmc(inform.getMaterialName()); + ywMaterialsRedis.setGgxh(inform.getMaterialStand()); + ywMaterialsRedis.setDl(inform.getMaterialBigClass()); + ywMaterialsRedis.setXl(inform.getMaterialSmallClass()); + listVo.add(ywMaterialsRedis); + } + + redisCache.setCacheObject(key, listVo); + + return listVo; + + } + } + + List list = ywMaterialsInformMapper.selectList(null); + + List listVo = new ArrayList<>(); + + for (YwMaterialsInform inform : list) { + YwMaterialsInformRedisVo ywMaterialsRedis = new YwMaterialsInformRedisVo(); + ywMaterialsRedis.setWzmc(inform.getMaterialName()); + ywMaterialsRedis.setGgxh(inform.getMaterialStand()); + ywMaterialsRedis.setDl(inform.getMaterialBigClass()); + ywMaterialsRedis.setXl(inform.getMaterialSmallClass()); + listVo.add(ywMaterialsRedis); + } + + redisCache.setCacheObject(key, listVo); + + return listVo; + } + + @Override + public Boolean insertMaterials(YwMaterialsInformDTO ywMaterialsInformDTO) { + + Validate(ywMaterialsInformDTO, "add"); + + YwMaterialsInform ywMaterialsInform = new YwMaterialsInform(); + + BeanUtils.copyBeanProp(ywMaterialsInform, ywMaterialsInformDTO); + + if (ywMaterialsInformMapper.insert(ywMaterialsInform) > 0) { + //新增成功后,更新下物资的缓存 + loadingMaterialsInfoCache(); + return true; + } + + return false; + } + + @Override + public Boolean updateMaterials(YwMaterialsInformDTO ywMaterialsInformDTO) { + + Validate(ywMaterialsInformDTO, "edit"); + + YwMaterialsInform ywMaterialsInform = new YwMaterialsInform(); + + BeanUtils.copyBeanProp(ywMaterialsInform, ywMaterialsInformDTO); + + //物资编码不用改 + ywMaterialsInform.setMaterialCode(null); + + //修改条件 + LambdaQueryWrapper condition = new LambdaQueryWrapper<>(); + condition.eq(YwMaterialsInform::getMaterialCode, ywMaterialsInformDTO.getMaterialCode()); + + + if (ywMaterialsInformMapper.update(ywMaterialsInform, condition) > 0) { + //修改成功后,更新下物资的缓存 + loadingMaterialsInfoCache(); + return true; + } + + return false; + } + + @Override + public Boolean deleteMaterials(YwMaterialsInformDTO ywMaterialsInformDTO) { + + if (StringUtils.isEmpty(ywMaterialsInformDTO.getMaterialCode())) { + throw new ServiceException("物资编码不允许为空"); + } + + LambdaQueryWrapper condition = new LambdaQueryWrapper<>(); + condition.eq(YwMaterialsInform::getMaterialCode, ywMaterialsInformDTO.getMaterialCode()); + + if (ywMaterialsInformMapper.delete(condition) > 0) { + //删除成功后,更新下物资的缓存 + loadingMaterialsInfoCache(); + return true; + } + + return false; + } + + @Override + public int deleteNotExistsMaterials() { + return ywMaterialsInformMapper.deleteNotExistsStock(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult doImport(List informs) throws Exception { + ImporterBase importer = new ImporterMaterialsInform(ywMaterialsClassesMapper, ywMaterialsInformMapper); + AjaxResult ajaxResult = importer.doAdd(informs, null, null); + if (HttpStatus.SUCCESS == (int) ajaxResult.get(AjaxResult.CODE_TAG)) { + //导入成功后,更新下物资的缓存 + loadingMaterialsInfoCache(); + } else { + return ajaxResult; + } + return AjaxResult.success(); + } + + @Override + public AjaxResult doImport(List informs, boolean delNotUse) throws Exception { + ImporterBase importer = new ImporterMaterialsInform(ywMaterialsClassesMapper, ywMaterialsInformMapper); + AjaxResult ajaxResult = null; + if(delNotUse) + { + ajaxResult = importer.doAdd(informs, null, null, delNotUse); + } + else + { + ajaxResult = importer.doAdd(informs, null, null); + } + if (HttpStatus.SUCCESS == (int) ajaxResult.get(AjaxResult.CODE_TAG)) { + //导入成功后,更新下物资的缓存 + loadingMaterialsInfoCache(); + } else { + return ajaxResult; + } + return AjaxResult.success(); + } + + @Override + public List getMaterialsBySearch(YwMaterialsSearchDTO ywMaterialsInform) { + return ywMaterialsInformMapper.listAll(ywMaterialsInform); + } + + void Validate(YwMaterialsInformDTO ywMaterialsInformDTO, String operType) { + if (StringUtils.isEmpty(ywMaterialsInformDTO.getMaterialName())) { + throw new ServiceException("物资名称不允许为空"); + } + + if (StringUtils.isEmpty(ywMaterialsInformDTO.getMaterialCode())) { + throw new ServiceException("物资编码不允许为空"); + } + + if (ObjectUtils.isEmpty(ywMaterialsInformDTO.getMaterialBigClass())) { + throw new ServiceException("大类不允许为空"); + } + + if (ObjectUtils.isEmpty(ywMaterialsInformDTO.getMaterialSmallClass())) { + throw new ServiceException("小类不允许为空"); + } + + if (StringUtils.isEmpty(ywMaterialsInformDTO.getMaterialStand())) { + throw new ServiceException("规格型号不允许为空"); + } + + if (StringUtils.isEmpty(ywMaterialsInformDTO.getMaterialUnit())) { + throw new ServiceException("单位型号不允许为空"); + } + + if (StringUtils.isEmpty(ywMaterialsInformDTO.getMaterialStand())) { + throw new ServiceException("规格型号不允许为空"); + } + + if (StringUtils.isEmpty(ywMaterialsInformDTO.getSnBand())) { + throw new ServiceException("SN绑定不允许为空"); + } + + //检查物资编号是否已经存在 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(YwMaterialsInform::getMaterialCode, ywMaterialsInformDTO.getMaterialCode()); + + YwMaterialsInform inform = ywMaterialsInformMapper.selectOne(query); + + if (operType.equals("add")) { + if (ObjectUtils.isNotEmpty(inform)) { + throw new ServiceException("物资编号已存在"); + } + } + + if (operType.equals("edit")) { + if (ObjectUtils.isEmpty(inform)) { + throw new ServiceException("物资编号不存在"); + } + } + + } + + +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsOrderLogServiceImpl.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsOrderLogServiceImpl.java new file mode 100644 index 0000000..0176877 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsOrderLogServiceImpl.java @@ -0,0 +1,300 @@ +package com.ruoyi.cmcc_gm.service.impl; + +import cn.hutool.core.date.LocalDateTimeUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.cmcc_gm.common.enums.OrderStatus; +import com.ruoyi.cmcc_gm.common.enums.OrderType; +import com.ruoyi.cmcc_gm.domain.YwMaterialsOrderLog; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsOrderLogDTO; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSearchDTO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsOrderLogVo; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsOrderLogMapper; +import com.ruoyi.cmcc_gm.service.GMCommonService; +import com.ruoyi.cmcc_gm.service.YwMaterialsOrderLogService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 物资工单日志表 服务实现类 + *

+ * + * @author jkj + * @since 2023-04-07 + */ +@Service +public class YwMaterialsOrderLogServiceImpl extends ServiceImpl implements YwMaterialsOrderLogService { + + + @Autowired + private YwMaterialsOrderLogMapper ywMaterialsOrderLogMapper; + + @Autowired + private GMCommonService commonService; + + @Override + public String insertMaterialsOrderLog(YwMaterialsOrderLogDTO ywMaterialsOrderLogDTO) { + + if(StringUtils.isNotEmpty(ywMaterialsOrderLogDTO.getWireTaskId())) + { + ywMaterialsOrderLogDTO.setWireTaskId(ywMaterialsOrderLogDTO.getWireTaskId().trim()); + } + + if(ObjectUtils.isEmpty(ywMaterialsOrderLogDTO.getOrderType())) + { + throw new ServiceException("工单类型不能为空"); + } + + if(ObjectUtils.isEmpty(ywMaterialsOrderLogDTO.getCheckName()) || ObjectUtils.isEmpty(ywMaterialsOrderLogDTO.getCheckId())) + { + throw new ServiceException("审核人不能为空"); + } + + if(ywMaterialsOrderLogDTO.getOrderType() == OrderType.ZXK.getCode() || ywMaterialsOrderLogDTO.getOrderType() == OrderType.TK.getCode()) + { + if(!ywMaterialsOrderLogDTO.getInStoreVenue().equals(0L)) + { + throw new ServiceException("中心库的库号不正确"); + } + } + + if(ywMaterialsOrderLogDTO.getOrderType() == OrderType.SL.getCode()) + { + if(!ywMaterialsOrderLogDTO.getOutStoreVenue().equals(0L)) + { + throw new ServiceException("中心库的库号不正确"); + } + } + + //根据工单类型生成工单号 + String type = OrderType.getAbbLabelByCode(ywMaterialsOrderLogDTO.getOrderType()); + + if(StringUtils.isEmpty(type)) + { + throw new ServiceException("工单类型不存在"); + } + + if(!ywMaterialsOrderLogDTO.getOrderType().equals(4)) { + if (ObjectUtils.isEmpty(ywMaterialsOrderLogDTO.getInStoreVenue())) { + throw new ServiceException("入库场馆不能为空"); + } + } + + if(!(ywMaterialsOrderLogDTO.getOrderType().equals(1) || ywMaterialsOrderLogDTO.getOrderType().equals(5))) + { + if(ObjectUtils.isEmpty(ywMaterialsOrderLogDTO.getOutStoreVenue())) + { + throw new ServiceException("出库场馆不能为空"); + } + } + + ywMaterialsOrderLogDTO.setOrderId(commonService.getJobNo(type)); + + if(ObjectUtils.isEmpty(ywMaterialsOrderLogDTO.getApplyName())) + { + ywMaterialsOrderLogDTO.setApplyId(SecurityUtils.getUserId()); + ywMaterialsOrderLogDTO.setApplyName(SecurityUtils.getLoginUser().getUser().getNickName()); + } + + YwMaterialsOrderLog ywMaterialsOrderLog=new YwMaterialsOrderLog(); + + BeanUtils.copyBeanProp(ywMaterialsOrderLog,ywMaterialsOrderLogDTO); + + ywMaterialsOrderLog.setTaskStatus(OrderStatus.DSQ.getCode()); + + ywMaterialsOrderLog.setTaskStartTime(LocalDateTimeUtil.now()); + + if(ywMaterialsOrderLogMapper.insert(ywMaterialsOrderLog)>0) + { + return ywMaterialsOrderLogDTO.getOrderId(); + } + + return ""; + + } + + @Override + public Boolean updateMaterialsOrderLog(YwMaterialsOrderLogDTO ywMaterialsOrderLogDTO) { + + if(StringUtils.isEmpty(ywMaterialsOrderLogDTO.getOrderId())) + { + throw new ServiceException("工单ID不能为空"); + } + + if(ObjectUtils.isEmpty(ywMaterialsOrderLogDTO.getOrderType())) + { + throw new ServiceException("工单类型不能为空"); + } + + QueryWrapper condition =new QueryWrapper<>(); + condition.eq("order_id",ywMaterialsOrderLogDTO.getOrderId()); + condition.eq("order_type",ywMaterialsOrderLogDTO.getOrderType()); + + YwMaterialsOrderLog ywMaterialsOrderLog=new YwMaterialsOrderLog(); + + if(ywMaterialsOrderLogDTO.getCheckId() != null) + { + ywMaterialsOrderLog.setCheckId(ywMaterialsOrderLogDTO.getCheckId()); + } + + if(StringUtils.isNotEmpty(ywMaterialsOrderLogDTO.getCheckName())) { + ywMaterialsOrderLog.setCheckName(ywMaterialsOrderLogDTO.getCheckName()); + } + + if(StringUtils.isNotEmpty(ywMaterialsOrderLogDTO.getFileUrl())) { + ywMaterialsOrderLog.setFileUrl(ywMaterialsOrderLogDTO.getFileUrl()); + } + + if(StringUtils.isNotEmpty(ywMaterialsOrderLogDTO.getFileName())) { + ywMaterialsOrderLog.setFileName(ywMaterialsOrderLogDTO.getFileName()); + } + + if(StringUtils.isNotEmpty(ywMaterialsOrderLogDTO.getFlwProcessid())) { + ywMaterialsOrderLog.setFlwProcessid(ywMaterialsOrderLogDTO.getFlwProcessid()); + } + + if(ywMaterialsOrderLogMapper.update(ywMaterialsOrderLog,condition)>0) + { + return true; + } + + return false; + } + + @Override + public Boolean updateMaterialsOrderLogInner(YwMaterialsOrderLogDTO ywMaterialsOrderLogDTO) { + + if(StringUtils.isEmpty(ywMaterialsOrderLogDTO.getOrderId())) + { + throw new ServiceException("工单ID不能为空"); + } + + if(ObjectUtils.isEmpty(ywMaterialsOrderLogDTO.getOrderType())) + { + throw new ServiceException("工单类型不能为空"); + } + + if(ObjectUtils.isEmpty(ywMaterialsOrderLogDTO.getTaskStatus())) + { + throw new ServiceException("任务状态不能为空"); + } + + QueryWrapper condition =new QueryWrapper<>(); + condition.eq("order_id",ywMaterialsOrderLogDTO.getOrderId()); + condition.eq("order_type",ywMaterialsOrderLogDTO.getOrderType()); + + YwMaterialsOrderLog ywMaterialsOrderLog=new YwMaterialsOrderLog(); + ywMaterialsOrderLog.setTaskStatus(ywMaterialsOrderLogDTO.getTaskStatus()); + + if(ywMaterialsOrderLogDTO.getInStoreId()!=null) + { + if(ywMaterialsOrderLogDTO.getInStoreId()>0) { + ywMaterialsOrderLog.setInStoreId(ywMaterialsOrderLogDTO.getInStoreId()); + } + else + { + ywMaterialsOrderLog.setInStoreId(null); + } + } + + if(ywMaterialsOrderLogDTO.getInStoreName()!=null) + { + ywMaterialsOrderLog.setInStoreName(ywMaterialsOrderLogDTO.getInStoreName()); + } + + if(ywMaterialsOrderLogMapper.update(ywMaterialsOrderLog,condition)>0) + { + return true; + } + + return false; + } + + @Override + public Boolean deleteMaterialsOrderLog(YwMaterialsOrderLogDTO ywMaterialsOrderLogDTO) { + + if(StringUtils.isEmpty(ywMaterialsOrderLogDTO.getOrderId())) + { + throw new ServiceException("工单ID不能为空"); + } + + if(ObjectUtils.isEmpty(ywMaterialsOrderLogDTO.getOrderType())) + { + throw new ServiceException("工单类型不能为空"); + } + + + QueryWrapper condition =new QueryWrapper<>(); + condition.eq("order_id",ywMaterialsOrderLogDTO.getOrderId()); + condition.eq("order_type",ywMaterialsOrderLogDTO.getOrderType()); + + if(ywMaterialsOrderLogMapper.delete(condition)>0) + { + return true; + } + + return false; + } + + @Override + public TableDataInfo getMaterialsOrderLog(YwMaterialsSearchDTO ywMaterialsSearchDTO) { + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + lambdaQueryWrapper.like(StringUtils.isNotEmpty(ywMaterialsSearchDTO.getOrderId()),YwMaterialsOrderLog::getOrderId, ywMaterialsSearchDTO.getOrderId()); + + lambdaQueryWrapper.eq(ObjectUtils.isNotEmpty(ywMaterialsSearchDTO.getOrderType()),YwMaterialsOrderLog::getOrderType, ywMaterialsSearchDTO.getOrderType()); + + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywMaterialsSearchDTO.getTaskStatus()),YwMaterialsOrderLog::getTaskStatus, ywMaterialsSearchDTO.getTaskStatus()); + + if(StringUtils.isNotEmpty(ywMaterialsSearchDTO.getSearchDate())) + { + lambdaQueryWrapper.between(YwMaterialsOrderLog::getTaskStartTime, LocalDateTime.parse(ywMaterialsSearchDTO.getSearchDate()+"T00:00:00"), LocalDateTime.parse(ywMaterialsSearchDTO.getSearchDate()+"T23:59:59")); + } + + TableDataInfo rspData = new TableDataInfo(); + Page page = ywMaterialsOrderLogMapper.selectPage(new Page<>(ywMaterialsSearchDTO.getPageNum(), ywMaterialsSearchDTO.getPageSize()), lambdaQueryWrapper); + + rspData.setRows(page.getRecords()); + rspData.setTotal(page.getTotal()); + + return rspData; + } + + @Override + public List selectMaterialsOrderLog(YwMaterialsSearchDTO ywMaterialsSearchDTO) { + +// 调拨传入-2,就显示全部场馆库 + if(ywMaterialsSearchDTO.getOrderType() == OrderType.DB.getCode()) + { + if (ywMaterialsSearchDTO.getInStoreId() == -2) { + ywMaterialsSearchDTO.setInStoreId(null); + } + if (ywMaterialsSearchDTO.getOutStoreId() == -2) { + ywMaterialsSearchDTO.setOutStoreId(null); + } + } + + // 前端绑定下拉框不好处理空字符串,传入all或者全部就置空 + if(StringUtils.isNotEmpty(ywMaterialsSearchDTO.getTaskStatus())) + { + if(ywMaterialsSearchDTO.getTaskStatus().equals("all")||ywMaterialsSearchDTO.getTaskStatus().equals("全部")) + { + ywMaterialsSearchDTO.setTaskStatus(""); + } + } + return ywMaterialsOrderLogMapper.selectMaterialsOrderLog(ywMaterialsSearchDTO); + } +} diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsSnListServiceImpl.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsSnListServiceImpl.java new file mode 100644 index 0000000..94d4dc0 --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsSnListServiceImpl.java @@ -0,0 +1,208 @@ +package com.ruoyi.cmcc_gm.service.impl; +; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import com.ruoyi.cmcc_gm.domain.YwMaterialsOrderLog; +import com.ruoyi.cmcc_gm.domain.YwMaterialsSnList; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsBatchDTO; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSnListDTO; +import com.ruoyi.cmcc_gm.domain.qo.YwMaterialsSnListQO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsBatchVo; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsBatchMapper; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsSnListMapper; +import com.ruoyi.cmcc_gm.service.YwMaterialsBatchService; +import com.ruoyi.cmcc_gm.service.YwMaterialsOrderLogService; +import com.ruoyi.cmcc_gm.service.YwMaterialsSnListService; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.StringUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; +import java.util.List; + +/** + * 物资批次表(YwMaterialsBatch)表服务实现类 + * + * @author makejava + * @since 2023-04-10 15:39:20 + */ +@Service("ywMaterialsSnListService") +@RequiredArgsConstructor +public class YwMaterialsSnListServiceImpl extends ServiceImpl implements YwMaterialsSnListService { + + private final YwMaterialsSnListMapper ywMaterialsSnListMapper; + private final YwMaterialsOrderLogService ywMaterialsOrderLogService; + + private final YwMaterialsBatchService ywMaterialsBatchService; + + + @Override + public Boolean deleteSnListALL(String orderId) { + + LambdaQueryWrapper querySn = new LambdaQueryWrapper<>(); + + querySn.eq(YwMaterialsSnList::getOrderid, orderId); + + List listSn = ywMaterialsSnListMapper.selectList(querySn); + + if(listSn.isEmpty()) + { + return true; + } + + int res = ywMaterialsSnListMapper.delete(querySn); + + if(res > 0) + { + return true; + } + + return false; + + } + + public Boolean deleteSnListALL(String orderId,String materialCode,Integer opType) { + + LambdaQueryWrapper querySn = new LambdaQueryWrapper<>(); + + querySn.eq(YwMaterialsSnList::getOrderid, orderId); + + querySn.eq(YwMaterialsSnList::getOpType,opType); + + querySn.eq(YwMaterialsSnList::getMaterialCode,materialCode); + + List listSn = ywMaterialsSnListMapper.selectList(querySn); + + if(listSn.isEmpty()) + { + return true; + } + + int res = ywMaterialsSnListMapper.delete(querySn); + + if(res > 0) + { + return true; + } + + throw new ServiceException("删除SN发生异常,稍后再试"); + + } + + + + @Override + @Transactional + public Boolean insertSnList(YwMaterialsSnListDTO ywMaterialsSnListDTO) { + + if (StringUtils.isEmpty(ywMaterialsSnListDTO.getOrderId())) { + throw new ServiceException("物资订单号不能为空"); + } + + if (ObjectUtils.isEmpty(ywMaterialsSnListDTO.getOpType())) { + throw new ServiceException("操作类型不能为空"); + } + + if (StringUtils.isEmpty(ywMaterialsSnListDTO.getMaterialCode())) { + throw new ServiceException("物资编号不能为空"); + } + + if(ywMaterialsSnListDTO.getOpType()!=0 && ywMaterialsSnListDTO.getOpType()!=1) + { + throw new ServiceException("操作类型不正确"); + } + + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(YwMaterialsOrderLog::getOrderId,ywMaterialsSnListDTO.getOrderId()); + + List listOrder = ywMaterialsOrderLogService.list(query); + + if (listOrder.isEmpty()) { + throw new ServiceException("物资订单不存在"); + } + + List ywMaterialsSnList = new ArrayList<>(); + + for (YwMaterialsSnList snDto : ywMaterialsSnListDTO.getData()) + { + + if (ObjectUtils.isEmpty(snDto.getMaterialStrCode())) { + throw new ServiceException("串码不能为空"); + } + + YwMaterialsSnList snList = new YwMaterialsSnList(); + snList.setOrderid(ywMaterialsSnListDTO.getOrderId()); + snList.setMaterialCode(ywMaterialsSnListDTO.getMaterialCode()); + snList.setOpType(ywMaterialsSnListDTO.getOpType()); + snList.setMaterialStrCode(snDto.getMaterialStrCode()); + ywMaterialsSnList.add(snList); + + + } + + try { + //删除旧的SN数据 + this.deleteSnListALL(ywMaterialsSnListDTO.getOrderId(), ywMaterialsSnListDTO.getMaterialCode(), ywMaterialsSnListDTO.getOpType()); + } + catch (Exception ex) + { + throw new ServiceException(ex.getMessage()); + } + + int res = 0; + + if(!ywMaterialsSnList.isEmpty()) { + res = ywMaterialsSnListMapper.insertSnList(ywMaterialsSnList); + } + + YwMaterialsBatch batch =new YwMaterialsBatch(); + + if(ywMaterialsSnListDTO.getOpType()==0) + { + batch.setOutSum(res); + } + if(ywMaterialsSnListDTO.getOpType()==1) + { + batch.setInSum(res); + } + + batch.setMaterialCode(ywMaterialsSnListDTO.getMaterialCode()); + batch.setOrderid(ywMaterialsSnListDTO.getOrderId()); + + ywMaterialsBatchService.updateBatchInner(batch); + + if(res>0) + { + return true; + } + + throw new ServiceException("修改数据失败"); + + } + + @Override + public List selectSnList(YwMaterialsSnListQO ywMaterialsSnListQO) { + + if(StringUtils.isEmpty(ywMaterialsSnListQO.getOrderId())) + { + throw new ServiceException("物资订单号不能为空"); + } + + if (ObjectUtils.isEmpty(ywMaterialsSnListQO.getOpType())) { + throw new ServiceException("操作类型不能为空"); + } + + if(StringUtils.isEmpty(ywMaterialsSnListQO.getMaterialCode())) + { + throw new ServiceException("物资编码不能为空"); + } + + return ywMaterialsSnListMapper.selectSnList(ywMaterialsSnListQO); + } + + +} + diff --git a/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsStockServiceImpl.java b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsStockServiceImpl.java new file mode 100644 index 0000000..94eca5a --- /dev/null +++ b/cmcc_gm/src/main/java/com/ruoyi/cmcc_gm/service/impl/YwMaterialsStockServiceImpl.java @@ -0,0 +1,1087 @@ +package com.ruoyi.cmcc_gm.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.cmcc_gm.common.enums.OrderStatus; +import com.ruoyi.cmcc_gm.common.enums.OrderType; +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import com.ruoyi.cmcc_gm.domain.YwMaterialsOrderLog; +import com.ruoyi.cmcc_gm.domain.YwMaterialsStock; +import com.ruoyi.cmcc_gm.domain.dto.*; +import com.ruoyi.cmcc_gm.domain.vo.MaterialsXlsToJsonArrayVo; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsVo; +import com.ruoyi.cmcc_gm.importer.ImporterMaterialsReturnList; +import com.ruoyi.cmcc_gm.importer.ImporterMaterialsStock; +import com.ruoyi.cmcc_gm.mapper.*; +import com.ruoyi.cmcc_gm.service.YwMaterialsOrderLogService; +import com.ruoyi.cmcc_gm.service.YwMaterialsStockService; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.FlowDealStatus; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 物资库存表 服务实现类 + *

+ * + * @author jkj + * @since 2023-04-06 + */ +@Service +public class YwMaterialsStockServiceImpl extends ServiceImpl implements YwMaterialsStockService { + + @Autowired + private YwMaterialsStockMapper ywMaterialsStockMapper; + + @Autowired + private YwMaterialsOrderLogService ywMaterialsOrderLogService; + + @Autowired + private YwMaterialsBatchMapper ywMaterialsBatchMapper; + + @Autowired + private YwMaterialsOrderLogMapper ywMaterialsOrderLogMapper; + + @Autowired + private YwMaterialsClassesMapper ywMaterialsClassesMapper; + + @Autowired + private YwMaterialsInformMapper ywMaterialsInformMapper; + + @Override + public List getMaterialsStock(YwMaterialsSearchDTO ywMaterialsSearchDTO) { + + return ywMaterialsStockMapper.getYwMaterial(ywMaterialsSearchDTO); + + } + + @Transactional + @Override + public Boolean freezeOutWayMaterialsStock(YwMaterialsDTO ywMaterialsDTO, YwMaterialsOrderLog ywMaterialsOrderLog) { + + Long outStoreVenue = ywMaterialsOrderLog.getOutStoreVenue(); + + if (outStoreVenue == null || outStoreVenue < 0) { + return true; + } + + if (!OrderStatus.DSQ.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前步骤和任务状态不同步"); + } + + //根据orderId查找批次数据 + List listMaterBat = ywMaterialsBatchMapper.selectList( + new LambdaQueryWrapper().eq(YwMaterialsBatch::getOrderid, ywMaterialsDTO.getOrderId()) + ); + + if (!listMaterBat.isEmpty()) { + YwMaterialsBatchDTO dto = new YwMaterialsBatchDTO(); + dto.setStoreId(outStoreVenue); + dto.setData(listMaterBat); + this.freezeOutWayMaterialsStock(dto); + } + + return true; + } + + @Transactional + @Override + public Boolean freezeOutWayMaterialsStock(YwMaterialsBatchDTO ywMaterialsBatchDTO) { + + for (YwMaterialsBatch stockDTO : ywMaterialsBatchDTO.getData()) { + LambdaQueryWrapper queryStock = new LambdaQueryWrapper<>(); + + queryStock.eq(YwMaterialsStock::getMaterialStoreId, ywMaterialsBatchDTO.getStoreId()); + + queryStock.eq(YwMaterialsStock::getMaterialCode, stockDTO.getMaterialCode()); + + List materialsStocks = ywMaterialsStockMapper.selectList(queryStock); + + //预处理,冻结要出库仓库的库存 + if (materialsStocks.isEmpty()) { + throw new ServiceException("出库仓库的物资库存不能为空"); + } + + if (materialsStocks.size() == 1) { + + YwMaterialsStock materialsStock = materialsStocks.get(0); + + if (materialsStock.getAvailSum() < stockDTO.getSum()) { + throw new ServiceException("出库仓库的物资库存数量不足"); + } + + YwMaterialsStock ywMaterialsStock = new YwMaterialsStock(); + + ywMaterialsStock.setMaterialStoreId(ywMaterialsBatchDTO.getStoreId()); + + ywMaterialsStock.setMaterialCode(stockDTO.getMaterialCode()); + + ywMaterialsStock.setAvailSum(materialsStock.getAvailSum() - stockDTO.getSum()); + + if (ObjectUtils.isEmpty(materialsStock.getOutWaySum())) { + ywMaterialsStock.setOutWaySum(stockDTO.getSum()); + } + + if (ObjectUtils.isNotEmpty(materialsStock.getOutWaySum())) { + ywMaterialsStock.setOutWaySum(materialsStock.getOutWaySum() + stockDTO.getSum()); + } + + int res = this.updateMaterialsStock(ywMaterialsStock); + + if (res == 0) { + throw new ServiceException("冻结出库仓库的物资失败"); + } + } + + if (materialsStocks.size() > 1) { + throw new ServiceException("出库仓库的物资库存数据有错误"); + } + } + + return true; + + } + + @Transactional + @Override + public Boolean freezeOutWayMaterialsStockBack(YwMaterialsBatchDTO ywMaterialsBatchDTO) { + + try { + List materialCodes = ywMaterialsBatchDTO.getData().stream() + .map(YwMaterialsBatch::getMaterialCode) + .distinct() + .collect(Collectors.toList()); + + LambdaQueryWrapper queryStock = new LambdaQueryWrapper<>(); + + queryStock.eq(YwMaterialsStock::getMaterialStoreId, ywMaterialsBatchDTO.getStoreId()) + .in(YwMaterialsStock::getMaterialCode, materialCodes); + + List materialsStocks = ywMaterialsStockMapper.selectList(queryStock); + + if (materialsStocks.size() != materialCodes.size()) { + throw new ServiceException("物资库存数据有错误"); + } + +// List updatedStocks = new ArrayList<>(); + for (YwMaterialsBatch stockDTO : ywMaterialsBatchDTO.getData()) { + YwMaterialsStock materialsStock = materialsStocks.stream() + .filter(s -> s.getMaterialCode().equals(stockDTO.getMaterialCode())) + .findFirst() + .orElseThrow(() -> new ServiceException("物资库存数据有错误")); + YwMaterialsStock updatedStock = new YwMaterialsStock(); + updatedStock.setId(materialsStock.getId()); + updatedStock.setAvailSum(materialsStock.getAvailSum() + stockDTO.getSum()); + updatedStock.setOutWaySum(materialsStock.getOutWaySum() - stockDTO.getSum()); + int res = ywMaterialsStockMapper.updateById(updatedStock); + if (res == 0) { + throw new ServiceException("回滚出库仓库的冻结物资失败"); + } + } + + return true; + } + catch (Exception e) { + throw new ServiceException("回滚出库仓库的冻结物资失败", e); + } + } + + @Transactional + @Override + public Boolean freezeOutWayMaterialsStockBack(YwMaterialsDTO ywMaterialsDTO, YwMaterialsOrderLog ywMaterialsOrderLog) { + + Long outStoreVenue = ywMaterialsOrderLog.getOutStoreVenue(); + + if (outStoreVenue == null || outStoreVenue < 0) { + return true; + } + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + lambdaQueryWrapper.eq(YwMaterialsBatch::getOrderid, ywMaterialsDTO.getOrderId()); + + //根据orderId查找批次数据 + List listMaterBat = ywMaterialsBatchMapper.selectList(lambdaQueryWrapper); + + if (!listMaterBat.isEmpty()) { + YwMaterialsBatchDTO dto = new YwMaterialsBatchDTO(); + dto.setStoreId(outStoreVenue); + dto.setData(listMaterBat); + this.freezeOutWayMaterialsStockBack(dto); + } + + return true; + } + + @Override + public Boolean updateInWayMaterialsStock(YwMaterialsDTO ywMaterialsDTO) { + + YwMaterialsOrderLog ywMaterialsOrderLog = Validate(ywMaterialsDTO); + + if (!OrderStatus.YSH.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前步骤和任务状态不同步"); + } + +// LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); +// +// lambdaQueryWrapper.eq(YwMaterialsBatch::getOrderid, ywMaterialsDTO.getOrderId()); +// +// //根据orderId查找批次数据 +// List listMaterBat = ywMaterialsBatchMapper.selectList(lambdaQueryWrapper); +// +// if (listMaterBat.isEmpty()) { +// throw new ServiceException("没有找到物资批次数据"); +// } + +// Long inStoreVenue = ywMaterialsOrderLog.getInStoreVenue(); +// +// if (ObjectUtils.isEmpty(inStoreVenue)) { +// throw new ServiceException("入库场馆号异常"); +// } +// +// if (inStoreVenue < 0) { +// return true; +// } +// +// +// for (YwMaterialsBatch ywMaterialsBatch : listMaterBat) { +// +// LambdaQueryWrapper queryStock = new LambdaQueryWrapper<>(); +// +// queryStock.eq(YwMaterialsStock::getMaterialStoreId, inStoreVenue); +// +// queryStock.eq(YwMaterialsStock::getMaterialCode, ywMaterialsBatch.getMaterialCode()); +// +// List materialsStocks = ywMaterialsStockMapper.selectList(queryStock); +// +// YwMaterialsStock ywMaterialsStock = new YwMaterialsStock(); +// +// ywMaterialsStock.setMaterialStoreId(inStoreVenue); +// +// ywMaterialsStock.setMaterialCode(ywMaterialsBatch.getMaterialCode()); +// +// //新增 +// if (materialsStocks.size() == 0) { +// +// ywMaterialsStock.setAvailSum(0); +// +// ywMaterialsStock.setInWaySum(ywMaterialsBatch.getSum()); +// +// this.insertMaterialsStock(ywMaterialsStock); +// +// } +// +//// 修改 +// if (materialsStocks.size() == 1) { +// YwMaterialsStock materialsStock = materialsStocks.get(0); +// +// if (!ObjectUtils.isEmpty(materialsStock.getInWaySum())) { +// ywMaterialsStock.setInWaySum(materialsStock.getInWaySum() + ywMaterialsBatch.getSum()); +// } +// +// if (ObjectUtils.isEmpty(materialsStock.getInWaySum())) { +// ywMaterialsStock.setInWaySum(ywMaterialsBatch.getSum()); +// } +// +// this.updateMaterialsStock(ywMaterialsStock); +// } +// +// +// if (materialsStocks.size() > 1) { +// throw new ServiceException("物资库存数据有错误"); +// } +// +// } + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + orderDto.setOrderId(ywMaterialsDTO.getOrderId()); + orderDto.setOrderType(ywMaterialsDTO.getOrderType()); + orderDto.setTaskStatus(OrderStatus.YCK.getCode()); + + return ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); +// return true; + } + + @Override + public Boolean updateInWayMaterialsStockBack(YwMaterialsDTO ywMaterialsDTO) { + + YwMaterialsOrderLog ywMaterialsOrderLog = Validate(ywMaterialsDTO); + + if (!OrderStatus.YCK.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前步骤和任务状态不同步"); + } + +// LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); +// +// lambdaQueryWrapper.eq(YwMaterialsBatch::getOrderid, ywMaterialsDTO.getOrderId()); +// +// //根据orderId查找批次数据 +// List listMaterBat = ywMaterialsBatchMapper.selectList(lambdaQueryWrapper); +// +// if (listMaterBat.isEmpty()) { +// throw new ServiceException("没有找到物资批次数据"); +// } +// +// Long inStoreVenue = ywMaterialsOrderLog.getInStoreVenue(); +// +// if (ObjectUtils.isEmpty(inStoreVenue)) { +// throw new ServiceException("入库场馆号异常"); +// } +// +// if (inStoreVenue < 0) { +// return true; +// } +// +// for (YwMaterialsBatch ywMaterialsBatch : listMaterBat) { +// +// LambdaQueryWrapper queryStock = new LambdaQueryWrapper<>(); +// +// queryStock.eq(YwMaterialsStock::getMaterialStoreId, inStoreVenue); +// +// queryStock.eq(YwMaterialsStock::getMaterialCode, ywMaterialsBatch.getMaterialCode()); +// +// List materialsStocks = ywMaterialsStockMapper.selectList(queryStock); +// +// YwMaterialsStock ywMaterialsStock = new YwMaterialsStock(); +// +// ywMaterialsStock.setMaterialStoreId(inStoreVenue); +// +// ywMaterialsStock.setMaterialCode(ywMaterialsBatch.getMaterialCode()); +// +// //新增 +// if (materialsStocks.size() == 0) { +// +// ywMaterialsStock.setAvailSum(0); +// ywMaterialsStock.setInWaySum(ywMaterialsBatch.getSum()); +// this.insertMaterialsStock(ywMaterialsStock); +// +// } +// +//// 修改 +// if (materialsStocks.size() == 1) { +// +// YwMaterialsStock materialsStock = materialsStocks.get(0); +// +// ywMaterialsStock.setInWaySum(materialsStock.getInWaySum() - ywMaterialsBatch.getSum()); +// +// this.updateMaterialsStock(ywMaterialsStock); +// } +// +// +// if (materialsStocks.size() > 1) { +// throw new ServiceException("物资库存数据有错误"); +// } +// +// } + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + orderDto.setOrderId(ywMaterialsDTO.getOrderId()); + orderDto.setOrderType(ywMaterialsDTO.getOrderType()); + orderDto.setTaskStatus(OrderStatus.YSH.getCode()); + ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); + return true; + } + + + @Transactional + @Override + public Boolean updateMaterialsStock(YwMaterialsDTO ywMaterialsDTO) { + + YwMaterialsOrderLog ywMaterialsOrderLog = Validate(ywMaterialsDTO); + + Long inStoreVenue = ywMaterialsOrderLog.getInStoreVenue(); + + if (ObjectUtils.isEmpty(inStoreVenue)) { + throw new ServiceException("入库场馆号异常"); + } + + //中心库做入库确认,任务状态是待审核 + if (OrderType.ZXK.getCode().equals(ywMaterialsOrderLog.getOrderType())) { + if (!OrderStatus.DSH.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前步骤和任务状态不同步"); + } + } + + if (!OrderType.ZXK.getCode().equals(ywMaterialsOrderLog.getOrderType())) { + + + if(OrderType.CK.getCode().equals(ywMaterialsDTO.getOrderType())) + { + throw new ServiceException("工程出库没有该操作"); + } + + //调拨和退库做入库确认,任务状态是已出库 + if (OrderType.DB.getCode().equals(ywMaterialsOrderLog.getOrderType()) || OrderType.TK.getCode().equals(ywMaterialsDTO.getOrderType())) { + if (!OrderStatus.YCK.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前步骤和任务状态不同步"); + } + } + + if (!(OrderType.DB.getCode().equals(ywMaterialsOrderLog.getOrderType()) || OrderType.TK.getCode().equals(ywMaterialsDTO.getOrderType()))) { + + //其它物资订单类型的入库确认,任务状态是已审核 + if (!OrderStatus.YSH.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前步骤和任务状态不同步"); + } + } + } + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + lambdaQueryWrapper.eq(YwMaterialsBatch::getOrderid, ywMaterialsDTO.getOrderId()); + + //根据orderId查找批次数据 + List listMaterBat = ywMaterialsBatchMapper.selectList(lambdaQueryWrapper); + + if (listMaterBat.isEmpty()) { + throw new ServiceException("没有找到物资批次数据"); + } + + if (inStoreVenue >= 0) { + + for (YwMaterialsBatch ywMaterialsBatch : listMaterBat) { + + LambdaQueryWrapper queryStock = new LambdaQueryWrapper<>(); + + queryStock.eq(YwMaterialsStock::getMaterialStoreId, inStoreVenue); + + queryStock.eq(YwMaterialsStock::getMaterialCode, ywMaterialsBatch.getMaterialCode()); + + List materialsStocks = ywMaterialsStockMapper.selectList(queryStock); + + YwMaterialsStock ywMaterialsStock = new YwMaterialsStock(); + + ywMaterialsStock.setMaterialStoreId(inStoreVenue); + + ywMaterialsStock.setMaterialCode(ywMaterialsBatch.getMaterialCode()); + + //新增 + if (materialsStocks.size() == 0) { + ywMaterialsStock.setAvailSum(ywMaterialsBatch.getSum()); + this.insertMaterialsStock(ywMaterialsStock); + } + +// 修改 + if (materialsStocks.size() == 1) { + + YwMaterialsStock materialsStock = materialsStocks.get(0); + + ywMaterialsStock.setAvailSum(materialsStock.getAvailSum() + ywMaterialsBatch.getSum()); + + //调拨要多做一步把在在途数去掉 +// if (ywMaterialsDTO.getOrderType() == OrderType.DB.getCode() || ywMaterialsDTO.getOrderType() == OrderType.TK.getCode()) { +// ywMaterialsStock.setInWaySum(materialsStock.getInWaySum() - ywMaterialsBatch.getSum()); +// } + + if (ywMaterialsDTO.getOrderType() != OrderType.ZXK.getCode()) { + ywMaterialsStock.setInWaySum(materialsStock.getInWaySum() - ywMaterialsBatch.getSum()); + } + + this.updateMaterialsStock(ywMaterialsStock); + + } + + + if (materialsStocks.size() > 1) { + throw new ServiceException("物资库存数据有错误"); + } + + } + } + + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + orderDto.setOrderId(ywMaterialsDTO.getOrderId()); + orderDto.setOrderType(ywMaterialsDTO.getOrderType()); +// 20230426工程出库,最后状态是已出库,用于解决前端的显示和查询 + if (OrderType.CK.getCode().equals(ywMaterialsDTO.getOrderType())) { + orderDto.setTaskStatus(OrderStatus.YCK.getCode()); + } + if (!OrderType.CK.getCode().equals(ywMaterialsDTO.getOrderType())) { + orderDto.setTaskStatus(OrderStatus.YRK.getCode()); + } + + orderDto.setInStoreName(SecurityUtils.getLoginUser().getUser().getNickName()); + orderDto.setInStoreId(SecurityUtils.getUserId()); + + ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); + + return true; + } + + @Override + public Boolean updateMaterialsStockBack(YwMaterialsDTO ywMaterialsDTO) { + + + YwMaterialsOrderLog ywMaterialsOrderLog = Validate(ywMaterialsDTO); + + if (!OrderStatus.YRK.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前任务状态不是已入库,无法回滚"); + } + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + lambdaQueryWrapper.eq(YwMaterialsBatch::getOrderid, ywMaterialsDTO.getOrderId()); + + //根据orderId查找批次数据 + List listMaterBat = ywMaterialsBatchMapper.selectList(lambdaQueryWrapper); + + if (listMaterBat.isEmpty()) { + throw new ServiceException("没有找到物资批次数据"); + } + + Long inStoreVenue = ywMaterialsOrderLog.getInStoreVenue(); + + Long outStoreVenue = ywMaterialsOrderLog.getOutStoreVenue(); + + if (inStoreVenue >= 0) { + + for (YwMaterialsBatch ywMaterialsBatch : listMaterBat) { + + LambdaQueryWrapper queryStock = new LambdaQueryWrapper<>(); + + queryStock.eq(YwMaterialsStock::getMaterialStoreId, inStoreVenue); + + queryStock.eq(YwMaterialsStock::getMaterialCode, ywMaterialsBatch.getMaterialCode()); + + List materialsStocks = ywMaterialsStockMapper.selectList(queryStock); + + YwMaterialsStock ywMaterialsStock = new YwMaterialsStock(); + + ywMaterialsStock.setMaterialStoreId(inStoreVenue); + + ywMaterialsStock.setMaterialCode(ywMaterialsBatch.getMaterialCode()); + +// 修改 + if (materialsStocks.size() == 1) { + YwMaterialsStock materialsStock = materialsStocks.get(0); + + if (!OrderType.DB.getCode().equals(ywMaterialsDTO.getOrderType())) { + ywMaterialsStock.setAvailSum(materialsStock.getAvailSum() - ywMaterialsBatch.getSum()); + } + if (OrderType.DB.getCode().equals(ywMaterialsDTO.getOrderType())) { + + ywMaterialsStock.setAvailSum(materialsStock.getAvailSum() - ywMaterialsBatch.getSum()); + ywMaterialsStock.setInWaySum(materialsStock.getInWaySum() + ywMaterialsBatch.getSum()); + + } + this.updateMaterialsStock(ywMaterialsStock); + } + + + if (materialsStocks.size() > 1) { + throw new ServiceException("物资库存数据有错误"); + } + + } + } + + if (outStoreVenue >= 0) { + //入库场馆入库了才会消掉出库场馆的冻结数 + //20230506审核通过了,直接消掉出库场馆的冻结数 + for (YwMaterialsBatch ywMaterialsBatch : listMaterBat) { + + LambdaQueryWrapper queryStock = new LambdaQueryWrapper<>(); + + queryStock.eq(YwMaterialsStock::getMaterialStoreId, outStoreVenue); + + queryStock.eq(YwMaterialsStock::getMaterialCode, ywMaterialsBatch.getMaterialCode()); + + List materialsStocks = ywMaterialsStockMapper.selectList(queryStock); + + YwMaterialsStock ywMaterialsStock = new YwMaterialsStock(); + + ywMaterialsStock.setMaterialStoreId(outStoreVenue); + + ywMaterialsStock.setMaterialCode(ywMaterialsBatch.getMaterialCode()); + + if (materialsStocks.size() == 0) { + throw new ServiceException("出库场馆的物资库存数据不存在"); + } + + if (materialsStocks.size() == 1) { + + YwMaterialsStock materialsStock = materialsStocks.get(0); + + ywMaterialsStock.setOutWaySum(materialsStock.getOutWaySum() + ywMaterialsBatch.getSum()); + + this.updateMaterialsStock(ywMaterialsStock); + + } + + } + + } + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + orderDto.setOrderId(ywMaterialsDTO.getOrderId()); + orderDto.setOrderType(ywMaterialsDTO.getOrderType()); + + if (OrderType.ZXK.getCode().equals(ywMaterialsOrderLog.getOrderType())) { + orderDto.setTaskStatus(OrderStatus.DSH.getCode()); + } else { + if (!OrderType.DB.getCode().equals(ywMaterialsOrderLog.getOrderType())) { + orderDto.setTaskStatus(OrderStatus.YSH.getCode()); + } + + if (OrderType.DB.getCode().equals(ywMaterialsOrderLog.getOrderType())) { + orderDto.setTaskStatus(OrderStatus.YCK.getCode()); + } + } + orderDto.setInStoreName(""); + orderDto.setInStoreId(-1L); + ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); + + return true; + + } + + //冻结数据释放掉 + @Transactional + @Override + public Boolean updateFreezeOutWayMaterialsStock(YwMaterialsDTO ywMaterialsDTO) { + + YwMaterialsOrderLog ywMaterialsOrderLog = Validate(ywMaterialsDTO); + + Long inStoreVenue = ywMaterialsOrderLog.getInStoreVenue(); + + if (ObjectUtils.isEmpty(inStoreVenue)) { + throw new ServiceException("入库场馆号异常"); + } + + Long outStoreVenue = ywMaterialsOrderLog.getOutStoreVenue(); + + if (ObjectUtils.isEmpty(outStoreVenue)) { + throw new ServiceException("出库场馆号异常"); + } + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + orderDto.setOrderId(ywMaterialsOrderLog.getOrderId()); + orderDto.setOrderType(ywMaterialsOrderLog.getOrderType()); + orderDto.setInStoreName(ywMaterialsDTO.getAuditor()); + + if(OrderType.SL.getCode().equals(ywMaterialsDTO.getOrderType())|| OrderType.RK.getCode().equals(ywMaterialsDTO.getOrderType())) { + if (!OrderStatus.DSH.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前步骤和任务状态不同步"); + } + orderDto.setTaskStatus(OrderStatus.YSH.getCode()); + } + + if(OrderType.TK.getCode().equals(ywMaterialsDTO.getOrderType()) || OrderType.CK.getCode().equals(ywMaterialsDTO.getOrderType()) || OrderType.DB.getCode().equals(ywMaterialsDTO.getOrderType())) { + if (!OrderStatus.YSH.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前步骤和任务状态不同步"); + } + orderDto.setTaskStatus(OrderStatus.YCK.getCode()); + } + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + lambdaQueryWrapper.eq(YwMaterialsBatch::getOrderid, ywMaterialsDTO.getOrderId()); + + //根据orderId查找批次数据 + List listMaterBat = ywMaterialsBatchMapper.selectList(lambdaQueryWrapper); + + if (listMaterBat.isEmpty()) { + throw new ServiceException("没有找到物资批次数据"); + } + + if (outStoreVenue >= 0) { + //20230506审核通过,消掉出库场馆的冻结数 + for (YwMaterialsBatch ywMaterialsBatch : listMaterBat) { + + LambdaQueryWrapper queryStock = new LambdaQueryWrapper<>(); + + queryStock.eq(YwMaterialsStock::getMaterialStoreId, outStoreVenue); + + queryStock.eq(YwMaterialsStock::getMaterialCode, ywMaterialsBatch.getMaterialCode()); + + List materialsStocks = ywMaterialsStockMapper.selectList(queryStock); + + YwMaterialsStock ywMaterialsStock = new YwMaterialsStock(); + + ywMaterialsStock.setMaterialStoreId(outStoreVenue); + + ywMaterialsStock.setMaterialCode(ywMaterialsBatch.getMaterialCode()); + + if (materialsStocks.size() == 0) { + throw new ServiceException("出库场馆的物资库存数据不存在"); + } + + if (materialsStocks.size() == 1) { + + YwMaterialsStock materialsStock = materialsStocks.get(0); + + if (ObjectUtils.isEmpty(materialsStock.getOutWaySum())) { + throw new ServiceException("出库场馆的冻结库存数据有问题"); + } + + if (!ObjectUtils.isEmpty(materialsStock.getOutWaySum())) { + + if (materialsStock.getOutWaySum() < ywMaterialsBatch.getSum()) { + + throw new ServiceException("出库场馆的冻结库存数据居然小于出库的库存数"); + } + + ywMaterialsStock.setOutWaySum(materialsStock.getOutWaySum() - ywMaterialsBatch.getSum()); + + } + + this.updateMaterialsStock(ywMaterialsStock); + + } + + } + + } + + + if (inStoreVenue >= 0) { + + for (YwMaterialsBatch ywMaterialsBatch : listMaterBat) { + + LambdaQueryWrapper queryStock = new LambdaQueryWrapper<>(); + + queryStock.eq(YwMaterialsStock::getMaterialStoreId, inStoreVenue); + + queryStock.eq(YwMaterialsStock::getMaterialCode, ywMaterialsBatch.getMaterialCode()); + + List materialsStocks = ywMaterialsStockMapper.selectList(queryStock); + + YwMaterialsStock ywMaterialsStock = new YwMaterialsStock(); + + ywMaterialsStock.setMaterialStoreId(inStoreVenue); + + ywMaterialsStock.setMaterialCode(ywMaterialsBatch.getMaterialCode()); + + //新增 + if (materialsStocks.size() == 0) { + + ywMaterialsStock.setAvailSum(0); + + ywMaterialsStock.setInWaySum(ywMaterialsBatch.getSum()); + + this.insertMaterialsStock(ywMaterialsStock); + + } + +// 修改 + if (materialsStocks.size() == 1) { + YwMaterialsStock materialsStock = materialsStocks.get(0); + + if (!ObjectUtils.isEmpty(materialsStock.getInWaySum())) { + ywMaterialsStock.setInWaySum(materialsStock.getInWaySum() + ywMaterialsBatch.getSum()); + } + + if (ObjectUtils.isEmpty(materialsStock.getInWaySum())) { + ywMaterialsStock.setInWaySum(ywMaterialsBatch.getSum()); + } + + this.updateMaterialsStock(ywMaterialsStock); + } + + + if (materialsStocks.size() > 1) { + throw new ServiceException("物资库存数据有错误"); + } + + } + } + + ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); + + return true; + + } + + @Override + public Boolean updateFreezeOutWayMaterialsStockBack(YwMaterialsDTO ywMaterialsDTO) { + + YwMaterialsOrderLog ywMaterialsOrderLog = Validate(ywMaterialsDTO); + + Long inStoreVenue = ywMaterialsOrderLog.getInStoreVenue(); + + if (ObjectUtils.isEmpty(inStoreVenue)) { + throw new ServiceException("入库场馆号异常"); + } + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + orderDto.setOrderId(ywMaterialsOrderLog.getOrderId()); + orderDto.setOrderType(ywMaterialsOrderLog.getOrderType()); + + if(OrderType.SL.getCode().equals(ywMaterialsDTO.getOrderType())|| OrderType.RK.getCode().equals(ywMaterialsDTO.getOrderType())) { + if (!OrderStatus.YSH.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前步骤和任务状态不同步"); + } + orderDto.setTaskStatus(OrderStatus.DSH.getCode()); + } + + if(OrderType.TK.getCode().equals(ywMaterialsDTO.getOrderType()) || OrderType.CK.getCode().equals(ywMaterialsDTO.getOrderType()) || OrderType.DB.getCode().equals(ywMaterialsDTO.getOrderType())) { + if (!OrderStatus.YCK.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前步骤和任务状态不同步"); + } + orderDto.setTaskStatus(OrderStatus.YSH.getCode()); + } + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + lambdaQueryWrapper.eq(YwMaterialsBatch::getOrderid, ywMaterialsDTO.getOrderId()); + + //根据orderId查找批次数据 + List listMaterBat = ywMaterialsBatchMapper.selectList(lambdaQueryWrapper); + + if (listMaterBat.isEmpty()) { + throw new ServiceException("没有找到物资批次数据"); + } + + Long outStoreVenue = ywMaterialsOrderLog.getOutStoreVenue(); + + if (ObjectUtils.isEmpty(outStoreVenue)) { + throw new ServiceException("出库场馆号异常"); + } + + if (outStoreVenue >= 0) { + + for (YwMaterialsBatch ywMaterialsBatch : listMaterBat) { + + LambdaQueryWrapper queryStock = new LambdaQueryWrapper<>(); + + queryStock.eq(YwMaterialsStock::getMaterialStoreId, outStoreVenue); + + queryStock.eq(YwMaterialsStock::getMaterialCode, ywMaterialsBatch.getMaterialCode()); + + List materialsStocks = ywMaterialsStockMapper.selectList(queryStock); + + YwMaterialsStock ywMaterialsStock = new YwMaterialsStock(); + + ywMaterialsStock.setMaterialStoreId(outStoreVenue); + + ywMaterialsStock.setMaterialCode(ywMaterialsBatch.getMaterialCode()); + + if (materialsStocks.size() == 0) { + throw new ServiceException("出库场馆的物资库存数据不存在"); + } + + if (materialsStocks.size() == 1) { + + YwMaterialsStock materialsStock = materialsStocks.get(0); + + if (ObjectUtils.isEmpty(materialsStock.getOutWaySum())) { + throw new ServiceException("出库场馆的冻结库存数据有问题"); + } + + if (!ObjectUtils.isEmpty(materialsStock.getOutWaySum())) { + + ywMaterialsStock.setOutWaySum(materialsStock.getOutWaySum() + ywMaterialsBatch.getSum()); + + } + + this.updateMaterialsStock(ywMaterialsStock); + + } + + } + + } + + + if (inStoreVenue >= 0) { + + for (YwMaterialsBatch ywMaterialsBatch : listMaterBat) { + + LambdaQueryWrapper queryStock = new LambdaQueryWrapper<>(); + + queryStock.eq(YwMaterialsStock::getMaterialStoreId, inStoreVenue); + + queryStock.eq(YwMaterialsStock::getMaterialCode, ywMaterialsBatch.getMaterialCode()); + + List materialsStocks = ywMaterialsStockMapper.selectList(queryStock); + + YwMaterialsStock ywMaterialsStock = new YwMaterialsStock(); + + ywMaterialsStock.setMaterialStoreId(inStoreVenue); + + ywMaterialsStock.setMaterialCode(ywMaterialsBatch.getMaterialCode()); + + //新增 + if (materialsStocks.size() == 0) { + + throw new ServiceException("物资库存数据有错误"); + + } + + // 修改 + if (materialsStocks.size() == 1) { + + YwMaterialsStock materialsStock = materialsStocks.get(0); + + ywMaterialsStock.setInWaySum(materialsStock.getInWaySum() - ywMaterialsBatch.getSum()); + + this.updateMaterialsStock(ywMaterialsStock); + } + + + if (materialsStocks.size() > 1) { + throw new ServiceException("物资库存数据有错误"); + } + + } + } + + + + ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); + + return true; + } + + @Override + public YwMaterialsOrderLog Validate(YwMaterialsDTO ywMaterialsDTO) { + + if (StringUtils.isEmpty(ywMaterialsDTO.getOrderId())) { + throw new ServiceException("物资工单ID不能为空"); + } + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + lambdaQueryWrapper.eq(YwMaterialsOrderLog::getOrderId, ywMaterialsDTO.getOrderId()); + + lambdaQueryWrapper.eq(YwMaterialsOrderLog::getOrderType, ywMaterialsDTO.getOrderType()); + + //根据物资order表查找order是否存在 + List list = ywMaterialsOrderLogMapper.selectList(lambdaQueryWrapper); + + if (list.isEmpty()) { + throw new ServiceException("物资工单数据不存在"); + } + + //核查当前操作的人员 + YwMaterialsOrderLog ywMaterialsOrderLog = list.get(0); + + if (FlowDealStatus.BUSINESS_STATUS_4.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + + if (!ywMaterialsDTO.getIsBack().equals("是")) { + throw new ServiceException("物资工单已完结"); + } + + } + } + + //工程出库不需要验证入库场馆 + if (OrderType.CK.getCode().equals(ywMaterialsOrderLog.getOrderType())) { + + if (ObjectUtils.isEmpty(ywMaterialsOrderLog.getInStoreVenue())) { + throw new ServiceException("物资工单入库场馆数据有错误"); + } + + } + + //不是更新中心库,需要有出库场馆的ID + if (!(OrderType.ZXK.getCode().equals(ywMaterialsDTO.getOrderType()) || OrderType.RK.getCode().equals(ywMaterialsDTO.getOrderType()))) { + if (ObjectUtils.isEmpty(ywMaterialsOrderLog.getOutStoreVenue())) { + throw new ServiceException("物资工单出库场馆数据有错误"); + } + } + + if (ywMaterialsDTO.getOpType().equals("审核任务")) { + + //从工作流获取当前用户的审核人 + Long shrId = ywMaterialsOrderLogMapper.selectCheckUserIdByFlwId(ywMaterialsOrderLog.getFlwProcessid()); + + if(ObjectUtils.isEmpty(shrId)) + { + throw new ServiceException("物资工单的审核人不存在"); + } + + if (!SecurityUtils.getUserId().equals(shrId)) { + throw new ServiceException("审核人不正确"); + } + + } + + return ywMaterialsOrderLog; + + } + + @Override + public int insertMaterialsStock(YwMaterialsStock ywMaterialsStock) { + + return ywMaterialsStockMapper.insert(ywMaterialsStock); + + } + + @Override + public int updateMaterialsStock(YwMaterialsStock ywMaterialsStock) { + + //根据库号和物资号,修改库存数据 + LambdaQueryWrapper condition = new LambdaQueryWrapper<>(); + condition.eq(YwMaterialsStock::getMaterialStoreId, ywMaterialsStock.getMaterialStoreId()); + condition.eq(YwMaterialsStock::getMaterialCode, ywMaterialsStock.getMaterialCode()); + + return ywMaterialsStockMapper.update(ywMaterialsStock, condition); + } + + /** + * 导入 + * + * @param beans 数据 + * @param sceneBigId 大场景id + * @param importType 导入方式 + * @param materialStoreId materialStoreId + * @return 导入结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult importXls(List beans, Long sceneBigId, String importType, Long materialStoreId) throws Exception { + ImporterBase importer = new ImporterMaterialsStock(ywMaterialsStockMapper, ywMaterialsClassesMapper, ywMaterialsInformMapper); + return importer.doAdd(beans, sceneBigId, importType, materialStoreId); + } + + /** + * 导入,返回List + * + * @param xls 数据 + * @param sceneId + * @return 导入的数据 + * @throws Exception 异常 + */ + @Override + public AjaxResult importXlsReturnList(List xls, Long sceneId) throws Exception { + ImporterBase importer = new ImporterMaterialsReturnList(ywMaterialsClassesMapper, ywMaterialsStockMapper, ywMaterialsInformMapper); + AjaxResult ajaxResult = importer.doAdd(xls, null, null, sceneId); + if (String.valueOf(HttpStatus.SUCCESS).equals(String.valueOf(ajaxResult.get(AjaxResult.CODE_TAG)))) { + JSONArray jsonArray = new JSONArray(); + for (MaterialsXlsToJsonArrayVo xl : xls) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(YwMaterialsStock::getMaterialStoreId, sceneId).eq(YwMaterialsStock::getMaterialCode, xl.getMaterialCode()).ge(YwMaterialsStock::getAvailSum, Integer.parseInt(xl.getSum())); + List list = ywMaterialsStockMapper.selectList(wrapper); + if (CollectionUtil.isNotEmpty(list)) { + xl.setAvailSum(String.valueOf(list.get(0).getAvailSum())); + } + JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(xl)); + jsonObject.remove("reason"); + jsonArray.add(jsonObject); + } + return AjaxResult.success(jsonArray); + } else { + return ajaxResult; + } + } + +} diff --git a/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsBatchMapper.xml b/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsBatchMapper.xml new file mode 100644 index 0000000..5f2ce5c --- /dev/null +++ b/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsBatchMapper.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + insert into public.yw_materials_batch(orderid, material_code, sum) + values + + (#{entity.orderid}, #{entity.materialCode}, #{entity.sum}) + + + + + + update public.yw_materials_batch + + + WHEN #{entity.materialCode} THEN #{entity.inSum} + + + WHEN #{entity.materialCode} THEN #{entity.outSum} + + + + + #{entity.materialCode} + + and orderid = #{orderId} + + + + + + + delete + from yw_materials_batch + where orderid = #{orderid,jdbcType=VARCHAR} + + + + diff --git a/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsClassesMapper.xml b/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsClassesMapper.xml new file mode 100644 index 0000000..488141d --- /dev/null +++ b/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsClassesMapper.xml @@ -0,0 +1,41 @@ + + + + + + + + + + truncate table yw_materials_classes; + + + + diff --git a/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsInformMapper.xml b/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsInformMapper.xml new file mode 100644 index 0000000..d2a47c1 --- /dev/null +++ b/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsInformMapper.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + insert into public.yw_materials_inform(material_name, material_code, material_stand, material_unit, material_big_class, material_small_class, sn_code, factory) + values + + (#{entity.materialName}, #{entity.materialCode}, #{entity.materialStand}, #{entity.materialUnit}, #{entity.materialBigClass}, #{entity.materialSmallClass}, #{entity.snCode}, #{entity.factory}) + + + + + insert into public.yw_materials_inform(material_name, material_code, material_stand, material_unit, material_big_class, material_small_class, sn_code) + values + + (#{entity.materialName}, #{entity.materialCode}, #{entity.materialStand}, #{entity.materialUnit}, #{entity.materialBigClass}, #{entity.materialSmallClass}, #{entity.snCode}) + + on duplicate key update + material_name = values(material_name) , material_code = values(material_code) , material_stand = values(material_stand) , material_unit = values(material_unit) , material_big_class = values(material_big_class) , material_small_class = values(material_small_class) , sn_code = values(sn_code) + + + + + + + + + + AND material_code = #{materialCode} + + + + + AND material_name = #{materialName} + + + + + AND material_stand = #{materialStand} + + + + AND sn_code = #{snCode} + + + + + + + delete + from yw_materials_inform + + + + + delete from yw_materials_inform t1 where not exists (SELECT 1 FROM yw_materials_stock t2 where t1.material_code = t2.material_code) + + + + diff --git a/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsOrderLogMapper.xml b/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsOrderLogMapper.xml new file mode 100644 index 0000000..735baba --- /dev/null +++ b/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsOrderLogMapper.xml @@ -0,0 +1,140 @@ + + + + + + + + + + and t1.order_id = like CONCAT('%',#{orderId} :: text,'%') + + + + + and t1.order_type = #{orderType} + + + + + and t1.task_status = #{taskStatus} + + + + and t1.flw_processid = #{flwId} + + + + and t1.in_store_venue = #{inStoreId} + + + + and t1.in_store_venue in + + #{arrInStoreId} + + + + + and t1.out_store_venue = #{outStoreId} + + + + and t1.out_store_venue in + + #{arrOutStoreId} + + + + + and t1.task_start_time between to_timestamp(#{searchDate}||' 00:00:00','yyyy-mm-dd hh24:mi:ss') and to_timestamp(#{searchDate}||' 23:59:59','yyyy-mm-dd hh24:mi:ss') + + + + + + + + + + + \ No newline at end of file diff --git a/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsSnListMapper.xml b/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsSnListMapper.xml new file mode 100644 index 0000000..f9e4d47 --- /dev/null +++ b/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsSnListMapper.xml @@ -0,0 +1,32 @@ + + + + + + + insert into public.yw_materials_list(orderid, material_code, material_str_code, op_type) + values + + (#{entity.orderid}, #{entity.materialCode}, #{entity.materialStrCode}, #{entity.opType}) + + + + + + + diff --git a/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsStockMapper.xml b/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsStockMapper.xml new file mode 100644 index 0000000..2a879fa --- /dev/null +++ b/cmcc_gm/src/main/resources/mapper/cmcc_gm/YwMaterialsStockMapper.xml @@ -0,0 +1,135 @@ + + + + + + + + + + and yms.material_store_id = #{storeId} + + + and yms.material_store_id > 0 + + + + + and yms.material_store_id in + + #{arrStoreId} + + + + + + and ymi.material_stand = #{materialStand} + + + + + and ymi.material_name = #{materialName} + + + + + + and ymi.material_big_class = #{materialBigClass} + + + + + and ymi.material_small_class = #{materialSmallClass} + + + + + + + insert into yw_materials_stock(material_store_id,material_code, + avail_sum,out_way_sum,in_way_sum, + scene_big_id) + values + + (#{item.materialStoreId,jdbcType=NUMERIC},#{item.materialCode,jdbcType=VARCHAR}, + #{item.availSum,jdbcType=NUMERIC},#{item.outWaySum,jdbcType=NUMERIC},#{item.inWaySum,jdbcType=NUMERIC}, + #{item.sceneBigId,jdbcType=NUMERIC}) + + + + delete from yw_materials_stock + + + AND material_store_id = #{materialStoreId,jdbcType=NUMERIC} + + + + + \ No newline at end of file diff --git "a/doc/\350\213\245\344\276\235\347\216\257\345\242\203\344\275\277\347\224\250\346\211\213\345\206\214.docx" "b/doc/\350\213\245\344\276\235\347\216\257\345\242\203\344\275\277\347\224\250\346\211\213\345\206\214.docx" new file mode 100644 index 0000000000000000000000000000000000000000..9e4daef4d9be2e445419109a02eaf321cd4d537e GIT binary patch literal 428430 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¾twym7CDwF0ZTRbgtZ;w&J#5V!jdB+^ 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%0AY2VEvQRzM9!H4$A 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

R( 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%0A58**rmk*;6Nc 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

-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

+ * + *

+ * + * @author yqf + * @since 2023-08-18 + */ +@Data +@TableName("dp_2_agis_link_5mi") +@ApiModel(value = "Dp2AgisLink5mi对象", description = "") +public class Dp2AgisLink5mi { + + private static final long serialVersionUID = 1L; + + @TableField("stat_date") + private LocalDateTime statDate; + + @TableField("city_code") + private String cityCode; + + @TableField("city_name") + private String cityName; + + @TableField("venue_code") + private String venueCode; + + @TableField("venue_name") + private String venueName; + + @TableField("link_value_code") + private String linkValueCode; + + @TableField("link_value") + private String linkValue; + + @TableField("link_code") + private String linkCode; + + @TableField("link_name") + private String linkName; + + @TableField("bandwith") + private Double bandwith; + + @TableField("delay") + private Double delay; + + @TableField("jitter") + private Double jitter; + + @TableField("lpack_ratio") + private Double lpackRatio; + + @TableField("ul_velocity") + private Double ulVelocity; + + @TableField("dl_velocity") + private Double dlVelocity; + + @TableField("ul_flow") + private Double ulFlow; + + @TableField("dl_flow") + private Double dlFlow; + + @TableField("ul_band_ratio") + private Double ulBandRatio; + + @TableField("dl_band_ratio") + private Double dlBandRatio; + + @TableField("total_band_ratio") + private Double totalBandRatio; + + @TableField("load_time") + private LocalDateTime loadTime; + + @TableField("a_device_alias") + private String aDeviceAlias; + + @TableField("z_device_alias") + private String zDeviceAlias; + + @TableField("dl_max_24h_ratio") + private Double dlMax24hRatio; + + @TableField("ul_max_24h_ratio") + private Double ulMax24hRatio; + + @TableField("dl_avg_24h_ratio") + private Double dlAvg24hRatio; + + @TableField("ul_avg_24h_ratio") + private Double ulAvg24hRatio; + + @TableField("a_device_name") + private String aDeviceName; + + @TableField("a_port_name") + private String aPortName; + + @TableField("z_device_name") + private String zDeviceName; + + @TableField("z_port_name") + private String zPortName; + + @TableField("a_port_full_name") + private String aPortFullName; + + @TableField("z_port_full_name") + private String zPortFullName; + + @TableField("a_port_short_name") + private String aPortShortName; + + @TableField("z_port_short_name") + private String zPortShortName; + + @TableField("update_time") + private LocalDateTime updateTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2MmlList.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2MmlList.java new file mode 100644 index 0000000..4a58d05 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2MmlList.java @@ -0,0 +1,107 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + *

+ * + *

+ * + * @author ck + * @since 2023-09-12 + */ +@Data +@TableName("dp_2_mml_list") +@ApiModel(value = "Dp2MmlList对象", description = "") +public class Dp2MmlList { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("小区名") + @TableField("cell_name") + @Excel(name = "小区名", sort = 2,width = 90) + private String cellName; + + @ApiModelProperty("统计时间") + @TableField("stat_time") + @Excel(name = "统计时间", dateFormat = "yyyy-MM-dd HH:mm:ss", sort = 11,width = 25) + private LocalDateTime statTime; + + @ApiModelProperty("上行Prb利用率") + @TableField("prb_up") + @Excel(name = "上行Prb利用率", sort = 3) + private BigDecimal prbUp; + + @ApiModelProperty("下行Prb利用率") + @TableField("prb_down") + @Excel(name = "下行Prb利用率", sort = 4) + private BigDecimal prbDown; + + @ApiModelProperty("最大用户数") + @TableField("max_user") + @Excel(name = "最大用户数", sort = 5) + private BigDecimal maxUser; + + @ApiModelProperty("综合得分") + @TableField("zh_score") + @Excel(name = "综合得分", sort = 6) + private BigDecimal zhScore; + + @ApiModelProperty("是否降低功率") + @TableField("desc_power") + @Excel(name = "是否降低功率", sort = 10,readConverterExp = "0=否,1=是") + private Integer descPower; + + @ApiModelProperty("关闭状态") + @TableField("close_state") +// @Excel(name = "关闭状态", sort = 1) + private Integer closeState; + + @ApiModelProperty("场馆号") + @TableField("scene_id") + private Integer sceneId; + + @ApiModelProperty("场馆名称") + @TableField(exist = false) + @Excel(name = "场馆名称",sort = 1,width = 30) + private String venueName; + + @ApiModelProperty("批次,每次写入批次号相同") + @TableField("batchno") +// @Excel(name = "批次,每次写入批次号相同", sort = 1) + private Long batchno; + + @ApiModelProperty("平均干扰") + @TableField("avg_disturb") + @Excel(name = "平均干扰", sort = 7) + private BigDecimal avgDisturb; + + @ApiModelProperty("坐席编号") + @TableField("seatid") + @Excel(name = "坐席编号", sort = 8) + private String seatid; + + @ApiModelProperty("4G/5G") + @TableField("nettype") + @Excel(name = "4G/5G", sort = 9) + private String nettype; + + @TableField("inputtime") +// @Excel(name = "inputtime", dateFormat = "yyyy-MM-dd HH:mm:ss", sort = 1) + private LocalDateTime inputtime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2PnNetVenue5mi.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2PnNetVenue5mi.java new file mode 100644 index 0000000..7ca2e33 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2PnNetVenue5mi.java @@ -0,0 +1,137 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * + *

+ * + * @author yqf + * @since 2023-08-21 + */ +@Data +@TableName("dp_2_pn_net_venue_5mi") +@ApiModel(value = "Dp2PnNetVenue5mi对象", description = "") +public class Dp2PnNetVenue5mi { + + private static final long serialVersionUID = 1L; + + @TableField("stat_date") + private LocalDateTime statDate; + + @TableField("city_code") + private String cityCode; + + @TableField("city_name") + private String cityName; + + @ApiModelProperty("互联网在线用户数") + @TableField("online_user_cnt") + private Double onlineUserCnt; + + @TableField("inter_exp_bandwith") + private Double interExpBandwith; + + @TableField("interc_bandwith") + private Double intercBandwith; + + @TableField("venue_bandwith") + private Double venueBandwith; + + @TableField("dl_inter_exp_flow") + private Double dlInterExpFlow; + + @TableField("ul_inter_exp_flow") + private Double ulInterExpFlow; + + @TableField("dl_interc_flow") + private Double dlIntercFlow; + + @TableField("ul_interc_flow") + private Double ulIntercFlow; + + @TableField("dl_venue_flow") + private Double dlVenueFlow; + + @TableField("ul_venue_flow") + private Double ulVenueFlow; + + @TableField("dl_inter_exp_band_ratio") + private Double dlInterExpBandRatio; + + @TableField("ul_inter_exp_band_ratio") + private Double ulInterExpBandRatio; + + @TableField("dl_interc_band_ratio") + private Double dlIntercBandRatio; + + @TableField("ul_interc_band_ratio") + private Double ulIntercBandRatio; + + @ApiModelProperty("互联网下行带宽利用率") + @TableField("dl_venue_band_ratio") + private Double dlVenueBandRatio; + + @ApiModelProperty("互联网上行带宽利用率") + @TableField("ul_venue_band_ratio") + private Double ulVenueBandRatio; + + @TableField("dl_inter_exp_velocity") + private Double dlInterExpVelocity; + + @TableField("ul_inter_exp_velocity") + private Double ulInterExpVelocity; + + @TableField("dl_interc_velocity") + private Double dlIntercVelocity; + + @TableField("ul_interc_velocity") + private Double ulIntercVelocity; + + @ApiModelProperty("互联网场馆出口_下行流速") + @TableField("dl_venue_velocity") + private Double dlVenueVelocity; + + @ApiModelProperty("互联网出口_上行流速") + @TableField("ul_venue_velocity") + private Double ulVenueVelocity; + + @TableField("interc_delay") + private Double intercDelay; + + @TableField("inter_exp_delay") + private Double interExpDelay; + + @TableField("interc_jitter") + private Double intercJitter; + + @TableField("inter_exp_jitter") + private Double interExpJitter; + + @TableField("interc_lpack_ratio") + private Double intercLpackRatio; + + @TableField("inter_exp_lpack_ratio") + private Double interExpLpackRatio; + + @TableField("load_time") + private LocalDateTime loadTime; + + @TableField("venue_code") + private String venueCode; + + @TableField("venue_name") + private String venueName; + + @TableField("update_time") + private LocalDateTime updateTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2SpotCell.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2SpotCell.java new file mode 100644 index 0000000..e005aac --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2SpotCell.java @@ -0,0 +1,231 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; + +/** + * @author ck + * @since 2023-08-10 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("dp_2_spot_cell") +@ApiModel(value = "Dp2SpotCell对象", description = "") +public class Dp2SpotCell { + + private static final long serialVersionUID = 1L; + + @TableField("id") + @TableId(type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("地市编码") + @TableField("地市编码") + @Excel(name = "地市编码") + private String 地市编码; + + @ApiModelProperty("地市") + @TableField("地市") + @Excel(name = "地市") + private String 地市; + + @ApiModelProperty("区县编码") + @TableField("区县编码") + @Excel(name = "区县编码") + private String 区县编码; + + @TableField("omc") + @Excel(name = "OMC") + private String omc; + + @ApiModelProperty("需要") + @TableField("县市") + @Excel(name = "县市") + private String 县市; + + @TableField("enodebid") + @Excel(name = "enodebid") + private Long enodebid; + + @TableField("本地小区标识") + @Excel(name = "本地小区标识") + private Long 本地小区标识; + + @TableField("小区标识") + @Excel(name = "小区标识") + private Long 小区标识; + + @ApiModelProperty("需要") + @TableField("站号") + @Excel(name = "站号") + private Long 站号; + + @ApiModelProperty("需要") + @TableField("ci") + @Excel(name = "CI") + private Long ci; + + @ApiModelProperty("需要") + @TableField("基站全称") + @Excel(name = "基站全称") + private String 基站全称; + + @TableField("en名称") + @Excel(name = "en名称") + private String en名称; + + @ApiModelProperty("需要") + @TableField("小区名称") + @Excel(name = "小区名称") + private String 小区名称; + + @ApiModelProperty("需要") + @TableField("小区频段") + @Excel(name = "小区频段") + private String 小区频段; + + @ApiModelProperty("lac") + @TableField("lac") + @Excel(name = "lac") + private String lac; + + @ApiModelProperty("需要") + @TableField("纬度") + @Excel(name = "纬度") + private Double 纬度; + + @ApiModelProperty("需要") + @TableField("经度") + @Excel(name = "经度") + private Double 经度; + + @TableField("纬度gcj") + @Excel(name = "纬度gcj") + private Double 纬度gcj; + + @TableField("经度gcj") + @Excel(name = "经度gcj") + private Double 经度gcj; + + @ApiModelProperty("需要") + @TableField("室内室外") + @Excel(name = "室内室外",combo={"室内","室外"}) + private String 室内室外; + + @ApiModelProperty("需要") + @TableField("网络") + @Excel(name = "网络",combo={"4G","5G"}) + private String 网络; + + @TableField("现网状态") + @Excel(name = "现网状态",combo={"正常","未建立"}) + private String 现网状态; + + @TableField("cgi") + @Excel(name = "CGI") + private String cgi; + + @TableField("频点") + @Excel(name = "频点") + private Long 频点; + + @TableField("pci") + @Excel(name = "pci") + private Long pci; + + @TableField("tac") + @Excel(name = "tac") + private Long tac; + + @TableField("一级场景") + @Excel(name = "一级场景") + private String 一级场景; + + @TableField("二级场景") + @Excel(name = "二级场景") + private String 二级场景; + + @ApiModelProperty("需要 spot_cell_type") + @TableField("设备类型") + @Excel(name = "设备类型") + private String 设备类型; + + @TableField(exist = false) + @Excel(name = "带宽") + private String 带宽str; + + @ApiModelProperty("需要") + @TableField("带宽") + private Double 带宽; + + @ApiModelProperty("需要") + @TableField("方位角") + @Excel(name = "方位角") + private Long 方位角; + + @TableField("扇区id") + @Excel(name = "扇区ID") + private Long 扇区id; + + @TableField("更新时间") + private LocalDateTime 更新时间; + + @ApiModelProperty("景区ID,需要") + @TableField("景区id") + @Excel(name = "景区ID") + private Integer 景区id; + + @ApiModelProperty("坐席编号") + @TableField("坐席编号") + @Excel(name = "坐席编号") + private String 坐席编号; + + @ApiModelProperty("场景类型编码") + @TableField("场景类型编码") + @Excel(name = "场景类型编码") + private String 场景类型编码; + + @ApiModelProperty("场景类型") + @TableField("场景类型") + @Excel(name = "场景类型") + private String 场景类型; + + @ApiModelProperty("场景子类型编码") + @TableField("场景子类型编码") + @Excel(name = "场景子类型编码") + private String 场景子类型编码; + + @ApiModelProperty("场景子类型") + @TableField("场景子类型") + @Excel(name = "场景子类型") + private String 场景子类型; + + @ApiModelProperty("场景编码") + @TableField("场景编码") + @Excel(name = "场景编码") + private String 场景编码; + + @ApiModelProperty("覆盖子场景编码") + @TableField("覆盖子场景编码") + @Excel(name = "覆盖子场景编码") + private String 覆盖子场景编码; + + @ApiModelProperty("覆盖子场景") + @TableField("覆盖子场景") + @Excel(name = "覆盖子场景") + private String 覆盖子场景; + + @TableField(exist = false) + @Excel(name = "失败原因") + private String reason; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2SpotConfig.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2SpotConfig.java new file mode 100644 index 0000000..a673210 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2SpotConfig.java @@ -0,0 +1,54 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * + *

+ * + * @author ck + * @since 2023-08-09 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("dp_2_spot_config") +@ApiModel(value = "Dp2SpotConfig对象", description = "") +public class Dp2SpotConfig { + + private static final long serialVersionUID = 1L; + + @TableField("景区id") + @TableId(value = "景区id",type = IdType.AUTO) + private Integer 景区id; + + @TableField("景区名称") + private String 景区名称; + + // yw_county + @TableField("行政区域") + private String 行政区域; + + @TableField("中心经度") + private Object 中心经度; + + @TableField("中心纬度") + private Object 中心纬度; + + @TableField("景区介绍") + private String 景区介绍; + + //spot_type + @TableField("景区大类") + private String 景区大类; + + @TableField("景区大类id") + private Integer 景区大类id; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2ViewPowerAlarm.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2ViewPowerAlarm.java new file mode 100644 index 0000000..9048426 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2ViewPowerAlarm.java @@ -0,0 +1,81 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * + *

+ * + * @author wqx + * @since 2023-08-31 + */ +@Data +@TableName("dp_2_view_power_alarm") +@ApiModel(value = "Dp2ViewPowerAlarm对象", description = "") +public class Dp2ViewPowerAlarm { + + private static final long serialVersionUID = 1L; + + @TableField("eventtime") + private LocalDateTime eventtime; + + @TableField("alarmname") + private String alarmname; + + @TableField("alarmid") + private Long alarmid; + + @TableField("severity") + private String severity; + + @TableField("site_id") + private String siteId; + + @TableField("site_name") + private String siteName; + + @TableField("device_name") + private String deviceName; + + @TableField("owner") + private String owner; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("area") + private String area; + + @TableField("logicalsites") + private String logicalsites; + + @TableField("场馆id") + private Integer 场馆id; + + @TableField("区域id") + private Integer 区域id; + + @TableField("场馆名称") + private String 场馆名称; + + @TableField("故障处理人") + private String 故障处理人; + + @TableField("phonenumber") + private String phonenumber; + + @TableField("deal_status") + private Integer dealStatus; + + @TableField("deal_time") + private LocalDateTime dealTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2ViewWirelessAlarm.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2ViewWirelessAlarm.java new file mode 100644 index 0000000..73f094b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2ViewWirelessAlarm.java @@ -0,0 +1,89 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * + *

+ * + * @author wqx + * @since 2023-09-01 + */ +@Data +@TableName("dp_2_view_wireless_alarm") +@ApiModel(value = "Dp2ViewWirelessAlarm对象", description = "") +public class Dp2ViewWirelessAlarm { + + private static final long serialVersionUID = 1L; + + @TableField("id") + private Long id; + + @TableField("eventtime") + private LocalDateTime eventtime; + + @TableField("alarmname") + private String alarmname; + + @TableField("omcname") + private String omcname; + + @TableField("site_id") + private String siteId; + + @TableField("site_name") + private String siteName; + + @TableField("area") + private String area; + + @TableField("alarmid") + private String alarmid; + + @TableField("sitetype") + private String sitetype; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("cell_name") + private String cellName; + + @TableField("场馆id") + private Long 场馆id; + + @TableField("场馆名称") + private String 场馆名称; + + @TableField("longitude") + private Object longitude; + + @TableField("latitude") + private Object latitude; + + @TableField("坐席编号") + private String 坐席编号; + + @TableField("场内场外") + private String 场内场外; + + @TableField("区域id") + private Integer 区域id; + + @TableField("故障处理人") + private String 故障处理人; + + @TableField("phonenumber") + private String phonenumber; + + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/DpSceneConfig.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/DpSceneConfig.java new file mode 100644 index 0000000..1c9adb8 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/DpSceneConfig.java @@ -0,0 +1,74 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("dp_scene_config") +@ApiModel(value = "DpSceneConfig对象", description = "") +public class DpSceneConfig { + + private static final long serialVersionUID = 1L; + @ApiModelProperty("自增id") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("颜色等级") + @TableField("level") + private Short level; + + @ApiModelProperty("指标名称") + @TableField("name") + private String name; + + @ApiModelProperty("最小值") + @TableField("range1") + private Object range1; + + @ApiModelProperty("最大值") + @TableField("range2") + private Object range2; + + @ApiModelProperty("颜色") + @TableField("color") + private String color; + + @ApiModelProperty("备注") + @TableField("content") + private String content; + + @ApiModelProperty("指标等级:cell、scene") + @TableField("type") + private String type; + + @ApiModelProperty("网络类型") + @TableField("nettype") + private String nettype; + + @ApiModelProperty("小区设备") + @TableField("celltype") + private String celltype; + + @ApiModelProperty("颜色分值") + @TableField("colorscore") + private Double colorscore; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/HmAlarmDerive.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/HmAlarmDerive.java new file mode 100644 index 0000000..f4de081 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/HmAlarmDerive.java @@ -0,0 +1,84 @@ +package com.ruoyi.eastcom_yw.domain; + + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +/** + *

+ * + *

+ * + * @author jkj + * @since 2023-08-02 + */ +@Data +@TableName("hm_alarm_derive") +public class HmAlarmDerive implements Serializable { + +private static final long serialVersionUID=1L; + + + private Long id; + + private Long groupid; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "告警时间" ,sort = 4) + private LocalDateTime 告警时间; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "恢复时间" ,sort = 5) + private LocalDateTime 恢复时间; + + @Excel(name = "区县" ,sort = 1) + private String 分公司; + + @Excel(name = "网元名称" ,sort = 6) + private String 网元名称; + + @Excel(name = "端口" ,sort = 7) + private String 端口; + + @Excel(name = "场馆名称" ,sort = 2) + private String 场馆名称; + + private String 场馆等级; + + @Excel(name = "告警名称" ,sort = 3) + private String 告警名称; + + @Excel(name = "详细位置" ,sort = 9) + private String 详细位置; + + @Excel(name = "专业" ,sort = 8) + private String 专业; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime 告警插入时间; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime 恢复更新时间; + + private String mark; + + private String yClearid; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime 修改时间; + + @TableField(exist = false) + private String alarmType = "yayun"; + + @TableField(exist = false) + private Long alarmId; + + @TableField(exist = false) + private String alarmKey; + +} \ No newline at end of file diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi4gCell.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi4gCell.java new file mode 100644 index 0000000..0611ed3 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi4gCell.java @@ -0,0 +1,200 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 场馆4G小区级15分钟指标 + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("pm_kpi4g_cell") +@ApiModel(value = "PmKpi4gCell对象", description = "场馆4G小区级15分钟指标") +public class PmKpi4gCell { + + private static final long serialVersionUID = 1L; +// @ApiModelProperty("id") +// @TableField("id") +// private Long id; + + @TableField("venue_id") + private Integer venueId; + + @TableField("venue_name") + private String venueName; + + @TableField("cellcodeci") + private String cellcodeci; + + @TableField("starttime") + private LocalDateTime starttime; + + @TableField("input_datetime") + private LocalDateTime inputDatetime; + + @TableField("小区名称") + private String 小区名称; + + @TableField("上行流量mb") + private BigDecimal 上行流量mb; + + @TableField("下行流量mb") + private BigDecimal 下行流量mb; + + @TableField("有效rrc连接平均数") + private BigDecimal 有效rrc连接平均数; + + @TableField("有效rrc连接最大数") + private BigDecimal 有效rrc连接最大数; + + @TableField("平均用户数") + private BigDecimal 平均用户数; + + @TableField("最大用户数") + private BigDecimal 最大用户数; + + @TableField("volte话务量") + private BigDecimal volte话务量; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率; + + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率; + + @TableField("上行平均干扰") + private BigDecimal 上行平均干扰; + + @TableField("rrc建立成功率") + private BigDecimal rrc建立成功率; + + @TableField("e_rab建立成功率") + private BigDecimal eRab建立成功率; + + @TableField("qci为1的e_rab建立成功率") + private BigDecimal qci为1的eRab建立成功率; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率; + + @TableField("掉线次数") + private BigDecimal 掉线次数; + + @TableField("切换成功率") + private BigDecimal 切换成功率; + + @TableField("esrvcc切换成功率") + private BigDecimal esrvcc切换成功率; + + @TableField("esrvcc切换请求次数") + private BigDecimal esrvcc切换请求次数; + + @TableField("rrc重建成功率") + private BigDecimal rrc重建成功率; + + @TableField("rrc重建次数") + private BigDecimal rrc重建次数; + + @TableField("volte掉话率") + private BigDecimal volte掉话率; + + @TableField("volte掉话次数") + private BigDecimal volte掉话次数; + + @TableField("rru_puschprbassn") + private BigDecimal rruPuschprbassn; + + @TableField("rru_puschprbtot") + private BigDecimal rruPuschprbtot; + + @TableField("rru_pdschprbassn") + private BigDecimal rruPdschprbassn; + + @TableField("rru_pdschprbtot") + private BigDecimal rruPdschprbtot; + + @TableField("rrc_succconnestab") + private BigDecimal rrcSuccconnestab; + + @TableField("rrc_attconnestab") + private BigDecimal rrcAttconnestab; + + @TableField("erab_nbrsuccestab_1") + private BigDecimal erabNbrsuccestab1; + + @TableField("erab_nbrattestab") + private BigDecimal erabNbrattestab; + + @TableField("erab_nbrattestab_1") + private BigDecimal erabNbrattestab1; + + @TableField("切换成功率_分母") + private BigDecimal 切换成功率分母; + + @TableField("切换成功率_分子") + private BigDecimal 切换成功率分子; + + @TableField("掉线率_分母") + private BigDecimal 掉线率分母; + + @TableField("iratho_succoutgeran") + private BigDecimal irathoSuccoutgeran; + + @TableField("rrc_attconnreestab") + private BigDecimal rrcAttconnreestab; + + @TableField("volte掉话率_分母") + private BigDecimal volte掉话率分母; + + @TableField("erab_nbrsuccestab") + private BigDecimal erabNbrsuccestab; + + @TableField("omcname") + private String omcname; + + @TableField("无线接通率") + private BigDecimal 无线接通率; + + @TableField("rrc_failconnestab") + private BigDecimal rrcFailconnestab; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("groupid") + private Long groupid; + + @TableField("endtime") + private LocalDateTime endtime; + + ///////////////////////////////// + @TableField(exist = false) + private Integer orderId; + + @TableField(exist = false) + private String 坐席编号; + + @TableField(exist = false) + private String 小区频段; + + @TableField(exist = false) + private String 设备类型; + + @TableField(exist = false) + private Long 带宽; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi4gMin.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi4gMin.java new file mode 100644 index 0000000..a0d19aa --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi4gMin.java @@ -0,0 +1,126 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 场馆4G小区级1分钟指标 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("pm_kpi4g_min") +@ApiModel(value = "PmKpi4gMin对象", description = "场馆4G小区级1分钟指标") +public class PmKpi4gMin { + + private static final long serialVersionUID = 1L; + + @TableField("groupid") + private Integer groupid; + + @TableField("时间") + private LocalDateTime 时间; + + @TableField("小区名称") + private String 小区名称; + + @TableField("地市区号") + private String 地市区号; + + @TableField("厂商id") + private String 厂商id; + + @TableField("avg_user") + private BigDecimal avgUser; + + @TableField("max_user") + private Integer maxUser; + + @TableField("prb_up") + private BigDecimal prbUp; + + @TableField("prb_down") + private BigDecimal prbDown; + + @TableField("avg_disturb") + private Integer avgDisturb; + + @TableField("speed_up") + private BigDecimal speedUp; + + @TableField("speed_down") + private BigDecimal speedDown; + + @TableField("call_succ_rate") + private BigDecimal callSuccRate; + + @TableField("call_drop_rate") + private BigDecimal callDropRate; + + @TableField("act_avg_user") + private BigDecimal actAvgUser; + + @TableField("act_max_user") + private Integer actMaxUser; + + @TableField("volte") + private BigDecimal volte; + + @TableField("volte_succ_rate") + private BigDecimal volteSuccRate; + + @TableField("volte_drop_rate") + private BigDecimal volteDropRate; + + @TableField("data_up") + private BigDecimal dataUp; + + @TableField("data_down") + private BigDecimal dataDown; + + @TableField("v1_max") + private BigDecimal v1Max; + + @TableField("v1_avg") + private String v1Avg; + + @TableField("update_time") + private LocalDateTime updateTime; + + ///////////////////////////////// + @TableField(exist = false) + private Integer orderId; + + @TableField(exist = false) + private String venueName; + + @TableField(exist = false) + private String venueId; + + @TableField(exist = false) + private String cellcodeci; + + @TableField(exist = false) + private String 小区频段; + + @TableField(exist = false) + private String 设备类型; + + @TableField(exist = false) + private Long 带宽; + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi4gVenue.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi4gVenue.java new file mode 100644 index 0000000..47cdd03 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi4gVenue.java @@ -0,0 +1,86 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/11 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("pm_kpi4g_venue") +@ApiModel(value = "PmKpi4gVenue对象", description = "4G场馆级15分钟指标") +public class PmKpi4gVenue { + + + private static final long serialVersionUID = 1L; + + @TableId("id") + private Long id; + + @TableField("开始时间") + private LocalDateTime 开始时间; + + @TableField("入库时间") + private LocalDateTime 入库时间; + + @TableField("区县") + private String 区县; + + @TableField("场馆id") + private Integer 场馆id; + + @TableField("无线接通率") + private BigDecimal 无线接通率; + +// @TableField("流量GB") +// private Short 流量GB; + + @TableField("最大用户数") + private Short 最大用户数; + + @TableField("话务量") + private Short 话务量; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率; + + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率; + + @TableField("上行平均干扰") + private Short 上行平均干扰; + + @TableField("volte接通率") + private BigDecimal volte接通率; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("结束时间") + private LocalDateTime 结束时间; + + @TableField("平均用户数") + private BigDecimal 平均用户数; + + ///////////////////////////////// + @TableField(exist = false) + private String venueName; + + @TableField(exist = false) + private String prbupColor; + + @TableField(exist = false) + private String prbdownColor; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi5gCell.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi5gCell.java new file mode 100644 index 0000000..07df6b5 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi5gCell.java @@ -0,0 +1,183 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 场馆5G小区级15分钟指标 + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("pm_kpi5g_cell_2") +@ApiModel(value = "PmKpi5gCell对象", description = "场馆5G小区级15分钟指标") +public class PmKpi5gCell { + + private static final long serialVersionUID = 1L; +// @ApiModelProperty("id") +// @TableField("id") +// private Long id; + + @TableField("venue_id") + private Integer venueId; + + @TableField("venue_name") + private String venueName; + + @TableField("ci") + private String ci; + + @TableField("starttime") + private LocalDateTime starttime; + + @TableField("小区名称") + private String 小区名称; + + @TableField("nr流量") + private BigDecimal nr流量; + + @TableField("上行5g流量") + private BigDecimal 上行5g流量; + + @TableField("下行5g流量") + private BigDecimal 下行5g流量; + + @TableField("小区rlc层下行丢包率") + private BigDecimal 小区rlc层下行丢包率; + + @TableField("小区级rlc层sdu下行空口丢包数") + private BigDecimal 小区级rlc层sdu下行空口丢包数; + + @TableField("小区rlc层收到的下行sdu包数") + private BigDecimal 小区rlc层收到的下行sdu包数; + + @TableField("平均用户数") + private BigDecimal 平均用户数; + + @TableField("最大用户数") + private BigDecimal 最大用户数; + + @TableField("sn异常释放率") + private BigDecimal sn异常释放率; + + @TableField("sgnb释放总次数") + private BigDecimal sgnb释放总次数; + + @TableField("sgnb触发sgnb异常释放总次数") + private BigDecimal sgnb触发sgnb异常释放总次数; + + @TableField("nsa_sgnb添加成功率") + private BigDecimal nsaSgnb添加成功率; + + @TableField("dc场景下发送sgnb增加成功的次数") + private BigDecimal dc场景下发送sgnb增加成功的次数; + + @TableField("dc场景下收到sgnb增加尝试的次数") + private BigDecimal dc场景下收到sgnb增加尝试的次数; + + @TableField("无线接通率") + private BigDecimal 无线接通率; + + @TableField("rrc建立成功次数") + private BigDecimal rrc建立成功次数; + + @TableField("rrc建立请求消息次数") + private BigDecimal rrc建立请求消息次数; + + @TableField("小区中qos_flow建立成功次数") + private BigDecimal 小区中qosFlow建立成功次数; + + @TableField("小区中qos_flow建立尝试次数") + private BigDecimal 小区中qosFlow建立尝试次数; + + @TableField("小区中ng信令连接建立成功次数") + private BigDecimal 小区中ng信令连接建立成功次数; + + @TableField("小区中ng信令连接建立尝试次数") + private BigDecimal 小区中ng信令连接建立尝试次数; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率; + + @TableField("小区中ue上下文异常释放的次数") + private BigDecimal 小区中ue上下文异常释放的次数; + + @TableField("小区中ue上下文正常释放的次数") + private BigDecimal 小区中ue上下文正常释放的次数; + + @TableField("无线掉线率分母") + private BigDecimal 无线掉线率分母; + + @TableField("切换成功率") + private BigDecimal 切换成功率; + + @TableField("切换成功率分子") + private BigDecimal 切换成功率分子; + + @TableField("切换成功率分母") + private BigDecimal 切换成功率分母; + + @TableField("下行平均使用的prb个数") + private BigDecimal 下行平均使用的prb个数; + + @TableField("下行平均可用prb个数") + private BigDecimal 下行平均可用prb个数; + + @TableField("上行平均使用的prb个数") + private BigDecimal 上行平均使用的prb个数; + + @TableField("上行平均可用prb个数") + private BigDecimal 上行平均可用prb个数; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率; + + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率; + + @TableField("input_datetime") + private LocalDateTime inputDatetime; + + @TableField("cell_name") + private String cellName; + + @TableField("groupid") + private Long groupid; + + @TableField("上行干扰值") + private Double 上行干扰值; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("endtime") + private LocalDateTime endtime; + + + ///////////////////////////////// + @TableField(exist = false) + private Integer orderId; + + @TableField(exist = false) + private String 小区频段; + + @TableField(exist = false) + private String 设备类型; + + @TableField(exist = false) + private Long 带宽; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi5gMin.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi5gMin.java new file mode 100644 index 0000000..83d5a03 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi5gMin.java @@ -0,0 +1,109 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 场馆5G小区级1分钟指标 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("pm_kpi5g_min") +@ApiModel(value = "PmKpi5gMin对象", description = "场馆5G小区级1分钟指标") +public class PmKpi5gMin { + + private static final long serialVersionUID = 1L; + + @TableField("groupid") + private Integer groupid; + + @TableField("时间") + private LocalDateTime 时间; + + @TableField("小区名称") + private String 小区名称; + + @TableField("地市区号") + private String 地市区号; + + @TableField("厂商id") + private String 厂商id; + + @TableField("prb_up") + private Double prbUp; + + @TableField("prb_down") + private Double prbDown; + + @TableField("up_disturb") + private Integer upDisturb; + + @TableField("speed_up") + private Double speedUp; + + @TableField("speed_down") + private Double speedDown; + + @TableField("act_max_user") + private Integer actMaxUser; + + @TableField("act_avg_user") + private Double actAvgUser; + + @TableField("rrc_avg_user") + private BigDecimal rrcAvgUser; + + @TableField("rrc_max_user") + private Integer rrcMaxUser; + + @TableField("call_succ_rate") + private BigDecimal callSuccRate; + + @TableField("drop_call_rate") + private BigDecimal dropCallRate; + + @TableField("data_down") + private BigDecimal dataDown; + + @TableField("data_up") + private BigDecimal dataUp; + + @TableField("update_time") + private LocalDateTime updateTime; + + ///////////////////////////////// + @TableField(exist = false) + private Integer orderId; + + @TableField(exist = false) + private String venueName; + + @TableField(exist = false) + private String venueId; + + @TableField(exist = false) + private String cellcodeci; + + @TableField(exist = false) + private String 小区频段; + + @TableField(exist = false) + private String 设备类型; + + @TableField(exist = false) + private Long 带宽; + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi5gVenue.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi5gVenue.java new file mode 100644 index 0000000..ef744b6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpi5gVenue.java @@ -0,0 +1,99 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 5G场馆级15分钟指标 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("pm_kpi5g_venue_2") +@ApiModel(value = "PmKpi5gVenue对象", description = "5G场馆级15分钟指标") +public class PmKpi5gVenue { + + private static final long serialVersionUID = 1L; + + @TableId("id") + private Long id; + + @TableField("开始时间") + private LocalDateTime 开始时间; + + @TableField("入库时间") + private LocalDateTime 入库时间; + + @TableField("区县") + private String 区县; + + @TableField("场馆id") + private Integer 场馆id; + + @TableField("无线接通率") + private BigDecimal 无线接通率; + + @TableField("nsa_sgnb添加成功率") + private BigDecimal nsaSgnb添加成功率; + + @TableField("切换成功率") + private BigDecimal 切换成功率; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率; + + @TableField("sn异常释放率") + private BigDecimal sn异常释放率; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率; + + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率; + + @TableField("流量GB") + private BigDecimal 流量GB; + + @TableField("最大用户数") + private Short 最大用户数; + + @TableField("话务量") + private BigDecimal 话务量; + + @TableField("上行干扰值") + private Double 上行干扰值; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("结束时间") + private LocalDateTime 结束时间; + + @TableField("平均用户数") + private BigDecimal 平均用户数; + + ///////////////////////////////// + @TableField(exist = false) + private String venueName; + + + @TableField(exist = false) + private String prbupColor; + + @TableField(exist = false) + private String prbdownColor; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpiMaxEntity.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpiMaxEntity.java new file mode 100644 index 0000000..fd09fb5 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpiMaxEntity.java @@ -0,0 +1,21 @@ +package com.ruoyi.eastcom_yw.domain; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @author yqf + * @date 2023/4/19 + */ +@Data +public class PmKpiMaxEntity { + + private BigDecimal avgNum; + private BigDecimal maxuserNum; + private BigDecimal prbupNum; + private BigDecimal prbdownNum; + private BigDecimal avgDisturb; + private BigDecimal succesNum; + private BigDecimal failNum; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpiMonitorEntity.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpiMonitorEntity.java new file mode 100644 index 0000000..83d33a4 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/PmKpiMonitorEntity.java @@ -0,0 +1,75 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/17 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "PmKpiMonitorEntity对象", description = "场馆4G小区级1分钟指标") +public class PmKpiMonitorEntity { + + private static final long serialVersionUID = 1L; + private Long id; + + private Integer venueid; + + private String venuename; + + private String cellcodeci; + + private LocalDateTime starttime; + + private String 小区名称; + + private BigDecimal 平均用户数; + + private BigDecimal 最大用户数; + + private BigDecimal 上行prb利用率; + + private BigDecimal 下行prb利用率; + + private BigDecimal 上行平均干扰; + + private BigDecimal 无线掉线率; + + private BigDecimal 无线接通率; + + private LocalDateTime endtime; + + private Integer orderId; + + private String 坐席编号; + + private LocalDateTime 时间; + + private Long stationno; + private String pointname; + private String pointid; + private Double longitude; + private Double latitude; + + private String maxuserColor; + private String prbupColor; + private String prbdownColor; + private String avgdisColor; + private Integer maxuserScore; + private Integer prbupScore; + private Integer prbdownScore; + private Integer avgdisScore; + + private String 小区频段; + private String 设备类型; + private Long 带宽; + private Long 方位角; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/SysNotice.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/SysNotice.java new file mode 100644 index 0000000..2929fcf --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/SysNotice.java @@ -0,0 +1,144 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.mybatis.JsonListLongTypeHandler; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知公告表 + *

+ * + * @author ck + * @since 2023-04-14 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName(value = "sys_notice" ,autoResultMap = true) +@ApiModel(value = "SysNotice对象", description = "通知公告表") +public class SysNotice { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增id") + @TableId(value = "notice_id", type = IdType.AUTO) + private Integer noticeId; + + @ApiModelProperty("通知标题") + @TableField("notice_title") + private String noticeTitle; + + @ApiModelProperty("通知类型--字典表sys_notice_type 短信3 移动办公5 IVR7") + @TableField("notice_type") + private String noticeType; + + @ApiModelProperty("通知内容") + @TableField("notice_content") + private String noticeContent; + + @ApiModelProperty("状态 0未读 1已读") + @TableField("status") + private String status; + + @ApiModelProperty("创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty("插入时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty("更新人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty("更新时间") + @TableField("update_time") + private LocalDateTime updateTime; + + @ApiModelProperty("备注") + @TableField("remark") + private String remark; + + @ApiModelProperty("接收人") + @TableField("recive_user") + private Long reciveUser; + + @ApiModelProperty("工作流id") + @TableField("flw_processid") + private String flwProcessid; + + @ApiModelProperty("工作流任务id") + @TableField("flw_taskid") + private String flwTaskid; + + @ApiModelProperty("实际发送时间") + @TableField("send_time") + private LocalDateTime sendTime; + + @ApiModelProperty("发送是否成功,1成功 0失败") + @TableField("send_status") + private String sendStatus; + + @ApiModelProperty("接收人手机号") + @TableField("recive_user_phone") + private String reciveUserPhone; + + @ApiModelProperty("计划发送时间(同天当前时间之前立即发送)") + @TableField("exp_send_time") + private LocalDateTime expSendTime; + + @ApiModelProperty("加入定时任务标记 默认0未加入 1已加入") + @TableField("add_flag") + private String addFlag; + + @ApiModelProperty("通知对象ids数组") + @TableField(value = "notice_object_id",typeHandler = JsonListLongTypeHandler.class) + private List noticeObjectId; + + @ApiModelProperty("通知模板id") + @TableField("notice_model_id") + private Long noticeModelId; + + @ApiModelProperty("通知场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @TableField("model_scene") + private String modelScene; + + @ApiModelProperty("对象属性--yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + private String objectProto; + + @ApiModelProperty("通知对象(是指具体的通知接受者,呈现方式包括场馆+群组;分公司+群组名;地市+群组名;ITCC+群组名;场馆+个人名;分公司+个人名;地市+个人名;ITCC+个人名这几种组合。具体呈现内容和对象属性、通知方式相关联)") + @TableField("notice_object") + private String noticeObject; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3简报") + @TableField("model_suit_type") + private String modelSuitType; + + @ApiModelProperty("接收人群号") + @TableField("group_id") + private String groupId; + + @ApiModelProperty("关联表id(yw_notice_handwork)") + @TableField("handwork_id") + private Long handworkId; + + @ApiModelProperty("通知对象名称数组") + @TableField("notice_object_name_str") + private String noticeObjectNameStr; + + @ApiModelProperty("发送人(由谁发送)") + @TableField("send_user") + private Long sendUser; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/SysUserImp.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/SysUserImp.java new file mode 100644 index 0000000..a0ae336 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/SysUserImp.java @@ -0,0 +1,45 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.importer.beans.ResultBean; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SysUserImp extends ResultBean { + private Long user_id; + @Excel(name = "姓名", sort = 2) + private String user_name; + @Excel(name = "手机号码", sort = 3) + private String phonenumber; + private String avatar; + @Excel(name = "账号状态", sort = 5) + private String status; + private Long roleId; + @Excel(name = "角色", sort = 6) + private String roleName; + private String specialtyCode; + @Excel(name = "专业", sort = 7) + private String specialty; + private String cityId; + @Excel(name = "地市", sort = 8) + private String city; + private String countyId; + @Excel(name = "区县", sort = 9) + private String county; + private Long sceneId; + @Excel(name = "场馆", sort = 10) + private String sceneName; + @Excel(name = "场馆分区", sort = 11) + private String belongArea; + @Excel(name = "是否要签到", sort = 12) + private String needSign; + @Excel(name = "自有/三方", sort = 13) + private String ywUserBelong; + private String createTime; + private String loginDate; + private String loginIp; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarm.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarm.java new file mode 100644 index 0000000..e264655 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarm.java @@ -0,0 +1,55 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + + +/** +* @author jkj +* @since 2023-01-12 +**/ + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("v_yw_alarm_all") +public class YwAlarm implements Serializable { + private static final long serialVersionUID=1L; + + private String id; + + private String 告警时间; + + private String 恢复时间; + + private String 告警编号; + + private String 告警名称; + + private String 场馆名称; + + private String 告警等级; + + private String 基站号; + + private String 基站名; + + private String 网元名称; + + private String 关联组号; + + private String 告警类型; + + private String 红线内; + + private String alarmType; + + private String 类型; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmCS.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmCS.java new file mode 100644 index 0000000..2957867 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmCS.java @@ -0,0 +1,55 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; + + +/** +* @author jkj +* @since 2023-01-12 +**/ + +@Data +@NoArgsConstructor +@AllArgsConstructor +@TableName("v_yw_alarm_last_cs") +public class YwAlarmCS extends YwAlarmView implements Serializable { + + private Long 场馆id; + + private String dealUserId; + + private String dealUser; + + private String dealStatus; + + private String processId; + + private String taskId; + + private Date endTime; + + private String areaCountyId; + + private String city; + + private String county; + + private String alarmType; + + private String alarmStatus; + + private String belongArea; + + private String lastClearTime; + + private String isHangup; + + private Integer clearNum; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmConfig.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmConfig.java new file mode 100644 index 0000000..6002a89 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmConfig.java @@ -0,0 +1,31 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author huamile + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("yw_alarm_config") +public class YwAlarmConfig { + + private Long id; + + private String alarmCode; + + private Long dealHour; + + private Long sceneBigId; + + private String alarmName; + + private String specialty; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmDH.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmDH.java new file mode 100644 index 0000000..519720b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmDH.java @@ -0,0 +1,55 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; + + +/** +* @author jkj +* @since 2023-01-12 +**/ + +@Data +@NoArgsConstructor +@AllArgsConstructor +@TableName("v_yw_alarm_last_dh") +public class YwAlarmDH extends YwAlarmView implements Serializable { + + private Long 场馆id; + + private String dealUserId; + + private String dealUser; + + private String dealStatus; + + private String processId; + + private String taskId; + + private Date endTime; + + private String areaCountyId; + + private String city; + + private String county; + + private String alarmType; + + private String alarmStatus; + + private String belongArea; + + private String lastClearTime; + + private String isHangup; + + private Integer clearNum; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmHangupLog.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmHangupLog.java new file mode 100644 index 0000000..168d0b2 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmHangupLog.java @@ -0,0 +1,77 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.Date; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * + *

+ * + * @author jkj + * @since 2023-02-15 + */ +@Data +@TableName("yw_alarm_hangup_log") +public class YwAlarmHangupLog implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type= IdType.AUTO) + private Long id; + + /** + * 大场景id + */ + private Long sceneBigId; + + /** + * 挂起时间 + */ + private Date hangupTime; + + /** + * 挂起人 + */ + private Long hangupUserId; + + /** + * 恢复处理时间 + */ + private Date recoveryTime; + + /** + * 恢复结果 + */ + private String recoveryResult; + + /** + * 挂起原因 + */ + private String hangupReason; + + /** + * 工作流进程id + */ + private String flwProcessid; + + /** + * 工作流任务id + */ + private String flwTaskid; + + /** + * 挂起状态 + */ + private String hangupStatus; + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmHangupReover.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmHangupReover.java new file mode 100644 index 0000000..3978646 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmHangupReover.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * + *

+ * + * @author jkj + * @since 2023-02-15 + */ +@Data +public class YwAlarmHangupReover extends YwAlarmHangupLog implements Serializable { + /** + * 告警是否恢复 + */ + private String isRecover; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmOprateLog.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmOprateLog.java new file mode 100644 index 0000000..c2f3931 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmOprateLog.java @@ -0,0 +1,49 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * + *

+ * + * @author jkj + * @since 2023-03-06 + */ +@Data +@TableName("yw_alarm_oprate_log") +public class YwAlarmOprateLog implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 序号 + */ + @TableId(value = "id",type = IdType.AUTO) + private Long id; + + /** + * 告警组号 + */ + private String alarmGroup; + + /** + * 用户id + */ + private Long userId; + + /** + * 操作时间 + */ + private String oprateTime; + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmRecover.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmRecover.java new file mode 100644 index 0000000..4bc292a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmRecover.java @@ -0,0 +1,44 @@ +package com.ruoyi.eastcom_yw.domain; + +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 告警自动恢复 + *

+ * + * @author jkj + * @since 2023-02-15 + */ +@Data +public class YwAlarmRecover implements Serializable { + + /** + * 告警分组号 + */ + private Long alarmId; + + /** + * 告警类型 + */ + private String alarmType; + + /** + * 工作流进程id + */ + private String flwProcessid; + + /** + * 工作流任务id + */ + private String flwTaskid; + + + /** + * 最后清除时间 + */ + private String lastClearTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmView.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmView.java new file mode 100644 index 0000000..6a20ba2 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmView.java @@ -0,0 +1,56 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; + + +/** +* @author jkj +* @since 2023-01-12 +**/ + +@Data +@NoArgsConstructor +@AllArgsConstructor +@TableName("v_yw_alarm_last") +public class YwAlarmView extends YwAlarm implements Serializable { + + private Long 场馆id; + + private String dealUserId; + + private String dealUser; + + private String dealStatus; + + private String processId; + + private String taskId; + + private Date endTime; + + private String areaCountyId; + + private String city; + + private String county; + + private String alarmType; + + private String alarmStatus; + + private String belongArea; + + private String lastClearTime; + + private String isHangup; + + private Integer clearNum; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmWX.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmWX.java new file mode 100644 index 0000000..9b26a33 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwAlarmWX.java @@ -0,0 +1,55 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; + + +/** +* @author jkj +* @since 2023-01-12 +**/ + +@Data +@NoArgsConstructor +@AllArgsConstructor +@TableName("v_yw_alarm_last_wx") +public class YwAlarmWX extends YwAlarmView implements Serializable { + + private Long 场馆id; + + private String dealUserId; + + private String dealUser; + + private String dealStatus; + + private String processId; + + private String taskId; + + private Date endTime; + + private String areaCountyId; + + private String city; + + private String county; + + private String alarmType; + + private String alarmStatus; + + private String belongArea; + + private String lastClearTime; + + private String isHangup; + + private Integer clearNum; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwDrsConfig.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwDrsConfig.java new file mode 100644 index 0000000..f016b5e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwDrsConfig.java @@ -0,0 +1,67 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; + +/** + *

+ * DRS配置表 + *

+ * + * @author ck + * @since 2023-06-13 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("yw_drs_config") +@ApiModel(value = "YwDrsConfig对象", description = "DRS配置表") +public class YwDrsConfig { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("任务名称") + @TableField("task_name") + private String taskName; + + @ApiModelProperty("任务类型 drs_task_type 0 / 1 签到 2巡检") + @TableField("drs_task_type") + private String drsTaskType; + + @ApiModelProperty("状态") + @TableField("status") + private String status; + + @ApiModelProperty("创建人") + @TableField(value = "create_by", fill = FieldFill.INSERT) + private String createBy; + + @ApiModelProperty("创建时间") + @TableField(value = "create_time", fill = FieldFill.INSERT) + private LocalDateTime createTime; + + @ApiModelProperty("修改人") + @TableField(value = "update_by", fill = FieldFill.INSERT_UPDATE) + private String updateBy; + + @ApiModelProperty("修改时间") + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updateTime; + + @ApiModelProperty("备注") + @TableField("remark") + private String remark; + + @ApiModelProperty("删除标记") + @TableField("del_flag") + private String delFlag; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwDrsTempTask.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwDrsTempTask.java new file mode 100644 index 0000000..7ddc7ef --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwDrsTempTask.java @@ -0,0 +1,93 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + *

+ * DRS临时任务表 + *

+ * + * @author ck + * @since 2023-06-13 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("yw_drs_temp_task") +@KeySequence(value ="yw_drs_temp_task_seq" ,dbType = DbType.POSTGRE_SQL) +@ApiModel(value = "YwDrsTempTask对象", description = "DRS临时任务表") +public class YwDrsTempTask { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; + + @ApiModelProperty("任务日期") + @TableField("task_date") + private LocalDate taskDate; + + @ApiModelProperty("任务时间") + @TableField("task_time") + private LocalDateTime taskTime; + + @ApiModelProperty("任务结束时间") + @TableField("task_end_time") + private LocalDateTime taskEndTime; + + @ApiModelProperty("任务名称") + @TableField("task_name") + private String taskName; + + @ApiModelProperty("DRS任务类型 drs_task_type 0 / 1 签到 2巡检") + @TableField("drs_task_type") + private String drsTaskType; + + @ApiModelProperty("DRS任务状态 drs_task_status 0未开始 1进行中 2已完成") + @TableField("drs_task_status") + private String drsTaskStatus; + + @ApiModelProperty("自动状态变更 drs_auto_update 0自动 1手动") + @TableField("drs_auto_update") + private String drsAutoUpdate; + + @ApiModelProperty("状态") + @TableField("status") + private String status; + + @ApiModelProperty("创建人") + @TableField(value = "create_by", fill = FieldFill.INSERT) + private String createBy; + + @ApiModelProperty("创建时间") + @TableField(value = "create_time", fill = FieldFill.INSERT) + private LocalDateTime createTime; + + @ApiModelProperty("修改人") + @TableField(value = "update_by", fill = FieldFill.INSERT_UPDATE) + private String updateBy; + + @ApiModelProperty("修改时间") + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updateTime; + + @ApiModelProperty("备注") + @TableField("remark") + private String remark; + + @ApiModelProperty("删除标记") + @TableField("del_flag") + private String delFlag; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwKpiConfig.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwKpiConfig.java new file mode 100644 index 0000000..22bdbde --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwKpiConfig.java @@ -0,0 +1,84 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.time.LocalDateTime; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 指标字段阈值配置表 + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("yw_kpi_config") +@ApiModel(value = "YwKpiConfig对象", description = "指标字段阈值配置表") +public class YwKpiConfig { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("序号") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("专业(字典表)") + @TableField("subject") + private String subject; + + @ApiModelProperty("网络模式(字典表)") + @TableField("net_type") + private String netType; + + @ApiModelProperty("指标字段") + @TableField("kpi_field") + private Long kpiField; + + @ApiModelProperty("阈值范围") + @TableField("threshold_value") + private String thresholdValue; + + @ApiModelProperty("颜色") + @TableField("color") + private String color; + + @ApiModelProperty("创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty("创建时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty("更新人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty("更新时间") + @TableField("update_time") + private LocalDateTime updateTime; + + @ApiModelProperty("最小是(包括本值)") + @TableField("min_value") + private Object minValue; + + @ApiModelProperty("最大值(不包括本值)") + @TableField("max_value") + private Object maxValue; + + @ApiModelProperty("指标名") + @TableField("kpi_field_name") + private String kpiFieldName; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeBriefing.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeBriefing.java new file mode 100644 index 0000000..d583b35 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeBriefing.java @@ -0,0 +1,108 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.ruoyi.common.mybatis.JsonListLongTypeHandler; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知通告简报计划表 + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName(value = "yw_notice_briefing",autoResultMap = true) +@ApiModel(value = "YwNoticeBriefing对象", description = "通知通告简报计划表") +public class YwNoticeBriefing { + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("地市") + @TableField("city") + private String city; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; + + @ApiModelProperty("对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + private String objectProto; + + @ApiModelProperty("通知方式sys_notice_type") + @TableField("notice_type") + private String noticeType; + + @ApiModelProperty("发送日期") + @TableField("send_date") + private LocalDate sendDate; + + @ApiModelProperty("开始时间") + @TableField("begin_time") + private LocalDateTime beginTime; + + @ApiModelProperty("结束时间") + @TableField("end_time") + private LocalDateTime endTime; + + @ApiModelProperty("区县") + @TableField("county") + private String county; + + @ApiModelProperty("对象ids数组") + @TableField(value = "object_ids",typeHandler = JsonListLongTypeHandler.class) + private List objectIds; + + @ApiModelProperty("模板id") + @TableField("model_id") + private Long modelId; + + @ApiModelProperty("排序号") + @TableField("order_num") + private Integer orderNum; + + @ApiModelProperty("时间间隔(单位分)") + @TableField("time_interval") + private Integer timeInterval; + + @ApiModelProperty("通知名称") + @TableField("notice_name") + private String noticeName; + + @ApiModelProperty("启用状态 sys_normal_disable 0启用 1停用") + @TableField("sys_normal_disable") + private String sysNormalDisable; + + @ApiModelProperty("通知对象名称数组") + @TableField("notice_object_name_str") + private String noticeObjectNameStr; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3文字简报 4h5简报)") + @TableField("model_suit_type") + private String modelSuitType; + + @ApiModelProperty("发送方式 send_type (1自动发送 2手工发送)") + @TableField("send_type") + private String sendType; + + @ApiModelProperty("发送人员") + @TableField("send_user") + private Long sendUser; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeHandwork.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeHandwork.java new file mode 100644 index 0000000..357a979 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeHandwork.java @@ -0,0 +1,96 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.ruoyi.common.mybatis.JsonListLongTypeHandler; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知通告手工通知计划表 + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName(value = "yw_notice_handwork",autoResultMap = true) +@ApiModel(value = "YwNoticeHandwork对象", description = "通知通告手工通知计划表") +public class YwNoticeHandwork { + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("通知名称") + @TableField("notice_name") + private String noticeName; + + @ApiModelProperty("通知模板id") + @TableField("notice_model") + private Long noticeModel; + + @ApiModelProperty("通知方式--sys_notice_type") + @TableField("notice_type") + private String noticeType; + + @ApiModelProperty("通知对象ids") + @TableField(value = "notice_object",typeHandler = JsonListLongTypeHandler.class) + private List noticeObject; + + @ApiModelProperty("通知内容") + @TableField("notice_content") + private String noticeContent; + + @ApiModelProperty("通知状态yw_veriy_status 0待提交 1待审核 2已审核") + @TableField("notice_status") + private String noticeStatus; + + @ApiModelProperty("日期") + @TableField("notice_date") + private LocalDateTime noticeDate; + + @ApiModelProperty("开始时间") + @TableField("begin_time") + private LocalDateTime beginTime; + + @ApiModelProperty("结束时间") + @TableField("end_time") + private LocalDateTime endTime; + + @ApiModelProperty("时间间隔(单位分)") + @TableField("time_interval") + private Integer timeInterval; + + @ApiModelProperty("工作流processid") + @TableField("flw_processid") + private String flwProcessid; + + @ApiModelProperty("申请人id") + @TableField("apply_id") + private Long applyId; + + @ApiModelProperty("审核人id") + @TableField("audit_id") + private Long auditId; + + @ApiModelProperty("已添加到sys_notice标记(0否 1是)") + @TableField("add_flag") + private String addFlag; + + @ApiModelProperty("通知对象名称数组") + @TableField("notice_object_name_str") + private String noticeObjectNameStr; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeHandworkdetail.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeHandworkdetail.java new file mode 100644 index 0000000..aefaf49 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeHandworkdetail.java @@ -0,0 +1,55 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 通知通告手工通知审核表 + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("yw_notice_handworkdetail") +@ApiModel(value = "YwNoticeHandworkdetail对象", description = "通知通告手工通知审核表") +public class YwNoticeHandworkdetail { + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("手工通知id") + @TableField("handwork_id") + private Long handworkId; + + @ApiModelProperty("操作人(提交审核的人 或者 审核的人)") + @TableField("oprate_user") + private Long oprateUser; + + @ApiModelProperty("审核结果(关联字典表yw_veriy_result 0通过 1驳回)") + @TableField("veriy_result") + private String veriyResult; + + @ApiModelProperty("审核状态(关联字典表yw_veriy_status 0 待审核 1 已审核)") + @TableField("veriy_status") + private String veriyStatus; + + @ApiModelProperty("驳回原因") + @TableField("fail_reason") + private String failReason; + + @ApiModelProperty("附件") + @TableField("appendix") + private String appendix; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeList.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeList.java new file mode 100644 index 0000000..0a896a5 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeList.java @@ -0,0 +1,100 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.ruoyi.common.mybatis.JsonListLongTypeHandler; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知通告记录表 + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName(value = "yw_notice_List",autoResultMap = true) +@ApiModel(value = "YwNoticeList对象", description = "通知通告记录表") +public class YwNoticeList { + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("通知名称") + @TableField("notice_name") + private String noticeName; + + @ApiModelProperty("通知场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @TableField("model_scene") + private String modelScene; + + @ApiModelProperty("对象属性--yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + private String objectProto; + + @ApiModelProperty("通知方式--sys_notice_type") + @TableField("notice_type") + private String noticeType; + + @ApiModelProperty("通知时间(计划发送时间(同天当前时间之前立即发送))") + @TableField("notice_time") + private LocalDateTime noticeTime; + + @ApiModelProperty("通知对象") + @TableField("notice_object") + private String noticeObject; + + @ApiModelProperty("通知内容") + @TableField("notice_content") + private String noticeContent; + + @ApiModelProperty("状态 0未读 1已读") + @TableField("status") + private String status; + + @ApiModelProperty("通知对象ids数组") + @TableField(value = "notice_object_id",typeHandler = JsonListLongTypeHandler.class) + private List noticeObjectId; + + @ApiModelProperty("通知模板id") + @TableField("notice_model_id") + private Long noticeModelId; + + @ApiModelProperty("实际发送时间") + @TableField("send_time") + private LocalDateTime sendTime; + + @ApiModelProperty("发送是否成功,1成功 0失败") + @TableField("send_status") + private String sendStatus; + + @ApiModelProperty("计划发送时间(同天当前时间之前立即发送)") + @TableField("exp_send_time") + private LocalDateTime expSendTime; + + @ApiModelProperty("加入定时任务标记 默认0未加入 1已加入") + @TableField("add_flag") + private String addFlag; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3简报") + @TableField("model_suit_type") + private String modelSuitType; + + @ApiModelProperty("计划id(手工与简报会先配置计划)") + @TableField("plan_id") + private Long planId; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeModel.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeModel.java new file mode 100644 index 0000000..60191c7 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeModel.java @@ -0,0 +1,84 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.Valid; +import javax.validation.constraints.Size; +import java.time.LocalDateTime; + +/** + *

+ * 通知通告模板表 + *

+ * + * @author ck + * @since 2023-04-07 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("yw_notice_model") +@ApiModel(value = "YwNoticeModel对象", description = "通知通告模板表") +public class YwNoticeModel { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("模板名称") + @TableField("model_name") + @Excel(name = "模板名称") + @Size(min = 1,max = 2,message = "模板名称最短为1,最长为10") + private String modelName; + + @ApiModelProperty("模板内容") + @TableField("model_content") + @Excel(name = "模板内容") + private String modelContent; + + @ApiModelProperty("场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @TableField("model_scene") + @Excel(name = "适用场景", dictType = "yw_notice_scene") + private String modelScene; + + @ApiModelProperty("创建用户id") + @TableField(value = "create_user_id", fill = FieldFill.INSERT) + private Long createUserId; + + @ApiModelProperty("创建用户昵称") + @TableField(value = "create_by", fill = FieldFill.INSERT) + private String createBy; + + @ApiModelProperty("创建时间") + @TableField(value = "create_time", fill = FieldFill.INSERT) + private LocalDateTime createTime; + + @ApiModelProperty("模板适用类型model_suit_type 1 普通 2 手工 3简报") + @TableField("model_suit_type") + @Excel(name = "适用类型", readConverterExp = "1=普通,2=手工,3=简报") + private String modelSuitType; + + @ApiModelProperty("备注(写一些触发要求)") + @TableField("model_des") + @Excel(name = "备注") + private String modelDes; + + @ApiModelProperty("模板类型--字典yw_model_type 0事件触发型") + @TableField("model_type") + @Excel(name = "模板类型", dictType = "yw_model_type") + private String modelType; + + @ApiModelProperty("排序号") + @TableField("order_num") + private Integer orderNum; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeObject.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeObject.java new file mode 100644 index 0000000..7e36de9 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeObject.java @@ -0,0 +1,103 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.ruoyi.common.mybatis.JsonListLongTypeHandler; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; + +/** + *

+ * 通知通告对象表 + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName(value = "yw_notice_object",autoResultMap = true) +@ApiModel(value = "YwNoticeObject对象", description = "通知通告对象表") +public class YwNoticeObject { + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("地市") + @TableField("city") + private String city; + + @ApiModelProperty("区县") + @TableField("county") + private String county; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; + + @ApiModelProperty("场馆名称") + @TableField(exist=false) + private String venueName; + + @ApiModelProperty("专业") + @TableField("specialty") + private Long specialty; + + @ApiModelProperty("角色id数组") + @TableField(value = "role_ids",typeHandler= JacksonTypeHandler.class) + private List roleIds; + + @ApiModelProperty("对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + private String objectProto; + + @ApiModelProperty("通知方式sys_notice_type") + @TableField("notice_type") + private String noticeType; + + @ApiModelProperty("短信组名") + @TableField("message_name") + private String messageName; + + @ApiModelProperty("短信组内成员id数组") + @TableField(value="message_users",typeHandler= JsonListLongTypeHandler.class) + private List messageUsers; + + @ApiModelProperty("排序号") + @TableField("order_num") + private Integer orderNum; + + @ApiModelProperty("群号") + @TableField("group_id") + private String groupId; + + @ApiModelProperty("群名") + @TableField("group_name") + private String groupName; + + @ApiModelProperty("备注") + @TableField("group_des") + private String groupDes; + + @ApiModelProperty("对象名称") + @TableField("object_name") + private String objectName; + + @ApiModelProperty("ivr组名") + @TableField("ivr_name") + private String ivrName; + + @ApiModelProperty("ivr组内成员id数组") + @TableField(value = "ivr_users",typeHandler= JsonListLongTypeHandler.class) + private List ivrUsers; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeUser.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeUser.java new file mode 100644 index 0000000..14110e5 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwNoticeUser.java @@ -0,0 +1,33 @@ +package com.ruoyi.eastcom_yw.domain; + + + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class YwNoticeUser implements Serializable { + + private static final long serialVersionUID=1L; + + private String flwProcessid; + + private String flwTaskid; + + private String title; + + private String content; + + private String userId; + + private String noticType; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectConfig.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectConfig.java new file mode 100644 index 0000000..8c3330c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectConfig.java @@ -0,0 +1,49 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author huamile + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("yw_rout_inspect_config") +public class YwRoutInspectConfig implements Serializable { + + private static final long serialVersionUID=1L; + + private Long id; + + private Long sceneId; + + private String specialty; + + private Integer checkNum; + + private String checkType; + + private String checkDesc; + + private Integer circle; + + private Long stopTimeOption; + + private Long intervalTime; + + private Long sceneBigId; + + private Integer inspectUserId; + + private String repWarnInterval; + + private String noticeType; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectLog.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectLog.java new file mode 100644 index 0000000..fa28d8b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectLog.java @@ -0,0 +1,41 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("yw_rout_inspect_log") +public class YwRoutInspectLog { + + private static final long serialVersionUID=1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private Long routInspectId; + + private String flwProcessid; + + private Integer checkNum; + + private Integer questionNum; + + private String questionDesc; + + private String feedBackUser; + + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date feedBackTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectPlan.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectPlan.java new file mode 100644 index 0000000..4ac1c46 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectPlan.java @@ -0,0 +1,66 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; + +/** + * @author huamile + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("yw_rout_inspect_plan") +public class YwRoutInspectPlan implements Serializable { + + private static final long serialVersionUID=1L; + + private Long id; + + private Long sceneId; + + private Date inspectDate; + + private String inspectSpecialty; + + private Date beginTime; + + private Date planFinTime; + + private Long sceneBigId; + + private Long type; + + private String inspectName; + + private Integer checkNum; + + private String checkType; + + private String checkDesc; + + private Integer circle; + + private Long stopTimeOption; + + private Long intervalTime; + + private Integer inspectUserId; + + private String repWarnInterval; + + private String noticeType; + + private String jobNo; + + @TableField(exist = false) + private String isGen; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectQuestionConfig.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectQuestionConfig.java new file mode 100644 index 0000000..832efdb --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwRoutInspectQuestionConfig.java @@ -0,0 +1,44 @@ +package com.ruoyi.eastcom_yw.domain; + +//import cn.afterturn.easypoi.excel.annotation.Excel; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.annotation.Excel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; + +/** + * @author huamile + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("yw_rout_inspect_question_config") +public class YwRoutInspectQuestionConfig { + + @Excel(name = "序号", width = 20, sort = 1) + private Long id; + + @Excel(name = "问题类型", width = 20, sort = 3) + @NotBlank(message = "问题类型不能为空") + private String questionType; + + @Excel(name = "问题子类型", width = 20, sort = 4) + @NotBlank(message = "问题子类型不能为空") + private String questionSonType; + + private Long sceneBigId; + + @NotBlank(message = "专业不能为空") + private String specialtyId; + + @Excel(name = "专业", width = 20, sort = 2) + @TableField(exist = false) + private String specialtyName; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwScene.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwScene.java new file mode 100644 index 0000000..75e2583 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwScene.java @@ -0,0 +1,169 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import java.io.Serializable; +import java.util.List; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.annotation.Excel; +import lombok.*; + +/** + *

+ * + *

+ * + * @author jkj + * @since 2023-01-12 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("yw_scene") +public class YwScene implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * 序号 + */ + @TableId(value = "id", type = IdType.AUTO) + @Excel(name = "场馆ID", type = Excel.Type.IMPORT, sort = 0) + private Long id; + + /** + * 场馆名称 + */ + @Excel(name = "场馆标准名称", type = Excel.Type.IMPORT, sort = 1) + private String venueName; + + /** + * 场馆介绍 + */ + @Excel(name = "备注", type = Excel.Type.IMPORT, sort = 15) + private String venueDesc; + + /** + * 场馆地址 + */ + @Excel(name = "地址", type = Excel.Type.IMPORT, sort = 14) + private String venueAddress; + + /** + * 所属区县id + */ + private String areaCountyId; + + @TableField(exist = false) + @Excel(name = "所属区县", type = Excel.Type.IMPORT, sort = 12) + private String county; + + /** + * 纬度 + */ + @Excel(name = "纬度GPS", type = Excel.Type.IMPORT, sort = 8) + private Double latitude; + + /** + * 经度 + */ + @Excel(name = "经度GPS", type = Excel.Type.IMPORT, sort = 7) + private Double longitude; + + /** + * 类型 + */ + @Excel(name = "场馆属性", type = Excel.Type.IMPORT, sort = 5) + private String venueType; + + /** + * 级别 + */ + @Excel(name = "场馆级别", type = Excel.Type.IMPORT, sort = 6) + private String venueLevel; + + /** + * 容纳人数 + */ + private Integer accPerson; + + /** + * 场景ID + */ + private Long sceneBigId; + + /** + * 签到范围 + */ + private Integer signScope; + + /** + * 1开 0关 + */ + private String status; + + private String createBy; + + private String createTime; + + private String updateBy; + + private String updateTime; + + /** + * 简称 + */ + @Excel(name = "场馆简称", type = Excel.Type.IMPORT, sort = 2) + private String venueShortname; + + /** + * 地市 + */ + private String cityId; + + @Excel(name = "所属地市", type = Excel.Type.IMPORT, sort = 11) + @TableField(exist = false) + private String cityName; + + /** + * 英文名称 + */ + private String englishName; + + /** + * 英文简称 + */ + @Excel(name = "场馆英文缩写", type = Excel.Type.IMPORT, sort = 3) + private String englishShortname; + + /** + * 维护类型 + */ + @Excel(name = "维护类别", type = Excel.Type.IMPORT, sort = 4) + private String maintainType; + + /** + * GCJ02纬度 + */ + @Excel(name = "纬度GCJ02", type = Excel.Type.IMPORT, sort = 10) + private Double latitudeGcj02; + + /** + * GCJ02经度 + */ + @Excel(name = "经度GCJ02", type = Excel.Type.IMPORT, sort = 9) + private Double longitudeGcj02; + + /** + * 赛事类型 + */ + @Excel(name = "赛事类型", type = Excel.Type.IMPORT, sort = 13) + private String matchType; + + @TableField(exist = false) + private List ywSceneFile; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneAlarm.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneAlarm.java new file mode 100644 index 0000000..0a6008c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneAlarm.java @@ -0,0 +1,33 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author huamile + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("yw_scene_alarm") +public class YwSceneAlarm { + + private Long id; + + private Long sceneId; + + private String alarmCode; + + private String alarmName; + + private String blackorwhite; + + private String alarmSpecityId; + + private String status; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneBigConfig.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneBigConfig.java new file mode 100644 index 0000000..cbbd9d4 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneBigConfig.java @@ -0,0 +1,45 @@ +package com.ruoyi.eastcom_yw.domain; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * @author huamile + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("yw_scene_big_config") +public class YwSceneBigConfig { + + private Long id; + + @Excel(name = "场景名称",width = 20,orderNum = "0") + private String name; + + private String createBy; + + private Date createTime; + + private String updateBy; + + private Date updateTime; + + @Excel(name = "备注",width = 20,isImportField = "true_st",orderNum = "1") + private String remark; + + private String status; + + @TableField(exist = false) + @Excel(name = "状态",width = 20,isImportField = "true_st",orderNum = "2") + private String statusName; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneCalendar.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneCalendar.java new file mode 100644 index 0000000..9c4d21a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneCalendar.java @@ -0,0 +1,62 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * @author huamile + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("yw_scene_calendar") +public class YwSceneCalendar { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private Long sceneId; + + private String matchType; + + private String matchName; + + private String matchRemark; + + @JsonFormat(pattern = "HH:mm:ss", timezone = "GMT+8", locale = "zh") + private Date beginTime; + + @JsonFormat(pattern = "HH:mm:ss", timezone = "GMT+8", locale = "zh") + private Date endTime; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8", locale = "zh") + private Date matchDate; + + private String status; + + private String createBy; + + private Date createTime; + + private String updateBy; + + private Date updateTime; + + private String goldPoint; + + @TableField(exist = false) + private String url; + + @TableField(exist = false) + private String scenePictureUrl; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneFile.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneFile.java new file mode 100644 index 0000000..29a74b9 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneFile.java @@ -0,0 +1,47 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * @author huamile + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("yw_scene_file") +public class YwSceneFile { + +// private Long id; + + private Long fileId; + + private Long sceneId; + + private String remark; + + private Long createBy; + + private Date createTime; + + private Long updateBy; + + private Date updateTime; + + private String fileName; + + private Long fileSize; + + private String fileUrl; + + private String fileType; + + private String fileResolution; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneNetelement.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneNetelement.java new file mode 100644 index 0000000..2676b52 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneNetelement.java @@ -0,0 +1,78 @@ +package com.ruoyi.eastcom_yw.domain; + +//import cn.afterturn.easypoi.excel.annotation.Excel; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.annotation.Excel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author huamile + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("yw_scene_netelement") +public class YwSceneNetelement { + + private Long id; + + private Long sceneId; + + @Excel(name = "场馆名称",width = 20,sort = 1) + @TableField(exist = false) + private String venueName; + + @Excel(name = "网元名称",width = 20,sort = 2) + private String netElementName; + + private String alarmSpecityId; + + @Excel(name = "专业",width = 20,sort = 3) + @TableField(exist = false) + private String specialty; + + @Excel(name = "网元编号",width = 20,sort = 4) + private String netElementCode; + + @Excel(name = "网元经度",width = 20,sort = 5) + private Float netElementLat; + + @Excel(name = "网元纬度",width = 20,sort = 6) + private Float netElementLon; + + @Excel(name = "网元类型",width = 20,sort = 7) + private String type; + + private String status; + + @Excel(name = "状态",width = 20,sort = 8) + @TableField(exist = false) + private String statusName; + + @Excel(name = "物理站名",width = 20,sort = 9) + private String netElementPhyname; + + @Excel(name = "是否红线内",width = 20,sort = 10) + private String inRedline; + + @Excel(name = "黑白名单",width = 20,sort = 11) + private String blackorwhite; + + @Excel(name = "机房",width = 20,sort = 12) + private String room; + + @Excel(name = "端口",width = 20,sort = 13) + private String port; + + @Excel(name = "网元中文名称",width = 20,sort = 14) + private String netElementCname; + + @Excel(name = "小区ci",width = 20,sort = 15) + private String ci; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneTestData.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneTestData.java new file mode 100644 index 0000000..e69ed3d --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneTestData.java @@ -0,0 +1,22 @@ +package com.ruoyi.eastcom_yw.domain; + +import lombok.Data; + +import java.util.Date; + +@Data +public class YwSceneTestData { + private Long id; + private String bzname; + private String scenename; + private String deviceoid; + private Float connectdelay; + private Float dlspeed; + private Float lat; + private Float lng; + private Float pagecomplete; + private Float ulspeed; + private Date updateTime; + private String nettype; + private Integer sceneId; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneUser.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneUser.java new file mode 100644 index 0000000..3ae4dd1 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneUser.java @@ -0,0 +1,61 @@ +package com.ruoyi.eastcom_yw.domain; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; +import java.util.List; + +/** + * @author huamile + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("yw_scene_user") +public class YwSceneUser { + + @TableId(value = "id",type = IdType.AUTO) + private Long id; + + private Long sceneId; + + @TableField(exist = false) + @Excel(name = "场馆名称",isImportField = "true_st",width = 20) + private String venueName; + + private Long userId; + + @TableField(exist = false) + @Excel(name = "用户名",isImportField = "true_st",width = 20) + private String userName; + + @Excel(name = "所属区域",isImportField = "true_st",width = 20) + private String belongArea; + + @Excel(name = "是否需要签到",isImportField = "true_st",width = 20) + private String needSign; + + @TableField(exist = false) + private List userIds; + + private String updateBy; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private Date updateTime; + + private String createBy; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private Date createTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneView.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneView.java new file mode 100644 index 0000000..2c85698 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSceneView.java @@ -0,0 +1,42 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.annotation.Excel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

+ * + *

+ * + * @author jkj + * @since 2023-01-12 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("v_yw_scene") +public class YwSceneView implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * 序号 + */ + private Long id; + + /** + * 场馆名称 + */ + private String venueName; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignLog.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignLog.java new file mode 100644 index 0000000..a419bb4 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignLog.java @@ -0,0 +1,39 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + + +import java.sql.Timestamp; +import java.util.Date; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("yw_sign_log") +public class YwSignLog { + + @TableId(value = "id") + private Long id; + + private Long signPlanId; + + private Long userId; + + private Date signTime; + + private Double signJ; + + private Double signW; + + private Long isDaiSign; + + private String signType; + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignLogView.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignLogView.java new file mode 100644 index 0000000..bc161ef --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignLogView.java @@ -0,0 +1,78 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + + +import java.sql.Timestamp; +import java.util.Date; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("v_yw_sign_log") +public class YwSignLogView { + + private Long signPlanId; + + private String signDate; + + private Date beginTime; + + private Date endTime; + + private Long userId; + + private String nickName; + + private String userTypeName; + + private String userType; + + private Long sceneId; + + private String venueName; + + private String areaCountyId; + + private String city; + + private String county; + + private Date signInTime; + + private Double signInJ; + + private Double signInW; + + private Long isDaiSignIn; + + private Date signOutTime; + + private Double signOutJ; + + private Double signOutW; + + private Long isDaiSignOut; + + private String signType; + + private String signStatus; + + private String checkType; + + private String belongArea; + + private Double latitude; + + private Double longitude; + + private Integer signScope; + + private Date genTime; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignPlan.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignPlan.java new file mode 100644 index 0000000..7d255b2 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignPlan.java @@ -0,0 +1,47 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("yw_sign_plan") +public class YwSignPlan { + + @TableId(value = "id") + private Long id; + + private Long sceneId; + + private Date signDate; + + private Date beginTime; + + private Date endTime; + + private String repWarnInterval; + + private Integer repSignInterval; + + private Long sceneBigId; + + private String isOpen; + + private String noticeType; + + private Integer signNum; + + private String signUsers; + + private Date updateTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignPlanRemind.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignPlanRemind.java new file mode 100644 index 0000000..2221942 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignPlanRemind.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.domain; + + + +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +@Data +public class YwSignPlanRemind extends YwSignPlan implements Serializable { + + private static final long serialVersionUID=1L; + + private Long userId; + + private String phoneNumber; + + private Date remindTime; + + private String noticeTitle; + + private String noticeContent; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignPlanView.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignPlanView.java new file mode 100644 index 0000000..aacb2c7 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSignPlanView.java @@ -0,0 +1,37 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@TableName("v_yw_sign_plan") +public class YwSignPlanView extends YwSignPlan{ + + private String noticeTypeName; + + private String venueName; + + private Double latitude; + + private Double longitude; + + private Integer signScope; + + private String areaCountyId; + + private String city; + + private String county; + + private String venueType; + + private String maintainType; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSpareParts.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSpareParts.java new file mode 100644 index 0000000..c17fda9 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwSpareParts.java @@ -0,0 +1,105 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; + +/** + *

+ * 亚运备件表 + *

+ * + * @author yqf + * @since 2023-08-31 + */ +@Data +@TableName("yw_spare_parts") +@ApiModel(value = "YwSpareParts对象", description = "亚运备件表") +public class YwSpareParts { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("序号") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("场馆名称") + @TableField("venue_name") + private String venueName; + + @ApiModelProperty("场馆类型") + @TableField("venue_type") + private String venueType; + + @ApiModelProperty("设备类型") + @TableField("device_type") + private String deviceType; + + @ApiModelProperty("单板型号") + @TableField("board_model") + private String boardModel; + + @ApiModelProperty("通用数量") + @TableField("current_num") + private String currentNum; + + @ApiModelProperty("单板数量") + @TableField("board_num") + private String boardNum; + + @ApiModelProperty("备件型号") + @TableField("part_model") + private String partModel; + + @ApiModelProperty("需求数量") + @TableField("need_num") + private String needNum; + + @ApiModelProperty("配置数量") + @TableField("configure_num") + private String configureNum; + + @ApiModelProperty("缺口") + @TableField("gap_num") + private String gapNum; + + @ApiModelProperty("专业") + @TableField("major") + private String major; + + @ApiModelProperty("备注") + @TableField("comment") + private String comment; + + @ApiModelProperty("联系人") + @TableField("contacts") + private String contacts; + + @ApiModelProperty("联系电话") + @TableField("telephone") + private String telephone; + + @ApiModelProperty("创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty("创建时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty("更新人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty("更新时间") + @TableField("update_time") + private LocalDateTime updateTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwWireTaskLog.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwWireTaskLog.java new file mode 100644 index 0000000..907b033 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/YwWireTaskLog.java @@ -0,0 +1,103 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + + +import java.util.Date; + +/** + * @author jkj + * @since 2023-02-07 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("v_yw_wire_task_log") +public class YwWireTaskLog { + + /** + * 序号 + */ + @TableId(value = "id") + private Long id; + + /** + * 工作流processid + */ + private String flwProcessid; + + private String taskId; + + /** + * 创建人 + */ + private Long createBy; + + private String createName; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 结束时间 + */ + private Date endTime; + + /** + * 施工单位 + */ + private String construcUnit; + + /** + * 任务主id:场馆id-时间戳 + */ + private String wireTaskId; + + private String wireTaskName; + + /** + * 任务类型:1:布线,2:拆线,3:布线结算 4:拆线结算 + */ + private Integer taskType; + + private String dealUser; + + private String curStep; + + private String dealStatus; + + private Long venueId; + + private String venueName; + + private String city; + + private String county; + + private String roleKey; + + private Integer isRemove; + + private Integer isSettle; + + private String report; + + private Integer taskSubType; + + private String matchId; + + private String areaCountyId; + + private String venueType; + + private String maintainType; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/CommonDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/CommonDTO.java new file mode 100644 index 0000000..3c0cf38 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/CommonDTO.java @@ -0,0 +1,16 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import lombok.Data; + +@Data +public class CommonDTO { + + private Integer pageNum = 1; + + private Integer pageSize = 10; + + private PageSizesDTO pageSizes; + + private PageNumsDTO pageNums; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2SpotCellDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2SpotCellDTO.java new file mode 100644 index 0000000..8d70d02 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2SpotCellDTO.java @@ -0,0 +1,135 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + *

+ * DTO + *

+ * + * @author ck + * @since 2023-08-10 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Dp2SpotCellDTO { + + + private static final long serialVersionUID = 1L; + + @TableField("id") + private Integer id; + + @TableField("omc") + private String omc; + + @ApiModelProperty("需要") + @TableField("县市") + private String 县市; + + @TableField("enodebid") + private Long enodebid; + + @TableField("本地小区标识") + private Long 本地小区标识; + + @TableField("小区标识") + private Long 小区标识; + + @ApiModelProperty("需要") + @TableField("站号") + private Long 站号; + + @ApiModelProperty("需要") + @TableField("ci") + private Long ci; + + @ApiModelProperty("需要") + @TableField("基站全称") + private String 基站全称; + + @TableField("en名称") + private String en名称; + + @ApiModelProperty("需要") + @TableField("小区名称") + private String 小区名称; + + @ApiModelProperty("需要") + @TableField("小区频段") + private String 小区频段; + + @ApiModelProperty("需要") + @TableField("纬度") + private Double 纬度; + + @ApiModelProperty("需要") + @TableField("经度") + private Double 经度; + + @TableField("纬度gcj") + private Double 纬度gcj; + + @TableField("经度gcj") + private Double 经度gcj; + + @ApiModelProperty("需要") + @TableField("室内室外") + private String 室内室外; + + @ApiModelProperty("需要") + @TableField("网络") + private String 网络; + + @TableField("现网状态") + private String 现网状态; + + @TableField("cgi") + private String cgi; + + @TableField("频点") + private Long 频点; + + @TableField("pci") + private Long pci; + + @TableField("tac") + private Long tac; + + @TableField("一级场景") + private String 一级场景; + + @TableField("二级场景") + private String 二级场景; + + @ApiModelProperty("需要") + @TableField("设备类型") + private String 设备类型; + + @ApiModelProperty("需要") + @TableField("带宽") + private Long 带宽; + + @ApiModelProperty("需要") + @TableField("方位角") + private Long 方位角; + + @TableField("扇区id") + private Long 扇区id; + + @TableField("更新时间") + private LocalDateTime 更新时间; + + @ApiModelProperty("景区ID,需要") + @TableField("景区id") + private Integer 景区id; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2SpotConfigDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2SpotConfigDTO.java new file mode 100644 index 0000000..13dfdd8 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2SpotConfigDTO.java @@ -0,0 +1,49 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * DTO + *

+ * + * @author ck + * @since 2023-08-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Dp2SpotConfigDTO { + + + private static final long serialVersionUID = 1L; + + @TableField("景区id") + private Integer 景区id; + + @TableField("景区名称") + private String 景区名称; + + @TableField("行政区域") + private String 行政区域; + + @TableField("中心经度") + private Object 中心经度; + + @TableField("中心纬度") + private Object 中心纬度; + + @TableField("景区介绍") + private String 景区介绍; + + @TableField("景区大类") + private String 景区大类; + + @TableField("景区大类id") + private Integer 景区大类id; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2ViewPowerAlarmDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2ViewPowerAlarmDTO.java new file mode 100644 index 0000000..2d866ad --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2ViewPowerAlarmDTO.java @@ -0,0 +1,83 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * DTO + *

+ * + * @author wqx + * @since 2023-08-31 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Dp2ViewPowerAlarmDTO { + + + private static final long serialVersionUID = 1L; + + @TableField("eventtime") + private LocalDateTime eventtime; + + @TableField("alarmname") + private String alarmname; + + @TableField("alarmid") + private Long alarmid; + + @TableField("severity") + private String severity; + + @TableField("site_id") + private String siteId; + + @TableField("site_name") + private String siteName; + + @TableField("device_name") + private String deviceName; + + @TableField("owner") + private String owner; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("area") + private String area; + + @TableField("logicalsites") + private String logicalsites; + + @TableField("场馆id") + private Integer 场馆id; + + @TableField("区域id") + private Integer 区域id; + + @TableField("场馆名称") + private String 场馆名称; + + @TableField("故障处理人") + private String 故障处理人; + + @TableField("phonenumber") + private String phonenumber; + + @TableField("deal_status") + private Integer deal_status; + + @TableField("deal_time") + private LocalDateTime deal_time; + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2ViewWirelessAlarmDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2ViewWirelessAlarmDTO.java new file mode 100644 index 0000000..8be497f --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/Dp2ViewWirelessAlarmDTO.java @@ -0,0 +1,89 @@ +package com.ruoyi.eastcom_yw.domain.dto; + + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * DTO + *

+ * + * @author wqx + * @since 2023-09-01 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Dp2ViewWirelessAlarmDTO { + + + private static final long serialVersionUID = 1L; + + @TableField("id") + private Long id; + + @TableField("eventtime") + private LocalDateTime eventtime; + + @TableField("alarmname") + private String alarmname; + + @TableField("omcname") + private String omcname; + + @TableField("site_id") + private String siteId; + + @TableField("site_name") + private String siteName; + + @TableField("area") + private String area; + + @TableField("alarmid") + private String alarmid; + + @TableField("sitetype") + private String sitetype; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("cell_name") + private String cellName; + + @TableField("场馆id") + private Long 场馆id; + + @TableField("场馆名称") + private String 场馆名称; + + @TableField("longitude") + private Object longitude; + + @TableField("latitude") + private Object latitude; + + @TableField("坐席编号") + private String 坐席编号; + + @TableField("场内场外") + private String 场内场外; + + @TableField("区域id") + private Integer 区域id; + + @TableField("故障处理人") + private String 故障处理人; + + @TableField("phonenumber") + private String phonenumber; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/DpSceneConfigDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/DpSceneConfigDTO.java new file mode 100644 index 0000000..c842eed --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/DpSceneConfigDTO.java @@ -0,0 +1,75 @@ +package com.ruoyi.eastcom_yw.domain.dto; + + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; + +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * DTO + *

+ * + * @author yqf + * @since 2023-04-12 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DpSceneConfigDTO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("自增id") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("颜色等级") + @TableField("level") + private Short level; + + @ApiModelProperty("指标名称") + @TableField("name") + private String name; + + @ApiModelProperty("最小值") + @TableField("range1") + private Object range1; + + @ApiModelProperty("最大值") + @TableField("range2") + private Object range2; + + @ApiModelProperty("颜色") + @TableField("color") + private String color; + + @ApiModelProperty("备注") + @TableField("content") + private String content; + + @ApiModelProperty("指标等级:cell、scene") + @TableField("type") + private String type; + + @ApiModelProperty("网络类型") + @TableField("nettype") + private String nettype; + + @ApiModelProperty("小区类型") + @TableField("celltype") + private String celltype; + + @ApiModelProperty("颜色分值") + @TableField("colorscore") + private Double colorscore; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/MmlObjectDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/MmlObjectDTO.java new file mode 100644 index 0000000..badf336 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/MmlObjectDTO.java @@ -0,0 +1,19 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author yqf + * @date 2023/6/6 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class MmlObjectDTO { + private String 基站名; + private List 指令集; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PageNumsDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PageNumsDTO.java new file mode 100644 index 0000000..ab5fa02 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PageNumsDTO.java @@ -0,0 +1,16 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import lombok.Data; + +@Data +public class PageNumsDTO { + + private Integer cs; + + private Integer dh; + + private Integer agis; + + private Integer wx; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PageSizesDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PageSizesDTO.java new file mode 100644 index 0000000..c47b9d6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PageSizesDTO.java @@ -0,0 +1,16 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import lombok.Data; + +@Data +public class PageSizesDTO { + + private Integer cs; + + private Integer dh; + + private Integer agis; + + private Integer wx; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi4gCellDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi4gCellDTO.java new file mode 100644 index 0000000..71d2ee2 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi4gCellDTO.java @@ -0,0 +1,185 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 场馆4G小区级15分钟指标DTO + *

+ * + * @author yqf + * @since 2023-04-11 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi4gCellDTO { + + + private static final long serialVersionUID = 1L; + +// @ApiModelProperty("id") +// @TableField("id") +// private Long id; + + @TableField("venue_id") + private Integer venueId; + + @TableField("venue_name") + private String venueName; + + @TableField("cellcodeci") + private String cellcodeci; + + @TableField("starttime") + private LocalDateTime starttime; + + @TableField("input_datetime") + private LocalDateTime inputDatetime; + + @TableField("小区名称") + private String 小区名称; + + @TableField("上行流量mb") + private BigDecimal 上行流量mb; + + @TableField("下行流量mb") + private BigDecimal 下行流量mb; + + @TableField("有效rrc连接平均数") + private BigDecimal 有效rrc连接平均数; + + @TableField("有效rrc连接最大数") + private BigDecimal 有效rrc连接最大数; + + @TableField("平均用户数") + private BigDecimal 平均用户数; + + @TableField("最大用户数") + private BigDecimal 最大用户数; + + @TableField("volte话务量") + private BigDecimal volte话务量; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率; + + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率; + + @TableField("上行平均干扰") + private BigDecimal 上行平均干扰; + + @TableField("rrc建立成功率") + private BigDecimal rrc建立成功率; + + @TableField("e_rab建立成功率") + private BigDecimal eRab建立成功率; + + @TableField("qci为1的e_rab建立成功率") + private BigDecimal qci为1的eRab建立成功率; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率; + + @TableField("掉线次数") + private BigDecimal 掉线次数; + + @TableField("切换成功率") + private BigDecimal 切换成功率; + + @TableField("esrvcc切换成功率") + private BigDecimal esrvcc切换成功率; + + @TableField("esrvcc切换请求次数") + private BigDecimal esrvcc切换请求次数; + + @TableField("rrc重建成功率") + private BigDecimal rrc重建成功率; + + @TableField("rrc重建次数") + private BigDecimal rrc重建次数; + + @TableField("volte掉话率") + private BigDecimal volte掉话率; + + @TableField("volte掉话次数") + private BigDecimal volte掉话次数; + + @TableField("rru_puschprbassn") + private BigDecimal rruPuschprbassn; + + @TableField("rru_puschprbtot") + private BigDecimal rruPuschprbtot; + + @TableField("rru_pdschprbassn") + private BigDecimal rruPdschprbassn; + + @TableField("rru_pdschprbtot") + private BigDecimal rruPdschprbtot; + + @TableField("rrc_succconnestab") + private BigDecimal rrcSuccconnestab; + + @TableField("rrc_attconnestab") + private BigDecimal rrcAttconnestab; + + @TableField("erab_nbrsuccestab_1") + private BigDecimal erabNbrsuccestab1; + + @TableField("erab_nbrattestab") + private BigDecimal erabNbrattestab; + + @TableField("erab_nbrattestab_1") + private BigDecimal erabNbrattestab1; + + @TableField("切换成功率_分母") + private BigDecimal 切换成功率分母; + + @TableField("切换成功率_分子") + private BigDecimal 切换成功率分子; + + @TableField("掉线率_分母") + private BigDecimal 掉线率分母; + + @TableField("iratho_succoutgeran") + private BigDecimal irathoSuccoutgeran; + + @TableField("rrc_attconnreestab") + private BigDecimal rrcAttconnreestab; + + @TableField("volte掉话率_分母") + private BigDecimal volte掉话率分母; + + @TableField("erab_nbrsuccestab") + private BigDecimal erabNbrsuccestab; + + @TableField("omcname") + private String omcname; + + @TableField("无线接通率") + private BigDecimal 无线接通率; + + @TableField("rrc_failconnestab") + private BigDecimal rrcFailconnestab; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("groupid") + private Long groupid; + + @TableField("endtime") + private LocalDateTime endtime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi4gMinDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi4gMinDTO.java new file mode 100644 index 0000000..1c80682 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi4gMinDTO.java @@ -0,0 +1,102 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 场馆4G小区级1分钟指标DTO + *

+ * + * @author yqf + * @since 2023-04-12 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi4gMinDTO { + + + private static final long serialVersionUID = 1L; + + + @TableField("groupid") + private Integer groupid; + + @TableField("时间") + private LocalDateTime 时间; + + @TableField("小区名称") + private String 小区名称; + + @TableField("地市区号") + private String 地市区号; + + @TableField("厂商id") + private String 厂商id; + + @TableField("avg_user") + private BigDecimal avgUser; + + @TableField("max_user") + private Integer maxUser; + + @TableField("prb_up") + private BigDecimal prbUp; + + @TableField("prb_down") + private BigDecimal prbDown; + + @TableField("avg_disturb") + private Integer avgDisturb; + + @TableField("speed_up") + private BigDecimal speedUp; + + @TableField("speed_down") + private BigDecimal speedDown; + + @TableField("call_succ_rate") + private BigDecimal callSuccRate; + + @TableField("call_drop_rate") + private BigDecimal callDropRate; + + @TableField("act_avg_user") + private BigDecimal actAvgUser; + + @TableField("act_max_user") + private Integer actMaxUser; + + @TableField("volte") + private BigDecimal volte; + + @TableField("volte_succ_rate") + private BigDecimal volteSuccRate; + + @TableField("volte_drop_rate") + private BigDecimal volteDropRate; + + @TableField("data_up") + private BigDecimal dataUp; + + @TableField("data_down") + private BigDecimal dataDown; + + @TableField("v1_max") + private BigDecimal v1Max; + + @TableField("v1_avg") + private String v1Avg; + + @TableField("update_time") + private LocalDateTime updateTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi4gVenueDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi4gVenueDTO.java new file mode 100644 index 0000000..b5395a4 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi4gVenueDTO.java @@ -0,0 +1,75 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi4gVenueDTO { + + private static final long serialVersionUID = 1L; + + + @TableId("id") + private Long id; + + @TableField("开始时间") + private LocalDateTime 开始时间; + + @TableField("入库时间") + private LocalDateTime 入库时间; + + @TableField("区县") + private String 区县; + + @TableField("场馆id") + private Integer 场馆id; + + @TableField("无线接通率") + private BigDecimal 无线接通率; + + @TableField("流量GB") + private Short 流量GB; + + @TableField("最大用户数") + private Short 最大用户数; + + @TableField("话务量") + private Short 话务量; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率; + + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率; + + @TableField("上行平均干扰") + private Short 上行平均干扰; + + @TableField("volte接通率") + private BigDecimal volte接通率; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("结束时间") + private LocalDateTime 结束时间; + + @TableField("平均用户数") + private BigDecimal 平均用户数; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi5gCellDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi5gCellDTO.java new file mode 100644 index 0000000..0ec97d0 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi5gCellDTO.java @@ -0,0 +1,170 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 场馆5G小区级15分钟指标DTO + *

+ * + * @author yqf + * @since 2023-04-11 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi5gCellDTO { + + + private static final long serialVersionUID = 1L; + +// @ApiModelProperty("id") +// @TableField("id") +// private Long id; + + @TableField("venue_id") + private Integer venueId; + + @TableField("venue_name") + private String venueName; + + @TableField("ci") + private String ci; + + @TableField("starttime") + private LocalDateTime starttime; + + @TableField("小区名称") + private String 小区名称; + + @TableField("nr流量") + private Short nr流量; + + @TableField("上行5g流量") + private Short 上行5g流量; + + @TableField("下行5g流量") + private Short 下行5g流量; + + @TableField("小区rlc层下行丢包率") + private BigDecimal 小区rlc层下行丢包率; + + @TableField("小区级rlc层sdu下行空口丢包数") + private Short 小区级rlc层sdu下行空口丢包数; + + @TableField("小区rlc层收到的下行sdu包数") + private Short 小区rlc层收到的下行sdu包数; + + @TableField("平均用户数") + private Short 平均用户数; + + @TableField("最大用户数") + private Short 最大用户数; + + @TableField("sn异常释放率") + private BigDecimal sn异常释放率; + + @TableField("sgnb释放总次数") + private Short sgnb释放总次数; + + @TableField("sgnb触发sgnb异常释放总次数") + private Short sgnb触发sgnb异常释放总次数; + + @TableField("nsa_sgnb添加成功率") + private BigDecimal nsaSgnb添加成功率; + + @TableField("dc场景下发送sgnb增加成功的次数") + private Short dc场景下发送sgnb增加成功的次数; + + @TableField("dc场景下收到sgnb增加尝试的次数") + private Short dc场景下收到sgnb增加尝试的次数; + + @TableField("无线接通率") + private BigDecimal 无线接通率; + + @TableField("rrc建立成功次数") + private Short rrc建立成功次数; + + @TableField("rrc建立请求消息次数") + private Short rrc建立请求消息次数; + + @TableField("小区中qos_flow建立成功次数") + private Short 小区中qosFlow建立成功次数; + + @TableField("小区中qos_flow建立尝试次数") + private Short 小区中qosFlow建立尝试次数; + + @TableField("小区中ng信令连接建立成功次数") + private Short 小区中ng信令连接建立成功次数; + + @TableField("小区中ng信令连接建立尝试次数") + private Short 小区中ng信令连接建立尝试次数; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率; + + @TableField("小区中ue上下文异常释放的次数") + private Short 小区中ue上下文异常释放的次数; + + @TableField("小区中ue上下文正常释放的次数") + private Short 小区中ue上下文正常释放的次数; + + @TableField("无线掉线率分母") + private Short 无线掉线率分母; + + @TableField("切换成功率") + private BigDecimal 切换成功率; + + @TableField("切换成功率分子") + private Short 切换成功率分子; + + @TableField("切换成功率分母") + private Short 切换成功率分母; + + @TableField("下行平均使用的prb个数") + private Short 下行平均使用的prb个数; + + @TableField("下行平均可用prb个数") + private Short 下行平均可用prb个数; + + @TableField("上行平均使用的prb个数") + private Short 上行平均使用的prb个数; + + @TableField("上行平均可用prb个数") + private Short 上行平均可用prb个数; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率; + + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率; + + @TableField("input_datetime") + private LocalDateTime inputDatetime; + + @TableField("cell_name") + private String cellName; + + @TableField("pmsid") + private Long pmsid; + + @TableField("上行干扰值") + private Double 上行干扰值; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("endtime") + private LocalDateTime endtime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi5gMinDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi5gMinDTO.java new file mode 100644 index 0000000..5a0d76b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi5gMinDTO.java @@ -0,0 +1,88 @@ +package com.ruoyi.eastcom_yw.domain.dto; + + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 场馆5G小区级1分钟指标DTO + *

+ * + * @author yqf + * @since 2023-04-12 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi5gMinDTO { + + + private static final long serialVersionUID = 1L; + + + @TableField("groupid") + private Integer groupid; + + @TableField("时间") + private LocalDateTime 时间; + + @TableField("小区名称") + private String 小区名称; + + @TableField("地市区号") + private String 地市区号; + + @TableField("厂商id") + private String 厂商id; + + @TableField("prb_up") + private Double prbUp; + + @TableField("prb_down") + private Double prbDown; + + @TableField("up_disturb") + private Integer upDisturb; + + @TableField("speed_up") + private Double speedUp; + + @TableField("speed_down") + private Double speedDown; + + @TableField("act_max_user") + private Integer actMaxUser; + + @TableField("act_avg_user") + private Double actAvgUser; + + @TableField("rrc_avg_user") + private BigDecimal rrcAvgUser; + + @TableField("rrc_max_user") + private Integer rrcMaxUser; + + @TableField("call_succ_rate") + private BigDecimal callSuccRate; + + @TableField("drop_call_rate") + private BigDecimal dropCallRate; + + @TableField("data_down") + private BigDecimal dataDown; + + @TableField("data_up") + private BigDecimal dataUp; + + @TableField("update_time") + private LocalDateTime updateTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi5gVenueDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi5gVenueDTO.java new file mode 100644 index 0000000..e9dfba9 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/PmKpi5gVenueDTO.java @@ -0,0 +1,88 @@ +package com.ruoyi.eastcom_yw.domain.dto; + + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 5G场馆级15分钟指标DTO + *

+ * + * @author yqf + * @since 2023-04-12 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi5gVenueDTO { + + + private static final long serialVersionUID = 1L; + + @TableId("id") + private Long id; + + @TableField("开始时间") + private LocalDateTime 开始时间; + + @TableField("入库时间") + private LocalDateTime 入库时间; + + @TableField("区县") + private String 区县; + + @TableField("场馆id") + private Integer 场馆id; + + @TableField("无线接通率") + private BigDecimal 无线接通率; + + @TableField("nsa_sgnb添加成功率") + private BigDecimal nsaSgnb添加成功率; + + @TableField("切换成功率") + private BigDecimal 切换成功率; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率; + + @TableField("sn异常释放率") + private BigDecimal sn异常释放率; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率; + + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率; + + @TableField("流量GB") + private BigDecimal 流量GB; + + @TableField("最大用户数") + private Short 最大用户数; + + @TableField("话务量") + private BigDecimal 话务量; + + @TableField("上行干扰值") + private Double 上行干扰值; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("结束时间") + private LocalDateTime 结束时间; + + @TableField("平均用户数") + private BigDecimal 平均用户数; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/SysNoticeDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/SysNoticeDTO.java new file mode 100644 index 0000000..8e63961 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/SysNoticeDTO.java @@ -0,0 +1,131 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知公告表DTO + *

+ * + * @author ck + * @since 2023-04-14 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SysNoticeDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增id") + @TableId(value = "notice_id", type = IdType.AUTO) + private Integer noticeId; + + @ApiModelProperty("通知标题") + @TableField("notice_title") + private String noticeTitle; + + @ApiModelProperty("通知类型--字典表sys_notice_type") + @TableField("notice_type") + private String noticeType; + + @ApiModelProperty("通知内容") + @TableField("notice_content") + private String noticeContent; + + @ApiModelProperty("状态 0未读 1已读") + @TableField("status") + private String status; + + @ApiModelProperty("创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty("插入时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty("更新人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty("更新时间") + @TableField("update_time") + private LocalDateTime updateTime; + + @ApiModelProperty("备注") + @TableField("remark") + private String remark; + + @ApiModelProperty("接收人") + @TableField("recive_user") + private Integer reciveUser; + + @ApiModelProperty("工作流id") + @TableField("flw_processid") + private String flwProcessid; + + @ApiModelProperty("工作流任务id") + @TableField("flw_taskid") + private String flwTaskid; + + @ApiModelProperty("实际发送时间") + @TableField("send_time") + private LocalDateTime sendTime; + + @ApiModelProperty("发送是否成功,1成功 0失败") + @TableField("send_status") + private String sendStatus; + + @ApiModelProperty("接收人手机号") + @TableField("recive_user_phone") + private String reciveUserPhone; + + @ApiModelProperty("计划发送时间(同天当前时间之前立即发送)") + @TableField("exp_send_time") + private LocalDateTime expSendTime; + + @ApiModelProperty("加入定时任务标记 默认0未加入 1已加入") + @TableField("add_flag") + private String addFlag; + + @ApiModelProperty("通知对象ids数组") + @TableField("notice_object_id") + private List noticeObjectId; + + @ApiModelProperty("通知模板id") + @TableField("notice_model_id") + private Long noticeModelId; + + @ApiModelProperty("通知场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @TableField("model_scene") + private String modelScene; + + @ApiModelProperty("对象属性--yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + private String objectProto; + + @ApiModelProperty("通知对象(是指具体的通知接受者,呈现方式包括场馆+群组;分公司+群组名;地市+群组名;ITCC+群组名;场馆+个人名;分公司+个人名;地市+个人名;ITCC+个人名这几种组合。具体呈现内容和对象属性、通知方式相关联)") + @TableField("notice_object") + private String noticeObject; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3简报") + @TableField("model_suit_type") + private String modelSuitType; + + @ApiModelProperty("关联表id(yw_notice_handwork)") + @TableField("handwork_id") + private Long handworkId; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/WorkFlowDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/WorkFlowDTO.java new file mode 100644 index 0000000..142e0c2 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/WorkFlowDTO.java @@ -0,0 +1,11 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import lombok.Data; + +@Data +public class WorkFlowDTO { + + private String processInstanceId; + + private String taskName; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwAlarmDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwAlarmDTO.java new file mode 100644 index 0000000..1885169 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwAlarmDTO.java @@ -0,0 +1,103 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.ruoyi.eastcom_yw.domain.model.StepInfo; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; +/** + * @author jkj + */ +@Data +public class YwAlarmDTO extends CommonDTO { + + private Long alarmId; + + private Long groupId; + + //告警类型 专业 wx 11种类型 + private String alarmType; + + //告警状态 0,1 PC端分别表示实时和全量 2 挂起,特殊要求 + private String alarmStatus; + + //告警的处理状态 + private String dealStatus; + + //告警处理人 + private String dealUser; + + //场馆Ids + private List venues; + + private List venueNames; + + //专业 + private String alarmGroup; + + //开始时间 + private String startTime; + + //结束时间 + private String endTime; + + private String city; + + //区县 + private String county; + + private List countys; + + //开始时间 + private LocalDateTime start; + + //结束时间 + private LocalDateTime end; + + //告警名称 + private String alarmName; + + //搜索框(告警名称、反馈人、告警网元、基站号) + private String searchBox; + + //进程号 + private String processId; + + //查询时间 + private String searchTime; + + private Long userId; + + //红线筛选 + private String inRedLine; + + private Integer isRefresh; + + private Boolean isAll; + + private Boolean isAPP = false; + + //默认false,导出需要设置未true + private Boolean isExport = false; + + private String venueName; + + private String venueType; + + private String maintainType; + + private String orderByTime; + + private String record; + + private String siteType; + + private Long [] alarmIds; + + private StepInfo stepInfo; + + private List alarmLevels; + +// private String orderBy; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwAlarmDTONoPage.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwAlarmDTONoPage.java new file mode 100644 index 0000000..0f240b7 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwAlarmDTONoPage.java @@ -0,0 +1,104 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.ruoyi.eastcom_yw.domain.model.StepInfo; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * @author jkj + */ +@Data +public class YwAlarmDTONoPage { + + private Long alarmId; + + private Long groupId; + + //告警类型 专业 wx 11种类型 + private String alarmType; + + //告警状态 0,1 PC端分别表示实时和全量 2 挂起,特殊要求 + private String alarmStatus; + + //告警的处理状态 + private String dealStatus; + + //告警处理人 + private String dealUser; + + //场馆Ids + private List venues; + + private List venueNames; + + //专业 + private String alarmGroup; + + //开始时间 + private String startTime; + + //结束时间 + private String endTime; + + private String city; + + //区县 + private String county; + + private List countys; + + //开始时间 + private LocalDateTime start; + + //结束时间 + private LocalDateTime end; + + //告警名称 + private String alarmName; + + //搜索框(告警名称、反馈人、告警网元、基站号) + private String searchBox; + + //进程号 + private String processId; + + //查询时间 + private String searchTime; + + private Long userId; + + //红线筛选 + private String inRedLine; + + private Integer isRefresh; + + private Boolean isAll; + + private Boolean isAPP = false; + + //默认false,导出需要设置未true + private Boolean isExport = false; + + private String venueName; + + private String venueType; + + private String maintainType; + + private String orderByTime; + + private String record; + + private String siteType; + + private Long [] alarmIds; + + private StepInfo stepInfo; + + private List alarmLevels; + +// private String orderBy; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwAlarmHangupLogDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwAlarmHangupLogDTO.java new file mode 100644 index 0000000..c595c6b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwAlarmHangupLogDTO.java @@ -0,0 +1,66 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * + *

+ * + * @author jkj + * @since 2023-02-15 + */ +@Data +public class YwAlarmHangupLogDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 大场景id + */ + private Long sceneBigId; + + /** + * 挂起时间 + */ + private String hangupTime; + + /** + * 挂起人 + */ + private Long hangupUserId; + + /** + * 恢复处理时间 + */ + private String recoveryTime; + + /** + * 挂起原因 + */ + private String hangupReason; + + /** + * 工作流进程id + */ + private String flwProcessid; + + /** + * 工作流任务id + */ + private String flwTaskid; + + + /** + * 挂起类型 + */ + private String hangupStatus; + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDataDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDataDTO.java new file mode 100644 index 0000000..e918b8a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDataDTO.java @@ -0,0 +1,32 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import lombok.Data; + +import java.util.List; + +/** + * @author jkj + */ +@Data +public class YwDataDTO { + + private Long signPlanId; + + private Long [] venueIds; + + private String [] roles; + + private String role; + + private String [] userTypes; + + //0签到1签退 + private Integer signType; + + private String signDate; + + private Long [] ids; + + private Long sceneBigId; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDrsConfigDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDrsConfigDTO.java new file mode 100644 index 0000000..33ea6cf --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDrsConfigDTO.java @@ -0,0 +1,71 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + *

+ * DRS配置表DTO + *

+ * + * @author ck + * @since 2023-06-13 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwDrsConfigDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("任务名称") + @TableField("task_name") + private String taskName; + + @ApiModelProperty("任务类型 drs_task_type 0 / 1 签到 2巡检") + @TableField("drs_task_type") + private String drsTaskType; + + @ApiModelProperty("状态") + @TableField("status") + private String status; + + @ApiModelProperty("创建人") + @TableField(value = "create_by", fill = FieldFill.INSERT) + private String createBy; + + @ApiModelProperty("创建时间") + @TableField(value = "create_time", fill = FieldFill.INSERT) + private LocalDateTime createTime; + + @ApiModelProperty("修改人") + @TableField(value = "update_by", fill = FieldFill.UPDATE) + private String updateBy; + + @ApiModelProperty("修改时间") + @TableField(value = "update_time", fill = FieldFill.UPDATE) + private LocalDateTime updateTime; + + @ApiModelProperty("备注") + @TableField("remark") + private String remark; + + @ApiModelProperty("删除标记") + @TableField("del_flag") + private String delFlag; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDrsTempTaskDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDrsTempTaskDTO.java new file mode 100644 index 0000000..a5d56d9 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDrsTempTaskDTO.java @@ -0,0 +1,100 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * DRS临时任务表DTO + *

+ * + * @author ck + * @since 2023-06-13 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwDrsTempTaskDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; + + @ApiModelProperty("任务日期") + @TableField("task_date") + private LocalDate taskDate; + + @ApiModelProperty("多组任务开始结束时间") + private List ywDrsTempTaskTimes; + + @ApiModelProperty("任务时间") + @TableField("task_time") + private LocalDateTime taskTime; + + @ApiModelProperty("任务结束时间") + @TableField("task_end_time") + private LocalDateTime taskEndTime; + + @ApiModelProperty("任务名称") + @TableField("task_name") + private String taskName; + + @ApiModelProperty("DRS任务类型 drs_task_type 0 / 1 签到 2巡检") + @TableField("drs_task_type") + private String drsTaskType; + + @ApiModelProperty("DRS任务状态 drs_task_status 0未开始 1进行中 2已完成") + @TableField("drs_task_status") + private String drsTaskStatus; + + @ApiModelProperty("自动状态变更 0自动 1手动") + @TableField("drs_auto_update") + private String drsAutoUpdate; + + @ApiModelProperty("状态") + @TableField("status") + private String status; + + @ApiModelProperty("创建人") + @TableField(value = "create_by", fill = FieldFill.INSERT) + private String createBy; + + @ApiModelProperty("创建时间") + @TableField(value = "create_time", fill = FieldFill.INSERT) + private LocalDateTime createTime; + + @ApiModelProperty("修改人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty("修改时间") + @TableField("update_time") + private LocalDateTime updateTime; + + @ApiModelProperty("备注") + @TableField("remark") + private String remark; + + @ApiModelProperty("删除标记") + @TableField("del_flag") + private String delFlag; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDrsTempTaskTimeDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDrsTempTaskTimeDTO.java new file mode 100644 index 0000000..3bc97af --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwDrsTempTaskTimeDTO.java @@ -0,0 +1,35 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwDrsTempTaskTimeDTO { + + @ApiModelProperty("任务时间") + @TableField("task_time") + private LocalDateTime taskTime; + + @ApiModelProperty("任务结束时间") + @TableField("task_end_time") + private LocalDateTime taskEndTime; + + @ApiModelProperty("任务名称") + @TableField("task_name") + private String taskName; + + @ApiModelProperty("DRS任务状态 drs_task_status 0未开始 1进行中 2已完成") + @TableField("drs_task_status") + private String drsTaskStatus; + + @ApiModelProperty("自动状态变更 0自动 1手动") + @TableField("drs_auto_update") + private String drsAutoUpdate; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectPlanDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectPlanDTO.java new file mode 100644 index 0000000..6ce7be6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectPlanDTO.java @@ -0,0 +1,65 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * @author huamile + */ +@Data +public class YwInspectPlanDTO { + + private Long id; + + private Long sceneId; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8", locale = "zh") + private Date inspectDate; + + private String inspectSpecialty; + + private List specialtyList; + + private String beginTime; + + private String planFinTime; + + private List> timePeriods; + + private Long sceneBigId; + + private Long type; + + private String inspectName; + + private Integer checkNum; + + private String checkType; + + private String checkDesc; + + private Integer circle; + + private Long stopTimeOption; + + private Long intervalTime; + + private Integer inspectUserId; + + private String repWarnInterval; + + private String noticeType; + + private String jobNo; + + private String city; + + private String county; + + private String description; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectPlanExportDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectPlanExportDTO.java new file mode 100644 index 0000000..daaf17a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectPlanExportDTO.java @@ -0,0 +1,41 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +/** + * @author huamile + */ +@Data +public class YwInspectPlanExportDTO { + + @Excel(name = "计划名称", width = 20) + private String inspectName; + + @Excel(name = "场馆",width = 20) + private String venueName; + + @Excel(name = "巡检日期",width = 20) + private String inspectDate; + + @Excel(name = "专业",width = 20) + private String specialtyName; + +// @Excel(name = "巡检周期",width = 20) + private Integer circle; + + @Excel(name = "计划开始时间",width = 20,exportFormat = "yyyy-MM-dd HH:mm:ss") + private Date beginTime; + + @Excel(name = "计划结束时间",width = 20,exportFormat = "yyyy-MM-dd HH:mm:ss") + private Date planFinTime; + +// @Excel(name = "提前通知时间量",width = 20) + private String repWarnInterval; + + @Excel(name = "通知方式",width = 20) + private String noticeType; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectStatDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectStatDTO.java new file mode 100644 index 0000000..0e1ad46 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectStatDTO.java @@ -0,0 +1,41 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +//import cn.afterturn.easypoi.excel.annotation.Excel; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +/** + * @author huamile + */ +@Data +public class YwInspectStatDTO { + + private Long sceneId; + + @Excel(name = "场馆", width = 20) + private String venueName; + + private String imageurl; + + @Excel(name = "应完成数", width = 20) + private Integer allNum; + + @Excel(name = "已完成数", width = 20) + private Integer completedNum; + + @Excel(name = "任务完成率", width = 20) + private Double rate; + + private String rateStr; + + @Excel(name = "总项数", width = 20) + private Integer resultAllNum; + + @Excel(name = "正常数", width = 20) + private Integer resulNormalNum; + + @Excel(name = "任务正常率", width = 20) + private Double resulRate; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectTaskDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectTaskDTO.java new file mode 100644 index 0000000..493bc03 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectTaskDTO.java @@ -0,0 +1,19 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.ruoyi.eastcom_yw.domain.YwRoutInspectConfig; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectPlan; +import lombok.Data; + +import java.util.List; + +/** + * @author huamile + */ +@Data +public class YwInspectTaskDTO { + + private YwInspectPlanDTO ywRoutInspectPlan; + + private List list; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectTaskExportDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectTaskExportDTO.java new file mode 100644 index 0000000..97f0999 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwInspectTaskExportDTO.java @@ -0,0 +1,50 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +/** + * @author huamile + */ +@Data +public class YwInspectTaskExportDTO { + + @Excel(name = "任务号", width = 20,sort = 1) + private String jobNo; + + @Excel(name = "任务名称", width = 20,sort = 2) + private String inspectName; + + @Excel(name = "场馆", width = 20,sort = 3) + private String venueName; + + @Excel(name = "专业", width = 20,sort = 4) + private String specialtyName; + + @Excel(name = "责任人", width = 20,sort = 5) + private String feedBackUserName; + + @Excel(name = "计划开始时间", width = 20, dateFormat = "yyyy-MM-dd HH:mm:ss",sort = 6) + private Date beginTime; + + @Excel(name = "计划完成时间", width = 20, dateFormat = "yyyy-MM-dd HH:mm:ss",sort = 7) + private Date planFinTime; + + @Excel(name = "是否超时", width = 20,sort = 8) + private String timeoutOrNot; + + @Excel(name = "任务状态", width = 20,sort = 9) + private String taskStatus; + +// @Excel(name = "异常数/总项数",sort = 10) + private String rate; + + @Excel(name = "异常数",sort = 11) + private Integer errorNum; + + @Excel(name = "总项数",sort = 12) + private Integer num; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwKpiConfigDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwKpiConfigDTO.java new file mode 100644 index 0000000..05f512c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwKpiConfigDTO.java @@ -0,0 +1,84 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 指标字段阈值配置表DTO + *

+ * + * @author yqf + * @since 2023-04-11 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwKpiConfigDTO { + + + private static final long serialVersionUID = 1L; + + + + @TableId(value = "id", type = IdType.AUTO) + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("专业(字典表)") + @TableField("subject") + private String subject; + + @ApiModelProperty("网络模式(字典表)") + @TableField("net_type") + private String netType; + + @ApiModelProperty("指标字段") + @TableField("kpi_field") + private Long kpiField; + + @ApiModelProperty("阈值范围") + @TableField("threshold_value") + private String thresholdValue; + + @ApiModelProperty("颜色") + @TableField("color") + private String color; + + @ApiModelProperty("创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty("创建时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty("更新人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty("更新时间") + @TableField("update_time") + private LocalDateTime updateTime; + + @ApiModelProperty("最小是(包括本值)") + @TableField("min_value") + private Object minValue; + + @ApiModelProperty("最大值(不包括本值)") + @TableField("max_value") + private Object maxValue; + + @ApiModelProperty("指标名") + @TableField("kpi_field_name") + private String kpiFieldName; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeBriefingDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeBriefingDTO.java new file mode 100644 index 0000000..a2ab3a0 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeBriefingDTO.java @@ -0,0 +1,101 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知通告简报计划表DTO + *

+ * + * @author ck + * @since 2023-04-11 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeBriefingDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("地市") + @TableField("city") + private String city; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; + + @ApiModelProperty("对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + private String objectProto; + + @ApiModelProperty("通知方式sys_notice_type") + @TableField("notice_type") + private List noticeType; + + @ApiModelProperty("发送日期") + @TableField("send_date") + private LocalDate sendDate; + + @ApiModelProperty("开始时间") + @TableField("begin_time") + private LocalDateTime beginTime; + + @ApiModelProperty("结束时间") + @TableField("end_time") + private LocalDateTime endTime; + + @ApiModelProperty("区县") + @TableField("county") + private String county; + + @ApiModelProperty("对象ids数组") + @TableField("object_ids") + private List objectIds; + + @ApiModelProperty("模板id") + @TableField("model_id") + private Long modelId; + + @ApiModelProperty("排序号") + @TableField("order_num") + private Integer orderNum; + + @ApiModelProperty("时间间隔(单位分)") + @TableField("time_interval") + private Integer timeInterval; + + @ApiModelProperty("通知名称") + @TableField("notice_name") + private String noticeName; + + @ApiModelProperty("启用状态 sys_normal_disable 0启用 1停用") + @TableField("sys_normal_disable") + private String sysNormalDisable; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3文字简报 4h5简报)") + @TableField("model_suit_type") + private String modelSuitType; + + @ApiModelProperty("发送方式 send_type (1自动发送 2手工发送)") + @TableField("send_type") + private String sendType; + + @ApiModelProperty("发送人员") + @TableField("send_user") + private Long sendUser; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeHandworkDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeHandworkDTO.java new file mode 100644 index 0000000..b28b60a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeHandworkDTO.java @@ -0,0 +1,90 @@ +package com.ruoyi.eastcom_yw.domain.dto; + + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知通告手工通知计划表DTO + *

+ * + * @author ck + * @since 2023-04-11 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeHandworkDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("通知名称") + @TableField("notice_name") + private String noticeName; + + @ApiModelProperty("通知模板id") + @TableField("notice_model") + private Long noticeModel; + + @ApiModelProperty("通知方式--sys_notice_type") + @TableField("notice_type") + private List noticeType; + + @ApiModelProperty("通知对象ids") + @TableField("notice_object") + private List noticeObject; + + @ApiModelProperty("通知内容") + @TableField("notice_content") + private String noticeContent; + + @ApiModelProperty("通知状态yw_veriy_status 0待提交 1待审核 2已审核") + @TableField("notice_status") + private String noticeStatus; + + @ApiModelProperty("日期") + @TableField("notice_date") + private LocalDateTime noticeDate; + + @ApiModelProperty("开始时间") + @TableField("begin_time") + private LocalDateTime beginTime; + + @ApiModelProperty("结束时间") + @TableField("end_time") + private LocalDateTime endTime; + + @ApiModelProperty("时间间隔(单位分)") + @TableField("time_interval") + private Integer timeInterval; + + @ApiModelProperty("工作流processid") + @TableField("flw_processid") + private String flwProcessid; + + @ApiModelProperty("申请人id") + @TableField("apply_id") + private Long applyId; + + @ApiModelProperty("审核人id") + @TableField("audit_id") + private Long auditId; + + @ApiModelProperty("已添加到sys_notice标记(0否 1是)") + @TableField("add_flag") + private String addFlag; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeHandworkdetailDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeHandworkdetailDTO.java new file mode 100644 index 0000000..d9c4832 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeHandworkdetailDTO.java @@ -0,0 +1,55 @@ +package com.ruoyi.eastcom_yw.domain.dto; + + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * 通知通告手工通知审核表DTO + *

+ * + * @author ck + * @since 2023-04-11 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeHandworkdetailDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("手工通知id") + @TableField("handwork_id") + private Long handworkId; + + @ApiModelProperty("操作人(提交审核的人 或者 审核的人)") + @TableField("oprate_user") + private Long oprateUser; + + @ApiModelProperty("审核结果(关联字典表yw_veriy_result 0通过 1驳回)") + @TableField("veriy_result") + private String veriyResult; + + @ApiModelProperty("审核状态(关联字典表yw_veriy_status 0 待审核 1 已审核)") + @TableField("veriy_status") + private String veriyStatus; + + @ApiModelProperty("驳回原因") + @TableField("fail_reason") + private String failReason; + + @ApiModelProperty("附件") + @TableField("appendix") + private String appendix; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeListDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeListDTO.java new file mode 100644 index 0000000..178de73 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeListDTO.java @@ -0,0 +1,98 @@ +package com.ruoyi.eastcom_yw.domain.dto; + + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知通告记录表DTO + *

+ * + * @author ck + * @since 2023-04-11 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeListDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("通知名称") + @TableField("notice_name") + private String noticeName; + + @ApiModelProperty("通知场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @TableField("model_scene") + private String modelScene; + + @ApiModelProperty("对象属性--yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + private String objectProto; + + @ApiModelProperty("通知方式--sys_notice_type") + @TableField("notice_type") + private String noticeType; + + @ApiModelProperty("通知时间(计划发送时间(同天当前时间之前立即发送))") + @TableField("notice_time") + private LocalDateTime noticeTime; + + @ApiModelProperty("通知对象") + @TableField("notice_object") + private String noticeObject; + + @ApiModelProperty("通知内容") + @TableField("notice_content") + private String noticeContent; + + @ApiModelProperty("状态 0未读 1已读") + @TableField("status") + private String status; + + @ApiModelProperty("通知对象ids数组") + @TableField("notice_object_id") + private List noticeObjectId; + + @ApiModelProperty("通知模板id") + @TableField("notice_model_id") + private Long noticeModelId; + + @ApiModelProperty("实际发送时间") + @TableField("send_time") + private LocalDateTime sendTime; + + @ApiModelProperty("发送是否成功,1成功 0失败") + @TableField("send_status") + private String sendStatus; + + @ApiModelProperty("计划发送时间(同天当前时间之前立即发送)") + @TableField("exp_send_time") + private LocalDateTime expSendTime; + + @ApiModelProperty("加入定时任务标记 默认0未加入 1已加入") + @TableField("add_flag") + private String addFlag; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3简报") + @TableField("model_suit_type") + private String modelSuitType; + + @ApiModelProperty("计划id(手工与简报会先配置计划)") + @TableField("plan_id") + private Long planId; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeModelDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeModelDTO.java new file mode 100644 index 0000000..3650696 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeModelDTO.java @@ -0,0 +1,77 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + *

+ * 通知通告模板表DTO + *

+ * + * @author ck + * @since 2023-04-07 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeModelDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("模板名称") + @TableField("model_name") + private String modelName; + + @ApiModelProperty("模板内容") + @TableField("model_content") + private String modelContent; + + @ApiModelProperty("场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @TableField("model_scene") + private String modelScene; + + @ApiModelProperty("用户id") + @TableField(value = "create_user_id",fill= FieldFill.INSERT) + private Long createUserId; + + @ApiModelProperty("创建用户昵称") + @TableField(value = "create_by",fill= FieldFill.INSERT) + private String createBy; + + @ApiModelProperty("创建时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty("模板适用类型model_suit_type 1 普通 2 手工 3简报") + @TableField("model_suit_type") + private String modelSuitType; + + @ApiModelProperty("备注(写一些触发要求)") + @TableField("model_des") + private String modelDes; + + @ApiModelProperty("模板类型--字典yw_model_type 0事件触发型") + @TableField("model_type") + private String modelType; + + @ApiModelProperty("排序号") + @TableField("order_num") + private Integer orderNum; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeObjectDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeObjectDTO.java new file mode 100644 index 0000000..a754a8e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwNoticeObjectDTO.java @@ -0,0 +1,97 @@ +package com.ruoyi.eastcom_yw.domain.dto; + + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + *

+ * 通知通告对象表DTO + *

+ * + * @author ck + * @since 2023-04-11 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeObjectDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("地市") + @TableField("city") + private String city; + + @ApiModelProperty("区县") + @TableField("county") + private String county; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; + + @ApiModelProperty("专业") + @TableField("specialty") + private Long specialty; + + @ApiModelProperty("角色id数组") + @TableField("roleIds") + private List roleIds; + + @ApiModelProperty("对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + private String objectProto; + + @ApiModelProperty("通知方式sys_notice_type") + @TableField("notice_type") + private String noticeType; + + @ApiModelProperty("短信组名") + @TableField("message_name") + private String messageName; + + @ApiModelProperty("短信组内成员id数组") + @TableField("message_users") + private List messageUsers; + + @ApiModelProperty("排序号") + @TableField("order_num") + private Integer orderNum; + + @ApiModelProperty("群号") + @TableField("group_id") + private String groupId; + + @ApiModelProperty("群名") + @TableField("group_name") + private String groupName; + + @ApiModelProperty("备注") + @TableField("group_des") + private String groupDes; + + @ApiModelProperty("对象名称") + @TableField("object_name") + private String objectName; + + @ApiModelProperty("ivr组名") + @TableField("ivr_name") + private String ivrName; + + @ApiModelProperty("ivr组内成员id数组") + @TableField("ivr_users") + private List ivrUsers; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSceneCalendarDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSceneCalendarDTO.java new file mode 100644 index 0000000..762bb09 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSceneCalendarDTO.java @@ -0,0 +1,29 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import lombok.Data; + +/** + * @author huamile + */ +@Data +public class YwSceneCalendarDTO { + + private Long id; + + private Long sceneId; + + private String matchType; + + private String matchName; + + private String matchRemark; + + private String beginTime; + + private String endTime; + + private String matchDate; + + private String status; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSceneDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSceneDTO.java new file mode 100644 index 0000000..1d3c9c6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSceneDTO.java @@ -0,0 +1,106 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.importer.beans.ResultBean; +import com.ruoyi.eastcom_yw.domain.YwSceneFile; +import lombok.Data; + +import java.util.List; + +/** + * @author huamile + */ +@Data +public class YwSceneDTO extends ResultBean { + + private Long id; + + @Excel(name = "场馆标准名称", type = Excel.Type.ALL, sort = 1) + private String venueName; + + @Excel(name = "场馆简称", type = Excel.Type.ALL, sort = 2) + private String venueShortname; + + @Excel(name = "场馆英文缩写", type = Excel.Type.ALL, sort = 3) + private String englishShortname; + + @Excel(name = "维护类别", type = Excel.Type.ALL, sort = 4) + private String maintainType; + + @Excel(name = "场馆属性", type = Excel.Type.ALL, sort = 5) + private String venueType; + + @Excel(name = "场馆级别", type = Excel.Type.ALL, sort = 6) + private String venueLevel; + + private Double longitude; + + @Excel(name = "经度GPS", type = Excel.Type.ALL, sort = 7) + @TableField(exist = false) + private String longitudeStr; + + private Double latitude; + + @Excel(name = "纬度GPS", type = Excel.Type.ALL, sort = 8) + @TableField(exist = false) + private String latitudeStr; + + private Double longitudeGcj02; + + @Excel(name = "经度GCJ02", type = Excel.Type.ALL, sort = 9) + @TableField(exist = false) + private String longitudeGcj02Str; + + private Double latitudeGcj02; + + @Excel(name = "纬度GCJ02", type = Excel.Type.ALL, sort = 10) + @TableField(exist = false) + private String latitudeGcj02Str; + + private String cityId; + + @Excel(name = "所属地市", type = Excel.Type.ALL, sort = 11) + @TableField(exist = false) + private String city; + + private String areaCountyId; + + @Excel(name = "所属区县", type = Excel.Type.ALL, sort = 12) + @TableField(exist = false) + private String county; + + @Excel(name = "赛事类型", type = Excel.Type.ALL, sort = 13) + private String matchType; + + @Excel(name = "地址", type = Excel.Type.ALL, sort = 14) + private String venueAddress; + + @Excel(name = "备注", type = Excel.Type.ALL, sort = 15) + private String venueDesc; + + private Integer accPerson; + + private Long sceneBigId; + + private Integer signScope; + + private String status; + + private String createBy; + + private String createTime; + + private String updateBy; + + private String updateTime; + + private String englishName; + + @TableField(exist = false) + private List files; + + + private String venueCategory; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSceneNoticeinfoSearchDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSceneNoticeinfoSearchDTO.java new file mode 100644 index 0000000..11cb3cf --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSceneNoticeinfoSearchDTO.java @@ -0,0 +1,14 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import lombok.Data; + +@Data +public class YwSceneNoticeinfoSearchDTO extends CommonDTO { + + private String sceneName; + + private Long sceneId; + + private Long userId; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSearchDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSearchDTO.java new file mode 100644 index 0000000..e016164 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSearchDTO.java @@ -0,0 +1,31 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import lombok.Data; + +//工作流查询,字段名必须小写 +@Data +public class YwSearchDTO { + + //城市区县 + private String area_county_id; + //子场景,场馆 + private String venue_id; + //场馆名称 + private String venue_name; + //地市名称 + private String city; + //区县名称 + private String county; + //任务类别 + private String task_type; + //名称 + private String task_name; + //专业 + private String specialty; + //网元名称 + private String net_name; + //告警名称 + private String alarm_name; + //基站名称 + private String site_name; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignDTO.java new file mode 100644 index 0000000..e16f9c6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignDTO.java @@ -0,0 +1,23 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import lombok.Data; + +@Data +public class YwSignDTO { + + //签到计划id + private Long signPlanId; + + //场馆id + private Long venueId; + + //签到类型 0签到1签退 + private Integer signType; + + //纬度 + private String latitude; + + //经度 + private String longitude; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignInDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignInDTO.java new file mode 100644 index 0000000..85936e6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignInDTO.java @@ -0,0 +1,22 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import lombok.Data; + +@Data +public class YwSignInDTO { + + private Long signPlanId; + + private Long venueId; + + private String[] userTypes; + + private String signTime; + + private Long[] users; + + private Long userId; + + private Integer signType; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignLogDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignLogDTO.java new file mode 100644 index 0000000..6599b37 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignLogDTO.java @@ -0,0 +1,41 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import lombok.Data; + +import java.util.Date; + +/** + * @author jkj + */ +@Data +public class YwSignLogDTO extends CommonDTO{ + + private String city; + + private String nickName; + + private String county; + + private Long[] venueIds; + + private String userType; + + private String startDate; + + private String endDate; + + private String signStatus; + + private Boolean isExport; + + private String venueType; + + private String maintainType; + + private boolean taskFlag = false; + + private Boolean genTime; + + private boolean isToday; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignPlanDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignPlanDTO.java new file mode 100644 index 0000000..33ffdd9 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignPlanDTO.java @@ -0,0 +1,67 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +@Data +public class YwSignPlanDTO extends CommonDTO { + + private Long id; + + private Long[] venueIds; + + private Long venueId; + + @Excel(name = "场馆", type = Excel.Type.ALL) + private String venueName; + + @Excel(name = "签到日期", type = Excel.Type.ALL, dateFormat = "yyyy-MM-dd") + private String signDate; + + private String[] signDates; + + private String startDate; + + private String endDate; + + private Double latitude; + + private Double longitude; + + private Integer signScope; + + @Excel(name = "早签到时间", type = Excel.Type.ALL, dateFormat = "HH:mm:ss") + private String beginTime; + + @Excel(name = "晚签到时间", type = Excel.Type.ALL, dateFormat = "HH:mm:ss") + private String endTime; + + @Excel(name = "通知时间量", type = Excel.Type.ALL) + private String repWarnInterval; + + @Excel(name = "签到时间量", type = Excel.Type.ALL) + private Integer repSignInterval; + + @Excel(name = "通知方式", type = Excel.Type.ALL) + private String noticeType; + + private String isOpen; + + private String createBy; + + private String updateBy; + + private Boolean isExport = false; + + @Excel(name = "失败原因", type = Excel.Type.EXPORT) + private String reason; + + private Integer signNum; + + private String signUsers; + + private String venueType; + + private String maintainType; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignPlanImportDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignPlanImportDTO.java new file mode 100644 index 0000000..ee2adb6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignPlanImportDTO.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.importer.beans.ResultBean; +import lombok.Data; + +@Data +public class YwSignPlanImportDTO extends ResultBean { + @Excel(name = "场馆", type = Excel.Type.ALL, sort = 1) + private String venueName; + + @Excel(name = "签到日期", type = Excel.Type.ALL, dateFormat = "yyyy-MM-dd", sort = 2) + private String signDate; + + @Excel(name = "早签到时间", type = Excel.Type.ALL, dateFormat = "HH:mm:ss", sort = 3) + private String beginTime; + + @Excel(name = "晚签到时间", type = Excel.Type.ALL, dateFormat = "HH:mm:ss", sort = 4) + private String endTime; + + @Excel(name = "提醒时间量", type = Excel.Type.ALL, sort = 5) + private String repWarnInterval; + + @Excel(name = "通知方式", type = Excel.Type.ALL, sort = 6) + private String noticeType; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignPlanUserDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignPlanUserDTO.java new file mode 100644 index 0000000..5500e60 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSignPlanUserDTO.java @@ -0,0 +1,15 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +@Data +public class YwSignPlanUserDTO { + + private String beginTime; + + private String endTime; + + private String[] signUsers; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSparePartsDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSparePartsDTO.java new file mode 100644 index 0000000..dfeb89f --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwSparePartsDTO.java @@ -0,0 +1,124 @@ +package com.ruoyi.eastcom_yw.domain.dto; + + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.importer.beans.ResultBean; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 亚运备件表DTO + *

+ * + * @author yqf + * @since 2023-08-31 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwSparePartsDTO extends ResultBean { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("序号") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @Excel(name = "场馆名称", type = Excel.Type.ALL, sort = 1) + @ApiModelProperty("场馆名称") + @TableField("venue_name") + private String venueName; + + @Excel(name = "场馆类型", type = Excel.Type.ALL, sort = 2) + @ApiModelProperty("场馆类型") + @TableField("venue_type") + private String venueType; + + @Excel(name = "设备类型", type = Excel.Type.ALL, sort = 3) + @ApiModelProperty("设备类型") + @TableField("device_type") + private String deviceType; + + @Excel(name = "单板型号", type = Excel.Type.ALL, sort = 4) + @ApiModelProperty("单板型号") + @TableField("board_model") + private String boardModel; + + @Excel(name = "单板数量", type = Excel.Type.ALL, sort = 5) + @ApiModelProperty("单板数量") + @TableField("board_num") + private String boardNum; + + @Excel(name = "备件型号", type = Excel.Type.ALL, sort = 6) + @ApiModelProperty("备件型号") + @TableField("part_model") + private String partModel; + + @Excel(name = "通用数量", type = Excel.Type.ALL, sort = 7) + @ApiModelProperty("通用数量") + @TableField("current_num") + private String currentNum; + + @Excel(name = "需求数量", type = Excel.Type.ALL, sort = 8) + @ApiModelProperty("需求数量") + @TableField("need_num") + private String needNum; + + @Excel(name = "配置数量", type = Excel.Type.ALL, sort = 9) + @ApiModelProperty("配置数量") + @TableField("configure_num") + private String configureNum; + + @Excel(name = "缺口", type = Excel.Type.ALL, sort = 10) + @ApiModelProperty("缺口") + @TableField("gap_num") + private String gapNum; + + @Excel(name = "专业", type = Excel.Type.ALL, sort = 11) + @ApiModelProperty("专业") + @TableField("major") + private String major; + + @Excel(name = "备注", type = Excel.Type.ALL, sort = 12) + @ApiModelProperty("备注") + @TableField("comment") + private String comment; + + @Excel(name = "联系人", type = Excel.Type.ALL, sort = 13) + @ApiModelProperty("联系人") + @TableField("contacts") + private String contacts; + + @Excel(name = "联系电话", type = Excel.Type.ALL, sort = 14) + @ApiModelProperty("联系电话") + @TableField("telephone") + private String telephone; + + @ApiModelProperty("创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty("创建时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty("更新人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty("更新时间") + @TableField("update_time") + private LocalDateTime updateTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwWireTaskLogDTO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwWireTaskLogDTO.java new file mode 100644 index 0000000..4185a47 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/dto/YwWireTaskLogDTO.java @@ -0,0 +1,71 @@ +package com.ruoyi.eastcom_yw.domain.dto; + +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * @author jkj + */ +@Data +public class YwWireTaskLogDTO extends CommonDTO { + + private String flwProcessid; + + private Long createBy; + + private String createTime; + + private String wireTaskId; + + private String wireTaskName; + + private String currentUser; + + private Long userId; + + //创建人 + private String creater; + + private Integer [] taskTypes; + + private Integer taskType; + + //必须要有,新增要用到 + private Long venueId; + + private Long [] venueIds; + + private String county; + + private String city; + + private String [] countys; + + private String status; + + private String curStep; + + //开始时间 + private String startTime; + + //结束时间 + private String endTime; + + //施工单位 + private String sgdw; + + private Boolean isApp= false; + + private String construcUnit; + + private String report; + + private String venueType; + + private String maintainType; + + private Boolean isExport = false; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/enums/TaskNameWithRoleEnum.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/enums/TaskNameWithRoleEnum.java new file mode 100644 index 0000000..8827845 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/enums/TaskNameWithRoleEnum.java @@ -0,0 +1,47 @@ +package com.ruoyi.eastcom_yw.domain.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum TaskNameWithRoleEnum { + +// 任务发起("任务发起",new Long[]{101L,14L},new String[]{"venuemanager,venueassistant"},new String[]{"场馆经理,场馆经理助理"}), + 任务发起("任务发起",new Long[]{101L},new String[]{"venuemanager"},new String[]{"场馆经理"}), + 任务审核("任务审核",new Long[]{19L},new String[]{"commdirector"},new String[]{"通信主管"}), + 图纸设计("图纸设计",new Long[]{15L},new String[]{"designer"},new String[]{"设计院人员"}), + 图纸确认("图纸确认",new Long[]{101L},new String[]{"venuemanager"},new String[]{"场馆经理"}), + 施工建设("施工建设",new Long[]{16L},new String[]{"builder"},new String[]{"施工队人员"}), + 工程监理("工程监理",new Long[]{17L},new String[]{"supervisor"},new String[]{"监理人员"}), + 现场验收("现场验收",new Long[]{101L},new String[]{"venuemanager"},new String[]{"场馆经理"}), + 任务派发("任务派发",new Long[]{101L},new String[]{"venuemanager"},new String[]{"场馆经理"}), +// 任务派发("任务派发",new Long[]{101L,14L},new String[]{"venuemanager,venueassistant"},new String[]{"场馆经理,场馆经理助理"}), + ; + + private final String taskName; + + private final Long[] roleId; + + private final String[] roleKey; + + private final String[] roleName; + + public static Long[] getRoleId(String taskName) { + for (TaskNameWithRoleEnum entry : values()) { + if (entry.getTaskName().equals(taskName)) { + return entry.getRoleId(); + } + } + return new Long[0]; + } + + public static String[] getRoleName(String taskName) { + for (TaskNameWithRoleEnum entry : values()) { + if (entry.getTaskName().equals(taskName)) { + return entry.getRoleName(); + } + } + return new String[0]; + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/enums/WireTaskStatus.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/enums/WireTaskStatus.java new file mode 100644 index 0000000..2b54c70 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/enums/WireTaskStatus.java @@ -0,0 +1,67 @@ +package com.ruoyi.eastcom_yw.domain.enums; + +public enum WireTaskStatus { + + rwfq(1, "任务发起"),rwpf(2, "任务派发") ,rwsh(3, "任务审核") ,tzsj(4,"图纸设计") ,tzqr(5,"图纸确认") ,sgjs(6,"施工建设"), + gcjl(7,"工程监理"),xcys(8,"现场验收"),lcjs(9,"流程结束"); + + /** code */ + private Integer code; + + /** 显示标签 */ + private String label; + + WireTaskStatus(Integer code, String label){ + + this.code = code; + + this.label = label; + } + + public static String getLabelByCode (Integer code) { + + for (WireTaskStatus enuma : WireTaskStatus.values()) { + + if (enuma.getCode().equals(code)) { + + return enuma.getLabel(); + } + } + return ""; + } + + public static Integer getCodeByLabel (String label) { + + for (WireTaskStatus enuma : WireTaskStatus.values()) { + + if (enuma.getLabel().equals(label)) { + + return enuma.getCode(); + } + } + return -1; + } + + + @Override + public String toString(){ + + return label; + + } + + public String getLabel() { + + return label; + + } + + + public Integer getCode(){ + + return this.code; + + } + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/model/AppEntity.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/model/AppEntity.java new file mode 100644 index 0000000..bba727b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/model/AppEntity.java @@ -0,0 +1,19 @@ +package com.ruoyi.eastcom_yw.domain.model; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * @author los + */ +@Data +@TableName("m_app") +public class AppEntity { + private Long id; + private String appId; + private String appName; + private String appSecret; + private String accessToken; + private String isFlag; + private String ip; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/model/StepInfo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/model/StepInfo.java new file mode 100644 index 0000000..05c83d3 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/model/StepInfo.java @@ -0,0 +1,9 @@ +package com.ruoyi.eastcom_yw.domain.model; + +import lombok.Data; + +@Data +public class StepInfo { + private String title; + private String info; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/SysUserParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/SysUserParam.java new file mode 100644 index 0000000..5caef87 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/SysUserParam.java @@ -0,0 +1,12 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.Data; + +@Data +public class SysUserParam extends CommonDTO { + private String userName; + private String nickName; + private Integer phoneNumber; + private Long sceneBigId; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwInspectQuestionConfigParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwInspectQuestionConfigParam.java new file mode 100644 index 0000000..6d793f0 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwInspectQuestionConfigParam.java @@ -0,0 +1,17 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.Data; + +/** + * @author huamile + */ +@Data +public class YwInspectQuestionConfigParam extends CommonDTO { + + private Long sceneBigId; + private String specialty; + private String questionType; + private String questionSonType; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwRoutInspectConfigParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwRoutInspectConfigParam.java new file mode 100644 index 0000000..a5083bd --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwRoutInspectConfigParam.java @@ -0,0 +1,33 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.Data; + + +/** + * @author huamile + */ +@Data +public class YwRoutInspectConfigParam extends CommonDTO { + + /** + * 场馆 + */ + private Long[] venueIds; + + /** + * 专业 + */ + private String specialty; + + private String beginDate; + + private String endDate; + + private Long userId; + + private String venueType; + + private String maintainType; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwRoutInspectPlanParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwRoutInspectPlanParam.java new file mode 100644 index 0000000..66696c6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwRoutInspectPlanParam.java @@ -0,0 +1,38 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.Data; + +/** + * @author huamile + */ +@Data +public class YwRoutInspectPlanParam extends CommonDTO { + + private String taskNo; + + private String taskName; + + private Long[] venueIds; + + private String specialty; + + private String beginDate; + + private String endDate; + + private String city; + + private String county; + + private String taskStatus; + + private Long userId; + + private Boolean isApp = false; + + private String maintainType; + + private String venueType; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwRoutInspectStatParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwRoutInspectStatParam.java new file mode 100644 index 0000000..93c3779 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwRoutInspectStatParam.java @@ -0,0 +1,46 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.Data; + +/** + * @author huamile + */ +@Data +public class YwRoutInspectStatParam extends CommonDTO { + + /** + * 地市 + */ + private String city; + + /** + * 区县 + */ + private String county; + + /** + * 场馆 + */ + private Long[] venueIds; + + /** + * 专业 + */ + private String specialty; + + private String beginDate; + + private String endDate; + + private Long userId; + + private String venueType; + + private String maintainType; + + private boolean isExport = false; + + private boolean taskFlag = false; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneAlarmParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneAlarmParam.java new file mode 100644 index 0000000..dca47eb --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneAlarmParam.java @@ -0,0 +1,18 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.Data; + +/** + * @author huamile + */ +@Data +public class YwSceneAlarmParam extends CommonDTO { + + private Long sceneId; + + private String alarmCode; + + private String keywords; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneCalendarParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneCalendarParam.java new file mode 100644 index 0000000..e767929 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneCalendarParam.java @@ -0,0 +1,24 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.Data; + +/** + * @author huamile + */ +@Data +public class YwSceneCalendarParam extends CommonDTO { + + private Long sceneId; + + private String matchType; + + private String matchName; + + private String beginDate; + + private String endDate; + + private String keywords; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneMatchParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneMatchParam.java new file mode 100644 index 0000000..414e4e1 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneMatchParam.java @@ -0,0 +1,7 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; + +public class YwSceneMatchParam extends CommonDTO { + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementAgisParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementAgisParam.java new file mode 100644 index 0000000..48a9b43 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementAgisParam.java @@ -0,0 +1,15 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.Data; + +@Data +public class YwSceneNetelementAgisParam extends CommonDTO { + + private Long sceneId; + private String sceneName; + private String keywords; + private Long sceneBigId; + private String alarmSpecityId; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementCsParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementCsParam.java new file mode 100644 index 0000000..837b605 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementCsParam.java @@ -0,0 +1,15 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.Data; + +@Data +public class YwSceneNetelementCsParam extends CommonDTO { + + private Long sceneId; + private String sceneName; + private String equipmentType; + private String networkingType; + private String keywords; + private Long sceneBigId; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementDhParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementDhParam.java new file mode 100644 index 0000000..8c052e6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementDhParam.java @@ -0,0 +1,18 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.Data; + +@Data +public class YwSceneNetelementDhParam extends CommonDTO { + + private String city; + private String county; + private String netElementPhyname; + private String inRedline; + private Long sceneId; + private String sceneName; + private String roomType; + private String keywords; + private Long sceneBigId; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementParam.java new file mode 100644 index 0000000..721f606 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementParam.java @@ -0,0 +1,18 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.Data; + +/** + * @author huamile + */ +@Data +public class YwSceneNetelementParam extends CommonDTO { + + private Long sceneId; + + private String status; + + private String keywords; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementWxParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementWxParam.java new file mode 100644 index 0000000..05382fd --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneNetelementWxParam.java @@ -0,0 +1,16 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.Data; + +@Data +public class YwSceneNetelementWxParam extends CommonDTO { + + private Long sceneId; + private String sceneName; + private String inRedline; + private String ci; + private String keywords; + private Long sceneBigId; + private Long[] sceneIds; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneParam.java new file mode 100644 index 0000000..0d2f4e1 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneParam.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.Data; + +/** + * @author huamile + */ +@Data +public class YwSceneParam extends CommonDTO { + + private Long sceneBigId; + + private String venueLevel; + + private String areaCountyId; + + private String keywords; + + private String status; + + private String city; + + private Long[] venueIds; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneUserParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneUserParam.java new file mode 100644 index 0000000..f561c9b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSceneUserParam.java @@ -0,0 +1,24 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.Data; + +/** + * @author huamile + */ +@Data +public class YwSceneUserParam extends CommonDTO { + + private Long sceneId; + + private String status; + + private String belongArea; + + private Long roleId; + + private String specialty; + + private String keywords; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSignPlanParam.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSignPlanParam.java new file mode 100644 index 0000000..419fdc2 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/param/YwSignPlanParam.java @@ -0,0 +1,63 @@ +package com.ruoyi.eastcom_yw.domain.param; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSignPlanUserDTO; +import lombok.Data; + +import java.util.List; + +@Data +public class YwSignPlanParam { + + private Long id; + + private Long[] venueIds; + + @Excel(name = "场馆" , type = Excel.Type.ALL) + private String venueName; + + @Excel(name = "签到日期" , type = Excel.Type.ALL, dateFormat = "yyyy-MM-dd") + private String signDate; + + private String[] signDates; + + private String startDate; + + private String endDate; + + private Double latitude; + + private Double longitude; + + private Integer signScope; + + @Excel(name = "早签到时间" , type = Excel.Type.ALL, dateFormat = "HH:mm:ss") + private String beginTime; + + @Excel(name = "晚签到时间" , type = Excel.Type.ALL, dateFormat = "HH:mm:ss") + private String endTime; + + @Excel(name = "提前通知时间量" , type = Excel.Type.ALL) + private String repWarnInterval; + + @Excel(name = "提前签到时间量" , type = Excel.Type.ALL) + private Integer repSignInterval; + + @Excel(name = "通知方式" , type = Excel.Type.ALL) + private String noticeType; + + private String isOpen; + + private String createBy; + + private Boolean isExport=false; + + @Excel(name = "失败原因", type = Excel.Type.EXPORT) + private String reason; + + private Integer signNum; + + private List timePeriods; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2MmlListQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2MmlListQO.java new file mode 100644 index 0000000..100c561 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2MmlListQO.java @@ -0,0 +1,32 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * QO + *

+ * + * @author ck + * @since 2023-09-12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Dp2MmlListQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("场馆名称") + private String venueName; + + @ApiModelProperty("场馆id") + private Long venueId; + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2SpotCellQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2SpotCellQO.java new file mode 100644 index 0000000..0ad4c9c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2SpotCellQO.java @@ -0,0 +1,137 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + *

+ * QO + *

+ * + * @author ck + * @since 2023-08-10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Dp2SpotCellQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + + private String keywords; + + @TableField("id") + private Integer id; + + @TableField("omc") + private String omc; + + @ApiModelProperty("需要") + @TableField("县市") + private String 县市; + + @TableField("enodebid") + private Long enodebid; + + @TableField("本地小区标识") + private Long 本地小区标识; + + @TableField("小区标识") + private Long 小区标识; + + @ApiModelProperty("需要") + @TableField("站号") + private Long 站号; + + @ApiModelProperty("需要") + @TableField("ci") + private Long ci; + + @ApiModelProperty("需要") + @TableField("基站全称") + private String 基站全称; + + @TableField("en名称") + private String en名称; + + @ApiModelProperty("需要") + @TableField("小区名称") + private String 小区名称; + + @ApiModelProperty("需要") + @TableField("小区频段") + private String 小区频段; + + @ApiModelProperty("需要") + @TableField("纬度") + private Object 纬度; + + @ApiModelProperty("需要") + @TableField("经度") + private Object 经度; + + @TableField("纬度gcj") + private Object 纬度gcj; + + @TableField("经度gcj") + private Object 经度gcj; + + @ApiModelProperty("需要") + @TableField("室内室外") + private String 室内室外; + + @ApiModelProperty("需要") + @TableField("网络") + private String 网络; + + @TableField("现网状态") + private String 现网状态; + + @TableField("cgi") + private String cgi; + + @TableField("频点") + private Long 频点; + + @TableField("pci") + private Long pci; + + @TableField("tac") + private Long tac; + + @TableField("一级场景") + private String 一级场景; + + @TableField("二级场景") + private String 二级场景; + + @ApiModelProperty("需要") + @TableField("设备类型") + private String 设备类型; + + @ApiModelProperty("需要") + @TableField("带宽") + private Long 带宽; + + @ApiModelProperty("需要") + @TableField("方位角") + private Long 方位角; + + @TableField("扇区id") + private Long 扇区id; + + @TableField("更新时间") + private LocalDateTime 更新时间; + + @ApiModelProperty("景区ID,需要") + @TableField("景区id") + private Integer 景区id; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2SpotConfigQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2SpotConfigQO.java new file mode 100644 index 0000000..f39a6be --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2SpotConfigQO.java @@ -0,0 +1,38 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * QO + *

+ * + * @author ck + * @since 2023-08-09 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Dp2SpotConfigQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + + @TableField("景区名称") + private String 景区名称; + + @TableField("行政区域") + private String 行政区域; + + @TableField("景区介绍") + private String 景区介绍; + + @TableField("景区大类") + private String 景区大类; + + private String keywords; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2ViewPowerAlarmQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2ViewPowerAlarmQO.java new file mode 100644 index 0000000..930254e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2ViewPowerAlarmQO.java @@ -0,0 +1,37 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.github.pagehelper.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * QO + *

+ * + * @author wqx + * @since 2023-08-31 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Dp2ViewPowerAlarmQO extends CommonDTO { + + private static final long serialVersionUID = 1L; + + private String keywords; + + //开始时间 + private String startTime; + + //结束时间 + private String endTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2ViewWirelessAlarmQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2ViewWirelessAlarmQO.java new file mode 100644 index 0000000..59883d0 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/Dp2ViewWirelessAlarmQO.java @@ -0,0 +1,100 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.github.pagehelper.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * QO + *

+ * + * @author wqx + * @since 2023-09-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Dp2ViewWirelessAlarmQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + + @TableField("id") + private Long id; + + @TableField("eventtime") + private LocalDateTime eventtime; + + @TableField("alarmname") + private String alarmname; + + @TableField("omcname") + private String omcname; + + @TableField("site_id") + private String siteId; + + @TableField("site_name") + private String siteName; + + @TableField("area") + private String area; + + @TableField("alarmid") + private String alarmid; + + @TableField("sitetype") + private String sitetype; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("cell_name") + private String cellName; + + @TableField("场馆id") + private Long 场馆id; + + @TableField("场馆名称") + private String 场馆名称; + + @TableField("longitude") + private Object longitude; + + @TableField("latitude") + private Object latitude; + + @TableField("坐席编号") + private String 坐席编号; + + @TableField("场内场外") + private String 场内场外; + + @TableField("区域id") + private Integer 区域id; + + @TableField("故障处理人") + private String 故障处理人; + + @TableField("phonenumber") + private String phonenumber; + + private String keywords; + + private Integer type; + + //开始时间 + private String startTime; + + //结束时间 + private String endTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/DpKpiMonitorQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/DpKpiMonitorQO.java new file mode 100644 index 0000000..72f6e8d --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/DpKpiMonitorQO.java @@ -0,0 +1,58 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/17 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DpKpiMonitorQO extends CommonDTO { + + @ApiModelProperty(value = "数据类型", required = true) + @NotBlank(message = "timetype不能为空") + private String datatype; + + @ApiModelProperty(value = "网络类型", required = true) + @NotBlank(message = "netType不能为空") + private String nettype; + + @ApiModelProperty(value = "场馆ids") + private Integer sceneid; + + @ApiModelProperty(value = "指标名称",required = true) + @NotBlank(message = "指标名称不能为空") + private String kpiname; + + + @ApiModelProperty(value = "开始时间") + @TableField("starttime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private LocalDateTime starttime; + + @ApiModelProperty(value = "结束时间") + @TableField("endtime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private LocalDateTime endtime; + + private String seatno; + + @ApiModelProperty(value = "查询表方式,1-查询特定表") + private int sceneruntype; + + @ApiModelProperty(value = "最大时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private LocalDateTime maxtime; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/DpSceneConfigQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/DpSceneConfigQO.java new file mode 100644 index 0000000..4825b6e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/DpSceneConfigQO.java @@ -0,0 +1,80 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.github.pagehelper.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * QO + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DpSceneConfigQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("自增id") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + + @ApiModelProperty("颜色等级") + @TableField("level") + private Short level; + + @ApiModelProperty("指标名称") + @TableField("name") + private String name; + + @ApiModelProperty("最小值") + @TableField("range1") + private Double range1; + + @ApiModelProperty("最大值") + @TableField("range2") + private Double range2; + + @ApiModelProperty("颜色") + @TableField("color") + private String color; + + @ApiModelProperty("备注") + @TableField("content") + private String content; + + + @ApiModelProperty("指标等级:cell、scene") + @TableField("type") + private String type; + + @ApiModelProperty("网络类型") + @TableField("nettype") + private String nettype; + + @ApiModelProperty("设备类型") + @TableField("celltype") + private String celltype; + + @ApiModelProperty("颜色分值") + @TableField("colorscore") + private Double colorscore; + + private BigDecimal value; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpi4gMinQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpi4gMinQO.java new file mode 100644 index 0000000..8c57432 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpi4gMinQO.java @@ -0,0 +1,103 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.github.pagehelper.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 场馆4G小区级1分钟指标QO + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi4gMinQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + + @TableField("groupid") + private Integer groupid; + + @TableField("时间") + private LocalDateTime 时间; + + @TableField("小区名称") + private String 小区名称; + + @TableField("地市区号") + private String 地市区号; + + @TableField("厂商id") + private String 厂商id; + + @TableField("avg_user") + private BigDecimal avgUser; + + @TableField("max_user") + private Integer maxUser; + + @TableField("prb_up") + private BigDecimal prbUp; + + @TableField("prb_down") + private BigDecimal prbDown; + + @TableField("avg_disturb") + private Integer avgDisturb; + + @TableField("speed_up") + private BigDecimal speedUp; + + @TableField("speed_down") + private BigDecimal speedDown; + + @TableField("call_succ_rate") + private BigDecimal callSuccRate; + + @TableField("call_drop_rate") + private BigDecimal callDropRate; + + @TableField("act_avg_user") + private BigDecimal actAvgUser; + + @TableField("act_max_user") + private Integer actMaxUser; + + @TableField("volte") + private BigDecimal volte; + + @TableField("volte_succ_rate") + private BigDecimal volteSuccRate; + + @TableField("volte_drop_rate") + private BigDecimal volteDropRate; + + @TableField("data_up") + private BigDecimal dataUp; + + @TableField("data_down") + private BigDecimal dataDown; + + @TableField("v1_max") + private BigDecimal v1Max; + + @TableField("v1_avg") + private String v1Avg; + + @TableField("update_time") + private LocalDateTime updateTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpi5gCellQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpi5gCellQO.java new file mode 100644 index 0000000..f9551ee --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpi5gCellQO.java @@ -0,0 +1,169 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.github.pagehelper.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 场馆5G小区级15分钟指标QO + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi5gCellQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; +// @ApiModelProperty("id") +// @TableField("id") +// private Long id; + + @TableField("venue_id") + private Integer venueId; + + @TableField("venue_name") + private String venueName; + + @TableField("ci") + private String ci; + + @TableField("starttime") + private LocalDateTime starttime; + + @TableField("小区名称") + private String 小区名称; + + @TableField("nr流量") + private Short nr流量; + + @TableField("上行5g流量") + private Short 上行5g流量; + + @TableField("下行5g流量") + private Short 下行5g流量; + + @TableField("小区rlc层下行丢包率") + private BigDecimal 小区rlc层下行丢包率; + + @TableField("小区级rlc层sdu下行空口丢包数") + private Short 小区级rlc层sdu下行空口丢包数; + + @TableField("小区rlc层收到的下行sdu包数") + private Short 小区rlc层收到的下行sdu包数; + + @TableField("平均用户数") + private Short 平均用户数; + + @TableField("最大用户数") + private Short 最大用户数; + + @TableField("sn异常释放率") + private BigDecimal sn异常释放率; + + @TableField("sgnb释放总次数") + private Short sgnb释放总次数; + + @TableField("sgnb触发sgnb异常释放总次数") + private Short sgnb触发sgnb异常释放总次数; + + @TableField("nsa_sgnb添加成功率") + private BigDecimal nsaSgnb添加成功率; + + @TableField("dc场景下发送sgnb增加成功的次数") + private Short dc场景下发送sgnb增加成功的次数; + + @TableField("dc场景下收到sgnb增加尝试的次数") + private Short dc场景下收到sgnb增加尝试的次数; + + @TableField("无线接通率") + private BigDecimal 无线接通率; + + @TableField("rrc建立成功次数") + private Short rrc建立成功次数; + + @TableField("rrc建立请求消息次数") + private Short rrc建立请求消息次数; + + @TableField("小区中qos_flow建立成功次数") + private Short 小区中qosFlow建立成功次数; + + @TableField("小区中qos_flow建立尝试次数") + private Short 小区中qosFlow建立尝试次数; + + @TableField("小区中ng信令连接建立成功次数") + private Short 小区中ng信令连接建立成功次数; + + @TableField("小区中ng信令连接建立尝试次数") + private Short 小区中ng信令连接建立尝试次数; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率; + + @TableField("小区中ue上下文异常释放的次数") + private Short 小区中ue上下文异常释放的次数; + + @TableField("小区中ue上下文正常释放的次数") + private Short 小区中ue上下文正常释放的次数; + + @TableField("无线掉线率分母") + private Short 无线掉线率分母; + + @TableField("切换成功率") + private BigDecimal 切换成功率; + + @TableField("切换成功率分子") + private Short 切换成功率分子; + + @TableField("切换成功率分母") + private Short 切换成功率分母; + + @TableField("下行平均使用的prb个数") + private Short 下行平均使用的prb个数; + + @TableField("下行平均可用prb个数") + private Short 下行平均可用prb个数; + + @TableField("上行平均使用的prb个数") + private Short 上行平均使用的prb个数; + + @TableField("上行平均可用prb个数") + private Short 上行平均可用prb个数; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率; + + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率; + + @TableField("input_datetime") + private LocalDateTime inputDatetime; + + @TableField("cell_name") + private String cellName; + + @TableField("pmsid") + private Long pmsid; + + @TableField("上行干扰值") + private Double 上行干扰值; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("endtime") + private LocalDateTime endtime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpi5gMinQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpi5gMinQO.java new file mode 100644 index 0000000..8b872cd --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpi5gMinQO.java @@ -0,0 +1,88 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.github.pagehelper.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 场馆5G小区级1分钟指标QO + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi5gMinQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + + @TableField("groupid") + private Integer groupid; + + @TableField("时间") + private LocalDateTime 时间; + + @TableField("小区名称") + private String 小区名称; + + @TableField("地市区号") + private String 地市区号; + + @TableField("厂商id") + private String 厂商id; + + @TableField("prb_up") + private Double prbUp; + + @TableField("prb_down") + private Double prbDown; + + @TableField("up_disturb") + private Integer upDisturb; + + @TableField("speed_up") + private Double speedUp; + + @TableField("speed_down") + private Double speedDown; + + @TableField("act_max_user") + private Integer actMaxUser; + + @TableField("act_avg_user") + private Double actAvgUser; + + @TableField("rrc_avg_user") + private BigDecimal rrcAvgUser; + + @TableField("rrc_max_user") + private Integer rrcMaxUser; + + @TableField("call_succ_rate") + private BigDecimal callSuccRate; + + @TableField("drop_call_rate") + private BigDecimal dropCallRate; + + @TableField("data_down") + private BigDecimal dataDown; + + @TableField("data_up") + private BigDecimal dataUp; + + @TableField("update_time") + private LocalDateTime updateTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiCellMonitorQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiCellMonitorQO.java new file mode 100644 index 0000000..8ad5abf --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiCellMonitorQO.java @@ -0,0 +1,96 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpiCellMonitorQO extends CommonDTO { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "数据类型", required = true) + @NotBlank(message = "timetype不能为空") + private String datatype; + + @ApiModelProperty(value = "网络类型", required = true) + @NotBlank(message = "netType不能为空") + private String nettype; + + @ApiModelProperty(value = "区县id") + private String regionid; + + @ApiModelProperty(value = "区县id") + private String regionIdv; + + @ApiModelProperty(value = "场馆ids") + private Integer[] sceneids; + + @ApiModelProperty(value = "场馆id") + private Integer sceneid; + + @ApiModelProperty(value = "小区id(多选)") + @TableField("小区id") + private String[] villageids; + + @ApiModelProperty(value = "小区名称(多选)") + @TableField("小区名称") + private String[] villagenames; + + @ApiModelProperty(value = "开始时间", required = true) + @TableField("starttime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @NotNull(message = "starttime不能为空") + private LocalDateTime starttime; + + @ApiModelProperty(value = "结束时间", required = true) + @TableField("endtime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @NotNull(message = "endtime不能为空") + private LocalDateTime endtime; + + @ApiModelProperty(value = "排序字段名") + @NotBlank(message = "排序字段名不能为空") + private String sortcol; + + @ApiModelProperty(value = "排序") + @NotBlank(message = "排序不能为空") + private String sort; + + @ApiModelProperty(value = "坐席区(多选)") + private String[] seat; + + @ApiModelProperty(value = "坐席区颜色") + private String seatcolor; + + @ApiModelProperty(value = "指标名称") + @NotBlank(message = "指标名称不能为空") + private String kpiname; + + @ApiModelProperty(value = "是否为缓存查询(是:true)",required = true) + @NotNull(message = "isCache参数不能为空") + private Boolean iscache; + + private String seatno; + + + @ApiModelProperty(value = "查询表方式,1-查询特定表") + private int sceneruntype; + + private String venuetype; + private String maintaintype; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiCellQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiCellQO.java new file mode 100644 index 0000000..fa6d52b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiCellQO.java @@ -0,0 +1,90 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.github.pagehelper.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; +import reactor.util.annotation.NonNull; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + *

+ * 场馆4G小区级15分钟指标QO + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpiCellQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "网络类型:0-4G,1-5G", required = true) + @NotBlank(message = "netType不能为空") + private String netType; + + @ApiModelProperty(value = "区县id") + private String regionId; + + @ApiModelProperty(value = "区县id") + private String regionIdv; + + @ApiModelProperty(value = "场馆ids") + private Integer[] venueIds; + + @ApiModelProperty(value = "场馆id") + private Integer venueid; + + + @ApiModelProperty(value = "小区id(多选)") + @TableField("小区id") + private String[] villageIds; + + @ApiModelProperty(value = "小区名称(多选)") + @TableField("小区名称") + private String[] villageNames; + + @ApiModelProperty(value = "开始时间", required = true) + @TableField("starttime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @NotNull(message = "starttime不能为空") + private LocalDateTime starttime; + + @ApiModelProperty(value = "结束时间", required = true) + @TableField("endtime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @NotNull(message = "endtime不能为空") + private LocalDateTime endtime; + + @ApiModelProperty(value = "排序字段名") + @NotBlank(message = "排序字段名不能为空") + private String sortcol; + + @ApiModelProperty(value = "排序") + @NotBlank(message = "排序不能为空") + private String sort; + + private LocalDateTime querystarttime; + + private Integer queryvenueid; + + private String venuetype; + private String maintaintype; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiColorQo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiColorQo.java new file mode 100644 index 0000000..772d45e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiColorQo.java @@ -0,0 +1,44 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * @author yqf + * @date 2023/4/26 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpiColorQo { + + + @ApiModelProperty(value = "网络类型") + private String nettype; + + @ApiModelProperty("最大用户数值") + private BigDecimal maxuservalue; + + @ApiModelProperty("上行prb利用率值") + private BigDecimal prbupvalue; + + @ApiModelProperty("下行prb利用率值") + private BigDecimal prbdownvalue; + + @ApiModelProperty("上行平均干扰值") + private BigDecimal avgdisvalue; + + @ApiModelProperty("小区频段") + private String freqtype; + + @ApiModelProperty("设备类型") + private String devicetype; + + @ApiModelProperty("带宽") + private Long bandwidth; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiMinQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiMinQO.java new file mode 100644 index 0000000..8486b48 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiMinQO.java @@ -0,0 +1,73 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpiMinQO extends CommonDTO { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "网络类型:0-4G,1-5G", required = true) + @NotBlank(message = "netType不能为空") + private String netType; + + @ApiModelProperty(value = "区县id") + private String regionId; + + @ApiModelProperty(value = "区县id") + private String regionIdv; + + @ApiModelProperty(value = "场馆ids") + private Integer[] venueIds; + + @ApiModelProperty(value = "场馆id") + private Integer venueid; + + @ApiModelProperty(value = "小区id(多选)") + @TableField("小区id") + private String[] villageIds; + + @ApiModelProperty(value = "小区名称(多选)") + @TableField("小区名称") + private String[] villageNames; + + @ApiModelProperty(value = "开始时间", required = true) + @TableField("starttime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @NotNull(message = "starttime不能为空") + private LocalDateTime starttime; + + @ApiModelProperty(value = "结束时间", required = true) + @TableField("endtime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @NotNull(message = "endtime不能为空") + private LocalDateTime endtime; + + @ApiModelProperty(value = "排序字段名") + @NotBlank(message = "排序字段名不能为空") + private String sortcol; + + @ApiModelProperty(value = "排序") + @NotBlank(message = "排序不能为空") + private String sort; + + private String venuetype; + private String maintaintype; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiVenueQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiVenueQO.java new file mode 100644 index 0000000..72994a0 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/PmKpiVenueQO.java @@ -0,0 +1,56 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpiVenueQO extends CommonDTO { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "网络类型:1-4G,2-5G", required = true) + @NotBlank(message = "netType不能为空") + private String netType; + + @ApiModelProperty(value = "市级id") + private String cityId; + + @ApiModelProperty(value = "区县id") + private String regionId; + + @ApiModelProperty(value = "场馆ids") + @TableField("venue_id") + private Integer[] venueIds; + + @TableField("venue_id") + private Integer venueId; + + @ApiModelProperty(value = "开始时间", required = true) + @TableField("starttime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @NotNull(message = "starttime不能为空") + private LocalDateTime starttime; + + @ApiModelProperty(value = "结束时间", required = true) + @TableField("endtime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @NotNull(message = "endtime不能为空") + private LocalDateTime endtime; + + private String orderby; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/SysNoticeQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/SysNoticeQO.java new file mode 100644 index 0000000..2a65dde --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/SysNoticeQO.java @@ -0,0 +1,138 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + *

+ * 通知公告表QO + *

+ * + * @author ck + * @since 2023-04-14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SysNoticeQO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增id") + @TableId(value = "notice_id", type = IdType.AUTO) + private Integer noticeId; + + @ApiModelProperty("通知标题") + @TableField("notice_title") + private String noticeTitle; + + @ApiModelProperty("通知类型--字典表sys_notice_type") + @TableField("notice_type") + private String noticeType; + + @ApiModelProperty("通知内容") + @TableField("notice_content") + private String noticeContent; + + @ApiModelProperty("状态 0未读 1已读") + @TableField("status") + private String status; + + @ApiModelProperty("创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty("插入时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty("更新人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty("更新时间") + @TableField("update_time") + private LocalDateTime updateTime; + + @ApiModelProperty("备注") + @TableField("remark") + private String remark; + + @ApiModelProperty("接收人") + @TableField("recive_user") + private Integer reciveUser; + + @ApiModelProperty("工作流id") + @TableField("flw_processid") + private String flwProcessid; + + @ApiModelProperty("工作流任务id") + @TableField("flw_taskid") + private String flwTaskid; + + @ApiModelProperty("实际发送时间") + @TableField("send_time") + private LocalDateTime sendTime; + + private LocalDateTime beginTime; + private LocalDateTime endTime; + + @ApiModelProperty("发送是否成功,1成功 0失败") + @TableField("send_status") + private String sendStatus; + + @ApiModelProperty("接收人手机号") + @TableField("recive_user_phone") + private String reciveUserPhone; + + @ApiModelProperty("计划发送时间(同天当前时间之前立即发送)") + @TableField("exp_send_time") + private LocalDateTime expSendTime; + + @ApiModelProperty("加入定时任务标记 默认0未加入 1已加入") + @TableField("add_flag") + private String addFlag; + + @ApiModelProperty("通知对象ids数组") + @TableField("notice_object_id") + private String noticeObjectId; + + @ApiModelProperty("通知模板id") + @TableField("notice_model_id") + private Long noticeModelId; + + @ApiModelProperty("通知场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @TableField("model_scene") + private String modelScene; + + @ApiModelProperty("对象属性--yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + private String objectProto; + + @ApiModelProperty("通知对象(是指具体的通知接受者,呈现方式包括场馆+群组;分公司+群组名;地市+群组名;ITCC+群组名;场馆+个人名;分公司+个人名;地市+个人名;ITCC+个人名这几种组合。具体呈现内容和对象属性、通知方式相关联)") + @TableField("notice_object") + private String noticeObject; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3简报") + @TableField("model_suit_type") + private String modelSuitType; + + @ApiModelProperty("关联表id(yw_notice_handwork)") + @TableField("handwork_id") + private Long handworkId; + + @ApiModelProperty("关键字") + private String keyWord; + + private Integer pageNum; + + private Integer pageSize; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwDrsConfigQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwDrsConfigQO.java new file mode 100644 index 0000000..04d2e90 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwDrsConfigQO.java @@ -0,0 +1,71 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + *

+ * DRS配置表QO + *

+ * + * @author ck + * @since 2023-06-13 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwDrsConfigQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("任务名称") + @TableField("task_name") + private String taskName; + + @ApiModelProperty("任务类型 drs_task_type 0 / 1 签到 2巡检") + @TableField("drs_task_type") + private String drsTaskType; + + @ApiModelProperty("状态") + @TableField("status") + private String status; + + @ApiModelProperty("创建人") + @TableField(value = "create_by", fill = FieldFill.INSERT) + private String createBy; + + @ApiModelProperty("创建时间") + @TableField(value = "create_time", fill = FieldFill.INSERT) + private LocalDateTime createTime; + + @ApiModelProperty("修改人") + @TableField(value = "update_by", fill = FieldFill.UPDATE) + private String updateBy; + + @ApiModelProperty("修改时间") + @TableField(value = "update_time", fill = FieldFill.UPDATE) + private LocalDateTime updateTime; + + @ApiModelProperty("备注") + @TableField("remark") + private String remark; + + @ApiModelProperty("删除标记") + @TableField("del_flag") + private String delFlag; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwDrsTempTaskQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwDrsTempTaskQO.java new file mode 100644 index 0000000..b1fab19 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwDrsTempTaskQO.java @@ -0,0 +1,106 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * DRS临时任务表QO + *

+ * + * @author ck + * @since 2023-06-13 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwDrsTempTaskQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; + + @ApiModelProperty("场馆属性") + private String venueType; + + @ApiModelProperty("维护类型") + private String maintainType; + + @ApiModelProperty("场馆id数组") + private List venueIds; + + @ApiModelProperty("任务日期") + @TableField("task_date") + private LocalDate taskDate; + + @ApiModelProperty("任务时间") + @TableField("task_time") + private LocalDateTime taskTime; + + @ApiModelProperty("任务结束时间") + @TableField("task_end_time") + private LocalDateTime taskEndTime; + + @ApiModelProperty("任务名称") + @TableField("task_name") + private String taskName; + + @ApiModelProperty("DRS任务类型 drs_task_type 0 / 1 签到 2巡检") + @TableField("drs_task_type") + private String drsTaskType; + + @ApiModelProperty("DRS任务状态 drs_task_status 0未开始 1进行中 2已完成") + @TableField("drs_task_status") + private String drsTaskStatus; + + @ApiModelProperty("自动状态变更 0自动 1手动") + @TableField("drs_auto_update") + private String drsAutoUpdate; + + @ApiModelProperty("状态") + @TableField("status") + private String status; + + @ApiModelProperty("创建人") + @TableField(value = "create_by", fill = FieldFill.INSERT) + private String createBy; + + @ApiModelProperty("创建时间") + @TableField(value = "create_time", fill = FieldFill.INSERT) + private LocalDateTime createTime; + + @ApiModelProperty("修改人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty("修改时间") + @TableField("update_time") + private LocalDateTime updateTime; + + @ApiModelProperty("备注") + @TableField("remark") + private String remark; + + @ApiModelProperty("删除标记") + @TableField("del_flag") + private String delFlag; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwKpiConfigQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwKpiConfigQO.java new file mode 100644 index 0000000..a65735c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwKpiConfigQO.java @@ -0,0 +1,84 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.github.pagehelper.Page; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 指标字段阈值配置表QO + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwKpiConfigQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("序号") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("专业(字典表)") + @TableField("subject") + private String subject; + + @ApiModelProperty("网络模式(字典表)") + @TableField("net_type") + private String netType; + + @ApiModelProperty("指标字段") + @TableField("kpi_field") + private Long kpiField; + + @ApiModelProperty("阈值范围") + @TableField("threshold_value") + private String thresholdValue; + + @ApiModelProperty("颜色") + @TableField("color") + private String color; + + @ApiModelProperty("创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty("创建时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty("更新人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty("更新时间") + @TableField("update_time") + private LocalDateTime updateTime; + + @ApiModelProperty("最小是(包括本值)") + @TableField("min_value") + private Object minValue; + + @ApiModelProperty("最大值(不包括本值)") + @TableField("max_value") + private Object maxValue; + + @ApiModelProperty("指标名") + @TableField("kpi_field_name") + private String kpiFieldName; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeBriefingQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeBriefingQO.java new file mode 100644 index 0000000..bf8ff8c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeBriefingQO.java @@ -0,0 +1,112 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonAlias; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知通告简报计划表QO + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeBriefingQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("地市") + @TableField("city") + //这个注解只在反序列化时起作用,指定该java属性可以接受的更多名称 (别名嘛~) + @JsonAlias({"city"}) + private String city; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private List venueId; + + @ApiModelProperty("场馆属性") + private String venueType; + + @ApiModelProperty("维护类型") + private String maintainType; + + @ApiModelProperty("对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + private String objectProto; + + @ApiModelProperty("通知方式sys_notice_type") + @TableField("notice_type") + private String noticeType; + + @ApiModelProperty("发送日期") + @TableField("send_date") + private LocalDate sendDate; + + @ApiModelProperty("开始时间") + @TableField("begin_time") + private LocalDateTime beginTime; + + @ApiModelProperty("结束时间") + @TableField("end_time") + private LocalDateTime endTime; + + @ApiModelProperty("区县") + @TableField("county") + private String county; + + @ApiModelProperty("对象ids数组") + @TableField("object_ids") + private List objectIds; + + @ApiModelProperty("模板id") + @TableField("model_id") + private Long modelId; + + @ApiModelProperty("排序号") + @TableField("order_num") + private Integer orderNum; + + @ApiModelProperty("时间间隔(单位分)") + @TableField("time_interval") + private Integer timeInterval; + + @ApiModelProperty("通知名称") + @TableField("notice_name") + private String noticeName; + + @ApiModelProperty("启用状态 sys_normal_disable 0启用 1停用") + @TableField("sys_normal_disable") + private String sysNormalDisable; + + @ApiModelProperty("关键字") + private String keyWord; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3文字简报 4h5简报)") + @TableField("model_suit_type") + private String modelSuitType; + + @ApiModelProperty("发送方式 send_type (1自动发送 2手工发送)") + @TableField("send_type") + private String sendType; + + @ApiModelProperty("发送人员") + @TableField("send_user") + private Long sendUser; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeHandworkQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeHandworkQO.java new file mode 100644 index 0000000..ddc38bc --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeHandworkQO.java @@ -0,0 +1,89 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知通告手工通知计划表QO + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeHandworkQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("通知名称") + @TableField("notice_name") + private String noticeName; + + @ApiModelProperty("通知模板id") + @TableField("notice_model") + private Long noticeModel; + + @ApiModelProperty("通知方式--sys_notice_type") + @TableField("notice_type") + private List noticeType; + + @ApiModelProperty("通知对象ids") + @TableField("notice_object") + private List noticeObject; + + @ApiModelProperty("通知内容") + @TableField("notice_content") + private String noticeContent; + + @ApiModelProperty("通知状态yw_veriy_status 0待提交 1待审核 2已审核") + @TableField("notice_status") + private List noticeStatus; + + @ApiModelProperty("日期") + @TableField("notice_date") + private LocalDateTime noticeDate; + + @ApiModelProperty("开始时间") + private LocalDateTime beginTime; + + @ApiModelProperty("结束时间") + private LocalDateTime endTime; + + @ApiModelProperty("时间间隔(单位分)") + @TableField("time_interval") + private Integer timeInterval; + + @ApiModelProperty("工作流processid") + @TableField("flw_processid") + private String flwProcessid; + + @ApiModelProperty("申请人id") + @TableField("apply_id") + private Long applyId; + + @ApiModelProperty("审核人id") + @TableField("audit_id") + private Long auditId; + + @ApiModelProperty("已添加到sys_notice标记(0否 1是)") + @TableField("add_flag") + private String addFlag; + + @ApiModelProperty("关键字") + private String keyWord; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeHandworkdetailQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeHandworkdetailQO.java new file mode 100644 index 0000000..0bb5698 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeHandworkdetailQO.java @@ -0,0 +1,55 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + *

+ * 通知通告手工通知审核表QO + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeHandworkdetailQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("手工通知id") + @TableField("handwork_id") + private Long handworkId; + + @ApiModelProperty("操作人(提交审核的人 或者 审核的人)") + @TableField("oprate_user") + private Long oprateUser; + + @ApiModelProperty("审核结果(关联字典表yw_veriy_result 0通过 1驳回)") + @TableField("veriy_result") + private String veriyResult; + + @ApiModelProperty("审核状态(关联字典表yw_veriy_status 0 待审核 1 已审核)") + @TableField("veriy_status") + private String veriyStatus; + + @ApiModelProperty("驳回原因") + @TableField("fail_reason") + private String failReason; + + @ApiModelProperty("附件") + @TableField("appendix") + private String appendix; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeListQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeListQO.java new file mode 100644 index 0000000..936af69 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeListQO.java @@ -0,0 +1,96 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知通告记录表QO + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeListQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("通知名称") + @TableField("notice_name") + private String noticeName; + + @ApiModelProperty("通知场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @TableField("model_scene") + private String modelScene; + + @ApiModelProperty("对象属性--yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + private String objectProto; + + @ApiModelProperty("通知方式--sys_notice_type") + @TableField("notice_type") + private String noticeType; + + @ApiModelProperty("通知时间(计划发送时间(同天当前时间之前立即发送))") + @TableField("notice_time") + private LocalDateTime noticeTime; + + @ApiModelProperty("通知对象") + @TableField("notice_object") + private String noticeObject; + + @ApiModelProperty("通知内容") + @TableField("notice_content") + private String noticeContent; + + @ApiModelProperty("状态 0未读 1已读") + @TableField("status") + private String status; + + @ApiModelProperty("通知对象ids数组") + @TableField("notice_object_id") + private List noticeObjectId; + + @ApiModelProperty("通知模板id") + @TableField("notice_model_id") + private Long noticeModelId; + + @ApiModelProperty("实际发送时间") + @TableField("send_time") + private LocalDateTime sendTime; + + @ApiModelProperty("发送是否成功,1成功 0失败") + @TableField("send_status") + private String sendStatus; + + @ApiModelProperty("计划发送时间(同天当前时间之前立即发送)") + @TableField("exp_send_time") + private LocalDateTime expSendTime; + + @ApiModelProperty("加入定时任务标记 默认0未加入 1已加入") + @TableField("add_flag") + private String addFlag; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3简报") + @TableField("model_suit_type") + private String modelSuitType; + + @ApiModelProperty("计划id(手工与简报会先配置计划)") + @TableField("plan_id") + private Long planId; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeModelQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeModelQO.java new file mode 100644 index 0000000..86e0b3e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeModelQO.java @@ -0,0 +1,80 @@ +package com.ruoyi.eastcom_yw.domain.qo; + + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.github.pagehelper.Page; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知通告模板表QO + *

+ * + * @author ck + * @since 2023-04-07 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeModelQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("模板名称") + @TableField("model_name") + private String modelName; + + @ApiModelProperty("模板内容") + @TableField("model_content") + private String modelContent; + + @ApiModelProperty("场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @TableField("model_scene") + private String modelScene; + + @ApiModelProperty("用户id") + @TableField(value = "create_user_id", fill = FieldFill.INSERT) + private Long createUserId; + + @ApiModelProperty("创建用户昵称") + @TableField(value = "create_by", fill = FieldFill.INSERT) + private String createBy; + + @ApiModelProperty("创建时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty("模板适用类型model_suit_type 1 普通 2 手工 3简报") + @TableField("model_suit_type") + private String modelSuitType; + + @ApiModelProperty("备注(写一些触发要求)") + @TableField("model_des") + private String modelDes; + + @ApiModelProperty("模板类型--字典model_type 0事件触发型") + @TableField("model_type") + private String modelType; + + @ApiModelProperty("排序号") + @TableField("order_num") + private Integer orderNum; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeObjectQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeObjectQO.java new file mode 100644 index 0000000..3885224 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwNoticeObjectQO.java @@ -0,0 +1,103 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + *

+ * 通知通告对象表QO + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeObjectQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("地市") + @TableField("city") + private String city; + + @ApiModelProperty("区县") + @TableField("county") + private String county; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private List venueId; + + @ApiModelProperty("场馆属性") + private String venueType; + + @ApiModelProperty("维护类型") + private String maintainType; + + @ApiModelProperty("专业") + @TableField("specialty") + private Long specialty; + + @ApiModelProperty("角色id数组") + @TableField("role_ids") + private List roleIds; + + @ApiModelProperty("对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + private String objectProto; + + @ApiModelProperty("通知方式sys_notice_type") + @TableField("notice_type") + private String noticeType; + + @ApiModelProperty("短信组名") + @TableField("message_name") + private String messageName; + + @ApiModelProperty("短信组内成员id数组") + @TableField("message_users") + private List messageUsers; + + @ApiModelProperty("排序号") + @TableField("order_num") + private Integer orderNum; + + @ApiModelProperty("群号") + @TableField("group_id") + private String groupId; + + @ApiModelProperty("群名") + @TableField("group_name") + private String groupName; + + @ApiModelProperty("备注") + @TableField("group_des") + private String groupDes; + + @ApiModelProperty("对象名称") + @TableField("object_name") + private String objectName; + + @ApiModelProperty("ivr组名") + @TableField("ivr_name") + private String ivrName; + + @ApiModelProperty("ivr组内成员id数组") + @TableField("ivr_users") + private List ivrUsers; + + @ApiModelProperty("关键字") + private String keyWord; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwSparePartsQO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwSparePartsQO.java new file mode 100644 index 0000000..6ad276b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/qo/YwSparePartsQO.java @@ -0,0 +1,59 @@ +package com.ruoyi.eastcom_yw.domain.qo; + +import com.github.pagehelper.Page; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; + +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 亚运备件表QO + *

+ * + * @author yqf + * @since 2023-08-31 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwSparePartsQO extends CommonDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("场馆名称") + @TableField("venue_name") + private String venueName; + + @ApiModelProperty("场馆类型") + @TableField("venue_type") + private String venueType; + + @ApiModelProperty("设备类型") + @TableField("device_type") + private String deviceType; + + @ApiModelProperty("专业") + @TableField("major") + private String major; + + + @ApiModelProperty("联系人") + @TableField("contacts") + private String contacts; + + @ApiModelProperty("联系电话") + @TableField("telephone") + private String telephone; + + @ApiModelProperty("搜索型号") + private String queryType; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/AlarmStaticListVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/AlarmStaticListVo.java new file mode 100644 index 0000000..cd531e5 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/AlarmStaticListVo.java @@ -0,0 +1,17 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; + +@Data +public class AlarmStaticListVo { + + private String venueName; + private Integer alarmNum; + private Integer alarmWxNum; + private Integer alarmCsNum; + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/AlarmStatisticsListVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/AlarmStatisticsListVo.java new file mode 100644 index 0000000..16777c6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/AlarmStatisticsListVo.java @@ -0,0 +1,10 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +@Data +public class AlarmStatisticsListVo { + private String subscene_name; + private String profession; + private Integer alarm_count; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/AlarmTopListVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/AlarmTopListVo.java new file mode 100644 index 0000000..a19c4a5 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/AlarmTopListVo.java @@ -0,0 +1,18 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; + +@Data +public class AlarmTopListVo { + private String alarm_serial; + private String alarm_title; + private String subscene_name; + private String ne_name; + private String profession; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private Date alarm_occr_time; + private String handler; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/DictTreeVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/DictTreeVO.java new file mode 100644 index 0000000..f56e59e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/DictTreeVO.java @@ -0,0 +1,17 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DictTreeVO { + + private String label; + private String value; + private List children; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2AgisLink5miVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2AgisLink5miVO.java new file mode 100644 index 0000000..d3bfb1c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2AgisLink5miVO.java @@ -0,0 +1,140 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * VO + *

+ * + * @author yqf + * @since 2023-08-18 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Dp2AgisLink5miVO { + + + private static final long serialVersionUID = 1L; + + @TableField("stat_date") + private LocalDateTime statDate; + + @TableField("city_code") + private String cityCode; + + @TableField("city_name") + private String cityName; + + @TableField("venue_code") + private String venueCode; + + @TableField("venue_name") + private String venueName; + + @TableField("link_value_code") + private String linkValueCode; + + @TableField("link_value") + private String linkValue; + + @TableField("link_code") + private String linkCode; + + @TableField("link_name") + private String linkName; + + @TableField("bandwith") + private BigDecimal bandwith; + + @TableField("delay") + private BigDecimal delay; + + @TableField("jitter") + private BigDecimal jitter; + + @TableField("lpack_ratio") + private BigDecimal lpackRatio; + + @TableField("ul_velocity") + private BigDecimal ulVelocity; + + @TableField("dl_velocity") + private BigDecimal dlVelocity; + + @TableField("ul_flow") + private BigDecimal ulFlow; + + @TableField("dl_flow") + private BigDecimal dlFlow; + + @TableField("ul_band_ratio") + private BigDecimal ulBandRatio; + + @TableField("dl_band_ratio") + private BigDecimal dlBandRatio; + + @TableField("total_band_ratio") + private BigDecimal totalBandRatio; + + @TableField("load_time") + private LocalDateTime loadTime; + + @TableField("a_device_alias") + private String aDeviceAlias; + + @TableField("z_device_alias") + private String zDeviceAlias; + + @TableField("dl_max_24h_ratio") + private BigDecimal dlMax24hRatio; + + @TableField("ul_max_24h_ratio") + private BigDecimal ulMax24hRatio; + + @TableField("dl_avg_24h_ratio") + private BigDecimal dlAvg24hRatio; + + @TableField("ul_avg_24h_ratio") + private BigDecimal ulAvg24hRatio; + + @TableField("a_device_name") + private String aDeviceName; + + @TableField("a_port_name") + private String aPortName; + + @TableField("z_device_name") + private String zDeviceName; + + @TableField("z_port_name") + private String zPortName; + + @TableField("a_port_full_name") + private String aPortFullName; + + @TableField("z_port_full_name") + private String zPortFullName; + + @TableField("a_port_short_name") + private String aPortShortName; + + @TableField("z_port_short_name") + private String zPortShortName; + + @TableField("update_time") + private LocalDateTime updateTime; + + //AGIS流量 + private BigDecimal flowcount; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2PnNetVenue5miVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2PnNetVenue5miVO.java new file mode 100644 index 0000000..0e20e19 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2PnNetVenue5miVO.java @@ -0,0 +1,138 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * VO + *

+ * + * @author yqf + * @since 2023-08-21 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Dp2PnNetVenue5miVO { + + + private static final long serialVersionUID = 1L; + + @TableField("stat_date") + private LocalDateTime statDate; + + @TableField("city_code") + private String cityCode; + + @TableField("city_name") + private String cityName; + + @ApiModelProperty("互联网在线用户数") + @TableField("online_user_cnt") + private Double onlineUserCnt; + + @TableField("inter_exp_bandwith") + private Double interExpBandwith; + + @TableField("interc_bandwith") + private Double intercBandwith; + + @TableField("venue_bandwith") + private Double venueBandwith; + + @TableField("dl_inter_exp_flow") + private Double dlInterExpFlow; + + @TableField("ul_inter_exp_flow") + private Double ulInterExpFlow; + + @TableField("dl_interc_flow") + private Double dlIntercFlow; + + @TableField("ul_interc_flow") + private Double ulIntercFlow; + + @TableField("dl_venue_flow") + private Double dlVenueFlow; + + @TableField("ul_venue_flow") + private Double ulVenueFlow; + + @TableField("dl_inter_exp_band_ratio") + private Double dlInterExpBandRatio; + + @TableField("ul_inter_exp_band_ratio") + private Double ulInterExpBandRatio; + + @TableField("dl_interc_band_ratio") + private Double dlIntercBandRatio; + + @TableField("ul_interc_band_ratio") + private Double ulIntercBandRatio; + + @ApiModelProperty("互联网下行带宽利用率") + @TableField("dl_venue_band_ratio") + private Double dlVenueBandRatio; + + @ApiModelProperty("互联网上行带宽利用率") + @TableField("ul_venue_band_ratio") + private Double ulVenueBandRatio; + + @TableField("dl_inter_exp_velocity") + private Double dlInterExpVelocity; + + @TableField("ul_inter_exp_velocity") + private Double ulInterExpVelocity; + + @TableField("dl_interc_velocity") + private Double dlIntercVelocity; + + @TableField("ul_interc_velocity") + private Double ulIntercVelocity; + + @ApiModelProperty("互联网场馆出口_下行流速") + @TableField("dl_venue_velocity") + private Double dlVenueVelocity; + + @ApiModelProperty("互联网出口_上行流速") + @TableField("ul_venue_velocity") + private Double ulVenueVelocity; + + @TableField("interc_delay") + private Double intercDelay; + + @TableField("inter_exp_delay") + private Double interExpDelay; + + @TableField("interc_jitter") + private Double intercJitter; + + @TableField("inter_exp_jitter") + private Double interExpJitter; + + @TableField("interc_lpack_ratio") + private Double intercLpackRatio; + + @TableField("inter_exp_lpack_ratio") + private Double interExpLpackRatio; + + @TableField("load_time") + private LocalDateTime loadTime; + + @TableField("venue_code") + private String venueCode; + + @TableField("venue_name") + private String venueName; + + @TableField("update_time") + private LocalDateTime updateTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2SpotCellVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2SpotCellVO.java new file mode 100644 index 0000000..e4355f1 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2SpotCellVO.java @@ -0,0 +1,167 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + *

+ * VO + *

+ * + * @author ck + * @since 2023-08-10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Dp2SpotCellVO { + + + private static final long serialVersionUID = 1L; + + @TableField("id") + private Integer id; + + @TableField("omc") + @Excel(name = "OMC") + private String omc; + + @ApiModelProperty("需要") + @TableField("县市") + @Excel(name = "县市") + private String 县市; + + @TableField("enodebid") + @Excel(name = "enodebid") + private Long enodebid; + + @TableField("本地小区标识") + @Excel(name = "本地小区标识") + private Long 本地小区标识; + + @TableField("小区标识") + @Excel(name = "小区标识") + private Long 小区标识; + + @ApiModelProperty("需要") + @TableField("站号") + @Excel(name = "站号") + private Long 站号; + + @ApiModelProperty("需要") + @TableField("ci") + @Excel(name = "ci") + private Long ci; + + @ApiModelProperty("需要") + @TableField("基站全称") + @Excel(name = "基站全称") + private String 基站全称; + + @TableField("en名称") + @Excel(name = "en名称") + private String en名称; + + @ApiModelProperty("需要") + @TableField("小区名称") + @Excel(name = "小区名称") + private String 小区名称; + + @ApiModelProperty("需要") + @TableField("小区频段") + @Excel(name = "小区频段") + private String 小区频段; + + @ApiModelProperty("需要") + @TableField("纬度") + @Excel(name = "纬度") + private Double 纬度; + + @ApiModelProperty("需要") + @TableField("经度") + @Excel(name = "经度") + private Double 经度; + + @TableField("纬度gcj") + @Excel(name = "纬度gcj") + private Double 纬度gcj; + + @TableField("经度gcj") + @Excel(name = "经度gcj") + private Double 经度gcj; + + @ApiModelProperty("需要") + @TableField("室内室外") + @Excel(name = "室内室外") + private String 室内室外; + + @ApiModelProperty("需要") + @TableField("网络") + @Excel(name = "网络") + private String 网络; + + @TableField("现网状态") + @Excel(name = "现网状态") + private String 现网状态; + + @TableField("cgi") + @Excel(name = "cgi") + private String cgi; + + @TableField("频点") + @Excel(name = "频点") + private Long 频点; + + @TableField("pci") + @Excel(name = "pci") + private Long pci; + + @TableField("tac") + @Excel(name = "tac") + private Long tac; + + @TableField("一级场景") + @Excel(name = "一级场景") + private String 一级场景; + + @TableField("二级场景") + @Excel(name = "二级场景") + private String 二级场景; + + @ApiModelProperty("需要") + @TableField("设备类型") + @Excel(name = "设备类型") + private String 设备类型; + + @ApiModelProperty("需要") + @TableField("带宽") + @Excel(name = "带宽") + private Double 带宽; + + @ApiModelProperty("需要") + @TableField("方位角") + @Excel(name = "方位角") + private Long 方位角; + + @TableField("扇区id") + @Excel(name = "扇区id") + private Long 扇区id; + + @TableField("更新时间") + private LocalDateTime 更新时间; + + @ApiModelProperty("景区ID,需要") + @TableField("景区id") + @Excel(name = "景区id") + private Integer 景区id; + + + private String reason; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2SpotConfigVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2SpotConfigVO.java new file mode 100644 index 0000000..65bc3cf --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2SpotConfigVO.java @@ -0,0 +1,48 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * VO + *

+ * + * @author ck + * @since 2023-08-09 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Dp2SpotConfigVO { + + + private static final long serialVersionUID = 1L; + + @TableField("景区id") + private Integer 景区id; + + @TableField("景区名称") + private String 景区名称; + + @TableField("行政区域") + private String 行政区域; + + @TableField("中心经度") + private Object 中心经度; + + @TableField("中心纬度") + private Object 中心纬度; + + @TableField("景区介绍") + private String 景区介绍; + + @TableField("景区大类") + private String 景区大类; + + @TableField("景区大类id") + private Integer 景区大类id; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2ViewPowerAlarmVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2ViewPowerAlarmVO.java new file mode 100644 index 0000000..402e49f --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2ViewPowerAlarmVO.java @@ -0,0 +1,95 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; + +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * VO + *

+ * + * @author wqx + * @since 2023-08-31 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Dp2ViewPowerAlarmVO { + + + private static final long serialVersionUID = 1L; + + @TableField("eventtime") + @Excel(name="告警时间") + private LocalDateTime eventtime; + + @TableField("alarmname") + @Excel(name="告警名称") + private String alarmname; + + @TableField("alarmid") + @Excel(name="告警ID") + private Long alarmid; + + @TableField("severity") + @Excel(name="severity") + private String severity; + + @TableField("site_id") + @Excel(name="基站ID") + private String siteId; + + @TableField("site_name") + @Excel(name="基站名称") + private String siteName; + + @TableField("device_name") + @Excel(name="设备名称") + private String deviceName; + + @TableField("owner") + @Excel(name="所有者") + private String owner; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("area") + @Excel(name="区域") + private String area; + + @TableField("logicalsites") + private String logicalsites; + + @TableField("场馆id") + @Excel(name="场馆ID") + private Integer 场馆id; + + @TableField("区域id") + @Excel(name="区域ID") + private Integer 区域id; + + @TableField("场馆名称") + @Excel(name="场馆名称") + private String 场馆名称; + + @TableField("故障处理人") + @Excel(name="故障处理人") + private String 故障处理人; + + @TableField("phonenumber") + @Excel(name="故障处理人联系电话") + private String phonenumber; + + @Excel(name="景区名称") + private String 景区名称; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2ViewWirelessAlarmVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2ViewWirelessAlarmVO.java new file mode 100644 index 0000000..c8d3b9e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/Dp2ViewWirelessAlarmVO.java @@ -0,0 +1,110 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; + +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * VO + *

+ * + * @author wqx + * @since 2023-09-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Dp2ViewWirelessAlarmVO { + + + private static final long serialVersionUID = 1L; + + @TableField("id") + private Long id; + + @TableField("eventtime") + @Excel(name ="告警时间") + private LocalDateTime eventtime; + + @TableField("alarmname") + @Excel(name ="告警名称") + private String alarmname; + + @TableField("omcname") + @Excel(name ="OMC名称") + private String omcname; + + @TableField("site_id") + @Excel(name ="基站ID") + private String siteId; + + @TableField("site_name") + @Excel(name ="基站名称") + private String siteName; + + @TableField("area") + @Excel(name ="基站区域") + private String area; + + @TableField("alarmid") + @Excel(name ="告警ID") + private String alarmid; + + @TableField("sitetype") + @Excel(name ="基站类型") + private String sitetype; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("cell_name") + @Excel(name ="小区名称") + private String cellName; + + @TableField("场馆id") + @Excel(name ="场馆id") + private Long 场馆id; + + @TableField("场馆名称") + @Excel(name ="场馆名称") + private String 场馆名称; + + @TableField("longitude") + @Excel(name ="经度") + private Object longitude; + + @TableField("latitude") + @Excel(name ="纬度") + private Object latitude; + + @TableField("坐席编号") + @Excel(name ="坐席编号") + private String 坐席编号; + + @TableField("场内场外") + @Excel(name ="场内场外") + private String 场内场外; + + @TableField("区域id") + @Excel(name ="区域id") + private Integer 区域id; + + @TableField("故障处理人") + @Excel(name ="故障处理人") + private String 故障处理人; + + @TableField("phonenumber") + @Excel(name ="故障处理人手机") + private String phonenumber; + @Excel(name ="景区名称") + private String 景区名称; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/DpSceneConfigVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/DpSceneConfigVO.java new file mode 100644 index 0000000..1695465 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/DpSceneConfigVO.java @@ -0,0 +1,94 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; + +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * VO + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DpSceneConfigVO { + + + private static final long serialVersionUID = 1L; + @Excel(name = "序号",width = 20) + @ApiModelProperty("自增id") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @Excel(name = "网络制式",width = 20) + @ApiModelProperty("网络类型") + @TableField("nettype") + private String nettype; + + @Excel(name = "指标等级",width = 20) + @ApiModelProperty("指标等级:cell、scene") + @TableField("type") + private String type; + + @Excel(name = "指标名称",width = 20) + @ApiModelProperty("指标名称") + @TableField("name") + private String name; + + @Excel(name = "设备类型",width = 20) + @ApiModelProperty("设备类型") + @TableField("celltype") + private String celltype; + + + @Excel(name = "最小值",width = 20) + @ApiModelProperty("最小值") + @TableField("range1") + private Object range1; + + @Excel(name = "最大值",width = 20) + @ApiModelProperty("最大值") + @TableField("range2") + private Object range2; + + @Excel(name = "颜色",width = 20) + @ApiModelProperty("颜色") + @TableField("color") + private String color; + + @Excel(name = "颜色分值",width = 20) + @ApiModelProperty("颜色分值") + @TableField("colorscore") + private Double colorscore; + + @Excel(name = "颜色等级",width = 20) + @ApiModelProperty("颜色等级") + @TableField("level") + private Short level; + + @Excel(name = "备注",width = 20) + @ApiModelProperty("备注") + @TableField("content") + private String content; + + + + + + + + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/DpcSeneControlVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/DpcSeneControlVo.java new file mode 100644 index 0000000..3c477de --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/DpcSeneControlVo.java @@ -0,0 +1,32 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * @author yqf + * @date 2023/4/21 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DpcSeneControlVo { + + @ApiModelProperty(value = "数据类型 1或15", required = true) + @NotNull(message = "mintype不能为空") + private Integer mintype; + + @ApiModelProperty(value = "网络类型", required = true) + @NotBlank(message = "nettype不能为空") + private String nettype; + + @ApiModelProperty(value = "指标名称", required = true) + @NotBlank(message = "kpiname不能为空") + private String kpiname; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/FlowContentVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/FlowContentVo.java new file mode 100644 index 0000000..b42d5e8 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/FlowContentVo.java @@ -0,0 +1,17 @@ +package com.ruoyi.eastcom_yw.domain.vo; + + +import lombok.Data; + +@Data +public class FlowContentVo { + + private String flwId; + + private String name; + + private String text; + + private String matchName; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/HmAlarmDeriveVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/HmAlarmDeriveVo.java new file mode 100644 index 0000000..c6a4001 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/HmAlarmDeriveVo.java @@ -0,0 +1,56 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * + *

+ * + * @author jkj + * @since 2023-08-02 + */ +@Data +public class HmAlarmDeriveVo implements Serializable { + +private static final long serialVersionUID=1L; + + private Long id; + + private Long groupid; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime 告警时间; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime 恢复时间; + + private String 分公司; + + private String 网元名称; + + private String 端口; + + private String 场馆名称; + + private String 场馆等级; + + private String 告警名称; + + private String 详细位置; + + private String 专业; + + private String 网元属性; + + private String 端口类型; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime 告警插入时间; + +} \ No newline at end of file diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiLinkTrendVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiLinkTrendVo.java new file mode 100644 index 0000000..b17c42c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiLinkTrendVo.java @@ -0,0 +1,31 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * @author yqf + * @date 2023/8/21 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class KpiLinkTrendVo { + + @TableField("链路名称") + private String linkname; + + @TableField("设备名称") + private String evicename; + + @TableField("指标值") + private BigDecimal number; + + @TableField("时间") + private String time; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiReport4gVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiReport4gVo.java new file mode 100644 index 0000000..84d4a80 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiReport4gVo.java @@ -0,0 +1,69 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +/** + * @author yqf + * @date 2023/5/24 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class KpiReport4gVo { + + + private List gbTop5List; + private List avgdisturbTop5List; + private List mauserTop5List; + private List prbupTop5List; + private List prbdownTop5List; + + @TableField("流量GB") + private BigDecimal 流量GB4g; + + @TableField("无线接通率") + private BigDecimal 无线接通率4g; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率4g; + + @TableField("切换成功率") + private BigDecimal 切换成功率4g; + + @TableField("上行平均干扰") + private Short 上行平均干扰4g; + + @TableField("最大用户数") + private BigDecimal 最大用户数4g; + +// @TableField("最大用户数") +// private String 最大用户数小区4g; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率4g; + +// @TableField("上行prb利用率") +// private String 上行prb利用率小区4g; + + @TableField("下行prb利用率") + private String 下行prb利用率4g; + +// @TableField("下行prb利用率") +// private String 下行prb利用率小区4g; + + + private List gbList; + private List avgdisturbList; + private List mauserList; + private List prbupList; + private List prbdownList; + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiReport5gVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiReport5gVo.java new file mode 100644 index 0000000..093e03b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiReport5gVo.java @@ -0,0 +1,80 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +/** + * @author yqf + * @date 2023/5/24 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class KpiReport5gVo { + +// @TableField("场馆id") +// private Integer 场馆id; +// +// @TableField("开始时间") +// private LocalDateTime 开始时间; +// +// @TableField("结束时间") +// private LocalDateTime 结束时间; + + @TableField("流量GB") + private BigDecimal 流量GB5g; + + @TableField("最大用户数") + private Short 最大用户数5g; + + @TableField("无线接通率") + private BigDecimal 无线接通率5g; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率5g; + + @TableField("切换成功率") + private BigDecimal 切换成功率5g; + + @TableField("上行干扰值") + private Double 上行干扰值5g; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率5g; + + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率5g; + + private List gbList; + private List avgdisturbList; + private List mauserList; + private List prbupList; + private List prbdownList; + + @TableField("上行流量") + private BigDecimal 上行流量5g; + + @TableField("下行流量") + private BigDecimal 下行流量5g; + + @TableField("小区RLC层下行丢包率") + private BigDecimal 小区RLC层下行丢包率5g; + + private List gbTop5List; + private List avgdisturbTop5List; + private List mauserTop5List; + private List prbupTop5List; + private List prbdownTop5List; + + @TableField("nsa_sgnb添加成功率") + private BigDecimal sgnb添加成功率5g; + + @TableField("sn异常释放率") + private BigDecimal sn异常释放率5g; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiTrendVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiTrendVo.java new file mode 100644 index 0000000..dbff500 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiTrendVo.java @@ -0,0 +1,32 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * @author yqf + * @date 2023/5/24 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class KpiTrendVo { + + @TableField("指标名称") + private String name; + + @TableField("指标值") + private BigDecimal number; + + @TableField("时间") + private String time; + + public KpiTrendVo(String name, BigDecimal number) { + this.name = name; + this.number = number; + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiVenueReportVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiVenueReportVo.java new file mode 100644 index 0000000..5d2e5d0 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/KpiVenueReportVo.java @@ -0,0 +1,123 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/25 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class KpiVenueReportVo { + + + @TableField("场馆id") + private Integer 场馆id; + + @TableField("开始时间") + private LocalDateTime 开始时间; + + @TableField("结束时间") + private LocalDateTime 结束时间; + + @TableField("流量GB") + private BigDecimal 流量GB4g; + + @TableField("无线接通率") + private BigDecimal 无线接通率4g; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率4g; + + @TableField("上行平均干扰") + private Short 上行平均干扰4g; + + @TableField("最大用户数") + private BigDecimal 最大用户数4g; + + + @TableField("平均用户数") + private BigDecimal 平均用户数4g; + + @TableField("最大用户数") + private String 最大用户数小区4g; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率4g; + + @TableField("上行prb利用率") + private String 上行prb利用率小区4g; + + @TableField("下行prb利用率") + private String 下行prb利用率4g; + + @TableField("下行prb利用率") + private String 下行prb利用率小区4g; + + @TableField("切换成功率") + private BigDecimal 切换成功率4g; + + + @TableField("流量GB") + private BigDecimal 流量GB5g; + + @TableField("平均用户数") + private BigDecimal 平均用户数5g; + + @TableField("最大用户数") + private Short 最大用户数5g; + + @TableField("sn异常释放率") + private BigDecimal sn异常释放率5g; + + @TableField("无线接通率") + private BigDecimal 无线接通率5g; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率5g; + + @TableField("切换成功率") + private BigDecimal 切换成功率5g; + + @TableField("上行干扰值") + private Double 上行干扰值5g; + + @TableField("nsa_sgnb添加成功率") + private BigDecimal sgnb添加成功率5g; + + + @TableField("最大用户数") + private BigDecimal 小区最大用户数5g; + + @TableField("最大用户数") + private String 小区最大用户数小区5g; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率5g; + + @TableField("上行prb利用率") + private String 上行prb利用率小区5g; + + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率5g; + + @TableField("下行prb利用率") + private String 下行prb利用率小区5g; + + @TableField("上行5g流量") + private BigDecimal 上行流量5g; + + @TableField("下行5g流量") + private BigDecimal 下行流量5g; + + @TableField("小区RLC层下行丢包率") + private BigDecimal 小区RLC层下行丢包率5g; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/MatchListVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/MatchListVo.java new file mode 100644 index 0000000..f3bcec3 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/MatchListVo.java @@ -0,0 +1,15 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; + +@Data +public class MatchListVo { + private Long stadium_id; + private String stadium_name; + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8", locale = "zh") + private Date event_time; + private String event_name; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/MedalListVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/MedalListVo.java new file mode 100644 index 0000000..364bd5c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/MedalListVo.java @@ -0,0 +1,12 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +@Data +public class MedalListVo { + private String area_name; + private Integer gold_count; + private Integer silver_count; + private Integer bronze_count; + private Integer medals_count; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/MonitorCellVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/MonitorCellVo.java new file mode 100644 index 0000000..929c061 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/MonitorCellVo.java @@ -0,0 +1,71 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author yqf + * @date 2023/4/13 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("MonitorCellVo实体类") +public class MonitorCellVo { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "排序") + private Integer orderid; + + @ApiModelProperty(value = "数据类型") + private String datatype; + + @ApiModelProperty(value = "网络类型") + private String nettype; + + @TableField("venue_id") + private Integer venueid; + + @ApiModelProperty(value = "场馆名称") + @TableField("venue_name") + private String venuename; + + @ApiModelProperty(value = "坐席编号") + private String seatid; + + @ApiModelProperty(value = "坐席颜色") + private String color; + + @ApiModelProperty(value = "坐席得分") + private Float score; + + @ApiModelProperty(value = "指标名") + private String kpiname; + + @ApiModelProperty(value = "小区类型") + private String celltype; + + @ApiModelProperty(value = "基站编号") + private Long stationno; + + @ApiModelProperty(value = "基站全称") + private String pointname; + + @ApiModelProperty(value = "坐席编号") + private String pointid; + + @ApiModelProperty(value = "经度") + private Double longitude; + + @ApiModelProperty(value = "纬度") + private Double latitude; + + private List celllist; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/NewsListVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/NewsListVo.java new file mode 100644 index 0000000..96ac0ee --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/NewsListVo.java @@ -0,0 +1,14 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; + +@Data +public class NewsListVo { + private String title; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private Date news_time; + private String content; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi15CellMonitorVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi15CellMonitorVO.java new file mode 100644 index 0000000..302b101 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi15CellMonitorVO.java @@ -0,0 +1,108 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("PmKpi15CellMonitorVO实体类") +public class PmKpi15CellMonitorVO { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "网络类型") + private String nettype; + + @TableField("venue_id") + private Integer venueid; + + @Excel(name = "场馆名称",width = 20) + @ApiModelProperty(value = "场馆名称") + @TableField("venue_name") + private String venuename; + + @Excel(name = "坐席编号",width = 20) + @ApiModelProperty(value = "坐席编号") + private String 坐席编号; + + @TableField("cellcodeci") + private String cellcodeci; + + @Excel(name = "开始时间",width = 20,dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField("starttime") + private LocalDateTime starttime; + + @Excel(name = "场馆名称",width = 20) + @TableField("小区名称") + @ApiModelProperty(value = "小区名称") + private String 小区名称; + + @Excel(name = "最大用户数",width = 20) + @ApiModelProperty(value = "最大用户数") + @TableField("最大用户数") + private PmKpiVO 最大用户数; + + @Excel(name = "上行prb利用率",width = 20) + @ApiModelProperty(value = "上行prb利用率") + @TableField("上行prb利用率") + private PmKpiVO 上行prb利用率; + + @Excel(name = "下行prb利用率",width = 20) + @ApiModelProperty(value = "下行prb利用率") + @TableField("下行prb利用率") + private PmKpiVO 下行prb利用率; + + @Excel(name = "上行平均干扰",width = 20) + @ApiModelProperty(value = "上行平均干扰") + @TableField("上行平均干扰") + private PmKpiVO 上行平均干扰; + + @Excel(name = "结束时间",width = 20,dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "结束时间") + @TableField("endtime") + private LocalDateTime endtime; + + @ApiModelProperty(value = "综合得分") + private PmKpiVO 综合得分; + + + + @ApiModelProperty(value = "基站编号") + private Long stationno; + + @ApiModelProperty(value = "基站全称") + private String pointname; + + @ApiModelProperty(value = "坐席编号") + private String pointid; + + @ApiModelProperty(value = "经度") + private Double longitude; + + @ApiModelProperty(value = "纬度") + private Double latitude; + + @ApiModelProperty(value = "小区频段") + private String 小区频段; + + @ApiModelProperty(value = "设备类型") + private String 设备类型; + + @ApiModelProperty(value = "带宽") + private Long 带宽; + + @ApiModelProperty(value = "方位角") + private Long 方位角; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi15MinCellVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi15MinCellVO.java new file mode 100644 index 0000000..0aaf6e7 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi15MinCellVO.java @@ -0,0 +1,102 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * @author yqf + * @date 2023/4/12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi15MinCellVO { + + + private static final long serialVersionUID = 1L; +// @ApiModelProperty("id") +// @TableField("id") +// private Long id; + + private Integer orderId; + + @ApiModelProperty(value = "网络类型") + private String netType; + + @TableField("venue_id") + private Integer venueId; + + @ApiModelProperty(value = "场馆名称") + @TableField("venue_name") + private String venueName; + + @TableField("cellcodeci") + private String cellcodeci; + + @TableField("starttime") + private LocalDateTime starttime; + + @TableField("input_datetime") + private LocalDateTime inputDatetime; + + @TableField("小区名称") + @ApiModelProperty(value = "小区名称") + private String 小区名称; + + @ApiModelProperty(value = "平均用户数") + @TableField("平均用户数") + private PmKpiVO 平均用户数; + + @ApiModelProperty(value = "最大用户数") + @TableField("最大用户数") + private PmKpiVO 最大用户数; + + @ApiModelProperty(value = "上行prb利用率") + @TableField("上行prb利用率") + private PmKpiVO 上行prb利用率; + + @ApiModelProperty(value = "下行prb利用率") + @TableField("下行prb利用率") + private PmKpiVO 下行prb利用率; + + @ApiModelProperty(value = "上行平均干扰") + @TableField("上行平均干扰") + private PmKpiVO 上行平均干扰; + + @ApiModelProperty(value = "无线掉线率") + @TableField("无线掉线率") + private PmKpiVO 无线掉线率; + + @ApiModelProperty(value = "无线接通率") + @TableField("无线接通率") + private PmKpiVO 无线接通率; + + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("groupid") + private Long groupid; + + @ApiModelProperty(value = "结束时间") + @TableField("endtime") + private LocalDateTime endtime; + + private List kpi6HourData; + + @ApiModelProperty(value = "小区频段") + private String 小区频段; + + @ApiModelProperty(value = "设备类型") + private String 设备类型; + + @ApiModelProperty(value = "带宽") + private Long 带宽; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gCellVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gCellVO.java new file mode 100644 index 0000000..04ab22f --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gCellVO.java @@ -0,0 +1,224 @@ +package com.ruoyi.eastcom_yw.domain.vo; + + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.Excel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + *

+ * 场馆4G小区级15分钟指标VO + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi4gCellVO { + + + private static final long serialVersionUID = 1L; + + @TableField("venue_id") + private Integer venueId; + + @TableField("venue_name") + @Excel(name = "场馆", width = 20,sort = 1) + private String venueName; + + @TableField("cellcodeci") + private String cellcodeci; + + @Excel(name = "开始时间",width = 20,dateFormat = "yyyy-MM-dd HH:mm:ss",sort = 3) + @TableField("starttime") + private LocalDateTime starttime; + + @TableField("input_datetime") + private LocalDateTime inputDatetime; + + @TableField("小区名称") + @Excel(name = "小区名称",width = 20,sort = 2) + private String 小区名称; + + @Excel(name = "上行流量mb",width = 20) + @TableField("上行流量mb") + private BigDecimal 上行流量mb; + + @Excel(name = "下行流量mb",width = 20) + @TableField("下行流量mb") + private BigDecimal 下行流量mb; + + @Excel(name = "有效rrc连接平均数",width = 20) + @TableField("有效rrc连接平均数") + private BigDecimal 有效rrc连接平均数; + + @Excel(name = "有效rrc连接最大数",width = 20) + @TableField("有效rrc连接最大数") + private BigDecimal 有效rrc连接最大数; + + @Excel(name = "平均用户数",width = 20) + @TableField("平均用户数") + private BigDecimal 平均用户数; + + @Excel(name = "最大用户数",width = 20) + @TableField("最大用户数") + private BigDecimal 最大用户数; + + @Excel(name = "volte话务量",width = 20) + @TableField("volte话务量") + private BigDecimal volte话务量; + + @TableField("上行prb利用率") + @Excel(name = "上行prb利用率",width = 20) + private BigDecimal 上行prb利用率; + + @TableField("下行prb利用率") + @Excel(name = "下行prb利用率",width = 20) + private BigDecimal 下行prb利用率; + + @TableField("上行平均干扰") + @Excel(name = "上行平均干扰",width = 20) + private BigDecimal 上行平均干扰; + + @Excel(name = "rrc建立成功率",width = 20) + @TableField("rrc建立成功率") + private BigDecimal rrc建立成功率; + + @Excel(name = "e_rab建立成功率",width = 20) + @TableField("e_rab建立成功率") + private BigDecimal eRab建立成功率; + + @Excel(name = "qci为1的e_rab建立成功率",width = 20) + @TableField("qci为1的e_rab建立成功率") + private BigDecimal qci为1的eRab建立成功率; + + @Excel(name = "无线掉线率",width = 20) + @TableField("无线掉线率") + private BigDecimal 无线掉线率; + + @Excel(name = "掉线次数",width = 20) + @TableField("掉线次数") + private BigDecimal 掉线次数; + + @Excel(name = "切换成功率",width = 20) + @TableField("切换成功率") + private BigDecimal 切换成功率; + + @Excel(name = "esrvcc切换成功率",width = 20) + @TableField("esrvcc切换成功率") + private BigDecimal esrvcc切换成功率; + + @Excel(name = "esrvcc切换请求次数",width = 20) + @TableField("esrvcc切换请求次数") + private BigDecimal esrvcc切换请求次数; + + @Excel(name = "rrc重建成功率",width = 20) + @TableField("rrc重建成功率") + private BigDecimal rrc重建成功率; + + @Excel(name = "rrc重建次数",width = 20) + @TableField("rrc重建次数") + private BigDecimal rrc重建次数; + + @Excel(name = "volte掉话率",width = 20) + @TableField("volte掉话率") + private BigDecimal volte掉话率; + + @Excel(name = "volte掉话次数",width = 20) + @TableField("volte掉话次数") + private BigDecimal volte掉话次数; + + @Excel(name = "rru_puschprbassn",width = 20) + @TableField("rru_puschprbassn") + private BigDecimal rruPuschprbassn; + + @Excel(name = "rru_puschprbtot",width = 20) + @TableField("rru_puschprbtot") + private BigDecimal rruPuschprbtot; + + @Excel(name = "rru_pdschprbassn",width = 20) + @TableField("rru_pdschprbassn") + private BigDecimal rruPdschprbassn; + + @Excel(name = "rru_pdschprbtot",width = 20) + @TableField("rru_pdschprbtot") + private BigDecimal rruPdschprbtot; + + @Excel(name = "rrc_succconnestab",width = 20) + @TableField("rrc_succconnestab") + private BigDecimal rrcSuccconnestab; + + @Excel(name = "rrc_attconnestab",width = 20) + @TableField("rrc_attconnestab") + private BigDecimal rrcAttconnestab; + + @Excel(name = "erab_nbrsuccestab_1",width = 20) + @TableField("erab_nbrsuccestab_1") + private BigDecimal erabNbrsuccestab1; + + @Excel(name = "erab_nbrattestab",width = 20) + @TableField("erab_nbrattestab") + private BigDecimal erabNbrattestab; + + @Excel(name = "erab_nbrattestab_1",width = 20) + @TableField("erab_nbrattestab_1") + private BigDecimal erabNbrattestab1; + + @Excel(name = "切换成功率_分母",width = 20) + @TableField("切换成功率_分母") + private BigDecimal 切换成功率分母; + + @Excel(name = "切换成功率_分子",width = 20) + @TableField("切换成功率_分子") + private BigDecimal 切换成功率分子; + + @Excel(name = "掉线率_分母",width = 20) + @TableField("掉线率_分母") + private BigDecimal 掉线率分母; + + @Excel(name = "iratho_succoutgeran",width = 20) + @TableField("iratho_succoutgeran") + private BigDecimal irathoSuccoutgeran; + + @Excel(name = "rrc_attconnreestab",width = 20) + @TableField("rrc_attconnreestab") + private BigDecimal rrcAttconnreestab; + + @Excel(name = "volte掉话率_分母",width = 20) + @TableField("volte掉话率_分母") + private BigDecimal volte掉话率分母; + + @Excel(name = "erab_nbrsuccestab",width = 20) + @TableField("erab_nbrsuccestab") + private BigDecimal erabNbrsuccestab; + + @Excel(name = "omcname",width = 20) + @TableField("omcname") + private String omcname; + + @Excel(name = "无线接通率",width = 20) + @TableField("无线接通率") + private BigDecimal 无线接通率; + + @Excel(name = "rrc_failconnestab",width = 20) + @TableField("rrc_failconnestab") + private BigDecimal rrcFailconnestab; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("groupid") + private Long groupid; + + @Excel(name = "结束时间",width = 20,dateFormat = "yyyy-MM-dd HH:mm:ss",sort = 4) + @TableField("endtime") + private LocalDateTime endtime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gMinVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gMinVO.java new file mode 100644 index 0000000..b2fc141 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gMinVO.java @@ -0,0 +1,138 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 场馆4G小区级1分钟指标VO + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi4gMinVO { + + + private static final long serialVersionUID = 1L; + + @Excel(name = "序号",width = 20) + private Integer orderId; + + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @TableField("groupid") + private Integer groupid; + + @Excel(name = "时间",width = 20) + @TableField("时间") + private LocalDateTime 时间; + + @TableField("地市区号") + private String 地市区号; + + @TableField("区县") + private String 区县; + + @Excel(name = "场馆名",width = 20) + private String venueName; + + @Excel(name = "小区名",width = 20) + @TableField("小区名称") + private String 小区名称; + + @Excel(name = "下行流量(MB)",width = 20) + @TableField("data_down") + private BigDecimal dataDown; + + @Excel(name = "上行流量(MB)",width = 20) + @TableField("data_up") + private BigDecimal dataUp; + + @Excel(name = "VOLTE掉话率(%)",width = 20) + @TableField("volte_drop_rate") + private BigDecimal volteDropRate; + + @Excel(name = "VOLTE接通率(%)",width = 20) + @TableField("volte_succ_rate") + private BigDecimal volteSuccRate; + + @Excel(name = "VOLTE语音话务量(ERL)",width = 20) + @TableField("volte") + private BigDecimal volte; + + @Excel(name = "最大激活用户数",width = 20) + @TableField("act_max_user") + private Integer actMaxUser; + + @Excel(name = "平均激活用户数",width = 20) + @TableField("act_avg_user") + private BigDecimal actAvgUser; + + @Excel(name = "无线掉线率(%)",width = 20) + @TableField("call_drop_rate") + private BigDecimal callDropRate; + + @Excel(name = "无线接通率(%)",width = 20) + @TableField("call_succ_rate") + private BigDecimal callSuccRate; + + @Excel(name = "下行用户体验速率(Mbps)",width = 20) + @TableField("speed_down") + private BigDecimal speedDown; + + @Excel(name = "上行用户体验速率(Mbps)",width = 20) + @TableField("speed_up") + private BigDecimal speedUp; + + @Excel(name = "上行干扰(dBm)",width = 20) + @TableField("avg_disturb") + private Integer avgDisturb; + + @Excel(name = "下行PRB利用率(%)",width = 20) + @TableField("prb_down") + private BigDecimal prbDown; + + @Excel(name = "上行PRB利用率(%)",width = 20) + @TableField("prb_up") + private BigDecimal prbUp; + + @Excel(name = "小区内的最大用户数",width = 20) + @TableField("max_user") + private Integer maxUser; + + @Excel(name = "小区内的平均用户数",width = 20) + @TableField("avg_user") + private BigDecimal avgUser; + + @TableField("厂商id") + private String 厂商id; + + @Excel(name = "系统每PRB的上行所接收到的干扰和噪声的最大值",width = 20) + @TableField("v1_max") + private BigDecimal v1Max; + + @Excel(name = "系统每PRB的上行所接收到的干扰和噪声的平均值",width = 20) + @TableField("v1_avg") + private String v1Avg; + + @TableField("update_time") + private LocalDateTime updateTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gVenueConvertVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gVenueConvertVO.java new file mode 100644 index 0000000..a155987 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gVenueConvertVO.java @@ -0,0 +1,43 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author yqf + * @date 2023/4/12 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi4gVenueConvertVO { + + @ApiModelProperty(value = "小区总数") + private PmKpiVO villagecount; + + @ApiModelProperty(value = "异常小区数") + private PmKpiVO unusualcount; + + @ApiModelProperty(value = "最大用户数") + private PmKpiVO maxusercount; + + @ApiModelProperty(value = "上行prb利用率") + @TableField("上行prb利用率") + private PmKpiVO 上行prb利用率; + + @ApiModelProperty(value = "下行prb利用率") + @TableField("下行prb利用率") + private PmKpiVO 下行prb利用率; + + @TableField("场馆id") + private Integer 场馆id; + + @TableField("场馆名称") + private String venueName; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gVenueVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gVenueVO.java new file mode 100644 index 0000000..5e2efc3 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi4gVenueVO.java @@ -0,0 +1,77 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +/** + * @author yqf + * @date 2023/4/11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi4gVenueVO { + + + private static final long serialVersionUID = 1L; + + + @TableId("id") + private Long id; + + @TableField("开始时间") + private LocalDateTime 开始时间; + + @TableField("入库时间") + private LocalDateTime 入库时间; + + @TableField("区县") + private String 区县; + + @TableField("场馆id") + private Integer 场馆id; + + @TableField("无线接通率") + private BigDecimal 无线接通率; + + @TableField("流量GB") + private Short 流量GB; + + @TableField("最大用户数") + private Short 最大用户数; + + @TableField("话务量") + private Short 话务量; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率; + + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率; + + @TableField("上行平均干扰") + private Short 上行平均干扰; + + @TableField("volte接通率") + private BigDecimal volte接通率; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("结束时间") + private LocalDateTime 结束时间; + + @TableField("平均用户数") + private BigDecimal 平均用户数; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi5gCellVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi5gCellVO.java new file mode 100644 index 0000000..33a783f --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi5gCellVO.java @@ -0,0 +1,206 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 场馆5G小区级15分钟指标VO + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi5gCellVO { + + + private static final long serialVersionUID = 1L; + + @TableField("venue_id") + private Integer venueId; + + @TableField("venue_name") + @Excel(name = "场馆名称",width = 20) + private String venueName; + + @TableField("ci") + private String ci; + + @Excel(name = "开始时间",width = 20,dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField("starttime") + private LocalDateTime starttime; + + @TableField("小区名称") + @Excel(name = "小区名称",width = 20) + private String 小区名称; + + @Excel(name = "nr流量",width = 20) + @TableField("nr流量") + private BigDecimal nr流量; + + @Excel(name = "上行5g流量",width = 20) + @TableField("上行5g流量") + private BigDecimal 上行5g流量; + + @Excel(name = "下行5g流量",width = 20) + @TableField("下行5g流量") + private BigDecimal 下行5g流量; + + @Excel(name = "小区rlc层下行丢包率",width = 20) + @TableField("小区rlc层下行丢包率") + private BigDecimal 小区rlc层下行丢包率; + + @Excel(name = "小区级rlc层sdu下行空口丢包数",width = 20) + @TableField("小区级rlc层sdu下行空口丢包数") + private BigDecimal 小区级rlc层sdu下行空口丢包数; + + @Excel(name = "小区rlc层收到的下行sdu包数",width = 20) + @TableField("小区rlc层收到的下行sdu包数") + private BigDecimal 小区rlc层收到的下行sdu包数; + + @Excel(name = "平均用户数",width = 20) + @TableField("平均用户数") + private BigDecimal 平均用户数; + + @Excel(name = "最大用户数",width = 20) + @TableField("最大用户数") + private BigDecimal 最大用户数; + + @Excel(name = "sn异常释放率",width = 20) + @TableField("sn异常释放率") + private BigDecimal sn异常释放率; + + @Excel(name = "sgnb释放总次数",width = 20) + @TableField("sgnb释放总次数") + private BigDecimal sgnb释放总次数; + + @Excel(name = "sgnb触发sgnb异常释放总次数",width = 20) + @TableField("sgnb触发sgnb异常释放总次数") + private BigDecimal sgnb触发sgnb异常释放总次数; + + @Excel(name = "nsa_sgnb添加成功率",width = 20) + @TableField("nsa_sgnb添加成功率") + private BigDecimal nsaSgnb添加成功率; + + @Excel(name = "dc场景下发送sgnb增加成功的次数",width = 20) + @TableField("dc场景下发送sgnb增加成功的次数") + private BigDecimal dc场景下发送sgnb增加成功的次数; + + @Excel(name = "dc场景下收到sgnb增加尝试的次数",width = 20) + @TableField("dc场景下收到sgnb增加尝试的次数") + private BigDecimal dc场景下收到sgnb增加尝试的次数; + + @Excel(name = "无线接通率",width = 20) + @TableField("无线接通率") + private BigDecimal 无线接通率; + + @Excel(name = "rrc建立成功次数",width = 20) + @TableField("rrc建立成功次数") + private BigDecimal rrc建立成功次数; + + @Excel(name = "rrc建立请求消息次数",width = 20) + @TableField("rrc建立请求消息次数") + private BigDecimal rrc建立请求消息次数; + + @Excel(name = "小区中qos_flow建立成功次数",width = 20) + @TableField("小区中qos_flow建立成功次数") + private BigDecimal 小区中qosFlow建立成功次数; + + @Excel(name = "小区中qos_flow建立尝试次数",width = 20) + @TableField("小区中qos_flow建立尝试次数") + private BigDecimal 小区中qosFlow建立尝试次数; + + @Excel(name = "小区中ng信令连接建立成功次数",width = 20) + @TableField("小区中ng信令连接建立成功次数") + private BigDecimal 小区中ng信令连接建立成功次数; + + @Excel(name = "小区中ng信令连接建立尝试次数",width = 20) + @TableField("小区中ng信令连接建立尝试次数") + private BigDecimal 小区中ng信令连接建立尝试次数; + + @Excel(name = "无线掉线率",width = 20) + @TableField("无线掉线率") + private BigDecimal 无线掉线率; + + @Excel(name = "小区中ue上下文异常释放的次数",width = 20) + @TableField("小区中ue上下文异常释放的次数") + private BigDecimal 小区中ue上下文异常释放的次数; + + @Excel(name = "小区中ue上下文正常释放的次数",width = 20) + @TableField("小区中ue上下文正常释放的次数") + private BigDecimal 小区中ue上下文正常释放的次数; + + @Excel(name = "无线掉线率分母",width = 20) + @TableField("无线掉线率分母") + private BigDecimal 无线掉线率分母; + + @Excel(name = "切换成功率",width = 20) + @TableField("切换成功率") + private BigDecimal 切换成功率; + + @Excel(name = "切换成功率分子",width = 20) + @TableField("切换成功率分子") + private BigDecimal 切换成功率分子; + + @Excel(name = "切换成功率分母",width = 20) + @TableField("切换成功率分母") + private BigDecimal 切换成功率分母; + + @Excel(name = "下行平均使用的prb个数",width = 20) + @TableField("下行平均使用的prb个数") + private BigDecimal 下行平均使用的prb个数; + + @Excel(name = "下行平均可用prb个数",width = 20) + @TableField("下行平均可用prb个数") + private BigDecimal 下行平均可用prb个数; + + @Excel(name = "上行平均使用的prb个数",width = 20) + @TableField("上行平均使用的prb个数") + private BigDecimal 上行平均使用的prb个数; + + @Excel(name = "上行平均可用prb个数",width = 20) + @TableField("上行平均可用prb个数") + private BigDecimal 上行平均可用prb个数; + + @Excel(name = "上行prb利用率",width = 20) + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率; + + @Excel(name = "下行prb利用率",width = 20) + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率; + + @TableField("input_datetime") + private LocalDateTime inputDatetime; + + @TableField("cell_name") + private String cellName; + + @TableField("pmsid") + private Long pmsid; + + @Excel(name = "上行干扰值",width = 20) + @TableField("上行干扰值") + private Double 上行干扰值; + + @TableField("update_time") + private LocalDateTime updateTime; + + @Excel(name = "结束时间",width = 20,dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField("endtime") + private LocalDateTime endtime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi5gMinVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi5gMinVO.java new file mode 100644 index 0000000..2a4c84f --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi5gMinVO.java @@ -0,0 +1,116 @@ +package com.ruoyi.eastcom_yw.domain.vo; + + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 场馆5G小区级1分钟指标VO + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi5gMinVO { + + + private static final long serialVersionUID = 1L; +@ApiModelProperty("id") +@TableField("id") +private Long id; + + @TableField("groupid") + private Integer groupid; + + @Excel(name = "序号",width = 20) + private Integer orderId; + + @Excel(name = "时间",width = 20) + @TableField("时间") + private LocalDateTime 时间; + + @TableField("地市区号") + private String 地市区号; + + @TableField("区县") + private String 区县; + + @Excel(name = "场馆名",width = 20) + private String venueName; + + @Excel(name = "小区名称",width = 20) + @TableField("小区名称") + private String 小区名称; + + @TableField("厂商id") + private String 厂商id; + + @Excel(name = "上行PRB平均利用率(%)",width = 20) + @TableField("prb_up") + private Double prbUp; + + @Excel(name = "下行PRB平均利用率(%)",width = 20) + @TableField("prb_down") + private Double prbDown; + + @Excel(name = "上行干扰(dBm)",width = 20) + @TableField("up_disturb") + private Integer upDisturb; + + @Excel(name = "上行用户平均速率(Mbps)",width = 20) + @TableField("speed_up") + private Double speedUp; + + @Excel(name = "下行用户平均速率(Mbps)",width = 20) + @TableField("speed_down") + private Double speedDown; + + @Excel(name = "小区最大激活用户数",width = 20) + @TableField("act_max_user") + private Integer actMaxUser; + + @Excel(name = "小区平均激活用户数",width = 20) + @TableField("act_avg_user") + private Double actAvgUser; + + @Excel(name = "小区内处于RRC连接态的平均用户数",width = 20) + @TableField("rrc_avg_user") + private BigDecimal rrcAvgUser; + + @Excel(name = "小区内处于RRC连接态的最大用户数",width = 20) + @TableField("rrc_max_user") + private Integer rrcMaxUser; + + @Excel(name = "无线接通率(%)",width = 20) + @TableField("call_succ_rate") + private BigDecimal callSuccRate; + + @Excel(name = "无线掉线率(%)",width = 20) + @TableField("drop_call_rate") + private BigDecimal dropCallRate; + + @Excel(name = "下行流量(MB)",width = 20) + @TableField("data_down") + private BigDecimal dataDown; + + @Excel(name = "上行流量(MB)",width = 20) + @TableField("data_up") + private BigDecimal dataUp; + + @TableField("update_time") + private LocalDateTime updateTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi5gVenueVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi5gVenueVO.java new file mode 100644 index 0000000..6dc9334 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpi5gVenueVO.java @@ -0,0 +1,90 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 5G场馆级15分钟指标VO + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpi5gVenueVO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableField("id") + private Long id; + + + @TableField("开始时间") + private LocalDateTime 开始时间; + + @TableField("入库时间") + private LocalDateTime 入库时间; + + @TableField("区县") + private String 区县; + + @TableField("场馆id") + private Integer 场馆id; + + @TableField("无线接通率") + private BigDecimal 无线接通率; + + @TableField("nsa_sgnb添加成功率") + private BigDecimal nsaSgnb添加成功率; + + @TableField("切换成功率") + private BigDecimal 切换成功率; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率; + + @TableField("sn异常释放率") + private BigDecimal sn异常释放率; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率; + + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率; + + @TableField("流量GB") + private BigDecimal 流量GB; + + @TableField("最大用户数") + private Short 最大用户数; + + @TableField("话务量") + private BigDecimal 话务量; + + @TableField("上行干扰值") + private Double 上行干扰值; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("结束时间") + private LocalDateTime 结束时间; + + @TableField("平均用户数") + private BigDecimal 平均用户数; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpiOneMinVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpiOneMinVO.java new file mode 100644 index 0000000..aa340f4 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpiOneMinVO.java @@ -0,0 +1,85 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +/** + * @author yqf + * @date 2023/4/12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpiOneMinVO { + + private static final long serialVersionUID = 1L; + + private Integer orderId; + + @ApiModelProperty(value = "网络类型") + private String netType; + + @TableField("venue_id") + private Integer venueId; + + @Excel(name = "场馆名称", sort = 1) + @TableField("venue_name") + private String venueName; + + @TableField("cellcodeci") + private String cellcodeci; + + @TableField("groupid") + private Integer groupid; + + @TableField("时间") + private LocalDateTime 时间; + + @TableField("小区名称") + private String 小区名称; + + @ApiModelProperty(value = "平均用户数") + @TableField("平均用户数") + private PmKpiVO 平均用户数; + + @ApiModelProperty(value = "最大用户数") + @TableField("最大用户数") + private PmKpiVO 最大用户数; + + @ApiModelProperty(value = "上行prb利用率") + @TableField("上行prb利用率") + private PmKpiVO 上行prb利用率; + + @ApiModelProperty(value = "下行prb利用率") + @TableField("下行prb利用率") + private PmKpiVO 下行prb利用率; + + @ApiModelProperty(value = "上行平均干扰") + @TableField("上行平均干扰") + private PmKpiVO 上行平均干扰; + + @ApiModelProperty(value = "无线掉线率") + @TableField("无线掉线率") + private PmKpiVO 无线掉线率; + + @ApiModelProperty(value = "无线接通率") + @TableField("无线接通率") + private PmKpiVO 无线接通率; + + @ApiModelProperty(value = "小区频段") + private String 小区频段; + + @ApiModelProperty(value = "设备类型") + private String 设备类型; + + @ApiModelProperty(value = "带宽") + private Long 带宽; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpiVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpiVO.java new file mode 100644 index 0000000..c5cb55d --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/PmKpiVO.java @@ -0,0 +1,52 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.List; + +/** + * @author yqf + * @date 2023/4/11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmKpiVO { + + @ApiModelProperty(value = "数值") + private BigDecimal value; + + @ApiModelProperty(value = "最大数值") + private BigDecimal maxvalue; + + @ApiModelProperty(value = "颜色") + private String color; + + @ApiModelProperty(value = "分数") + private float score; + + @ApiModelProperty(value = "data") + private List data; + + public PmKpiVO(BigDecimal maxvalue, String color) { + this.maxvalue = maxvalue; + this.color = color; + } + + public PmKpiVO(BigDecimal value, BigDecimal maxvalue, String color) { + this.value = value; + this.maxvalue = maxvalue; + this.color = color; + } + + public PmKpiVO(String color) { + this.color = color; + } + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/RaceScheduleListVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/RaceScheduleListVo.java new file mode 100644 index 0000000..cc89f8e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/RaceScheduleListVo.java @@ -0,0 +1,18 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; + +@Data +public class RaceScheduleListVo { + private Long stadium_id; + private String stadium_name; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private Date start_time; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private Date end_time; + private String task_name; + private String task_status; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/RecordVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/RecordVo.java new file mode 100644 index 0000000..eeebeb6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/RecordVo.java @@ -0,0 +1,27 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RecordVo { + + private LocalDateTime time; + + private BigDecimal prbupcount; + private BigDecimal prbdowncount; + private BigDecimal maxusercount; + private BigDecimal avgdisturbcount; + private BigDecimal gbcount; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/SceneBaseStation.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/SceneBaseStation.java new file mode 100644 index 0000000..9ab56fa --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/SceneBaseStation.java @@ -0,0 +1,98 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.importer.beans.ResultBean; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author yqf + * @date 2023/6/5 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SceneBaseStation extends ResultBean { + + @Excel(name = "站号", type = Excel.Type.ALL) + private String siteNo; + + @Excel(name = "基站名称", type = Excel.Type.ALL) + private String siteName; + + @Excel(name = "区域", type = Excel.Type.ALL) + private String region; + + @Excel(name = "RHUB编号", type = Excel.Type.ALL) + private String rhubName; + + @Excel(name = "RHUB柜框槽", type = Excel.Type.ALL) + private String rhubUniqueId; + + @Excel(name = "RHUB端口", type = Excel.Type.ALL) + private String rhubPortNo; + + @Excel(name = "pRRU编号", type = Excel.Type.ALL) + private String prruName; + + @Excel(name = "pRRU柜框槽", type = Excel.Type.ALL) + private String prruUniqueId; + + @Excel(name = "设备型号", type = Excel.Type.ALL) + private String prruModel; + + @Excel(name = "pRRU安装位置(CAD)", type = Excel.Type.ALL) + private String prruPosition; + + @Excel(name = "AP编号(CAD)", type = Excel.Type.ALL) + private String apId; + + @Excel(name = "天线编号(CAD)", type = Excel.Type.ALL) + private String antId; + + @Excel(name = "天线类型(CAD)", type = Excel.Type.ALL) + private String antType; + + @Excel(name = "覆盖区域(CAD)", type = Excel.Type.ALL) + private String coverageArea; + + @Excel(name = "本地小区标识", type = Excel.Type.ALL) + private String localCellId; + + @Excel(name = "CGI", type = Excel.Type.ALL) + private String cellCgi; + + @Excel(name = "小区名称", type = Excel.Type.ALL) + private String cellName; + + @Excel(name = "PCI", type = Excel.Type.ALL) + private String pci; + + @Excel(name = "频点", type = Excel.Type.ALL) + private String frequency; + + @Excel(name = "直连基带处理板端口信息", type = Excel.Type.ALL) + private String directlyBaseband; + + @Excel(name = "服务基带处理板信息", type = Excel.Type.ALL) + private String servingBaseband; + + @Excel(name = "单板配置类型", type = Excel.Type.ALL) + private String boardConfigType; + + +// private String mptUniqueId; +// private String fanUniqueId; +// private String peuUniqueId; +// private String rhubId; +// private String prruEsn; +// private String frequencyBand; +// private String prruInstallMode; +// private String antCoordinate; +// private String prruCoordinate; +// private String prruId; +// private String antInstallMode; + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/SysNoticeVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/SysNoticeVO.java new file mode 100644 index 0000000..ed401d0 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/SysNoticeVO.java @@ -0,0 +1,185 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.annotation.BindDict; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.mybatis.JsonListLongTypeHandler; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知公告表VO + *

+ * + * @author ck + * @since 2023-04-14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@TableName(value = "sys_notice" ,autoResultMap = true) +public class SysNoticeVO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增id") + @TableId(value = "notice_id", type = IdType.AUTO) + @Excel(name = "序号",sort = 1) + private Integer noticeId; + + @ApiModelProperty("通知标题") + @TableField("notice_title") + @Excel(name = "通知名称",sort = 2) + private String noticeTitle; + + @ApiModelProperty("通知类型--字典表sys_notice_type") + @TableField("notice_type") + @Excel(name = "通知方式", dictType = "sys_notice_type",sort = 7) + private String noticeType; + + @ApiModelProperty("通知类型--字典表sys_notice_type") + @BindDict(filedMapping = "noticeType", type = "sys_notice_type") + private String noticeTypeStr; + + @ApiModelProperty("通知内容") + @TableField("notice_content") +// @Excel(name = "通知内容") + private String noticeContent; + + @ApiModelProperty("状态 0未读 1已读") + @TableField("status") + private String status; + + @ApiModelProperty("创建人") + @TableField("create_by") +// @Excel(name = "创建人") + private String createBy; + + @ApiModelProperty("插入时间") + @TableField("create_time") +// @Excel(name = "通知时间",sort = 6,dateFormat = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + + @ApiModelProperty("更新人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty("更新时间") + @TableField("update_time") + private LocalDateTime updateTime; + + @ApiModelProperty("备注") + @TableField("remark") + private String remark; + + @ApiModelProperty("接收人") + @TableField("recive_user") + private Integer reciveUser; + + @ApiModelProperty("工作流id") + @TableField("flw_processid") + private String flwProcessid; + + @ApiModelProperty("工作流任务id") + @TableField("flw_taskid") + private String flwTaskid; + + @ApiModelProperty("实际发送时间") + @TableField("send_time") + @Excel(name = "实际通知时间",sort = 9,dateFormat = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime sendTime; + + @ApiModelProperty("发送是否成功,1成功 0失败") + @TableField("send_status") + private String sendStatus; + + @ApiModelProperty("接收人手机号") + @TableField("recive_user_phone") + private String reciveUserPhone; + + @ApiModelProperty("计划发送时间(同天当前时间之前立即发送)") + @TableField("exp_send_time") + @Excel(name = "通知时间",sort = 8,dateFormat = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime expSendTime; + + @ApiModelProperty("加入定时任务标记 默认0未加入 1已加入") + @TableField("add_flag") + private String addFlag; + + @ApiModelProperty("通知对象ids数组") + @TableField(value = "notice_object_id",typeHandler = JsonListLongTypeHandler.class) + private List noticeObjectId; + + @ApiModelProperty("通知对象ids数组") + @BindDict() + private List noticeObjectIdStr; + + @ApiModelProperty("通知模板id") + @TableField("notice_model_id") + private Long noticeModelId; + + @ApiModelProperty("通知模板名称") + @Excel(name = "模板名称",sort = 6) + private String noticeModelName; + + @ApiModelProperty("通知模板id") + @BindDict() + private YwNoticeModelVO noticeModelIdStr; + + @ApiModelProperty("通知场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @TableField("model_scene") + @Excel(name = "通知场景",dictType = "yw_notice_scene",sort = 3) + private String modelScene; + + @ApiModelProperty("通知场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @BindDict(filedMapping = "modelScene", type = "yw_notice_scene") + private String modelSceneStr; + + @ApiModelProperty("对象属性--yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + @Excel(name = "对象属性",dictType = "yw_notice_object",sort = 4) + private String objectProto; + + @ApiModelProperty("对象属性--yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @BindDict(filedMapping = "objectProto", type = "yw_notice_object") + private String objectProtoStr; + +// @ApiModelProperty("通知对象(是指具体的通知接受者,呈现方式包括场馆+群组;分公司+群组名;地市+群组名;ITCC+群组名;场馆+个人名;分公司+个人名;地市+个人名;ITCC+个人名这几种组合。具体呈现内容和对象属性、通知方式相关联)") +// @TableField("notice_object") +//// @Excel(name = "通知对象",sort = 7) +// private String noticeObject; + + @ApiModelProperty("对象名称数组") + @Excel(name = "对象名称",sort = 5) + private String noticeObject; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3简报") + @TableField("model_suit_type") +// @Excel(name = "通知类型",dictType = "model_suit_type") + private String modelSuitType; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3简报") + @BindDict(filedMapping = "modelSuitType", type = "model_suit_type") + private String modelSuitTypeStr; + + @ApiModelProperty("关联表id(yw_notice_handwork)") + @TableField("handwork_id") + private Long handworkId; + + @ApiModelProperty("发送人(由谁发送)") + @TableField("send_user") + private Long sendUser; + + @ApiModelProperty("是否可修改 0否 1是") + private String canUpdate; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/SysUserVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/SysUserVo.java new file mode 100644 index 0000000..78bb8b4 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/SysUserVo.java @@ -0,0 +1,203 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.annotation.Excel.Type; +import com.ruoyi.common.core.domain.entity.SysDept; +import com.ruoyi.common.core.domain.entity.SysRole; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * 用户对象 sys_user + * + * @author ruoyi + */ +@TableName("sys_user") +@Data +public class SysUserVo { + + /** + * 用户ID + */ +// @Excel(name = "ID", sort = 1) + @TableId(value = "user_id") + private Long userId; + + /** + * 部门ID + */ + @TableField(value = "dept_id") + private Long deptId; + + /** + * 用户账号 + */ + @TableField(value = "user_name") + private String userName; + + /** + * 用户昵称 + */ + @Excel(name = "姓名", type = Type.EXPORT, sort = 2) + @TableField(value = "nick_name") + private String nickName; + + @Excel(name = "专业", type = Type.EXPORT, sort = 7) + @TableField(value = "user_type") + private String userType; + + @TableField(exist = false) + private String userTypeStr; + + /** + * 用户邮箱 + */ + private String email; + + /** + * 手机号码 + */ + @Excel(name = "手机号码", type = Type.EXPORT, sort = 3) + @TableField(value = "phonenumber") + private String phonenumber; + + /** + * 用户性别 + */ + private String sex; + + /** + * 用户头像 + */ +// @Excel(name = "头像", sort = 4, type = Type.EXPORT) + private String avatar; + + /** + * 密码 + */ + private String password; + + /** + * 账号状态(0正常 1锁定 2冻结) + */ + @Excel(name = "账号状态", type = Type.EXPORT, sort = 5) + private String status; + + /** + * 删除标志(0代表存在 2代表删除) + */ + @TableField(value = "del_flag") + private String delFlag; + + /** + * 最后登录IP + */ +// @Excel(name = "最后登录IP", sort = 7) + @TableField(value = "login_ip") + private String loginIp; + + @TableField(value = "first_page") + private String firstPage; + + @Excel(name = "地市", type = Type.EXPORT, sort = 8) + private String city; + + + @Excel(name = "区县", type = Type.EXPORT, sort = 9) + private String county; + + @Excel(name = "场馆分区", type = Type.EXPORT, sort = 11) + private String distinctArea; + + @Excel(name = "是否要签到", type = Type.EXPORT, sort = 12) + private String needSign; + + /** + * 最后登录时间 + */ +// @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT, sort = 8) + @TableField(value = "login_date") + private Date loginDate; + + /** + * 部门对象 + */ + private SysDept dept; + + /** + * 角色对象 + */ + private List roles; + + /** + * 角色组 + */ + private Long[] roleIds; + + /** + * 岗位组 + */ + private Long[] postIds; + + /** + * 角色ID + */ + private Long roleId; + + private String belongArea; + + private String[] venueIds; + + private String[] venueNames; + + @Excel(name = "角色", sort = 6, type = Type.EXPORT) + private String strRoles; + + @Excel(name = "场馆", sort = 10, type = Type.EXPORT) + private String strVenueNames; + + private String strVenueIds; + + /** 创建时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private Date createTime; + + + private String strBelongArea; + + private String[] roleNames; + + public SysUserVo() { + + } + + public SysUserVo(Long userId) { + this.userId = userId; + } + + public boolean isAdmin() { + return isAdmin(this.userId); + } + + public static boolean isAdmin(Long userId) { + return userId != null && 1L == userId; + } + + public boolean isAdmin(SysUserVo user) { + Boolean isAdmin = false; + for (SysRole sysRole : user.getRoles()) { +// if("admin".equals(sysRole.getRoleKey())||"monitor".equals(sysRole.getRoleKey())) + if (sysRole.getRoleKey().contains("admin") || sysRole.getRoleKey().contains("monitor")) { + isAdmin = true; + break; + } + } + return isAdmin; + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/TaskMangeListVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/TaskMangeListVo.java new file mode 100644 index 0000000..bb0aa57 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/TaskMangeListVo.java @@ -0,0 +1,13 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +@Data +public class TaskMangeListVo { + private Long stadium_id; + private String stadium_name; + private Integer xunjian_finish_count; + private Integer xunjian_total_count; + private Integer buxian_finish_count; + private Integer buxian_total_count; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/WholeAreaAssureCellSheet.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/WholeAreaAssureCellSheet.java new file mode 100644 index 0000000..2aeacb4 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/WholeAreaAssureCellSheet.java @@ -0,0 +1,35 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class WholeAreaAssureCellSheet { + private String cityCode; + @TableField(exist = false) + private String cityName; + private String countrysideCode; + @TableField(exist = false) + private String countrysideName; + private String rat; + private String cellName; + private String cgi; + private String lac; + private String ci; + private String baseStation; + private String siteId; + private String longitude; + private String latitude; + private String sceneTypeCode; + private String sceneTypeName; + private String sceneSubTypeCode; + private String sceneSubTypeName; + private String sceneCode; + private String sceneName; + private String coverSubSceneCode; + private String coverSubSceneName; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmAGISVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmAGISVo.java new file mode 100644 index 0000000..017dc57 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmAGISVo.java @@ -0,0 +1,45 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + + +@Data +public class YwAlarmAGISVo { + + + private Integer venueId; + @Excel(name = "场馆" ,sort = 1) + private String cg; + private String gd; + + //带下划线开始的时候设计,前端已经在使用 + private String venue_id; + private String site_id; + @Excel(name = "网元名称" ,sort = 2) + private String site_name; + @Excel(name = "端口" ,sort = 3) + private String net_name; + + private Long alarmId; + private String alarmName; + private String siteId; + private String siteName; + private String netName; + @Excel(name = "告警名称" ,sort = 5) + private String name; + @Excel(name = "生成时间" ,sort = 5) + private String start; + @Excel(name = "恢复时间" ,sort = 6) + private String end; + @Excel(name = "红线内" ,sort = 4, readConverterExp = "Y=内,N=外") + private String inRedLine; + private String groupId; + private String alarmType; + private String alarmCode; + private String alarmLevel; + private String alarmLoc; + @Excel(name = "历时" ,sort = 7) + private String duration; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmAppVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmAppVo.java new file mode 100644 index 0000000..9e3469b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmAppVo.java @@ -0,0 +1,12 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +import java.util.List; + +@Data +public class YwAlarmAppVo { + + private String specialty; + private List ywAlarmLastVoList; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmCSVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmCSVo.java new file mode 100644 index 0000000..4670388 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmCSVo.java @@ -0,0 +1,45 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + + +@Data +public class YwAlarmCSVo { + + + private Integer venueId; + @Excel(name = "场馆" ,sort = 1) + private String cg; + private String gd; + + //带下划线开始的时候设计,前端已经在使用 + private String venue_id; + private String site_id; + @Excel(name = "设备名称" ,sort = 2) + private String site_name; + @Excel(name = "端口号" ,sort = 3) + private String net_name; + + private Long alarmId; + private String alarmName; + private String siteId; + private String siteName; + private String netName; + @Excel(name = "告警名称" ,sort = 5) + private String name; + @Excel(name = "生成时间" ,sort = 5) + private String start; + @Excel(name = "恢复时间" ,sort = 6) + private String end; + @Excel(name = "红线内" ,sort = 4, readConverterExp = "Y=内,N=外") + private String inRedLine; + private String groupId; + private String alarmType; + private String alarmCode; + private String alarmLevel; + private String alarmLoc; + @Excel(name = "历时" ,sort = 7) + private String duration; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmClassificationDetail.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmClassificationDetail.java new file mode 100644 index 0000000..2edda9e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmClassificationDetail.java @@ -0,0 +1,13 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +import java.util.List; + +@Data +public class YwAlarmClassificationDetail { + private String alarmName; + private List alarmList; + + private Integer alarmNum; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmDHVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmDHVo.java new file mode 100644 index 0000000..c53633b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmDHVo.java @@ -0,0 +1,45 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + + +@Data +public class YwAlarmDHVo { + + + private Integer venueId; + @Excel(name = "场馆" ,sort = 1) + private String cg; + private String gd; + + //带下划线开始的时候设计,前端已经在使用 + private String venue_id; + private String site_id; + @Excel(name = "基站名称" ,sort = 2) + private String site_name; + @Excel(name = "设备名称" ,sort = 3) + private String net_name; + + private Long alarmId; + private String alarmName; + private String siteId; + private String siteName; + private String netName; + @Excel(name = "告警名称" ,sort = 5) + private String name; + @Excel(name = "生成时间" ,sort = 5) + private String start; + @Excel(name = "恢复时间" ,sort = 6) + private String end; + @Excel(name = "红线内" ,sort = 4, readConverterExp = "Y=内,N=外") + private String inRedLine; + private String groupId; + private String alarmType; + private String alarmCode; + private String alarmLevel; + private String alarmLoc; + @Excel(name = "历时" ,sort = 7) + private String duration; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmInfoVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmInfoVo.java new file mode 100644 index 0000000..d839c9e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmInfoVo.java @@ -0,0 +1,40 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +import java.util.Date; +import java.util.List; + +@Data +public class YwAlarmInfoVo { + + private String groupId; + private String primaryId; + private String processId; + private String taskId; + private String dealStatus; + private String beginTime; + private String alarmContent; + private String lastClearTime; + private String lastBeginTime; + private String hangupReason; + private String hangupTime; + private String siteId; + private String alarmLevel; + private String alarmType; + private String alarmTypeCode; + private String alarmLoc; + + private String venue_id; + private String cg; + private String gd; + private String site_name; + private String net_name; + private String name; + private String start; + private String end; + private List alarmchildren; + + private String siteType; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmLastVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmLastVo.java new file mode 100644 index 0000000..cf1fcf3 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmLastVo.java @@ -0,0 +1,31 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +import java.util.List; + + +@Data +public class YwAlarmLastVo extends YwAlarmVo { + + private String key; + private String state; + private String person; + private String userId; + private String processId; + private String taskId; + private String alarmStatus; + //是否当前登录用户待办 0否 1是 + private int isTodo; + private String dealStatus; + private String belongArea; + private String lastClearTime; + private List alarmchildren; + private Long opId; + private String isHangup; + private Integer clearNum; + private String clearNumDisplay; + + private String beginTime; + private String endTime; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmNewNumVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmNewNumVo.java new file mode 100644 index 0000000..b1aa21b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmNewNumVo.java @@ -0,0 +1,18 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +import java.util.List; + +@Data +public class YwAlarmNewNumVo { + + private String alarmType; + + private Long Num; + + private Long redInNum; + + private Long redOutNum; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmNoticeVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmNoticeVo.java new file mode 100644 index 0000000..390ee94 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmNoticeVo.java @@ -0,0 +1,13 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +import java.util.List; + +@Data +public class YwAlarmNoticeVo { + + private String groupId; + private String processId; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmQuestionVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmQuestionVo.java new file mode 100644 index 0000000..58da236 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmQuestionVo.java @@ -0,0 +1,23 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author huamile + */ +@Data +public class YwAlarmQuestionVo { + + + private Long value; + + private String label; + + private String specialty; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmStatistics.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmStatistics.java new file mode 100644 index 0000000..4c92c36 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmStatistics.java @@ -0,0 +1,31 @@ +package com.ruoyi.eastcom_yw.domain.vo; + + +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +import java.util.Date; + +/** + * (YwAlarmStatistics)表实体类 + * + * @author lee + * @since 2023-04-24 20:22:13 + */ +@Data +public class YwAlarmStatistics extends Model { + // 时间 + private String time; + //专业 + private String profession; + //统计时间 + private Date createTime; + //id + private Long id; + //场馆id + private Long sceneId; + //告警数 + private Long num; + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmViewVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmViewVo.java new file mode 100644 index 0000000..ca2d3f9 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmViewVo.java @@ -0,0 +1,57 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.alibaba.fastjson2.JSONWriter; +import com.alibaba.fastjson2.annotation.JSONField; +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +@Data +public class YwAlarmViewVo extends YwAlarmVo { + + private String key; + @Excel(name = "处理状态" ,sort = 14, readConverterExp = "1=未完成,2=挂起,4=已完成,5=人工闭环") + private String state; + @Excel(name = "反馈人" ,sort = 13) + private String person; + private String userId; + + private String processId; + private String taskId; + private String alarmStatus; + //是否当前登录用户待办 0否 1是 + private int isTodo; + private String dealStatus; + private String belongArea; + private String lastClearTime; + @JSONField(serializeFeatures = JSONWriter.Feature.WriteMapNullValue) + private List alarmchildren; + private Long opId; + private String isHangup; + //挂起的时长 + private Integer hangupTimespan; + private Integer clearNum; + @Excel(name = "故障数" ,sort = 12) + private String clearNumDisplay; + + private String noticeInfo; + + @Excel(name = "基站名称" ,sort = 3) + private String siteNameExport; + + @Excel(name = "告警网元" ,sort = 4) + private String netNameExport; + + private String record; + + @Excel(name = "网络类型" ,sort = 8) + private String siteType; + + private String alarmKey; + + @Excel(name = "阶段处理记录" ,sort = 15) + private String recordExport; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmVo.java new file mode 100644 index 0000000..cea14f3 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmVo.java @@ -0,0 +1,58 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.alibaba.fastjson2.JSONWriter; +import com.alibaba.fastjson2.annotation.JSONField; +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + + +@Data +public class YwAlarmVo { + + @Excel(name = "序号" ,sort = 1) + private Integer id; + + private Integer venueId; + @Excel(name = "场馆" ,sort = 2) + private String cg; + private String gd; + + //带下划线开始的时候设计,前端已经在使用 + private String venue_id; + private String site_id; + @Excel(name = "基站名称" ,sort = 3) + public String site_name; + @Excel(name = "告警网元" ,sort = 4) + public String net_name; + + private Long alarmId; + + private String alarmName; + + private String siteId; + + private String siteName; + + private String netName; + @Excel(name = "告警名称" ,sort = 6) + private String name; + @Excel(name = "生成时间" ,sort = 9) + private String start; + @Excel(name = "恢复时间" ,sort = 10) + private String end; + @Excel(name = "红线内" ,sort = 5, readConverterExp = "Y=内,N=外") + private String inRedLine; + private String groupId; + private String alarmType; + + private String alarmCode; + @Excel(name = "告警级别" ,sort = 7) + private String alarmLevel; + private String alarmLoc; + + @Excel(name = "历时" ,sort = 11) + private String duration; + + private String siteType; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmWXVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmWXVo.java new file mode 100644 index 0000000..8a69145 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwAlarmWXVo.java @@ -0,0 +1,45 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + + +@Data +public class YwAlarmWXVo { + + + private Integer venueId; + @Excel(name = "场馆" ,sort = 1) + private String cg; + private String gd; + + //带下划线开始的时候设计,前端已经在使用 + private String venue_id; + private String site_id; + @Excel(name = "基站名称" ,sort = 2) + private String site_name; + @Excel(name = "告警网元" ,sort = 3) + private String net_name; + + private Long alarmId; + private String alarmName; + private String siteId; + private String siteName; + private String netName; + @Excel(name = "告警名称" ,sort = 5) + private String name; + @Excel(name = "生成时间" ,sort = 5) + private String start; + @Excel(name = "恢复时间" ,sort = 6) + private String end; + @Excel(name = "红线内" ,sort = 4, readConverterExp = "Y=内,N=外") + private String inRedLine; + private String groupId; + private String alarmType; + private String alarmCode; + private String alarmLevel; + private String alarmLoc; + @Excel(name = "历时" ,sort = 7) + private String duration; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwConstrucTeamVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwConstrucTeamVo.java new file mode 100644 index 0000000..f007022 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwConstrucTeamVo.java @@ -0,0 +1,14 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; + +@Data +public class YwConstrucTeamVo { + + //施工队名称 + private String venderName; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwDrsConfigVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwDrsConfigVO.java new file mode 100644 index 0000000..237ee88 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwDrsConfigVO.java @@ -0,0 +1,76 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.ruoyi.common.annotation.BindDict; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + *

+ * DRS配置表VO + *

+ * + * @author ck + * @since 2023-06-13 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwDrsConfigVO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("任务名称") + @TableField("task_name") + private String taskName; + + @ApiModelProperty("任务类型 drs_task_type 1 签到 2巡检") + @TableField("drs_task_type") + private String drsTaskType; + + @ApiModelProperty("DRS任务类型 drs_task_type 1 签到 2巡检") + @TableField("drs_task_type") + @BindDict(filedMapping = "drsTaskType",type = "drs_task_type") + private String drsTaskTypeStr; + + @ApiModelProperty("状态") + @TableField("status") + private String status; + + @ApiModelProperty("创建人") + @TableField(value = "create_by", fill = FieldFill.INSERT) + private String createBy; + + @ApiModelProperty("创建时间") + @TableField(value = "create_time", fill = FieldFill.INSERT) + private LocalDateTime createTime; + + @ApiModelProperty("修改人") + @TableField(value = "update_by", fill = FieldFill.UPDATE) + private String updateBy; + + @ApiModelProperty("修改时间") + @TableField(value = "update_time", fill = FieldFill.UPDATE) + private LocalDateTime updateTime; + + @ApiModelProperty("备注") + @TableField("remark") + private String remark; + + @ApiModelProperty("删除标记") + @TableField("del_flag") + private String delFlag; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwDrsTempTaskVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwDrsTempTaskVO.java new file mode 100644 index 0000000..96fd1d8 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwDrsTempTaskVO.java @@ -0,0 +1,129 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.ruoyi.common.annotation.BindDict; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.utils.poi.LocalDateExcelHandlerAdapter; +import com.ruoyi.common.utils.poi.LocalDateTimeExcelHandlerAdapter; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + *

+ * DRS临时任务表VO + *

+ * + * @author ck + * @since 2023-06-13 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwDrsTempTaskVO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("configId") + private Long configId; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; + + @ApiModelProperty("场馆名称") + @Excel(name = "场馆名称", width = 25, sort = 1) + private String venueName; + + @ApiModelProperty("任务日期") + @TableField("task_date") + @Excel(name = "任务日期", dateFormat = "yyyy-MM-dd", width = 32, sort = 2, handler = LocalDateExcelHandlerAdapter.class) + private LocalDate taskDate; + + @ApiModelProperty("任务时间") + @TableField("task_time") + @Excel(name = "开始时间", dateFormat = "HH:mm:ss", width = 32, sort = 2, handler = LocalDateTimeExcelHandlerAdapter.class) + private LocalDateTime taskTime; + + @ApiModelProperty("任务结束时间") + @TableField("task_end_time") + @Excel(name = "结束时间", dateFormat = "yyyy-MM-dd HH:mm:ss", width = 32, sort = 3, handler = LocalDateTimeExcelHandlerAdapter.class) + private LocalDateTime taskEndTime; + + @ApiModelProperty("任务名称") + @TableField("task_name") + @Excel(name = "任务名称", width = 25, sort = 3) + private String taskName; + + @ApiModelProperty("DRS任务类型 drs_task_type 0 / 1 签到 2巡检") + @TableField("drs_task_type") + private String drsTaskType; + + @ApiModelProperty("DRS任务类型 drs_task_type 0 / 1 签到 2巡检") + @TableField("drs_task_type") + @BindDict(filedMapping = "drsTaskType", type = "drs_task_type") + private String drsTaskTypeStr; + + @ApiModelProperty("DRS任务状态 drs_task_status 0未开始 1进行中 2已完成") + @TableField("drs_task_status") + @Excel(name = "任务状态", dictType = "drs_task_status", combo = {"未开始", "进行中", "已完成"}, width = 25, sort = 4) + private String drsTaskStatus; + + @ApiModelProperty("DRS任务状态 drs_task_status 0未开始 1进行中 2已完成") + @TableField("drs_task_status") + @BindDict(filedMapping = "drsTaskStatus", type = "drs_task_status") + private String drsTaskStatusStr; + + @ApiModelProperty("自动状态变更 drs_auto_update 0自动 1手动") + @TableField("drs_auto_update") + @Excel(name = "派发方式", dictType = "drs_auto_update", combo = {"自动", "手动"}, width = 25, sort = 4) + private String drsAutoUpdate; + + @ApiModelProperty("状态") + @TableField("status") + private String status; + + @ApiModelProperty("创建人") + @TableField(value = "create_by", fill = FieldFill.INSERT) + private String createBy; + + @ApiModelProperty("创建时间") + @TableField(value = "create_time", fill = FieldFill.INSERT) + private LocalDateTime createTime; + + @ApiModelProperty("修改人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty("修改时间") + @TableField("update_time") + private LocalDateTime updateTime; + + @ApiModelProperty("备注") + @TableField("remark") + private String remark; + + @ApiModelProperty("删除标记") + @TableField("del_flag") + private String delFlag; + + /** + * 失败原因 + */ + @Excel(name = "失败原因", type = Excel.Type.EXPORT, width = 40, sort = 15) + @TableField(exist = false) + private String reason; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwErrorAlarmVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwErrorAlarmVO.java new file mode 100644 index 0000000..7b77c9c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwErrorAlarmVO.java @@ -0,0 +1,18 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +@Data +public class YwErrorAlarmVO { + + //告警id + private Long id; + + private String 场馆名称; + + private String 类型; + + private String 名称; + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwInspectLogVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwInspectLogVo.java new file mode 100644 index 0000000..313cc5a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwInspectLogVo.java @@ -0,0 +1,102 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +/** + * @author huamile + */ +@Data +public class YwInspectLogVo { + + private Long routInspectId; + + private Long sceneId; + + @Excel(name = "场馆",width = 20) + private String venueName; + + @Excel(name = "巡检日期",width = 20) + private String inspectDate; + + private String inspectSpecialty; + + @Excel(name = "巡检专业",width = 20) + private String specialtyName; + + @Excel(name = "开始时间",width = 20,exportFormat = "yyyy-MM-dd HH:mm:ss") + private Date beginTime; + + @Excel(name = "计划完成时间",width = 20,exportFormat = "yyyy-MM-dd HH:mm:ss") + private Date planFinTime; + + @Excel(name = "巡检类型",width = 20,replace = {"临时_0,计划_1"}) + private Integer type; + + @Excel(name = "任务名称",width = 20) + private String inspectName; + + @Excel(name = "巡检项数",width = 20) + private Integer checkNum; + + @Excel(name = "巡检类别",width = 20) + private String checkType; + + @Excel(name = "说明",width = 20) + private String checkDesc; + + @Excel(name = "周期次数",width = 20) + private Integer circle; + + @Excel(name = "截止时效",width = 20) + private Long stopTimeOption; + + @Excel(name = "间隔时间",width = 20) + private Long intervalTime; + + private Integer inspectUserId; + + private String jobNo; + + @Excel(name = "巡检人员",width = 20) + private String nickName; + + @Excel(name = "提醒时间",width = 20) + private String repWarnInterval; + + private String noticeType; + + @Excel(name = "通知方式",width = 20) + private String noticeName; + + private String areaCountyId; + + @Excel(name = "市",width = 20) + private String city; + + @Excel(name = "区县",width = 20) + private String county; + + private String flwProcessid; + + @Excel(name = "问题项数",width = 20) + private Integer questionNum; + + @Excel(name = "问题描述",width = 20) + private String questionDesc; + + private Integer feedBackUser; + + @Excel(name = "反馈人",width = 20) + private String feedBackUserName; + + @Excel(name = "反馈时间",width = 20) + private Date feedBackTime; + + private String description; + + private String dealStatus; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwInspectPlanStaticVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwInspectPlanStaticVo.java new file mode 100644 index 0000000..938181d --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwInspectPlanStaticVo.java @@ -0,0 +1,30 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +/** + * @author yqf + * @date 2023/6/27 + */ +@Data +public class YwInspectPlanStaticVo { + + private Long sceneId; + + @Excel(name = "场馆名称", sort = 1) + private String venueName; + + @Excel(name = "应完成", sort = 2) + private Integer allNum; + + @Excel(name = "已完成", sort = 3) + private Integer completedNum; + + @Excel(name = "完成率", sort = 4) + private String rate; + + private double finishRate; + + private String fileUrl; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwInspectPlanVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwInspectPlanVo.java new file mode 100644 index 0000000..9c02198 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwInspectPlanVo.java @@ -0,0 +1,28 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +/** + * @author huamile + */ +@Data +public class YwInspectPlanVo extends YwInspectLogVo { + + @Excel(name = "任务号",width = 20) + private String taskNo; + + private String taskId; + + private String typeName; + + @Excel(name = "是否超时",width = 20) + private String timeoutOrNot; + + @Excel(name = "任务状态",width = 20) + private String taskStatus; + + //是否当前登录用户待办 0否 1是 + private int isTodo; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwKpiConfigVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwKpiConfigVO.java new file mode 100644 index 0000000..63c6ecd --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwKpiConfigVO.java @@ -0,0 +1,84 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.time.LocalDateTime; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 指标字段阈值配置表VO + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwKpiConfigVO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("序号") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("专业(字典表)") + @TableField("subject") + private String subject; + + @ApiModelProperty("网络模式(字典表)") + @TableField("net_type") + private String netType; + + @ApiModelProperty("指标字段") + @TableField("kpi_field") + private Long kpiField; + + @ApiModelProperty("阈值范围") + @TableField("threshold_value") + private String thresholdValue; + + @ApiModelProperty("颜色") + @TableField("color") + private String color; + + @ApiModelProperty("创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty("创建时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty("更新人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty("更新时间") + @TableField("update_time") + private LocalDateTime updateTime; + + @ApiModelProperty("最小是(包括本值)") + @TableField("min_value") + private Object minValue; + + @ApiModelProperty("最大值(不包括本值)") + @TableField("max_value") + private Object maxValue; + + @ApiModelProperty("指标名") + @TableField("kpi_field_name") + private String kpiFieldName; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeBriefingPlanVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeBriefingPlanVO.java new file mode 100644 index 0000000..97c9117 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeBriefingPlanVO.java @@ -0,0 +1,135 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.annotation.BindDict; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.mybatis.JsonListLongTypeHandler; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@TableName(value = "v_yw_notice_briefing_plan",autoResultMap = true) +public class YwNoticeBriefingPlanVO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("地市") + @TableField("city") + @Excel(name = "地市") + private String city; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; + + @ApiModelProperty("场馆名") + @Excel(name = "场馆名") + private String venueName; + + @ApiModelProperty("对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + @Excel(name = "对象属性") + private String objectProto; + + @ApiModelProperty("对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @BindDict(filedMapping = "objectProto", type = "yw_notice_object") + private String objectProtoStr; + + @ApiModelProperty("通知方式sys_notice_type") + @TableField("notice_type") + @Excel(name = "通知方式") + private String noticeType; + + @ApiModelProperty("通知方式sys_notice_type") + @BindDict(filedMapping = "noticeType", type = "sys_notice_type") + private String noticeTypeStr; + + @ApiModelProperty("发送日期") + @TableField("send_date") + @Excel(name = "发送日期") + private LocalDate sendDate; + + @ApiModelProperty("开始时间") + @TableField("begin_time") + @Excel(name = "开始时间") + private LocalDateTime beginTime; + + @ApiModelProperty("结束时间") + @TableField("end_time") + @Excel(name = "结束时间") + private LocalDateTime endTime; + + @ApiModelProperty("区县") + @TableField("county") + @Excel(name = "区县") + private String county; + + @ApiModelProperty("对象ids数组") + @TableField(value = "object_ids") + private List objectIds; + + @ApiModelProperty("对象ids数组") + private String objectIdsStr; + + @ApiModelProperty("通知对象ids数组") + @BindDict() + private List noticeObjectIdStr; + + @ApiModelProperty("模板id") + @TableField("model_id") + private Long modelId; + + @ApiModelProperty("通知模板id") + @BindDict() + private YwNoticeModelVO noticeModelIdStr; + + @ApiModelProperty("排序号") + @TableField("order_num") + private Integer orderNum; + + @ApiModelProperty("时间间隔(单位分)") + @TableField("time_interval") + private Integer timeInterval; + + @ApiModelProperty("通知名称") + @TableField("notice_name") + @Excel(name = "通知名称") + private String noticeName; + + @ApiModelProperty("启用状态 sys_normal_disable 0启用 1停用") + @TableField("sys_normal_disable") + @Excel(name = "启用状态") + private String sysNormalDisable; + + @ApiModelProperty("启用状态 sys_normal_disable 0启用 1停用") + @BindDict(filedMapping = "sysNormalDisable", type = "sys_normal_disable") + private String sysNormalDisableStr; + + @ApiModelProperty("发送时间") + private LocalDateTime sendTime; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3文字简报 4h5简报)") + @TableField("model_suit_type") + private String modelSuitType; + + @ApiModelProperty("发送方式 send_type (1自动发送 2手工发送)") + @TableField("send_type") + private String sendType; + + @ApiModelProperty("发送人员") + @TableField("send_user") + private Long sendUser; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeBriefingVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeBriefingVO.java new file mode 100644 index 0000000..a2c37e6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeBriefingVO.java @@ -0,0 +1,183 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.BindDict; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.utils.poi.LocalDateExcelHandlerAdapter; +import com.ruoyi.common.utils.poi.LocalDateTimeExcelHandlerAdapter; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知通告简报计划表VO + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeBriefingVO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableField("id") + @Excel(name = "序号",type = Excel.Type.EXPORT,sort = 1) + private Long id; + + @ApiModelProperty("地市") + @TableField("city") + @Excel(name = "地市", dictType = "yw_city",sort = 4) + private String city; + + @ApiModelProperty("地市") + @BindDict(filedMapping = "city", type = "yw_city") + private String cityStr; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; + + @ApiModelProperty("场馆名") + @Excel(name = "场馆名称",sort = 6) + private String venueName; + + @ApiModelProperty("对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + @Excel(name = "对象属性", dictType = "yw_notice_object",sort = 3,combo={"场馆层","分公司层","亚运指挥层","ITCC层"}) + private String objectProto; + + @ApiModelProperty("对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @BindDict(filedMapping = "objectProto", type = "yw_notice_object") + private String objectProtoStr; + + @ApiModelProperty("通知方式sys_notice_type") + @TableField("notice_type") + private List noticeType; + + @ApiModelProperty("通知方式sys_notice_type") + @Excel(name = "通知方式",sort = 14) + @BindDict(filedMapping = "noticeType", type = "sys_notice_type") + private String noticeTypeStr; + + //自定义handler没用 + @ApiModelProperty("发送日期") + @TableField("send_date") + @Excel(name = "发送日期",sort = 10,dateFormat = "yyyy-MM-dd",handler= LocalDateExcelHandlerAdapter.class) + private LocalDate sendDate; + + @ApiModelProperty("开始时间") + @TableField("begin_time") + @Excel(name = "开始时间",sort = 11,dateFormat = "yyyy-MM-dd HH:mm:ss",handler= LocalDateTimeExcelHandlerAdapter.class) + private LocalDateTime beginTime; + + @ApiModelProperty("结束时间") + @TableField("end_time") + @Excel(name = "结束时间",sort = 12,dateFormat = "yyyy-MM-dd HH:mm:ss",handler= LocalDateTimeExcelHandlerAdapter.class) + private LocalDateTime endTime; + + @ApiModelProperty("区县") + @TableField("county") + @Excel(name = "区县", dictType = "yw_county",sort = 5) + private String county; + + @ApiModelProperty("区县") + @BindDict(filedMapping = "county", type = "yw_county") + private String countyStr; + + @ApiModelProperty("对象ids数组") + @TableField("object_ids") + private List objectIds; + + @ApiModelProperty("对象名称数组") + private String objectNameStr; + + @ApiModelProperty("通知对象ids数组") + @BindDict() + private List noticeObjectIdStr; + + @ApiModelProperty("模板id") + @TableField("model_id") + private Long modelId; + + @ApiModelProperty("模板名") + @Excel(name = "通知模板",sort = 8) + private String modelName; + + @ApiModelProperty("通知模板id") + @BindDict() + private YwNoticeModelVO noticeModelIdStr; + + @ApiModelProperty("排序号") + @TableField("order_num") + private Integer orderNum; + + @ApiModelProperty("时间间隔(单位分)") + @TableField("time_interval") + @Excel(name = "通报间隔",sort = 9,combo = {"15","60","120"}) + private Integer timeInterval; + + @ApiModelProperty("对象名称") + @Excel(name = "通知对象",sort = 7) + private String objectName; + + @ApiModelProperty("通知名称") + @TableField("notice_name") +// @Excel(name = "通知名称",sort = 5) + private String noticeName; + + @ApiModelProperty("启用状态 sys_normal_disable 0启用 1停用") + @TableField("sys_normal_disable") + @Excel(name = "启用状态", dictType = "sys_normal_disable",sort = 10,combo = {"启用","停用"}) + private String sysNormalDisable; + + @ApiModelProperty("启用状态 sys_normal_disable 0启用 1停用") + @BindDict(filedMapping = "sysNormalDisable", type = "sys_normal_disable") + private String sysNormalDisableStr; + + /** + * 失败原因 + */ + @Excel(name = "失败原因",type = Excel.Type.EXPORT,sort = 15) + @TableField(exist = false) + private String reason; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3文字型简报 4H5型简报)") + @TableField("model_suit_type") + @Excel(name = "简报类型", dictType = "model_suit_type",sort = 2,combo = {"文字型简报","H5型简报"}) + private String modelSuitType; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3文字简报 4h5简报)") + @BindDict(filedMapping = "modelSuitType", type = "model_suit_type") + private String modelSuitTypeStr; + + @ApiModelProperty("发送方式 send_type (1自动发送 2手工发送)") + @TableField("send_type") + @Excel(name = "发送方式", dictType = "send_type",sort = 13,combo = {"自动发送","手工发送"}) + private String sendType; + + @ApiModelProperty("发送方式 send_type (1自动发送 2手工发送)") + @BindDict(filedMapping = "sendType", type = "send_type") + private String sendTypeStr; + + @ApiModelProperty("发送人员") + @TableField("send_user") + private Long sendUser; + + @ApiModelProperty("发送人员") + @Excel(name = "发送人员",sort = 10) + private String sendUserStr; + + @ApiModelProperty("发送人员") + @Excel(name = "发送人员手机号",sort = 10) + private String sendUserPhoneStr; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeHandworkVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeHandworkVO.java new file mode 100644 index 0000000..f296434 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeHandworkVO.java @@ -0,0 +1,134 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.BindDict; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知通告手工通知计划表VO + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeHandworkVO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("通知名称") + @TableField("notice_name") + @Excel(name = "通知名称",sort = 1) + private String noticeName; + + @ApiModelProperty("通知模板id") + @TableField("notice_model") + private Long noticeModel; + + @ApiModelProperty("通知模板id") + @Excel(name = "通知模板",sort = 3) + private String noticeModelName; + + @ApiModelProperty("通知模板id") + @BindDict() + private YwNoticeModelVO noticeModelIdStr; + + @ApiModelProperty("通知场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @TableField("model_scene") +// @Excel(name = "通知场景",dictType = "yw_notice_scene",sort = 3) + private String modelScene; + + @ApiModelProperty("通知场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @BindDict(filedMapping = "modelScene", type = "yw_notice_scene") + private String modelSceneStr; + + @ApiModelProperty("通知方式--sys_notice_type") + @TableField("notice_type") + private List noticeType; + + @ApiModelProperty("通知方式--sys_notice_type") + @Excel(name = "通知方式") + @BindDict(filedMapping = "noticeType", type = "sys_notice_type") + private String noticeTypeStr; + + @ApiModelProperty("通知对象ids") + @TableField("notice_object") + private List noticeObject; + + @ApiModelProperty("对象名称数组") + @Excel(name = "通知对象",sort = 4) + private String objectNameStr; + + @ApiModelProperty("通知对象ids数组") + @BindDict() + private List noticeObjectIdStr; + + @ApiModelProperty("通知内容") + @TableField("notice_content") + @Excel(name = "通知内容",sort = 5) + private String noticeContent; + + @ApiModelProperty("通知状态yw_veriy_status 0待提交 1待审核 2已审核") + @TableField("notice_status") + @Excel(name = "通知状态",dictType = "yw_veriy_status",sort = 6) + private String noticeStatus; + + @ApiModelProperty("通知状态yw_veriy_status 0待提交 1待审核 2已审核") + @BindDict(filedMapping = "noticeStatus", type = "yw_veriy_status") + private String noticeStatusStr; + + @ApiModelProperty("日期") + @TableField("notice_date") + @Excel(name = "日期",dateFormat = "yyyy-MM-dd HH:mm:ss",sort = 7) + private LocalDateTime noticeDate; + + @ApiModelProperty("开始时间") + @TableField("begin_time") + private LocalDateTime beginTime; + + @ApiModelProperty("结束时间") + @TableField("end_time") + private LocalDateTime endTime; + + @ApiModelProperty("时间间隔(单位分)") + @TableField("time_interval") + private Integer timeInterval; + + @ApiModelProperty("工作流processid") + @TableField("flw_processid") + private String flwProcessid; + + @ApiModelProperty("申请人id") + @TableField("apply_id") + private Long applyId; + + @ApiModelProperty("审核人id") + @TableField("audit_id") + private Long auditId; + + @ApiModelProperty("任务id") + private String taskId; + + @ApiModelProperty("已添加到sys_notice标记(0否 1是)") + @TableField("add_flag") + private String addFlag; + + @ApiModelProperty("通知对象名称数组") + @TableField("notice_object_name_str") + private String noticeObjectNameStr; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeHandworkdetailVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeHandworkdetailVO.java new file mode 100644 index 0000000..b04eda4 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeHandworkdetailVO.java @@ -0,0 +1,61 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.BindDict; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * 通知通告手工通知审核表VO + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeHandworkdetailVO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("手工通知id") + @TableField("handwork_id") + private Long handworkId; + + @ApiModelProperty("操作人(提交审核的人 或者 审核的人)") + @TableField("oprate_user") + private Long oprateUser; + + @ApiModelProperty("审核结果(关联字典表yw_veriy_result 0通过 1驳回)") + @TableField("veriy_result") + private String veriyResult; + + @ApiModelProperty("审核结果(关联字典表yw_veriy_result 0通过 1驳回)") + @BindDict(filedMapping = "veriyResult", type = "yw_veriy_result") + private String veriyResultStr; + + @ApiModelProperty("审核状态(关联字典表yw_veriy_status 0 待审核 1 已审核)") + @TableField("veriy_status") + private String veriyStatus; + + @ApiModelProperty("审核状态(关联字典表yw_veriy_status 0 待审核 1 已审核)") + @BindDict(filedMapping = "veriyStatus", type = "yw_veriy_status") + private String veriyStatusStr; + + @ApiModelProperty("驳回原因") + @TableField("fail_reason") + private String failReason; + + @ApiModelProperty("附件") + @TableField("appendix") + private String appendix; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeListVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeListVO.java new file mode 100644 index 0000000..6ebc8e2 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeListVO.java @@ -0,0 +1,136 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.BindDict; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知通告记录表VO + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeListVO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableField("id") + private Long id; + + @ApiModelProperty("通知名称") + @TableField("notice_name") + @Excel(name = "通知名称") + private String noticeName; + + @ApiModelProperty("通知场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @TableField("model_scene") + @Excel(name = "通知场景") + private String modelScene; + + @ApiModelProperty("通知场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @BindDict(filedMapping = "modelScene", type = "yw_notice_scene") + private String modelSceneStr; + + @ApiModelProperty("对象属性--yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + @Excel(name = "对象属性") + private String objectProto; + + @ApiModelProperty("对象属性--yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @BindDict(filedMapping = "objectProto", type = "yw_notice_object") + private String objectProtoStr; + + @ApiModelProperty("通知方式--sys_notice_type") + @TableField("notice_type") + @Excel(name = "通知方式") + private String noticeType; + + @ApiModelProperty("通知方式--sys_notice_type") + @BindDict(filedMapping = "noticeType", type = "sys_notice_type") + private String noticeTypeStr; + + @ApiModelProperty("通知时间(计划发送时间(同天当前时间之前立即发送))") + @TableField("notice_time") + @Excel(name = "通知时间") + private LocalDateTime noticeTime; + + @ApiModelProperty("通知对象") + @TableField("notice_object") + @Excel(name = "通知对象") + private String noticeObject; + + @ApiModelProperty("通知内容") + @TableField("notice_content") + @Excel(name = "通知内容") + private String noticeContent; + + @ApiModelProperty("状态 0未读 1已读") + @TableField("status") + private String status; + + @ApiModelProperty("通知对象ids数组") + @TableField("notice_object_id") + private List noticeObjectId; + + @ApiModelProperty("通知对象ids数组") + @BindDict() + private List noticeObjectIdStr; + + @ApiModelProperty("通知模板id") + @TableField("notice_model_id") + private Long noticeModelId; + + @ApiModelProperty("通知模板id") + @BindDict() + private YwNoticeModelVO noticeModelIdStr; + + @ApiModelProperty("实际发送时间") + @TableField("send_time") + private LocalDateTime sendTime; + + @ApiModelProperty("发送是否成功,1成功 0失败") + @TableField("send_status") + private String sendStatus; + + @ApiModelProperty("计划发送时间(同天当前时间之前立即发送)") + @TableField("exp_send_time") + private LocalDateTime expSendTime; + + @ApiModelProperty("加入定时任务标记 默认0未加入 1已加入") + @TableField("add_flag") + private String addFlag; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3简报") + @TableField("model_suit_type") + @Excel(name = "通知类型") + private String modelSuitType; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3简报") + @BindDict(filedMapping = "modelSuitType", type = "model_suit_type") + private String modelSuitTypeStr; + + @ApiModelProperty("计划id(手工与简报会先配置计划)") + @TableField("plan_id") + private Long planId; + + @ApiModelProperty("手工计划信息") + @BindDict + private YwNoticeHandworkVO YwNoticeHandworkVO; + + @ApiModelProperty("简报计划信息") + @BindDict + private YwNoticeBriefingVO ywNoticeBriefingVO; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeModelVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeModelVO.java new file mode 100644 index 0000000..05af9bc --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeModelVO.java @@ -0,0 +1,104 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.BindDict; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + *

+ * 通知通告模板表VO + *

+ * + * @author ck + * @since 2023-04-07 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeModelVO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableField("id") + @Excel(name = "序号",sort = 1) + private Long id; + + @ApiModelProperty("模板名称") + @TableField("model_name") + @Excel(name = "模板名称",sort = 2) + private String modelName; + + @ApiModelProperty("模板内容") + @TableField("model_content") + @Excel(name = "模板内容",sort = 5) + private String modelContent; + + @ApiModelProperty("场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @TableField("model_scene") + @Excel(name = "模板场景", dictType = "yw_notice_scene",sort = 3) + private String modelScene; + + @ApiModelProperty("场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @TableField("model_scene") + @BindDict(filedMapping = "modelScene", type = "yw_notice_scene") + private String modelSceneStr; + + @ApiModelProperty("用户id") + @TableField(value = "create_user_id", fill = FieldFill.INSERT) + private Long createUserId; + + @ApiModelProperty("创建用户昵称") + @TableField(value = "create_by", fill = FieldFill.INSERT) + @Excel(name = "创建者",sort = 5) + private String createBy; + + @ApiModelProperty("创建时间") + @TableField("create_time") + @Excel(name = "创建时间",sort = 6,dateFormat = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + + @ApiModelProperty("模板适用类型model_suit_type 1 普通 2 手工 3简报") + @TableField("model_suit_type") + @Excel(name = "模板类型", dictType = "model_suit_type",sort = 4) + private String modelSuitType; + + @ApiModelProperty("模板适用类型 1 普通 2 手工 3简报") + @TableField("model_suit_type") + @BindDict(filedMapping = "modelSuitType", type = "model_suit_type") + private String modelSuitTypeStr; + + @ApiModelProperty("备注(写一些触发要求)") + @TableField("model_des") +// @Excel(name = "备注") + private String modelDes; + + @ApiModelProperty("模板类型--字典yw_model_type 0事件触发型") + @TableField("model_type") +// @Excel(name = "模板类型", dictType = "yw_model_type") + private String modelType; + + @ApiModelProperty("模板类型--字典yw_model_type 0事件触发型") + @TableField("model_type") + @BindDict(filedMapping = "modelType", type = "yw_model_type") + private String modelTypeStr; + + @ApiModelProperty("排序号") + @TableField("order_num") + private Integer orderNum; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; + + @ApiModelProperty("发送方式 send_type (1自动发送 2手工发送)") + private String sendTypeStr; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeObjectVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeObjectVO.java new file mode 100644 index 0000000..6601fb6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeObjectVO.java @@ -0,0 +1,158 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.BindDict; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + *

+ * 通知通告对象表VO + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeObjectVO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableField("id") + @Excel(name = "序号",sort = 1) + private Long id; + + @ApiModelProperty("地市") + @TableField("city") + @Excel(name = "地市",dictType ="yw_city",sort = 4) + private String city; + + @ApiModelProperty("地市") + @BindDict(filedMapping = "city", type = "yw_city") + private String cityStr; + + @ApiModelProperty("区县") + @TableField("county") + @Excel(name = "区县",dictType ="yw_county",sort = 5 ) + private String county; + + @ApiModelProperty("区县") + @BindDict(filedMapping = "county", type = "yw_county") + private String countyStr; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; + + @ApiModelProperty("场馆名") + @Excel(name = "场馆",sort = 6) + private String venueName; + + @ApiModelProperty("专业") + @TableField("specialty") + private Long specialty; + + @ApiModelProperty("角色id数组") + @TableField("role_ids") + private List roleIds; + + @ApiModelProperty("对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + @Excel(name = "对象属性",sort = 3,dictType = "yw_notice_object",combo={"场馆层","分公司层","亚运指挥层","ITCC层"}) + private String objectProto; + + @ApiModelProperty("对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + @BindDict(filedMapping = "objectProto", type = "yw_notice_object") + private String objectProtoStr; + + @ApiModelProperty("通知方式sys_notice_type") + @TableField("notice_type") +// @Excel(name = "通知方式", dictType = "sys_notice_type") + private String noticeType; + + @ApiModelProperty("通知方式sys_notice_type") + @TableField("notice_type") + @BindDict(filedMapping = "noticeType", type = "sys_notice_type") + private String noticeTypeStr; + + @ApiModelProperty("短信组名") + @TableField("message_name") + @Excel(name = "短信组名",sort = 9) + private String messageName; + + @ApiModelProperty("短信组内成员id数组") + @TableField("message_users") + private List messageUsers; + + @ApiModelProperty("短信组内成员id数组") + private List messageUsersStr; + + @ApiModelProperty("短信组内成员id数组") + @Excel(name = "短信组内成员",needMerge=true,sort = 10) + private String messageUsersExcelStr; + + @ApiModelProperty("短信组内成员id数组") + @Excel(name = "短信组内成员手机号",needMerge=true,sort = 11) + private String messageUsersExcelPhoneStr; + + @ApiModelProperty("排序号") + @TableField("order_num") + private Integer orderNum; + + @ApiModelProperty("群号") + @TableField("group_id") + @Excel(name = "群号",sort = 7) + private String groupId; + + @ApiModelProperty("群名") + @TableField("group_name") + @Excel(name = "群名",sort = 8) + private String groupName; + + @ApiModelProperty("备注") + @TableField("group_des") + @Excel(name = "备注",sort = 15) + private String groupDes; + + @ApiModelProperty("对象名称") + @TableField("object_name") + @Excel(name = "对象名称",sort = 2) + private String objectName; + + @ApiModelProperty("ivr组名") + @TableField("ivr_name") + @Excel(name = "ivr组名",sort = 12) + private String ivrName; + + @ApiModelProperty("ivr组内成员id数组") + @TableField("ivr_users") + private List ivrUsers; + + @ApiModelProperty("ivr组内成员id数组") + private List ivrUsersStr; + + @ApiModelProperty("ivr组内成员id数组") + @Excel(name = "ivr组内成员",sort = 13) + private String ivrUsersExcelStr; + + @ApiModelProperty("ivr组内成员id数组") + @Excel(name = "ivr组内成员手机号",sort = 14) + private String ivrUsersExcelPhoneStr; + + /** + * 失败原因 + */ + @Excel(name = "失败原因",type = Excel.Type.EXPORT,sort = 16) + @TableField(exist = false) + private String reason; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeObjectaVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeObjectaVO.java new file mode 100644 index 0000000..bf0aae8 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwNoticeObjectaVO.java @@ -0,0 +1,158 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.BindDict; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + *

+ * 通知通告对象表VO + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwNoticeObjectaVO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("id") + @TableField("id") + @Excel(name = "序号",sort = 1) + private Long id; + + @ApiModelProperty("地市") + @TableField("city") + @Excel(name = "地市",dictType ="yw_city",sort = 4) + private String city; + + @ApiModelProperty("地市") + @BindDict(filedMapping = "city", type = "yw_city") + private String cityStr; + + @ApiModelProperty("区县") + @TableField("county") + @Excel(name = "区县",dictType ="yw_county",sort = 5 ) + private String county; + + @ApiModelProperty("区县") + @BindDict(filedMapping = "county", type = "yw_county") + private String countyStr; + + @ApiModelProperty("场馆id") + @TableField("venue_id") + private Long venueId; + + @ApiModelProperty("场馆名") + @Excel(name = "场馆名",sort = 6) + private String venueName; + + @ApiModelProperty("专业") + @TableField("specialty") + private Long specialty; + + @ApiModelProperty("角色id数组") + @TableField("role_ids") + private List roleIds; + + @ApiModelProperty("对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + @Excel(name = "对象属性",sort = 3,dictType = "yw_notice_object") + private String objectProto; + + @ApiModelProperty("对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + @BindDict(filedMapping = "objectProto", type = "yw_notice_object") + private String objectProtoStr; + + @ApiModelProperty("通知方式sys_notice_type") + @TableField("notice_type") +// @Excel(name = "通知方式", dictType = "sys_notice_type") + private String noticeType; + + @ApiModelProperty("通知方式sys_notice_type") + @TableField("notice_type") + @BindDict(filedMapping = "noticeType", type = "sys_notice_type") + private String noticeTypeStr; + + @ApiModelProperty("短信组名") + @TableField("message_name") + @Excel(name = "短信组名",sort = 9) + private String messageName; + + @ApiModelProperty("短信组内成员id数组") + @TableField("message_users") + private List messageUsers; + + @ApiModelProperty("短信组内成员id数组") + private List messageUsersStr; + + @ApiModelProperty("短信组内成员id数组") + @Excel(name = "短信组内成员",needMerge=true,sort = 10) + private String messageUsersExcelStr; + + @ApiModelProperty("短信组内成员id数组") + @Excel(name = "短信组内成员手机号",needMerge=true,sort = 11) + private String messageUsersExcelPhoneStr; + + @ApiModelProperty("排序号") + @TableField("order_num") + private Integer orderNum; + + @ApiModelProperty("群号") + @TableField("group_id") + @Excel(name = "群号",sort = 7) + private String groupId; + + @ApiModelProperty("群名") + @TableField("group_name") + @Excel(name = "群名",sort = 8) + private String groupName; + + @ApiModelProperty("备注") + @TableField("group_des") + @Excel(name = "备注",sort = 15) + private String groupDes; + + @ApiModelProperty("对象名称") + @TableField("object_name") + @Excel(name = "对象名称",sort = 2) + private String objectName; + + @ApiModelProperty("ivr组名") + @TableField("ivr_name") + @Excel(name = "ivr组名",sort = 12) + private String ivrName; + + @ApiModelProperty("ivr组内成员id数组") + @TableField("ivr_users") + private List ivrUsers; + + @ApiModelProperty("ivr组内成员id数组") + private List ivrUsersStr; + + @ApiModelProperty("ivr组内成员id数组") + @Excel(name = "ivr组内成员",sort = 13) + private String ivrUsersExcelStr; + + @ApiModelProperty("ivr组内成员id数组") + @Excel(name = "ivr组内成员手机号",sort = 14) + private String ivrUsersExcelPhoneStr; + + /** + * 失败原因 + */ + @Excel(name = "失败原因",sort = 16) + @TableField(exist = false) + private String reason; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneAlarmVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneAlarmVo.java new file mode 100644 index 0000000..17617a8 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneAlarmVo.java @@ -0,0 +1,41 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +//import cn.afterturn.easypoi.excel.annotation.Excel; +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +/** + * @author huamile + */ +@Data +public class YwSceneAlarmVo { + + private Long id; + + @Excel(name = "场馆名称",width = 20,sort = 1) + private String venueName; + + @Excel(name = "告警名称",width = 20,sort = 2) + private String alarmName; + + private String specialty; + + @Excel(name = "专业",width = 20,sort = 3) + private String specialtyName; + + @Excel(name = "处理时长限制",width = 20,sort = 4) + private Long dealHour; + + @Excel(name = "告警编号",width = 20,sort = 5) + private String alarmCode; + + @Excel(name = "黑白名单",width = 20,sort = 6) + private String blackorwhite; + + @Excel(name = "告警等级",width = 20,sort = 7) + private Integer alarmLevel; + + @Excel(name = "状态",width = 20,sort = 8) + private String status; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneBaseInfoVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneBaseInfoVo.java new file mode 100644 index 0000000..5491248 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneBaseInfoVo.java @@ -0,0 +1,9 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +@Data +public class YwSceneBaseInfoVo { + private String managerName; + private String phone; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneCalendar2Vo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneCalendar2Vo.java new file mode 100644 index 0000000..c5d5ba5 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneCalendar2Vo.java @@ -0,0 +1,58 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.importer.beans.ResultBean; +import lombok.Data; + +import java.util.Date; + +/** + * @author huamile + */ +@Data +public class YwSceneCalendar2Vo extends ResultBean { + + private Long id; + + @Excel(name = "编号", sort = 1) + private String idStr; + + private Long sceneId; + + @Excel(name = "场馆", width = 20, sort = 2) + private String venueName; + + private String matchType; + + @Excel(name = "比赛类型", width = 20, sort = 3) + private String matchTypeName; + + @Excel(name = "比赛名称", width = 20, sort = 4) + private String matchName; + + @Excel(name = "比赛日期", width = 20, dateFormat = "yyyy-MM-dd", sort = 5) + private String matchDate; + + @Excel(name = "开始时间", width = 20, dateFormat = "HH:mm", sort = 6) + private String beginTime; + + @Excel(name = "结束时间", width = 20, dateFormat = "HH:mm", sort = 7) + private String endTime; + + private String status; + + @Excel(name = "状态", width = 20, sort = 8) + private String statusName; + + @Excel(name = "备注", width = 20, sort = 9) + private String matchRemark; + + private String createBy; + + private Date createTime; + + private String updateBy; + + private Date updateTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneCalendarVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneCalendarVo.java new file mode 100644 index 0000000..60cea0e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneCalendarVo.java @@ -0,0 +1,45 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +//import cn.afterturn.easypoi.excel.annotation.Excel; +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +/** + * @author huamile + */ +@Data +public class YwSceneCalendarVo { + + private Long id; + + private Long sceneId; + + @Excel(name = "场馆名称",width = 20,sort = 1) + private String venueName; + + private String matchType; + + @Excel(name = "赛事类型",width = 20,sort = 2) + private String matchTypeName; + + @Excel(name = "赛事名称",width = 20,sort = 3) + private String matchName; + + @Excel(name = "赛事说明",width = 20,sort = 4) + private String matchRemark; + + @Excel(name = "开始时间",width = 20,sort = 5) + private String beginTime; + + @Excel(name = "结束时间",width = 20,sort = 6) + private String endTime; + + @Excel(name = "比赛日期",width = 20,sort = 7) + private String matchDate; + + private String status; + + @Excel(name = "状态",width = 20,sort = 8) + private String statusName; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneExportVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneExportVo.java new file mode 100644 index 0000000..f519e80 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneExportVo.java @@ -0,0 +1,57 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +/** + * @author liqiz + */ +@Data +public class YwSceneExportVo { + + @Excel(name = "场馆标准名称", type = Excel.Type.EXPORT, sort = 1) + private String venueName; + + @Excel(name = "备注", type = Excel.Type.EXPORT, sort = 15) + private String venueDesc; + + @Excel(name = "地址", type = Excel.Type.EXPORT, sort = 14) + private String venueAddress; + + @Excel(name = "所属区县", type = Excel.Type.EXPORT, sort = 12) + private String county; + + @Excel(name = "纬度GPS", type = Excel.Type.EXPORT, sort = 8) + private Double latitude; + + @Excel(name = "经度GPS", type = Excel.Type.EXPORT, sort = 7) + private Double longitude; + + @Excel(name = "场馆属性", type = Excel.Type.EXPORT, sort = 5) + private String venueType; + + @Excel(name = "场馆级别", type = Excel.Type.EXPORT, sort = 6) + private String venueLevel; + + @Excel(name = "场馆简称", type = Excel.Type.EXPORT, sort = 2) + private String venueShortname; + + @Excel(name = "所属地市", type = Excel.Type.EXPORT, sort = 11) + private String city; + + @Excel(name = "场馆英文缩写", type = Excel.Type.EXPORT, sort = 3) + private String englishShortname; + + @Excel(name = "维护类别", type = Excel.Type.EXPORT, sort = 4) + private String maintainType; + + @Excel(name = "经度GCJ02", type = Excel.Type.EXPORT, sort = 9) + private Double longitudeGcj02; + + @Excel(name = "纬度GCJ02", type = Excel.Type.EXPORT, sort = 10) + private Double latitudeGcj02; + + @Excel(name = "赛事类型", type = Excel.Type.EXPORT, sort = 13) + private String matchType; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneKPIStatisticsVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneKPIStatisticsVo.java new file mode 100644 index 0000000..1457c22 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneKPIStatisticsVo.java @@ -0,0 +1,38 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +/** + * 场馆性能(15分粒度) + */ +@Data +public class YwSceneKPIStatisticsVo { + /** + * x轴 + */ + private String datetime; + /** + * 上行prb利用率 + */ + private Float value; + /** + * 下行prb利用率 + */ + private Float value2; + /** + * 最大用户数 + */ + private Float maxUserNum; + /** + * 上行平均干扰 + */ + private Float avgInterfere; + /** + * 流量GB + */ + private Float flux; + /** + * 无线接通率 + */ + private Float wirelessCompletionRate; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneMatchVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneMatchVo.java new file mode 100644 index 0000000..997f78a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneMatchVo.java @@ -0,0 +1,54 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.importer.beans.ResultBean; +import lombok.Data; + +import java.util.Date; + +/** + * @author los + */ +@Data +@TableName("yw_scene_match") +public class YwSceneMatchVo extends ResultBean { + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @Excel(name = "编号", sort = 1) + @TableField(exist = false) + private String idStr; + private Long sceneId; + @Excel(name = "场馆名称", sort = 2) + @TableField(exist = false) + private String sceneName; + private String taskType; + @Excel(name = "赛程类型", sort = 3) + @TableField(exist = false) + private String taskTypeName; + @Excel(name = "赛程名称", sort = 4) + private String taskName; + private String taskStatus; + @Excel(name = "开始时间", dateFormat = "yyyy-MM-dd HH:mm:ss", sort = 5) + @TableField(exist = false) + private String beginTimeStr; + private Date beginTime; + @Excel(name = "结束时间", dateFormat = "yyyy-MM-dd HH:mm:ss", sort = 6) + @TableField(exist = false) + private String endTimeStr; + private Date endTime; + @Excel(name = "赛程状态", sort = 7) + @TableField(exist = false) + private String taskStatusName; + + private String createBy; + + private Date createTime; + + private String updateBy; + + private Date updateTime; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetAgixStaVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetAgixStaVo.java new file mode 100644 index 0000000..9ab1cf6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetAgixStaVo.java @@ -0,0 +1,71 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +import java.util.List; + +/** + * @author yqf + * @date 2023/8/14 + */ +@Data +public class YwSceneNetAgixStaVo { + + private String statdate; + //总流量 + private float flowcount; + + //汇聚-核心链路平均时延 + private float convcoreavgdelay; + + //汇聚-核心链路平均抖动 + private float convcoreavgjitter; + + //汇聚-核心链路平均丢包 + private float convcoreavglpackratio; + + //AGIS下行总流量 + private float dlconvcoreflow; + + //AGIS上行总流量 + private float ulconvcoreflow; + + //场馆出口下行流速 + private float dlvenuevelocity; + + //场馆出口上行流速 + private float ulvenuevelocity; + + //AGIS汇聚_CPU利用率 + private float conswitchcpuratio; + + //AGIS汇聚_内存利用率 + private float convswitchramratio; + + //AGIS接入_CPU利用率 + private float accessswitchcpuratio; + + //AGIS接入_内存利用率 + private float accessswitchraratio; + + //AGIS上行带宽利用率 + private float ulvenuebandratio; + + //AGIS下行带宽利用率 + private float dlvenuebandratio; + + //AGIS流量top5 + private List flowTop5List; + + //上行流速top5 + private List ullocityTop5List; + + //下行流速top5 + private List dllocityTop5List; + + //上行带宽利用率top5 + private List ulbandratioTop5List; + + //下行带宽利用率top5 + private List dlbandratioTop5List; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetFixtelRegSuccVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetFixtelRegSuccVo.java new file mode 100644 index 0000000..f8acde8 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetFixtelRegSuccVo.java @@ -0,0 +1,14 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/8/16 + */ +@Data +public class YwSceneNetFixtelRegSuccVo { + + private String time; + private float regsuccratio; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetFixtelStaVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetFixtelStaVo.java new file mode 100644 index 0000000..386cca0 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetFixtelStaVo.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +import java.util.List; + +/** + * @author yqf + * @date 2023/8/15 + */ +@Data +public class YwSceneNetFixtelStaVo { + + private String statdate; + + //固话开户数 + private float opencnt; + + //固话在线用户数 + private float onlineusercnt; + + private float regsuccratio; + + private List list; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetStaVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetStaVo.java new file mode 100644 index 0000000..e7dc1f7 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetStaVo.java @@ -0,0 +1,54 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +import java.util.List; + +/** + * @author yqf + * @date 2023/8/14 + */ +@Data +public class YwSceneNetStaVo { + + private String statdate; + + //互联网在线用户数 + private Integer onlineusercnt; + + //互联网上行带宽利用率 + private float ulvenuebandratio; + + //互联网下行带宽利用率 + private float dlvenuebandratio; + + //互联网场馆出口_下行流速 + private float dlvenuevelocity; + + //互联网出口_上行流速 + private float ulvenuevelocity; + + //总流量 + private float flowcount; + + //互联网出口带宽 + private float venuebandwith; + + private List list; + + +// //AGIS流量top5 +// private List flowTop5List; +// +// //上行流速top5 +// private List ullocityTop5List; +// +// //下行流速top5 +// private List dllocityTop5List; +// +// //上行带宽利用率top5 +// private List ulbandratioTop5List; +// +// //下行带宽利用率top5 +// private List dlbandratioTop5List; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetVelocityStaVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetVelocityStaVo.java new file mode 100644 index 0000000..f12d4ff --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetVelocityStaVo.java @@ -0,0 +1,17 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/8/14 + */ +@Data +public class YwSceneNetVelocityStaVo { + + private String statdate; + + private float dlvenuevelocity; + + private float ulvenuevelocity; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetWifiStaVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetWifiStaVo.java new file mode 100644 index 0000000..21ee83c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetWifiStaVo.java @@ -0,0 +1,50 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +import java.util.List; + +/** + * @author yqf + * @date 2023/8/21 + */ +@Data +public class YwSceneNetWifiStaVo { + + private String statdate; + //总流量 + private float flowcount; + + //下行流速 + private float dlvenuevelocity; + + //上行流速 + private float ulvenuevelocity; + + //上行带宽利用率 + private float ulvenuebandratio; + + //下行带宽利用率 + private float dlvenuebandratio; + + //互联网出口带宽 + private float venuebandwith; + + //互联网在线用户数 + private int onlineusercnt; + + //AGIS流量top5 + private List flowTop5List; + + //上行流速top5 + private List ullocityTop5List; + + //下行流速top5 + private List dllocityTop5List; + + //上行带宽利用率top5 + private List ulbandratioTop5List; + + //下行带宽利用率top5 + private List dlbandratioTop5List; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementAgis.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementAgis.java new file mode 100644 index 0000000..8cd75bb --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementAgis.java @@ -0,0 +1,46 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.importer.beans.ResultBean; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * @author los + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwSceneNetelementAgis extends ResultBean { + @TableId(value = "id", type = IdType.AUTO) + private Long id; + private Long sceneId; + @Excel(name = "专业", type = Excel.Type.ALL, sort = 1) + private String alarmSpecityName; + private String alarmSpecityId; + @Excel(name = "场馆", type = Excel.Type.ALL, sort = 2) + private String sceneName; + @Excel(name = "网元名称", type = Excel.Type.ALL, sort = 3) + private String netElementName; + @Excel(name = "端口", type = Excel.Type.ALL, sort = 4) + private String portA; + @Excel(name = "设备类型", type = Excel.Type.ALL, sort = 5) + private String equipmentType; + @Excel(name = "对端网元", type = Excel.Type.ALL, sort = 6) + private String netElementB; + @Excel(name = "对端端口", type = Excel.Type.ALL, sort = 7) + private String portB; + @Excel(name = "对端设备类型", type = Excel.Type.ALL, sort = 8) + private String equipmentTypeB; + @Excel(name = "备注", type = Excel.Type.ALL, sort = 9) + private String desc; + private String updateBy; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private Date updateTime; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementCs.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementCs.java new file mode 100644 index 0000000..743c643 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementCs.java @@ -0,0 +1,45 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.importer.beans.ResultBean; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * @author los + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwSceneNetelementCs extends ResultBean { + @TableId(value = "id", type = IdType.AUTO) + private Long id; + private Long sceneId; + @Excel(name = "场馆", type = Excel.Type.ALL, sort = 1) + private String sceneName; + @Excel(name = "设备类型", type = Excel.Type.ALL, sort = 2) + private String equipmentType; + @Excel(name = "A端网元", type = Excel.Type.ALL, sort = 4) + private String netElementNameA; + @Excel(name = "A端端口", type = Excel.Type.ALL, sort = 5) + private String portA; + @Excel(name = "A端属性(红线内外)", type = Excel.Type.ALL, sort = 6) + private String attributeA; + @Excel(name = "组网类型", type = Excel.Type.ALL, sort = 3) + private String networkingType; + @Excel(name = "Z端网元", type = Excel.Type.ALL, sort = 7) + private String netElementZ; + @Excel(name = "Z端端口", type = Excel.Type.ALL, sort = 8) + private String portZ; + @Excel(name = "Z端属性(红线内外)", type = Excel.Type.ALL, sort = 9) + private String attributeZ; + private String updateBy; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private Date updateTime; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementDh.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementDh.java new file mode 100644 index 0000000..3eecf57 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementDh.java @@ -0,0 +1,39 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.importer.beans.ResultBean; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * @author los + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwSceneNetelementDh extends ResultBean { + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @Excel(name = "地市", type = Excel.Type.ALL, sort = 2) + private String city; + @Excel(name = "区县", type = Excel.Type.ALL, sort = 3) + private String county; + @Excel(name = "物理站名", type = Excel.Type.ALL, sort = 4) + private String netElementPhyname; + @Excel(name = "红线内外", type = Excel.Type.ALL, sort = 6) + private String inRedline; + private Long sceneId; + @Excel(name = "场馆", type = Excel.Type.ALL, sort = 1) + private String sceneName; + @Excel(name = "机房类型", type = Excel.Type.ALL, sort = 5) + private String roomType; + private String updateBy; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private Date updateTime; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementWx.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementWx.java new file mode 100644 index 0000000..a8132c7 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNetelementWx.java @@ -0,0 +1,125 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.importer.beans.ResultBean; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwSceneNetelementWx extends ResultBean { + @TableId(value = "id", type = IdType.AUTO) + private Long id; + private Long sceneId; + @Excel(name = "场馆名称", type = Excel.Type.ALL, sort = 1) + @TableField(exist = false) + private String sceneName; + @Excel(name = "场景名称", type = Excel.Type.ALL, sort = 1) + private String 场景名称; + @Excel(name = "OMC", type = Excel.Type.ALL, sort = 2) + private String omc; + @Excel(name = "地市", type = Excel.Type.ALL, sort = 3) + @TableField(exist = false) + private String city; + @Excel(name = "县市", type = Excel.Type.ALL, sort = 4) + @TableField(exist = false) + private String county; + private String 地市; + private String 县市; + @Excel(name = "enodebid", type = Excel.Type.ALL, sort = 5, cellType = Excel.ColumnType.NUMERIC) + private String enodebidStr; + private Integer enodebid; + @Excel(name = "本地小区标识", type = Excel.Type.ALL, sort = 6, cellType = Excel.ColumnType.NUMERIC) + private String 本地小区标识Str; + private Integer 本地小区标识; + @Excel(name = "小区标识", type = Excel.Type.ALL, sort = 7, cellType = Excel.ColumnType.NUMERIC) + private String 小区标识Str; + private Integer 小区标识; + @Excel(name = "站号", type = Excel.Type.ALL, sort = 8, cellType = Excel.ColumnType.NUMERIC) + private String 站号Str; + private Integer 站号; + @Excel(name = "基站全称", type = Excel.Type.ALL, sort = 9) + private String 基站全称; + @Excel(name = "en", type = Excel.Type.ALL, sort = 10) + private String en名称; + @Excel(name = "小区名称", type = Excel.Type.ALL, sort = 11) + private String 小区名称; + @Excel(name = "小区别名", type = Excel.Type.ALL, sort = 11) + private String 小区别名; + @Excel(name = "ci", type = Excel.Type.ALL, sort = 12) + private String ci; + @Excel(name = "红线内外", type = Excel.Type.ALL, sort = 13) + private String inRedline; + @Excel(name = "小区频段", type = Excel.Type.ALL, sort = 14) + private String 小区频段; + @Excel(name = "纬度", type = Excel.Type.ALL, sort = 15, cellType = Excel.ColumnType.NUMERIC) + private String 纬度Str; + private Double 纬度; + @Excel(name = "经度", type = Excel.Type.ALL, sort = 16, cellType = Excel.ColumnType.NUMERIC) + private String 经度Str; + private Double 经度; + @Excel(name = "纬度gcj", type = Excel.Type.ALL, sort = 17, cellType = Excel.ColumnType.NUMERIC) + private String 纬度gcj; + @Excel(name = "经度gcj", type = Excel.Type.ALL, sort = 18, cellType = Excel.ColumnType.NUMERIC) + private String 经度gcj; + @Excel(name = "室内室外", type = Excel.Type.ALL, sort = 19) + private String 室内室外; + @Excel(name = "网络", type = Excel.Type.ALL, sort = 20) + private String 网络; + @Excel(name = "0427现网状态", type = Excel.Type.ALL, sort = 21) + private String 现网状态; + @Excel(name = "CGI", type = Excel.Type.ALL, sort = 22) + private String cgi; + @Excel(name = "频点", type = Excel.Type.ALL, sort = 23, cellType = Excel.ColumnType.NUMERIC) + private String 频点Str; + private Integer 频点; + @Excel(name = "pci", type = Excel.Type.ALL, sort = 24, cellType = Excel.ColumnType.NUMERIC) + private String pciStr; + private Integer pci; + @Excel(name = "tac", type = Excel.Type.ALL, sort = 25, cellType = Excel.ColumnType.NUMERIC) + private String tacStr; + private Integer tac; + @Excel(name = "一级场景", type = Excel.Type.ALL, sort = 26) + private String 一级场景; + @Excel(name = "二级场景", type = Excel.Type.ALL, sort = 27) + private String 二级场景; + @Excel(name = "设备类型", type = Excel.Type.ALL, sort = 28) + private String 设备类型; + @Excel(name = "带宽", type = Excel.Type.ALL, sort = 29, cellType = Excel.ColumnType.NUMERIC) + private String 带宽Str; + private Integer 带宽; + @Excel(name = "方位角", type = Excel.Type.ALL, sort = 30, cellType = Excel.ColumnType.NUMERIC) + private String 方位角Str; + private Float 方位角; + @Excel(name = "扇区id", type = Excel.Type.ALL, sort = 31) + private String 扇区id; + @Excel(name = "坐席编号", type = Excel.Type.ALL, sort = 32) + private String 坐席编号; + @Excel(name = "场景类型编码", type = Excel.Type.ALL, sort = 33) + private String sceneTypeCode; + @Excel(name = "场景类型", type = Excel.Type.ALL, sort = 34) + private String sceneType; + @Excel(name = "场景子类型编码", type = Excel.Type.ALL, sort = 35) + private String subSceneTypeCode; + @Excel(name = "场景子类型", type = Excel.Type.ALL, sort = 36) + private String subSceneType; + @Excel(name = "场景编码", type = Excel.Type.ALL, sort = 37) + private String sceneCode; + @Excel(name = "覆盖子场景编码", type = Excel.Type.ALL, sort = 38) + private String coverSubSceneCode; + @Excel(name = "覆盖子场景", type = Excel.Type.ALL, sort = 39) + private String coverSubScene; + private String updateBy; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private Date updateTime; + + private String areacountyid; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNoticeinfo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNoticeinfo.java new file mode 100644 index 0000000..8ffa017 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneNoticeinfo.java @@ -0,0 +1,187 @@ +package com.ruoyi.eastcom_yw.domain.vo; + + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.importer.beans.ResultBean; +import lombok.Data; + +/** + * (YwSceneNoticeinfo)表实体类 + * + * @author lee + * @since 2023-04-27 11:13:53 + */ +@Data +public class YwSceneNoticeinfo extends ResultBean { + + @TableId(type = IdType.AUTO) + private Long id; + + private Long sceneId; + + private Integer frontuser; + + private Integer backuser; + + private Integer emergencycar; + + private String county; + + private Integer publicNetNum; + + private int transportEquipNum; + + private Integer interfaceRingNum; + + private int netTotalNum; + + private Integer emergencyWarehouse; + + private Integer wxNetNum; + + //agis+wifi+voip + private Integer agisNetNum; + + private Integer dhNetNum; + + private Integer agisNum; + private Integer wifiNetNum; + private Integer voipNetNum; + + private Integer internetNetNum; + + private Integer publicTransportEquipNum; + + private Integer publicInterfaceRingNum; + + private Integer privateTransportEquipNum; + + private Integer privateInterfaceRingNum; + + private Integer supportcar; + + private Integer dictEquipNum; + + private Integer emergencyCommunicationCar; + + private Integer emergencyElectricCar; + + private Integer emergencyRepairCar; + + private Integer wifiSpare; + + private Integer dredgeSpare; + + private Integer transSpare; + + private Integer publicPowerEquip; + + private Integer privatePowerEquip; + + @Excel(name = "场馆名称", sort = 1) + @TableField(exist = false) + private String sceneName; + + @Excel(name = "无线网元数", sort = 2) + @TableField(exist = false) + private String wxNetNumStr; + + @Excel(name = "专网网元数", sort = 4) + @TableField(exist = false) + private String agisNetNumStr; + + @Excel(name = "动环网元数", sort = 3) + @TableField(exist = false) + private String dhNetNumStr; + + @Excel(name = "agis网元数", sort = 4) + @TableField(exist = false) + private String agisNumStr; + + @Excel(name = "互联网网元数", sort = 4) + @TableField(exist = false) + private String wifiNetNumStr; + + @Excel(name = "固话网元数", sort = 4) + @TableField(exist = false) + private String voipNetNumStr; + + @TableField(exist = false) + private String internetNetNumStr; + + @Excel(name = "公网传输设备", sort = 5) + @TableField(exist = false) + private String publicTransportEquipNumStr; + + @Excel(name = "公网接入环", sort = 6) + @TableField(exist = false) + private String publicInterfaceRingNumStr; + +// @Excel(name = "专网传输设备", sort = 7) + @TableField(exist = false) + private String privateTransportEquipNumStr; + +// @Excel(name = "专网接入环", sort = 8) + @TableField(exist = false) + private String privateInterfaceRingNumStr; + + @Excel(name = "现场保障人数", sort = 9) + @TableField(exist = false) + private String frontuserStr; + + @Excel(name = "后台保障人数", sort = 10) + @TableField(exist = false) + private String backuserStr; + + @Excel(name = "场馆部署应急车", sort = 11) + @TableField(exist = false) + private String emergencycarStr; + + @Excel(name = "场馆部署应急仓", sort = 12) + @TableField(exist = false) + private String emergencyWarehouseStr; + + @Excel(name = "保障车辆数", sort = 13) + @TableField(exist = false) + private String supportcarStr; + + @Excel(name = "DICT设备数", sort = 14) + @TableField(exist = false) + private String dictEquipNumStr; + + @Excel(name = "应急通信车", sort = 15) + @TableField(exist = false) + private String emergencyCommunicationCarStr; + + @Excel(name = "应急发电车", sort = 16) + @TableField(exist = false) + private String emergencyElectricCarStr; + + @Excel(name = "应急抢修车", sort = 17) + @TableField(exist = false) + private String emergencyRepairCarStr; + + @Excel(name = "无线备件数", sort = 18) + @TableField(exist = false) + private String wifiSpareStr; + + @Excel(name = "疏通备件数", sort = 19) + @TableField(exist = false) + private String dredgeSpareStr; + + @Excel(name = "传输备件数", sort = 20) + @TableField(exist = false) + private String transSpareStr; + + @Excel(name = "公网动力设备", sort = 21) + @TableField(exist = false) + private String publicPowerEquipStr; + + @Excel(name = "专网动力设备", sort = 22) + @TableField(exist = false) + private String privatePowerEquipStr; +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneRedisVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneRedisVO.java new file mode 100644 index 0000000..e448811 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneRedisVO.java @@ -0,0 +1,12 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +@Data +public class YwSceneRedisVO { + + private Long id; + + private String venueName; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTestDataInterface.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTestDataInterface.java new file mode 100644 index 0000000..0feff02 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTestDataInterface.java @@ -0,0 +1,23 @@ +package com.ruoyi.eastcom_yw.domain.vo; + + +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +/** + * (YwSceneTestDataInterface)表实体类 + * + * @author lee + * @since 2023-09-07 09:59:11 + */ +@Data +public class YwSceneTestDataInterface extends Model { + //接口地址 + private String url; + //是否启用(0否1是) + private String enable; + //场馆id + private Integer sceneId; + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTransGbStaVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTransGbStaVo.java new file mode 100644 index 0000000..c7b55b6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTransGbStaVo.java @@ -0,0 +1,16 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/8/16 + */ +@Data +public class YwSceneTransGbStaVo { + + private String mename; + private String portname; + private float flow; + public String dateTime; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTransOpticalpowerStaVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTransOpticalpowerStaVo.java new file mode 100644 index 0000000..2a1d7d2 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTransOpticalpowerStaVo.java @@ -0,0 +1,20 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/8/16 + */ +@Data +public class YwSceneTransOpticalpowerStaVo { + + public String venue; + public String mename; + public String portname; + //收光功率 + public float inOpticalpower; + //出光功率 + public float outOpticalpower; + public String dateTime; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTransStaVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTransStaVo.java new file mode 100644 index 0000000..04a0932 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneTransStaVo.java @@ -0,0 +1,20 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +import java.util.List; + +/** + * @author yqf + * @date 2023/8/29 + */ +@Data +public class YwSceneTransStaVo { + + private List opticalpowerTop5; + + private List outopticalpowerTop5; + + private String maxInOpticalpower; + private String maxOutOpticalpower; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneUserVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneUserVo.java new file mode 100644 index 0000000..8f5e27a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneUserVo.java @@ -0,0 +1,50 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +//import cn.afterturn.easypoi.excel.annotation.Excel; +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +/** + * @author huamile + */ +@Data +public class YwSceneUserVo { + + private Long id; + + @Excel(name = "场馆名称",width = 20) + private String venueName; + + private Long userId; + + @Excel(name = "姓名",width = 20) + private String userName; + + private String belongArea; + + private String distinctArea; + + @Excel(name = "所属区域",width = 20) + private String belongAreaName; + + @Excel(name = "手机号",width = 20) + private String phonenumber; + + @Excel(name = "角色",width = 20) + private String roleName; + + private String specialty; + + @Excel(name = "专业",width = 20) + private String specialtyName; + + private String status; + + @Excel(name = "状态",width = 20) + private String statusName; + +// @Excel(name = "是否需要签到",width = 20,replace = {"是_1,否_0"}) + @Excel(name = "是否需要签到",width = 20,readConverterExp = "0=否,1=是") + private String needSign; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneVo.java new file mode 100644 index 0000000..9e02a22 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSceneVo.java @@ -0,0 +1,93 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +//import cn.afterturn.easypoi.excel.annotation.Excel; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.eastcom_yw.domain.YwSceneFile; +import lombok.Data; + +import java.util.List; + +/** + * @author huamile + */ +@Data +public class YwSceneVo { + + @Excel(name = "ID",sort = 1) + private Long id; + + @Excel(name = "场馆名称",width = 20,sort = 2) + private String venueName; + + private String venueDesc; + + @Excel(name = "场馆地址",width = 20,sort = 3) + private String venueAddress; + + private String cityId; + + @Excel(name = "地市",width = 20,sort = 4) + private String city; + + private String areaCountyId; + + @Excel(name = "区县",width = 20,sort = 5) + private String county; + + @Excel(name = "经度",width = 20,sort = 6) + private Double latitude; + + @Excel(name = "纬度",width = 20,sort = 7) + private Double longitude; + + @Excel(name = "签到范围",width = 20,sort = 8) + private Integer signScope; + + private String venueType; + + @Excel(name = "场馆属性",width = 20,sort = 9) + private String venueTypeName; + + private String venueLevel; + + @Excel(name = "级别",width = 20,sort = 10) + private String venueLevelName; + + private Integer accPerson; + + private Integer status; + + private String statusName; + + @Excel(name = "所属场景ID",sort = 11) + private Long sceneBigId; + + @Excel(name = "简称",width = 20,sort = 12) + private String venueShortname; + + private String englishName; + + @Excel(name = "英文简称",width = 20,sort = 13) + private String englishShortname; + + private String maintainType; + + @Excel(name = "维护类型",width = 20,sort = 14) + private String maintainTypeName; + + @Excel(name = "GCJ02经度",width = 20,sort = 15) + private Double longitudeGcj02; + + @Excel(name = "GCJ02纬度",width = 20,sort = 16) + private Double latitudeGcj02; + + private List files; + + private List userIds; + + private String matchType; + + @Excel(name = "场馆类别",readConverterExp="1=场,2=馆", sort = 17) + private String venueCategory; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignLogStaticVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignLogStaticVo.java new file mode 100644 index 0000000..8a63ede --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignLogStaticVo.java @@ -0,0 +1,27 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +@Data +public class YwSignLogStaticVo { + + private Long sceneId; + + @Excel(name = "场馆名称", sort = 1) + private String venueName; + + @Excel(name = "总人数", sort = 2) + private long allNum; + + @Excel(name = "签到人数", sort = 3) + private long finishNum; + + @Excel(name = "签到率", sort = 4) + private String strFinishRate; + + private double finishRate; + + private String fileUrl; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignLogVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignLogVo.java new file mode 100644 index 0000000..312c03f --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignLogVo.java @@ -0,0 +1,93 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.eastcom_yw.domain.YwSceneUser; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +@Data +public class YwSignLogVo { + + private Long signPlanId; + + private Date beginTime; + + private Date endTime; + + @Excel(name = "应签到时间",sort = 7) + private String strBeginTime; + + @Excel(name = "应签退时间",sort = 12) + private String strEndTime; + + private Long userId; + + @Excel(name = "人员",sort = 4) + private String nickName; + + @Excel(name = "专业",sort = 6) + private String userTypeName; + + private String[] roleNames; + + private List sceneUser; + + @Excel(name = "场馆",sort = 3) + private String venueName; + + @Excel(name = "地市",sort = 1) + private String city; + + @Excel(name = "区县",sort = 2) + private String county; + + private Date signInTime; + + @Excel(name = "签到时间",sort = 8) + private String strSignInTime; + + @Excel(name = "签到经度",sort = 9) + private Double signInJ; + + @Excel(name = "签到纬度",sort = 10) + private Double signInW; + + private Long isDaiSignIn; + + private Date signOutTime; + + @Excel(name = "签退时间",sort = 13) + private String strSignOutTime; + + @Excel(name = "签退经度",sort = 14) + private Double signOutJ; + + @Excel(name = "签退纬度",sort = 15) + private Double signOutW; + + //签到状态显示值 + @Excel(name = "签到状态",sort = 11) + private String signType; + + //签到状态值 + private String signStatus; + + @Excel(name = "考勤",sort = 16) + private String checkType; + + @Excel(name = "所属区域",sort = 5) + private String belongArea; + + private String venueType; + + private String maintainType; + + private Double latitude; + + private Double longitude; + + private Integer signScope; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignPlanVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignPlanVo.java new file mode 100644 index 0000000..55eba00 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignPlanVo.java @@ -0,0 +1,73 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.entity.SysUser; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +@Data +public class YwSignPlanVo { + + private Long id; + + private Long sceneId; + + private Date signDate; + + private Date beginTime; + + private Date endTime; + + @Excel(name = "签到日期",cellType = Excel.ColumnType.STRING , sort = 5) + private String strSignDate; + + @Excel(name = "早签到时间",cellType = Excel.ColumnType.STRING, sort = 6) + private String strBeginTime; + + @Excel(name = "晚签到时间",cellType = Excel.ColumnType.STRING, sort = 7) + private String strEndTime; + + @Excel(name = "提醒时间量",sort = 8) + private String repWarnInterval; + + private Integer repSignInterval; + + @Excel(name = "状态",sort = 10,readConverterExp = "0=关闭,1=开启") + private String isOpen; + + private String areaCountyId; + + private String noticeType; + + @Excel(name = "通知方式",sort = 9) + private String noticeTypeName; + + @Excel(name = "场馆" ,sort = 1) + private String venueName; + + @Excel(name = "北纬" ,sort = 2) + private Double latitude; + + @Excel(name = "东经" ,sort = 3) + private Double longitude; + + @Excel(name = "签到范围(米)",sort = 4) + private Integer signScope; + + private String city; + + private String county; + + private Integer signNum; + + private List signUsers; + + private Date updateTime; + +// @Excel(name = "应签到人数",sort = 11) +// private Integer signUsersNum; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignUserVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignUserVo.java new file mode 100644 index 0000000..bfa435c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignUserVo.java @@ -0,0 +1,12 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Data; + +@Data +public class YwSignUserVo { + + private Long userId; + + private String userName; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignVo.java new file mode 100644 index 0000000..f13ea28 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSignVo.java @@ -0,0 +1,21 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class YwSignVo { + + //false不可签到 true可 + private Boolean couldSign; + //不可签到类型 + /** + * 1、时间不允许 + * 2、地理位置不允许 + * 3、时间和地理位置都不允许 + */ + private Integer failType; + //不可签到原因 + private String failMsg; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSparePartsVO.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSparePartsVO.java new file mode 100644 index 0000000..9b861a7 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwSparePartsVO.java @@ -0,0 +1,122 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; + +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * 亚运备件表VO + *

+ * + * @author yqf + * @since 2023-08-31 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YwSparePartsVO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("序号") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @Excel(name = "场馆名称", type = Excel.Type.ALL, sort = 1) + @ApiModelProperty("场馆名称") + @TableField("venue_name") + private String venueName; + + @Excel(name = "场馆类型", type = Excel.Type.ALL, sort = 2) + @ApiModelProperty("场馆类型") + @TableField("venue_type") + private String venueType; + + @Excel(name = "设备类型", type = Excel.Type.ALL, sort = 3) + @ApiModelProperty("设备类型") + @TableField("device_type") + private String deviceType; + + @Excel(name = "单板型号", type = Excel.Type.ALL, sort = 4) + @ApiModelProperty("单板型号") + @TableField("board_model") + private String boardModel; + + @Excel(name = "单板数量", type = Excel.Type.ALL, sort = 5) + @ApiModelProperty("单板数量") + @TableField("board_num") + private String boardNum; + + @Excel(name = "备件型号", type = Excel.Type.ALL, sort = 6) + @ApiModelProperty("备件型号") + @TableField("part_model") + private String partModel; + + @Excel(name = "通用数量", type = Excel.Type.ALL, sort = 7) + @ApiModelProperty("通用数量") + @TableField("current_num") + private String currentNum; + + @Excel(name = "需求数量", type = Excel.Type.ALL, sort = 8) + @ApiModelProperty("需求数量") + @TableField("need_num") + private String needNum; + + @Excel(name = "配置数量", type = Excel.Type.ALL, sort = 9) + @ApiModelProperty("配置数量") + @TableField("configure_num") + private String configureNum; + + @Excel(name = "缺口", type = Excel.Type.ALL, sort = 10) + @ApiModelProperty("缺口") + @TableField("gap_num") + private String gapNum; + + @Excel(name = "专业", type = Excel.Type.ALL, sort = 11) + @ApiModelProperty("专业") + @TableField("major") + private String major; + + @Excel(name = "备注", type = Excel.Type.ALL, sort = 12) + @ApiModelProperty("备注") + @TableField("comment") + private String comment; + + @Excel(name = "联系人", type = Excel.Type.ALL, sort = 13) + @ApiModelProperty("联系人") + @TableField("contacts") + private String contacts; + + @Excel(name = "联系电话", type = Excel.Type.ALL, sort = 14) + @ApiModelProperty("联系电话") + @TableField("telephone") + private String telephone; + + @ApiModelProperty("创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty("创建时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty("更新人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty("更新时间") + @TableField("update_time") + private LocalDateTime updateTime; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwWireTaskLogVo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwWireTaskLogVo.java new file mode 100644 index 0000000..5d443fa --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/vo/YwWireTaskLogVo.java @@ -0,0 +1,112 @@ +package com.ruoyi.eastcom_yw.domain.vo; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.eastcom_yw.domain.dto.CommonDTO; +import lombok.Data; + +import java.util.Date; + +/** + * @author jkj + */ +@Data +public class YwWireTaskLogVo { + + private Long id; + /** + * 创建时间 + */ + private Date createTime; + + private String flwProcessid; + + private String taskId; + /** + * 结束时间 + */ + private Date endTime; + + @Excel(name = "任务开始时间",sort = 8) + private String strCreateTime; + + @Excel(name = "任务结束时间",sort = 9) + private String strEndTime; + + @Excel(name = "创建人",sort = 7) + private String createName; + + @Excel(name = "任务单号",sort = 1) + private String wireTaskId; + + @Excel(name = "任务名称",sort = 2) + private String wireTaskName; + + @Excel(name = "任务类型", readConverterExp = "1=临时布线,2=布线拆除", sort = 6) + private Integer taskType; + + private Long venueId; + + @Excel(name = "当前环节",sort = 10) + private String curStep; + + @Excel(name = "当前处理组",sort = 11) + private String dealUser; + + @Excel(name = "场馆",sort = 5) + private String venueName; + + @Excel(name = "地市",sort = 3) + private String city; + + @Excel(name = "区县",sort = 4) + private String county; + + /** + * 施工单位 + */ + private String construcUnit; + + //是否拆线 + private Integer isRemove; + + //是否结算 + private Integer isSettle; + + //报告路径 + private String report; + + //是否当前登录用户待办 0否 1是 + private int isTodo; + + @Excel(name = "任务子类",readConverterExp = "1=AGIS专网,2=互联网专网,3=固话专网",sort = 12) + private String taskSubType; + + @Excel(name = "比赛名称",sort = 13) + private String scxx; + + @Excel(name = "任务描述",sort = 14) + private String rwms; + + @Excel(name = "任务审核结果", readConverterExp = "0=驳回,1=通过",sort = 15) + private Integer shjg; + + @Excel(name = "任务审核说明",sort = 16) + private String shsm; + + @Excel(name = "图纸说明",sort = 17) + private String tzsm; + + @Excel(name = "图纸确认结果", readConverterExp = "0=驳回,1=通过",sort = 18) + private Integer tzjg; + + @Excel(name = "图纸确认说明",sort = 19) + private String tzqrsm; + + @Excel(name = "现场验收结果", readConverterExp = "0=驳回,1=通过",sort = 20) + private Integer ysjg; + + @Excel(name = "现场验收说明",sort = 21) + private String yssm; + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/yw_alarm_deal_log.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/yw_alarm_deal_log.java new file mode 100644 index 0000000..aff6c97 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/yw_alarm_deal_log.java @@ -0,0 +1,59 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("yw_alarm_deal_log") +public class yw_alarm_deal_log implements Serializable { + private static final long serialVersionUID=1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private String alarmCode; + + private String alarmType; + + private String groupColnum; + + private String flwProcessid; + + private String dealUser; + + private String dealStatus; + + private Date beginTime; + + private Date endTime; + + private Long sceneBigId; + + private String primaryId; + + private String isRed; + + private Long sceneId; + + private Date alarmTime; + + private Integer hangupTimespan; + + private Long groupId; + + private String record; + + private String siteType; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/yw_alarm_deal_res.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/yw_alarm_deal_res.java new file mode 100644 index 0000000..ac83777 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/yw_alarm_deal_res.java @@ -0,0 +1,34 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("v_yw_alarm_deal") +public class yw_alarm_deal_res implements Serializable { + + private static final long serialVersionUID=1L; + + private Long id; + + private String flwProcessid; + + private Date endTime; + + private String assignee; + + private String processstatus; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImportSpareParts.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImportSpareParts.java new file mode 100644 index 0000000..eea55b0 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImportSpareParts.java @@ -0,0 +1,149 @@ +package com.ruoyi.eastcom_yw.importer; + +import cn.hutool.core.date.DateUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.importer.service.YwBatchAddService; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwSpareParts; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSparePartsDTO; +import com.ruoyi.eastcom_yw.mapper.YwSceneMapper; +import com.ruoyi.eastcom_yw.mapper.YwSparePartsMapper; +import lombok.RequiredArgsConstructor; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.Date; +import java.util.List; + +/** + * @author yqf + * @date 2023/8/31 + */ +@RequiredArgsConstructor +public class ImportSpareParts extends ImporterBase implements YwBatchAddService { + + + private final YwSparePartsMapper ywSparePartsMapper; + + { + cellFormatBeans.add(new CellFormatBean("场馆名称", "venueName", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("场馆类型", "venueType", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("设备类型", "deviceType", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("单板型号", "boardModel", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("单板数量", "boardNum", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("备件型号", "partModel", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("通用数量", "currentNum", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("需求数量", "needNum", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("配置数量", "configureNum", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("缺口", "gapNum", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("专业", "major", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("备注", "comment", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("联系人", "contacts", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("联系电话", "telephone", "", "", "", "", "", "", "")); + } + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception { + + } + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @throws Exception 异常 + */ + @Override + protected void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception { + + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @param j 列 + * @throws Exception 异常 + */ + @Override + protected void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) throws Exception { + + } + + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) throws Exception { + + String userName = SecurityUtils.getUsername(); + + + datas.forEach(x -> x.setCreateBy(userName)); + datas.forEach(x -> x.setCreateTime(LocalDateTime.now())); + + + ywSparePartsMapper.deleteAllData(); + + add(datas); + + } + + + /** + * 实现类提供具体插入方法 + * + * @param collect 数据 + */ + @Override + public void insertB(List collect) { + ywSparePartsMapper.insertBatch(collect); + } + + private boolean judgeIfEdit(YwSceneDTO dto, List scenes) { + for (YwScene ywScene : scenes) { + if (StringUtils.isNotEmpty(ywScene.getVenueName()) && dto.getVenueName().equals(ywScene.getVenueName()) & + dto.getSceneBigId().equals(ywScene.getSceneBigId())) { + dto.setId(ywScene.getId()); + return true; + } + } + return false; + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterAgis.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterAgis.java new file mode 100644 index 0000000..2874abe --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterAgis.java @@ -0,0 +1,168 @@ +package com.ruoyi.eastcom_yw.importer; + +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.eastcom_yw.common.constant.NetElementConstants; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementAgis; +import com.ruoyi.eastcom_yw.mapper.YwSceneNetelementAgisMapper; +import com.ruoyi.common.importer.service.YwBatchAddService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author los + */ +@Slf4j +@RequiredArgsConstructor +public class ImporterAgis extends ImporterBase implements YwBatchAddService { + + private final YwSceneNetelementAgisMapper ywSceneNetelementAgisMapper; + + private String sceneName; + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception { + + } + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i + * @throws Exception 异常 + */ + @Override + protected void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception { + + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行-1 + * @param j 列-1 + */ + @Override + protected void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) { + + if ("sceneName".equals(format.getColumnEn())) { + if (isNotEmpty(s)) { + sceneName = (String) args[1]; + if (NetElementConstants.SINGLE_SCENE_COVER.equals(importType) && !sceneName.equals(s)) { + reasonS.append("单场馆覆盖导入模式下只能导入指定场馆。"); + } + if (NetElementConstants.SINGLE_SCENE_COVER.equals(importType) && s.contains("|")) { + reasonS.append("单场馆覆盖导入模式下场馆列不能包含|。"); + } + List ywSceneList = (List) args[0]; + List sceneNameList = ywSceneList.stream().map(x -> x.getVenueName()).collect(Collectors.toList()); + if (s.contains("|")) { + String[] str = s.split("\\|"); + for (String st : str) { + if (!sceneNameList.contains(st)) { + if (!reasonS.toString().contains("场馆不存在")) { + reasonS.append("场馆不存在。"); + } + } + } + } else { + if (!sceneNameList.contains(s)) { + reasonS.append("场馆不存在。"); + } + } + } + } + + } + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + */ + @Override + protected void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) { + + // 获取大场景下场馆信息 + List ywSceneList = (List) args[0]; + // 导入 + List list = new ArrayList<>(); + for (YwSceneNetelementAgis y : datas) { + if (y.getSceneName().contains("|")) { + String[] str = y.getSceneName().split("\\|"); + for (String s : str) { + YwSceneNetelementAgis n = new YwSceneNetelementAgis(); + BeanUtils.copyBeanProp(n, y); + n.setSceneName(s); + list.add(n); + } + } else { + list.add(y); + } + } + for (YwSceneNetelementAgis y : list) { + for (YwScene ywScene : ywSceneList) { + if (StringUtils.isNotEmpty(y.getSceneName()) && y.getSceneName().equals(ywScene.getVenueName())) { + y.setSceneId(ywScene.getId()); + break; + } + } + y.setAlarmSpecityId(DictUtils.getDictValue("yw_alarm_specialty", y.getAlarmSpecityName())); + y.setUpdateBy(SecurityUtils.getUsername()); + y.setUpdateTime(DateUtils.getNowDate()); + } + List collect = list.stream().filter(x -> x.getSceneId() != null).collect(Collectors.toList()); + if (NetElementConstants.SINGLE_SCENE_COVER.equals(importType)) { + ywSceneNetelementAgisMapper.deleteBySceneId(collect.get(0).getSceneId()); + } else { + ywSceneNetelementAgisMapper.deleteBySceneBigId(sceneBigId); + } + add(collect); + + } + + /** + * 实现类提供具体插入方法 + */ + @Override + public void insertB(List collect) { + ywSceneNetelementAgisMapper.insertBatch(collect); + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterCalendar.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterCalendar.java new file mode 100644 index 0000000..f3c2eb8 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterCalendar.java @@ -0,0 +1,223 @@ +package com.ruoyi.eastcom_yw.importer; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.importer.service.YwBatchAddService; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwSceneCalendar; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneCalendar2Vo; +import com.ruoyi.eastcom_yw.mapper.YwSceneCalendarMapper; +import lombok.RequiredArgsConstructor; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +public class ImporterCalendar extends ImporterBase implements YwBatchAddService { + + private final YwSceneCalendarMapper ywSceneCalendarMapper; + private String matchDate; + private String beginTime; + private String endTime; + + { + cellFormatBeans.add(new CellFormatBean("编号", "idStr", "", "", "true", "positiveInt", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("场馆", "venueName", "false", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("比赛类型", "matchTypeName", "true", "", "", "", "", "yw_match_type", "", "")); + cellFormatBeans.add(new CellFormatBean("比赛名称", "matchName", "false", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("比赛日期", "matchDate", "false", "true", "", "", "yyyy-MM-dd", "", "", "")); + cellFormatBeans.add(new CellFormatBean("开始时间", "beginTime", "false", "true", "", "", "HH:mm", "", "", "")); + cellFormatBeans.add(new CellFormatBean("结束时间", "endTime", "false", "true", "", "", "HH:mm", "", "", "")); + cellFormatBeans.add(new CellFormatBean("状态", "statusName", "", "", "", "", "", "", "启用,停用", "")); + cellFormatBeans.add(new CellFormatBean("备注", "matchRemark", "", "", "", "", "", "", "", "")); + } + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception { + + } + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @throws Exception 异常 + */ + @Override + protected void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception { + if (isNotEmpty(beginTime) && isNotEmpty(endTime)) { + if (DateUtils.parseDate(endTime, "HH:mm"). + compareTo(DateUtils.parseDate(beginTime, "HH:mm")) <= 0) { + reasonL.append("结束时间必须晚于开始时间。"); + } + } + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @param j 列 + * @throws Exception 异常 + */ + @Override + protected void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) throws Exception { + if (isNotEmpty(s)) { + if ("venueName".equals(format.getColumnEn())) { + String[] str = s.split("\\|"); + for (String s1 : str) { + if (!checkSceneExists(s1, (List) args[0])) { + reasonS.append("场馆[").append(s1).append("]不存在。"); + } + } + } else if ("matchDate".equals(format.getColumnEn())) { + matchDate = s; + if (DateUtils.parseDate(s, "yyyy-MM-dd"). + compareTo(DateUtils.parseDate(DateUtils.getDate())) < 0) { + reasonS.append("比赛日期不能早于当前日期。"); + } + } else if ("beginTime".equals(format.getColumnEn())) { + beginTime = s; + if (DateUtils.parseDate(matchDate + " " + s, "yyyy-MM-dd HH:mm"). + compareTo(DateUtils.getNowDate()) < 0) { + reasonS.append("开始时间不能早于当前时间。"); + } + } else if ("endTime".equals(format.getColumnEn())) { + endTime = s; + } + } + } + + private boolean checkSceneExists(String s, List ywSceneList) { + for (YwScene ywScene : ywSceneList) { + if (s.equals(ywScene.getVenueName())) { + return true; + } + } + return false; + } + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) throws Exception { + // 导入 + List list = new ArrayList<>(); + for (YwSceneCalendar2Vo y : datas) { + String[] str = y.getVenueName().split("\\|"); + for (String s : str) { + YwSceneCalendar2Vo n = new YwSceneCalendar2Vo(); + BeanUtils.copyBeanProp(n, y); + n.setVenueName(s); + list.add(n); + } + } + for (YwSceneCalendar2Vo y : list) { + for (YwScene ywScene : (List) args[0]) { + if (StringUtils.isNotEmpty(y.getVenueName()) && y.getVenueName().equals(ywScene.getVenueName())) { + y.setSceneId(ywScene.getId()); + break; + } + } + y.setMatchType(DictUtils.getDictValue("yw_match_type", y.getMatchTypeName())); + if ("停用".equals(y.getStatusName())) { + y.setStatus("1"); + } else if ("启用".equals(y.getStatusName())) { + y.setStatus("0"); + } else { + y.setStatus("0"); + } + y.setId(isEmpty(y.getIdStr()) ? null : Long.parseLong(y.getIdStr())); + } + List collect = list.stream().filter(x -> x.getSceneId() != null).collect(Collectors.toList()); + String ids = ywSceneCalendarMapper.selectIds(sceneBigId); + if ("0".equals(importType)) { + ywSceneCalendarMapper.deleteBySceneBigId(sceneBigId); + for (YwSceneCalendar2Vo x : collect) { + x.setCreateBy(SecurityUtils.getUsername()); + x.setCreateTime(DateUtils.getNowDate()); + } + add(collect); + } else { + for (YwSceneCalendar2Vo v : collect) { + YwSceneCalendar ywSceneCalendar = new YwSceneCalendar(); + BeanUtils.copyBeanProp(ywSceneCalendar, v); + ywSceneCalendar.setId(v.getId()); + ywSceneCalendar.setBeginTime(DateUtils.parseDate(v.getBeginTime(), "HH:mm")); + ywSceneCalendar.setEndTime(DateUtils.parseDate(v.getEndTime(), "HH:mm")); + ywSceneCalendar.setMatchDate(DateUtils.parseDate(v.getMatchDate(), "yyyy-MM-dd")); + ywSceneCalendar.setMatchRemark(v.getMatchRemark()); + boolean exists = ywSceneCalendarMapper.exists(new LambdaQueryWrapper() +// .eq(YwSceneCalendar::getId, v.getId()) + .eq(YwSceneCalendar::getSceneId, v.getSceneId()) + .eq(YwSceneCalendar::getMatchType, v.getMatchType()) + .eq(YwSceneCalendar::getMatchName, v.getMatchName()) + .eq(YwSceneCalendar::getBeginTime, ywSceneCalendar.getBeginTime()) + .eq(YwSceneCalendar::getEndTime, ywSceneCalendar.getEndTime()) + .eq(YwSceneCalendar::getStatus, v.getStatus()) + .eq(YwSceneCalendar::getMatchRemark, v.getMatchRemark()) + ); +// if (ywSceneCalendar.getId() == null || !Arrays.asList(ids.split(",")).contains(String.valueOf(ywSceneCalendar.getId()))) { + if (!exists) { + ywSceneCalendar.setId(null); + ywSceneCalendar.setCreateBy(SecurityUtils.getUsername()); + ywSceneCalendar.setCreateTime(DateUtils.getNowDate()); + ywSceneCalendarMapper.insert(ywSceneCalendar); + } +// else { +// ywSceneCalendar.setUpdateBy(SecurityUtils.getUsername()); +// ywSceneCalendar.setUpdateTime(DateUtils.getNowDate()); +// ywSceneCalendarMapper.updateById(ywSceneCalendar); +// } + } + } + } + + /** + * 实现类提供具体插入方法 + * + * @param collect 数据 + */ + @Override + public void insertB(List collect) { + ywSceneCalendarMapper.insertBatch(collect); + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterCs.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterCs.java new file mode 100644 index 0000000..60abba0 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterCs.java @@ -0,0 +1,184 @@ +package com.ruoyi.eastcom_yw.importer; + +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.eastcom_yw.common.constant.NetElementConstants; +import com.ruoyi.eastcom_yw.common.enums.InRedLine; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementCs; +import com.ruoyi.eastcom_yw.mapper.YwSceneNetelementCsMapper; +import com.ruoyi.common.importer.service.YwBatchAddService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@Slf4j +public class ImporterCs extends ImporterBase implements YwBatchAddService { + + private final YwSceneNetelementCsMapper ywSceneNetelementCsMapper; + + private String sceneName; + + /** + * 实现类提供具体插入方法 + * + * @param collect + */ + @Override + public void insertB(List collect) { + ywSceneNetelementCsMapper.insertBatch(collect); + } + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception { + + } + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i + * @throws Exception 异常 + */ + @Override + protected void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception { + + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i + * @param j + * @throws Exception 异常 + */ + @Override + protected void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) throws Exception { + + if ("sceneName".equals(format.getColumnEn())) { + if (isNotEmpty(s)) { + sceneName = (String) args[1]; + if (NetElementConstants.SINGLE_SCENE_COVER.equals(importType) && !sceneName.equals(s)) { + reasonS.append("单场馆覆盖导入模式下只能导入指定场馆。"); + } + if (NetElementConstants.SINGLE_SCENE_COVER.equals(importType) && s.contains("|")) { + reasonS.append("单场馆覆盖导入模式下场馆列不能包含|。"); + } + List ywSceneList = (List) args[0]; + List sceneNameList = ywSceneList.stream().map(x -> x.getVenueName()).collect(Collectors.toList()); + if (s.contains("|")) { + String[] str = s.split("\\|"); + for (String st : str) { + if (!sceneNameList.contains(st)) { + if (!reasonS.toString().contains("场馆不存在")) { + reasonS.append("场馆不存在。"); + } + } + } + } else { + if (!sceneNameList.contains(s)) { + reasonS.append("场馆不存在。"); + } + } + } + } + + } + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) throws Exception { + + List ywSceneList = (List) args[0]; + + // 导入 + List list = new ArrayList<>(); + for (YwSceneNetelementCs y : datas) { + if (y.getSceneName().contains("|")) { + String[] str = y.getSceneName().split("\\|"); + for (String s : str) { + YwSceneNetelementCs n = new YwSceneNetelementCs(); + BeanUtils.copyBeanProp(n, y); + n.setSceneName(s); + list.add(n); + } + } else { + list.add(y); + } + } + for (YwSceneNetelementCs y : list) { + if (isNotEmpty(y.getAttributeA()) && InRedLine.IN_RED_LINE.getLabel().equals(y.getAttributeA())) { + y.setAttributeA(InRedLine.IN_RED_LINE.getCode()); + } else if (isNotEmpty(y.getAttributeA()) && InRedLine.NOT_IN_RED_LINE.getLabel().equals(y.getAttributeA())) { + y.setAttributeA(InRedLine.NOT_IN_RED_LINE.getCode()); + } else { + y.setAttributeA(""); + } + + if (isNotEmpty(y.getAttributeZ()) && InRedLine.IN_RED_LINE.getLabel().equals(y.getAttributeZ())) { + y.setAttributeZ(InRedLine.IN_RED_LINE.getCode()); + } else if (isNotEmpty(y.getAttributeZ()) && InRedLine.NOT_IN_RED_LINE.getLabel().equals(y.getAttributeZ())) { + y.setAttributeZ(InRedLine.NOT_IN_RED_LINE.getCode()); + } else { + y.setAttributeZ(""); + } + for (YwScene ywScene : ywSceneList) { + if (isNotEmpty(y.getSceneName()) && y.getSceneName().equals(ywScene.getVenueName())) { + y.setSceneId(ywScene.getId()); + break; + } + } + y.setUpdateBy(SecurityUtils.getUsername()); + y.setUpdateTime(DateUtils.getNowDate()); + } + + List collect = list.stream().filter(x -> x.getSceneId() != null).collect(Collectors.toList()); + + if (NetElementConstants.SINGLE_SCENE_COVER.equals(importType)) { + ywSceneNetelementCsMapper.deleteBySceneId(collect.get(0).getSceneId()); + } else { + ywSceneNetelementCsMapper.deleteBySceneBigId(sceneBigId); + } + add(collect); + + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterDh.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterDh.java new file mode 100644 index 0000000..d5c7c8b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterDh.java @@ -0,0 +1,176 @@ +package com.ruoyi.eastcom_yw.importer; + +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.importer.service.YwBatchAddService; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.eastcom_yw.common.constant.NetElementConstants; +import com.ruoyi.eastcom_yw.common.enums.InRedLine; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementDh; +import com.ruoyi.eastcom_yw.mapper.YwSceneNetelementDhMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@Slf4j +@RequiredArgsConstructor +public class ImporterDh extends ImporterBase implements YwBatchAddService { + + private final YwSceneNetelementDhMapper ywSceneNetelementDhMapper; + + private String sceneName; + + /** + * 实现类提供具体插入方法 + * + * @param collect + */ + @Override + public void insertB(List collect) { + ywSceneNetelementDhMapper.insertBatch(collect); + } + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception { + + } + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i + * @throws Exception 异常 + */ + @Override + protected void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception { + + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i + * @param j + * @throws Exception 异常 + */ + @Override + protected void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) throws Exception { + if ("sceneName".equals(format.getColumnEn())) { + if (isNotEmpty(s)) { + sceneName = (String) args[1]; + if (NetElementConstants.SINGLE_SCENE_COVER.equals(importType) && !sceneName.equals(s)) { + reasonS.append("单场馆覆盖导入模式下只能导入指定场馆。"); + } + if (NetElementConstants.SINGLE_SCENE_COVER.equals(importType) && s.contains("|")) { + reasonS.append("单场馆覆盖导入模式下场馆列不能包含|。"); + } + List ywSceneList = (List) args[0]; + List sceneNameList = ywSceneList.stream().map(x -> x.getVenueName()).collect(Collectors.toList()); + if (s.contains("|")) { + String[] str = s.split("\\|"); + for (String st : str) { + if (!sceneNameList.contains(st)) { + if (!reasonS.toString().contains("场馆不存在")) { + reasonS.append("场馆不存在。"); + } + } + } + } else { + if (!sceneNameList.contains(s)) { + reasonS.append("场馆不存在。"); + } + } + } + } + } + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) throws Exception { + + // 获取大场景下场馆信息 + List ywSceneList = (List) args[0]; + + // 导入 + List list = new ArrayList<>(); + for (YwSceneNetelementDh y : datas) { + if (y.getSceneName().contains("|")) { + String[] str = y.getSceneName().split("\\|"); + for (String s : str) { + YwSceneNetelementDh n = new YwSceneNetelementDh(); + BeanUtils.copyBeanProp(n, y); + n.setSceneName(s); + list.add(n); + } + } else { + list.add(y); + } + } + + for (YwSceneNetelementDh y : list) { + if (InRedLine.IN_RED_LINE.getLabel().equals(y.getInRedline())) { + y.setInRedline(InRedLine.IN_RED_LINE.getCode()); + } else if (InRedLine.NOT_IN_RED_LINE.getLabel().equals(y.getInRedline())) { + y.setInRedline(InRedLine.NOT_IN_RED_LINE.getCode()); + } else { + y.setInRedline(""); + } + for (YwScene ywScene : ywSceneList) { + if (isNotEmpty(y.getSceneName()) && y.getSceneName().equals(ywScene.getVenueName())) { + y.setSceneId(ywScene.getId()); + y.setCity(StringUtils.isNotEmpty(ywScene.getCityId()) ? DictUtils.getDictLabel("yw_city", ywScene.getCityId()) : ""); + y.setCounty(StringUtils.isNotEmpty(ywScene.getAreaCountyId()) ? DictUtils.getDictLabel("yw_county", ywScene.getAreaCountyId()) : ""); + break; + } + } + y.setUpdateBy(SecurityUtils.getUsername()); + y.setUpdateTime(DateUtils.getNowDate()); + } + List collect = list.stream().filter(x -> x.getSceneId() != null).collect(Collectors.toList()); + if (NetElementConstants.SINGLE_SCENE_COVER.equals(importType)) { + ywSceneNetelementDhMapper.deleteBySceneId(collect.get(0).getSceneId()); + } else { + ywSceneNetelementDhMapper.deleteBySceneBigId(sceneBigId); + } + add(collect); + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterMatch.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterMatch.java new file mode 100644 index 0000000..02220f6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterMatch.java @@ -0,0 +1,198 @@ +package com.ruoyi.eastcom_yw.importer; + +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.importer.service.YwBatchAddService; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneMatchVo; +import com.ruoyi.eastcom_yw.mapper.YwSceneMatchMapper; +import lombok.RequiredArgsConstructor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +public class ImporterMatch extends ImporterBase implements YwBatchAddService { + + private final YwSceneMatchMapper ywSceneMatchMapper; + + { + cellFormatBeans.add(new CellFormatBean("编号", "idStr", "", "", "true", "positiveInt", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("场馆名称", "sceneName", "false", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("赛程类型", "taskTypeName", "false", "", "", "", "", "yw_match_type", "", "")); + cellFormatBeans.add(new CellFormatBean("赛程名称", "taskName", "false", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("开始时间", "beginTimeStr", "false", "true", "", "", "yyyy-MM-dd HH:mm:ss", "", "", "")); + cellFormatBeans.add(new CellFormatBean("结束时间", "endTimeStr", "false", "true", "", "", "yyyy-MM-dd HH:mm:ss", "", "", "")); + cellFormatBeans.add(new CellFormatBean("赛程状态", "taskStatusName", "", "", "", "", "", "", "启用,停用", "")); + } + + private String beginTime; + + private String endTime; + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception { + + } + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @throws Exception 异常 + */ + @Override + protected void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception { + if (isNotEmpty(beginTime) && isNotEmpty(endTime)) { + if (DateUtils.parseDate(endTime, "yyyy-MM-dd HH:mm:ss"). + compareTo(DateUtils.parseDate(beginTime, "yyyy-MM-dd HH:mm:ss")) <= 0) { + reasonL.append("结束时间必须晚于开始时间"); + } + } + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @param j 列 + * @throws Exception 异常 + */ + @Override + protected void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) throws Exception { + if (isNotEmpty(s)) { + if ("sceneName".equals(format.getColumnEn())) { + String[] str = s.split("\\|"); + for (String s1 : str) { + if (!checkSceneExists(s1, (List) args[0])) { + reasonS.append("场馆[").append(s1).append("]不存在"); + } + } + } else if ("beginTimeStr".equals(format.getColumnEn())) { + beginTime = s; + if (DateUtils.parseDate(s, "yyyy-MM-dd HH:mm:ss").compareTo(DateUtils.getNowDate()) < 0) { + reasonS.append("开始时间不能早于当前时间。"); + } + } else if ("endTimeStr".equals(format.getColumnEn())) { + endTime = s; + } + } + } + + private boolean checkSceneExists(String sceneName, List ywSceneList) { + for (YwScene ywScene : ywSceneList) { + if (sceneName.equals(ywScene.getVenueName())) { + return true; + } + } + return false; + } + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) throws Exception { + List list = new ArrayList<>(); + for (YwSceneMatchVo y : datas) { + String[] str = y.getSceneName().split("\\|"); + for (String s : str) { + YwSceneMatchVo n = new YwSceneMatchVo(); + BeanUtils.copyBeanProp(n, y); + n.setSceneName(s); + list.add(n); + } + } + for (YwSceneMatchVo y : list) { + for (YwScene ywScene : (List) args[0]) { + if (StringUtils.isNotEmpty(y.getSceneName()) && y.getSceneName().equals(ywScene.getVenueName())) { + y.setSceneId(ywScene.getId()); + break; + } + } + if ("停用".equals(y.getTaskStatusName())) { + y.setTaskStatus("1"); + } else if ("启用".equals(y.getTaskStatusName())) { + y.setTaskStatus("0"); + } else { + y.setTaskStatus("0"); + } + y.setId(isEmpty(y.getIdStr()) ? null : Long.parseLong(y.getIdStr())); + y.setTaskType(DictUtils.getDictValue("yw_match_type", y.getTaskTypeName())); + } + List collect = list.stream().filter(x -> x.getSceneId() != null).collect(Collectors.toList()); + String ids = ywSceneMatchMapper.selectIds(sceneBigId); + if ("0".equals(importType)) { + ywSceneMatchMapper.deleteBySceneBigId(sceneBigId); + for (YwSceneMatchVo x : collect) { + x.setBeginTime(DateUtils.parseDate(x.getBeginTimeStr(), "yyyy-MM-dd HH:mm:ss")); + x.setEndTime(DateUtils.parseDate(x.getEndTimeStr(), "yyyy-MM-dd HH:mm:ss")); + x.setCreateBy(SecurityUtils.getUsername()); + x.setCreateTime(DateUtils.getNowDate()); + } + add(collect); + } else { + for (YwSceneMatchVo v : collect) { + v.setBeginTime(DateUtils.parseDate(v.getBeginTimeStr(), "yyyy-MM-dd HH:mm:ss")); + v.setEndTime(DateUtils.parseDate(v.getEndTimeStr(), "yyyy-MM-dd HH:mm:ss")); + if (v.getId() == null || !Arrays.asList(ids.split(",")).contains(String.valueOf(v.getId()))) { + v.setId(null); + v.setCreateBy(SecurityUtils.getUsername()); + v.setCreateTime(DateUtils.getNowDate()); + ywSceneMatchMapper.insert(v); + } else { + v.setUpdateBy(SecurityUtils.getUsername()); + v.setUpdateTime(DateUtils.getNowDate()); + ywSceneMatchMapper.updateById(v); + } + } + } + } + + /** + * 实现类提供具体插入方法 + * + * @param collect 数据 + */ + @Override + public void insertB(List collect) { + ywSceneMatchMapper.insertBatch(collect); + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterScene.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterScene.java new file mode 100644 index 0000000..14d3856 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterScene.java @@ -0,0 +1,172 @@ +package com.ruoyi.eastcom_yw.importer; + +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.importer.service.YwBatchAddService; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneDTO; +import com.ruoyi.eastcom_yw.mapper.YwSceneMapper; +import com.ruoyi.eastcom_yw.mapper.YwSceneUserMapper; +import lombok.RequiredArgsConstructor; + +import java.util.Date; +import java.util.List; + +@RequiredArgsConstructor +public class ImporterScene extends ImporterBase implements YwBatchAddService { + + private final YwSceneMapper ywSceneMapper; + private final YwSceneUserMapper ywSceneUserMapper; + + { + cellFormatBeans.add(new CellFormatBean("场馆标准名称", "venueName", "false", "", "", "", "", "", "true")); + cellFormatBeans.add(new CellFormatBean("场馆简称", "venueShortname", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("场馆英文缩写", "englishShortname", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("维护类别", "maintainType", "", "", "", "", "yw_scene_maintain_type", "", "")); + cellFormatBeans.add(new CellFormatBean("场馆属性", "venueType", "", "", "", "", "yw_scene_type", "", "")); + cellFormatBeans.add(new CellFormatBean("场馆级别", "venueLevel", "", "", "", "", "yw_scene_level", "", "")); + cellFormatBeans.add(new CellFormatBean("经度GPS", "longitudeStr", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("纬度GPS", "latitudeStr", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("经度GCJ02", "longitudeGcj02Str", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("纬度GCJ02", "latitudeGcj02Str", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("所属地市", "city", "false", "", "", "", "yw_city", "", "")); + cellFormatBeans.add(new CellFormatBean("所属区县", "county", "false", "", "", "", "yw_county", "", "")); + cellFormatBeans.add(new CellFormatBean("赛事类型", "matchType", "", "", "", "", "yw_match_type", "", "")); + cellFormatBeans.add(new CellFormatBean("地址", "venueAddress", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("备注", "venueDesc", "", "", "", "", "", "", "")); + } + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception { + + } + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @throws Exception 异常 + */ + @Override + protected void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception { + + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @param j 列 + * @throws Exception 异常 + */ + @Override + protected void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) throws Exception { + + } + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) throws Exception { + + List scenes = ywSceneMapper.selectList(null); + + String userName = SecurityUtils.getUsername(); + + for (YwSceneDTO ywScene : datas) { + String lonStr = ywScene.getLongitudeStr(); + String latStr = ywScene.getLatitudeStr(); + String lonGcjStr = ywScene.getLongitudeGcj02Str(); + String latGcjStr = ywScene.getLatitudeGcj02Str(); + ywScene.setLongitude(isEmpty(lonStr) ? null : Double.parseDouble(lonStr)); + ywScene.setLatitude(isEmpty(latStr) ? null : Double.parseDouble(latStr)); + ywScene.setLongitudeGcj02(isNotEmpty(lonGcjStr) ? Double.parseDouble(lonGcjStr) : null); + ywScene.setLatitudeGcj02(isNotEmpty(latGcjStr) ? Double.parseDouble(latGcjStr) : null); + ywScene.setSceneBigId(sceneBigId); + ywScene.setAreaCountyId(getDictValue("yw_county", ywScene.getCounty())); + ywScene.setCityId(getDictValue("yw_city", ywScene.getCity())); + ywScene.setMaintainType(getDictValue("yw_scene_maintain_type", ywScene.getMaintainType())); + ywScene.setVenueType(getDictValue("yw_scene_type", ywScene.getVenueType())); + ywScene.setVenueLevel(getDictValue("yw_scene_level", ywScene.getVenueLevel())); + + } + + if ("0".equals(importType)) { + // 覆盖导入 + ywSceneUserMapper.deleteBySceneBigId(sceneBigId); + ywSceneMapper.deleteBySceneBigId(sceneBigId); + datas.forEach(x -> x.setCreateBy(userName)); + add(datas); + } else if ("1".equals(importType)) { + // 更新导入 + for (YwSceneDTO ywScene : datas) { + if (!judgeIfEdit(ywScene, scenes)) { + ywScene.setCreateBy(userName); + ywScene.setCreateTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date())); + ywSceneMapper.insertSelective(ywScene); + } else { + ywScene.setUpdateBy(userName); + ywScene.setUpdateTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date())); + ywSceneMapper.updateByPrimaryKeySelective(ywScene); + } + } + } + + } + + /** + * 实现类提供具体插入方法 + * + * @param collect 数据 + */ + @Override + public void insertB(List collect) { + ywSceneMapper.insertBatch(collect); + } + + private boolean judgeIfEdit(YwSceneDTO dto, List scenes) { + for (YwScene ywScene : scenes) { + if (StringUtils.isNotEmpty(ywScene.getVenueName()) && dto.getVenueName().equals(ywScene.getVenueName()) & + dto.getSceneBigId().equals(ywScene.getSceneBigId())) { + dto.setId(ywScene.getId()); + return true; + } + } + return false; + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterSceneNoticeinfo.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterSceneNoticeinfo.java new file mode 100644 index 0000000..d5433d7 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterSceneNoticeinfo.java @@ -0,0 +1,176 @@ +package com.ruoyi.eastcom_yw.importer; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.importer.service.YwBatchAddService; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneNoticeinfoSearchDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNoticeinfo; +import com.ruoyi.eastcom_yw.mapper.YwSceneMapper; +import com.ruoyi.eastcom_yw.mapper.YwSceneNoticeinfoMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +@Slf4j +@RequiredArgsConstructor +public class ImporterSceneNoticeinfo extends ImporterBase implements YwBatchAddService { + + private final YwSceneNoticeinfoMapper ywSceneNoticeinfoMapper; + + private final YwSceneMapper ywSceneMapper; + + { + cellFormatBeans.add(new CellFormatBean("场馆名称", "sceneName", "false", "", "", "", "", "", "", "true")); + cellFormatBeans.add(new CellFormatBean("无线网元数", "wxNetNumStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("专网网元数", "agisNetNumStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("动环网元数", "dhNetNumStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("公网传输设备", "publicTransportEquipNumStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("公网接入环", "publicInterfaceRingNumStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("专网传输设备", "privateTransportEquipNumStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("专网接入环", "privateInterfaceRingNumStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("现场保障人数", "frontuserStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("后台保障人数", "backuserStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("场馆部署应急车", "emergencycarStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("场馆部署应急仓", "emergencyWarehouseStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("保障车辆数", "supportcarStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("DICT设备数", "dictEquipNumStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("应急通信车", "emergencyCommunicationCarStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("应急发电车", "emergencyElectricCarStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("应急抢修车", "emergencyRepairCarStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("无线备件数", "wifiSpareStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("疏通备件数", "dredgeSpareStr", "", "", "true", "nonNegative", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("传输备件数", "transSpareStr", "", "", "true", "nonNegative", "", "", "", "")); + } + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception { + + } + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @throws Exception 异常 + */ + @Override + protected void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception { + + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @param j 列 + * @throws Exception 异常 + */ + @Override + protected void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) throws Exception { + if (isNotEmpty(s)) { + if ("sceneName".equals(format.getColumnEn())) { + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.eq(YwScene::getVenueName, s).eq(YwScene::getSceneBigId, 1); + YwScene ywScene = ywSceneMapper.selectOne(lambdaQueryWrapper); + if (ObjectUtils.isEmpty(ywScene)) { + reasonS.append("场馆不存在。"); + } + } + } + } + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) throws Exception { + for (YwSceneNoticeinfo data : datas) { + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.eq(YwScene::getVenueName, data.getSceneName()).eq(YwScene::getSceneBigId, 1); + data.setSceneId(ywSceneMapper.selectOne(lambdaQueryWrapper).getId()); + data.setAgisNetNum(StringUtils.isNotEmpty(data.getAgisNetNumStr()) ? Integer.parseInt(data.getAgisNetNumStr()) : null); + data.setWxNetNum(StringUtils.isNotEmpty(data.getWxNetNumStr()) ? Integer.parseInt(data.getWxNetNumStr()) : null); + data.setDhNetNum(StringUtils.isNotEmpty(data.getDhNetNumStr()) ? Integer.parseInt(data.getDhNetNumStr()) : null); + data.setInternetNetNum(StringUtils.isNotEmpty(data.getInternetNetNumStr()) ? Integer.parseInt(data.getInternetNetNumStr()) : null); + data.setPublicTransportEquipNum(StringUtils.isNotEmpty(data.getPublicTransportEquipNumStr()) ? Integer.parseInt(data.getPublicTransportEquipNumStr()) : null); + data.setPublicInterfaceRingNum(StringUtils.isNotEmpty(data.getPublicInterfaceRingNumStr()) ? Integer.parseInt(data.getPublicInterfaceRingNumStr()) : null); + data.setPrivateTransportEquipNum(StringUtils.isNotEmpty(data.getPrivateTransportEquipNumStr()) ? Integer.parseInt(data.getPrivateTransportEquipNumStr()) : null); + data.setPrivateInterfaceRingNum(StringUtils.isNotEmpty(data.getPrivateInterfaceRingNumStr()) ? Integer.parseInt(data.getPrivateInterfaceRingNumStr()) : null); + data.setFrontuser(StringUtils.isNotEmpty(data.getFrontuserStr()) ? Integer.parseInt(data.getFrontuserStr()) : null); + data.setBackuser(StringUtils.isNotEmpty(data.getBackuserStr()) ? Integer.parseInt(data.getBackuserStr()) : null); + data.setEmergencycar(StringUtils.isNotEmpty(data.getEmergencycarStr()) ? Integer.parseInt(data.getEmergencycarStr()) : null); + data.setEmergencyWarehouse(StringUtils.isNotEmpty(data.getEmergencyWarehouseStr()) ? Integer.parseInt(data.getEmergencyWarehouseStr()) : null); + data.setSupportcar(StringUtils.isNotEmpty(data.getSupportcarStr()) ? Integer.parseInt(data.getSupportcarStr()) : null); + data.setDictEquipNum(StringUtils.isNotEmpty(data.getDictEquipNumStr()) ? Integer.parseInt(data.getDictEquipNumStr()) : null); + data.setEmergencyCommunicationCar(StringUtils.isNotEmpty(data.getEmergencyCommunicationCarStr()) ? Integer.parseInt(data.getEmergencyCommunicationCarStr()) : null); + data.setEmergencyElectricCar(StringUtils.isNotEmpty(data.getEmergencyElectricCarStr()) ? Integer.parseInt(data.getEmergencyElectricCarStr()) : null); + data.setEmergencyRepairCar(StringUtils.isNotEmpty(data.getEmergencyRepairCarStr()) ? Integer.parseInt(data.getEmergencyRepairCarStr()) : null); + data.setWifiSpare(StringUtils.isNotEmpty(data.getWifiSpareStr()) ? Integer.parseInt(data.getWifiSpareStr()) : null); + data.setDredgeSpare(StringUtils.isNotEmpty(data.getDredgeSpareStr()) ? Integer.parseInt(data.getDredgeSpareStr()) : null); + data.setTransSpare(StringUtils.isNotEmpty(data.getTransSpareStr()) ? Integer.parseInt(data.getTransSpareStr()) : null); + data.setPublicPowerEquip(StringUtils.isNotEmpty(data.getPublicPowerEquipStr()) ? Integer.parseInt(data.getPublicPowerEquipStr()) : null); + data.setPrivatePowerEquip(StringUtils.isNotEmpty(data.getPrivatePowerEquipStr()) ? Integer.parseInt(data.getPrivatePowerEquipStr()) : null); + } + if ("1".equals(importType)) { + for (YwSceneNoticeinfo data : datas) { + YwSceneNoticeinfoSearchDTO dto = new YwSceneNoticeinfoSearchDTO(); + dto.setSceneId(data.getSceneId()); + List ywSceneNoticeinfos = ywSceneNoticeinfoMapper.selectBySearch(dto); + if (CollectionUtils.isNotEmpty(ywSceneNoticeinfos)) { + ywSceneNoticeinfoMapper.updateSelective(data); + } else { + ywSceneNoticeinfoMapper.insertSelective(data); + } + } + } else if ("0".equals(importType)) { + ywSceneNoticeinfoMapper.clear(); + add(datas); + } + } + + /** + * 实现类提供具体插入方法 + * + * @param collect 数据 + */ + @Override + public void insertB(List collect) { + ywSceneNoticeinfoMapper.insertBatch(collect); + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterSceneUser.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterSceneUser.java new file mode 100644 index 0000000..50c8b87 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterSceneUser.java @@ -0,0 +1,377 @@ +package com.ruoyi.eastcom_yw.importer; + +import cn.hutool.core.collection.CollectionUtil; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.importer.service.YwBatchAddService; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.domain.SysUserImp; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwSceneUser; +import com.ruoyi.eastcom_yw.mapper.YwSceneUserMapper; +import com.ruoyi.system.domain.SysUserRole; +import com.ruoyi.system.mapper.SysUserMapper; +import com.ruoyi.system.mapper.SysUserRoleMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@RequiredArgsConstructor +@Slf4j +public class ImporterSceneUser extends ImporterBase implements YwBatchAddService { + + private final SysUserMapper sysUserMapper; + + private final SysUserRoleMapper sysUserRoleMapper; + + private final YwSceneUserMapper ywSceneUserMapper; + + private String phoneNumber; + private String city; + private String county; + + { + cellFormatBeans.add(new CellFormatBean("姓名", "user_name", "", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("手机号码", "phonenumber", "false", "", "true", "phone", "", "", "", "true")); + cellFormatBeans.add(new CellFormatBean("账号状态", "status", "", "", "", "", "", "sys_user_status", "", "")); + cellFormatBeans.add(new CellFormatBean("角色", "roleName", "", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("专业", "specialty", "", "", "", "", "", "yw_specialty", "", "")); + cellFormatBeans.add(new CellFormatBean("地市", "city", "", "", "", "", "", "yw_city", "", "")); + cellFormatBeans.add(new CellFormatBean("区县", "county", "", "", "", "", "", "yw_county", "", "")); + cellFormatBeans.add(new CellFormatBean("场馆", "sceneName", "", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("场馆分区", "belongArea", "", "", "", "", "", "yw_belong_area", "", "")); + cellFormatBeans.add(new CellFormatBean("是否要签到", "needSign", "", "", "", "", "", "", "是,否", "")); + cellFormatBeans.add(new CellFormatBean("自有/三方", "ywUserBelong", "", "", "", "", "", "yw_user_belong", "", "")); + } + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception { + + } + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @throws Exception 异常 + */ + @Override + protected void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception { + + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @param j 列 + * @throws Exception 异常 + */ + @Override + protected void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) throws Exception { + + if ("phonenumber".equals(format.getColumnEn())) { + phoneNumber = s; + if (isNotEmpty(s)) { + if (s.length() != 11) { + reasonS.append("必须是11位手机号码。"); + } + } + } else if ("status".equals(format.getColumnEn())) { + if (isNotEmpty(s)) { + List sysUsers = sysUserMapper.selectUserByUserNameAndPhone(phoneNumber); + if (CollectionUtil.isNotEmpty(sysUsers)) { + SysUser sysUser = sysUsers.get(0); + if (sysUser != null) { + String statusOld = sysUser.getStatus(); + if (("0".equals(statusOld) || "2".equals(statusOld)) && "锁定".equals(s)) { + reasonS.append("不能将“正常”或“冻结”的账号修改为“锁定”。"); + } + } + } + } + } else if ("roleName".equals(format.getColumnEn())) { + if (isNotEmpty(s)) { + String[] str = s.split("\\|"); + List roleNames = new ArrayList<>(); + for (String t : str) { + if (roleNames.contains(t)) { + reasonS.append("角色重复。"); + } + roleNames.add(t); + SysRole role = checkRoleNameUnique((List) args[0], t); + if (role == null) { + reasonS.append("角色不存在。"); + } + } + } + } else if ("sceneName".equals(format.getColumnEn())) { + if (isNotEmpty(s)) { + String[] str = s.split("\\|"); + List sceneNames = new ArrayList<>(); + for (String t : str) { + if (sceneNames.contains(t)) { + reasonS.append("场馆重复。"); + } + sceneNames.add(t); + Long id = getSceneIdBySceneNameAndSceneBigId(t, sceneBigId, (List) args[1]); + if (id == null) { + reasonS.append("场馆不存在。"); + } else { + if(str.length<=1) { + YwScene scene = getSceneBySceneNameAndSceneBigId(t, sceneBigId, (List) args[1]); + if (scene != null && StringUtils.isNotEmpty(city) && (!city.equals(scene.getCityId()) || + !county.equals(scene.getAreaCountyId()))) { + reasonS.append("场馆不在该地市区县下。"); + } + } + } + } + } + } else if ("city".equals(format.getColumnEn())) { + city = getDictValue("yw_city", s); + } else if ("county".equals(format.getColumnEn())) { + county = getDictValue("yw_county", s); + } + + } + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) throws Exception { + String userName = SecurityUtils.getUsername(); + List roles = (List) args[0]; + List ywScenes = (List) args[1]; + List ywSceneUsers = (List) args[2]; + for (SysUserImp user : datas) { + SysUser sysUser = new SysUser(); + sysUser.setUserName(user.getPhonenumber()); + sysUser.setNickName(user.getUser_name()); + sysUser.setPhonenumber(user.getPhonenumber()); + sysUser.setStatus(DictUtils.getDictValue("sys_user_status", user.getStatus())); + if (StringUtils.isNotEmpty(user.getBelongArea())) { + sysUser.setDistinctArea(getDictValue("yw_belong_area", user.getBelongArea())); + } + if (StringUtils.isNotEmpty(user.getSpecialty())) { + sysUser.setUserType(DictUtils.getDictValue("yw_specialty", user.getSpecialty())); + } + if (StringUtils.isNotEmpty(user.getCity())) { + sysUser.setCity(DictUtils.getDictValue("yw_city", user.getCity())); + } + if (StringUtils.isNotEmpty(user.getCounty())) { + sysUser.setCounty(DictUtils.getDictValue("yw_county", user.getCounty())); + } + if (StringUtils.isNotEmpty(user.getYwUserBelong())) { + sysUser.setYwUserBelong(DictUtils.getDictValue("yw_user_belong", user.getYwUserBelong())); + } + if (validateUserPhone(sysUser)) { + if (StringUtils.isEmpty(user.getUser_name())) { + sysUser.setNickName(user.getPhonenumber()); + } + if (StringUtils.isEmpty(user.getStatus())) { + sysUser.setStatus(DictUtils.getDictValue("sys_user_status", "正常")); + } + sysUser.setCreateBy(userName); + sysUser.setPassword(SecurityUtils.encryptPassword("123456")); + sysUserMapper.insertUser(sysUser); + } else { + sysUser.setUpdateBy(userName); + sysUser.setUpdateTime(DateUtils.getNowDate()); + sysUserMapper.updateUser(sysUser); + } + user.setUser_id(sysUser.getUserId()); + if (StringUtils.isEmpty(user.getNeedSign())) { + user.setNeedSign("否"); + } + } + if ("0".equals(importType)) { + for (SysUserImp user : datas) { + if (user.getUser_id() != null && StringUtils.isNotEmpty(user.getRoleName())) { + sysUserRoleMapper.deleteUserRoleByUserId(user.getUser_id()); + String[] str = user.getRoleName().split("\\|"); + List sysUserRoles = new ArrayList<>(); + for (String t : str) { + SysUserRole sysUserRole = new SysUserRole(); + sysUserRole.setUserId(user.getUser_id()); + SysRole sysRole = checkRoleNameUnique(roles, t); + if (sysRole != null) { + sysUserRole.setRoleId(sysRole.getRoleId()); + } + sysUserRoles.add(sysUserRole); + } + sysUserRoleMapper.batchUserRole(sysUserRoles); + } + } + } else if ("1".equals(importType)) { + for (SysUserImp user : datas) { + if (StringUtils.isNotEmpty(user.getRoleName()) && user.getUser_id() != null) { + String[] str = user.getRoleName().split("\\|"); + for (String t : str) { + addUserRole(user, t, roles, userName); + } + } + } + } + if ("1".equals(importType)) { + // 更新导入 + for (SysUserImp user : datas) { + if (user.getUser_id() != null && StringUtils.isNotEmpty(user.getSceneName())) { + String[] str = user.getSceneName().split("\\|"); + for (String t : str) { + addUserScene(user, t, sceneBigId, ywScenes, ywSceneUsers); + } + } + } + } else if ("0".equals(importType)) { + List list = new ArrayList<>(); + for (SysUserImp user : datas) { + // 先删除该用户下的场馆绑定 + if (user.getUser_id() != null && StringUtils.isNotEmpty(user.getSceneName())) { + ywSceneUserMapper.deleteCurrentBigSceneUserVenue(user.getUser_id(), sceneBigId); + String[] str = user.getSceneName().split("\\|"); + for (String t : str) { + YwSceneUser ywSceneUser = new YwSceneUser(); + ywSceneUser.setUserId(user.getUser_id()); + ywSceneUser.setSceneId(getSceneIdBySceneNameAndSceneBigId(t, sceneBigId, ywScenes)); + ywSceneUser.setCreateBy(userName); + ywSceneUser.setCreateTime(DateUtils.getNowDate()); + list.add(ywSceneUser); + } + } + } + add(list); + } + } + + private void addUserScene(SysUserImp user, String t, Long sceneBigId, List ywScenes, List ywSceneUsers) { + YwSceneUser ywSceneUser = new YwSceneUser(); + ywSceneUser.setUserId(user.getUser_id()); + ywSceneUser.setSceneId(getSceneIdBySceneNameAndSceneBigId(t, sceneBigId, ywScenes)); + String userName = SecurityUtils.getUsername(); + if (null != ywSceneUser.getSceneId() && null != ywSceneUser.getUserId()) { + if (validateUserScene(ywSceneUser, ywSceneUsers)) { + ywSceneUser.setCreateBy(userName); + ywSceneUser.setCreateTime(DateUtils.getNowDate()); + ywSceneUserMapper.insertSelective(ywSceneUser); + } else { + ywSceneUser.setUpdateTime(DateUtils.getNowDate()); + ywSceneUser.setUpdateBy(userName); + ywSceneUserMapper.updateByUserIdAndSceneId(ywSceneUser); + } + } + } + + private void addUserRole(SysUserImp user, String t, List roles, String userName) { + List list = new ArrayList<>(); + SysUserRole sysUserRole = new SysUserRole(); + sysUserRole.setUserId(user.getUser_id()); + SysRole role = checkRoleNameUnique(roles, t); + if (role != null) { + sysUserRole.setRoleId(role.getRoleId()); + } + if (null != sysUserRole.getUserId() && null != sysUserRole.getRoleId()) { + list.add(sysUserRole); + sysUserRoleMapper.deleteUserRoleInfo(sysUserRole); + log.info(userName + "删除用户角色,参数:" + sysUserRole); + sysUserRoleMapper.batchUserRole(list); + } + } + + private Long getSceneIdBySceneNameAndSceneBigId(String sceneName, Long sceneBigId, List ywScenes) { + for (YwScene ywScene : ywScenes) { + if (ywScene.getVenueName().equals(sceneName) && Objects.equals(sceneBigId, ywScene.getSceneBigId())) { + return ywScene.getId(); + } + } + return null; + } + + private YwScene getSceneBySceneNameAndSceneBigId(String sceneName, Long sceneBigId, List ywScenes) { + for (YwScene ywScene : ywScenes) { + if (ywScene.getVenueName().equals(sceneName) && Objects.equals(sceneBigId, ywScene.getSceneBigId())) { + return ywScene; + } + } + return null; + } + + private SysRole checkRoleNameUnique(List roles, String t) { + SysRole role = null; + for (SysRole r : roles) { + if (StringUtils.isNotEmpty(r.getRoleName()) && r.getRoleName().equals(t)) { + role = r; + break; + } + } + return role; + } + + private boolean validateUserScene(YwSceneUser ywSceneUser, List ywSceneUsers) { + for (YwSceneUser y : ywSceneUsers) { + if (ywSceneUser.getUserId().equals(y.getUserId()) && + ywSceneUser.getSceneId().equals(y.getSceneId())) { + return false; + } + } + return true; + } + + private boolean validateUserPhone(SysUser user) { + List sysUsers = sysUserMapper.selectUserByUserNameAndPhone(user.getPhonenumber()); + if (CollectionUtils.isEmpty(sysUsers)) { + return true; + } + user.setUserId(sysUsers.get(0).getUserId()); + return false; + } + + /** + * 实现类提供具体插入方法 + * + * @param collect 数据 + */ + @Override + public void insertB(List collect) { + ywSceneUserMapper.insertBatch(collect); + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterSignPlan.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterSignPlan.java new file mode 100644 index 0000000..1885780 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterSignPlan.java @@ -0,0 +1,183 @@ +package com.ruoyi.eastcom_yw.importer; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwSignPlan; +import com.ruoyi.eastcom_yw.domain.YwSignPlanView; +import com.ruoyi.eastcom_yw.domain.dto.YwSignPlanDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSignPlanImportDTO; +import com.ruoyi.eastcom_yw.mapper.YwSceneMapper; +import com.ruoyi.eastcom_yw.mapper.YwSignPlanMapper; +import lombok.RequiredArgsConstructor; + +import java.util.Date; +import java.util.List; + +@RequiredArgsConstructor +public class ImporterSignPlan extends ImporterBase { + + private final YwSceneMapper ywSceneMapper; + private final YwSignPlanMapper ywSignPlanMapper; + private String signDate; + private String beginTime; + private String endTime; + private Date signBeginTime; + private String venueName; + + { + cellFormatBeans.add(new CellFormatBean("场馆", "venueName", "false", "", "", "", "", "", "", "true")); + cellFormatBeans.add(new CellFormatBean("签到日期", "signDate", "false", "true", "", "", "yyyy-MM-dd", "", "", "true")); + cellFormatBeans.add(new CellFormatBean("早签到时间", "beginTime", "false", "true", "", "", "HH:mm:ss", "", "", "")); + cellFormatBeans.add(new CellFormatBean("晚签到时间", "endTime", "false", "true", "", "", "HH:mm:ss", "", "", "")); + cellFormatBeans.add(new CellFormatBean("提醒时间量", "repWarnInterval", "false", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("通知方式", "noticeType", "false", "", "", "", "", "sys_notice_type", "", "")); + } + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception { + + } + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @throws Exception 异常 + */ + @Override + protected void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception { + if (isNotEmpty(venueName) && isNotEmpty(signDate)) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("venue_name", venueName); + queryWrapper.eq("scene_big_id", sceneBigId); + List venues = ywSceneMapper.selectList(queryWrapper); + if (venues.isEmpty()) { + reasonL.append("系统中没有该场馆。"); + } + Long venueId = venues.get(0).getId(); + LambdaQueryWrapper lambdaQueryWrapper2 = new LambdaQueryWrapper<>(); + lambdaQueryWrapper2.eq(YwSignPlan::getSceneId, venueId); + lambdaQueryWrapper2.eq(YwSignPlan::getSignDate, signDate); + // 验证是否存在这个场馆的签到日期 + List venuePlan = ywSignPlanMapper.selectList(lambdaQueryWrapper2); + if (!venuePlan.isEmpty()) { + reasonL.append("[").append(signDate).append("],场馆[").append(venueName).append("]的签到计划已存在"); + } + } + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @param j 列 + * @throws Exception 异常 + */ + @Override + protected void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) throws Exception { + if (isNotEmpty(s)) { + if ("venueName".equals(format.getColumnEn())) { + venueName = s; + SysUser user = SecurityUtils.getLoginUser().getUser(); + if (!user.isAdmin(user)) { + List venues = ywSceneMapper.getVenueByQuery(user.getUserId(), s, sceneBigId); + if (venues.isEmpty()) { + reasonS.append("当前用户没有操作[").append(s).append("]场馆的权限。"); + } + } + } else if ("signDate".equals(format.getColumnEn())) { + signDate = s; + Date signDate = DateUtils.parseDate(s, "yyyy-MM-dd"); + if (signDate.before(DateUtils.dateTime("yyyy-MM-dd", DateUtils.getDate()))) { + reasonS.append("签到日期不能早于当前日期。"); + } + } else if ("beginTime".equals(format.getColumnEn())) { + beginTime = s; + String beginTime = signDate + " " + s; + signBeginTime = DateUtils.parseDate(beginTime, "yyyy-MM-dd HH:mm:ss"); + if (signBeginTime.before(DateUtils.getNowDate())) { + reasonS.append("签到时间不能早于当前时间。"); + } + } else if ("endTime".equals(format.getColumnEn())) { + endTime = s; + String endTime = signDate + " " + s; + Date signEndTime = DateUtils.parseDate(endTime, "yyyy-MM-dd HH:mm:ss"); + if (signBeginTime != null && signEndTime.before(signBeginTime)) { + reasonS.append("晚签到时间必须大于早签到时间。"); + } + } else if ("repWarnInterval".equals(format.getColumnEn())) { + String[] arrIntervals = s.split(","); + for (String strInterval : arrIntervals) { + if (!StringUtils.isInt(strInterval)) { + reasonS.append("提醒时间量必须是数字,多个用英文逗号隔开"); + } else { + int interval = Integer.parseInt(strInterval); + if (interval <= 0) { + reasonS.append("提醒时间量必须大于0"); + } + } + } + } + } + } + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) throws Exception { + for (YwSignPlanImportDTO data : datas) { + YwSignPlanDTO ywSignPlanDTO = new YwSignPlanDTO(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("venue_name", data.getVenueName()); + queryWrapper.eq("scene_big_id", sceneBigId); + List venues = ywSceneMapper.selectList(queryWrapper); + ywSignPlanDTO.setVenueIds(new Long[]{venues.get(0).getId()}); + ywSignPlanDTO.setSignDates(new String[]{data.getSignDate()}); + ywSignPlanDTO.setBeginTime(data.getBeginTime()); + ywSignPlanDTO.setEndTime(data.getEndTime()); + ywSignPlanDTO.setRepWarnInterval(data.getRepWarnInterval()); + ywSignPlanDTO.setNoticeType(DictUtils.getDictValue("sys_notice_type", data.getNoticeType())); + ywSignPlanDTO.setCreateBy(SecurityUtils.getUsername()); + ywSignPlanMapper.insertSignPlan(ywSignPlanDTO); + } + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterWx.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterWx.java new file mode 100644 index 0000000..e81d23a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/importer/ImporterWx.java @@ -0,0 +1,233 @@ +package com.ruoyi.eastcom_yw.importer; + +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.importer.service.YwBatchAddService; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.eastcom_yw.common.constant.NetElementConstants; +import com.ruoyi.eastcom_yw.common.enums.InRedLine; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementWx; +import com.ruoyi.eastcom_yw.mapper.YwSceneNetelementWxMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@Slf4j +public class ImporterWx extends ImporterBase implements YwBatchAddService { + + private final YwSceneNetelementWxMapper ywSceneNetelementWxMapper; + + private String sceneName; + + /** + * 数据预处理 + * + * @param s cell + * @param cellFormatBean 校验规则 + */ + @Override + protected String preHandleCellValue(String s, CellFormatBean cellFormatBean) { + super.preHandleCellValue(s, cellFormatBean); + if ("city".equalsIgnoreCase(cellFormatBean.getColumnEn())) { + s = s.replaceAll("市", "").trim(); + } else if ("county".equalsIgnoreCase(cellFormatBean.getColumnEn())) { + s = s.replaceAll("区", "").trim(); + } else if ("带宽Str".equalsIgnoreCase(cellFormatBean.getColumnEn())) { + s = s.toUpperCase().replaceAll("M", "").trim(); + } + return s; + } + + /** + * 实现类提供具体插入方法 + * + * @param collect + */ + @Override + public void insertB(List collect) { + ywSceneNetelementWxMapper.insertBatch(collect); + } + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception { + + } + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i + * @throws Exception 异常 + */ + @Override + protected void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception { + + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i + * @param j + * @throws Exception 异常 + */ + @Override + protected void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) throws Exception { + + if ("sceneName".equals(format.getColumnEn())) { + if (isNotEmpty(s)) { + sceneName = (String) args[1]; + if (NetElementConstants.SINGLE_SCENE_COVER.equals(importType) && !sceneName.equals(s)) { + reasonS.append("单场馆覆盖导入模式下只能导入指定场馆。"); + } + if (NetElementConstants.SINGLE_SCENE_COVER.equals(importType) && s.contains("|")) { + reasonS.append("单场馆覆盖导入模式下场馆列不能包含|。"); + } + List ywSceneList = (List) args[0]; + List sceneNameList = ywSceneList.stream().map(x -> x.getVenueName()).collect(Collectors.toList()); + if (s.contains("|")) { + String[] str = s.split("\\|"); + for (String st : str) { + if (!sceneNameList.contains(st)) { + if (!reasonS.toString().contains("场馆不存在")) { + reasonS.append("场馆不存在。"); + } + } + } + } else { + if (!sceneNameList.contains(s)) { + reasonS.append("场馆不存在。"); + } + } + } + } + + } + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + @Override + protected void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) throws Exception { + + List ywSceneList = (List) args[0]; + + // 导入 + List list1 = new ArrayList<>(); + for (YwSceneNetelementWx y : datas) { + if (y.getSceneName().contains("|")) { + String[] str = y.getSceneName().split("\\|"); + for (String s : str) { + YwSceneNetelementWx n = new YwSceneNetelementWx(); + BeanUtils.copyBeanProp(n, y); + n.setSceneName(s); + list1.add(n); + } + } else { + list1.add(y); + } + } + + List list = new ArrayList<>(); + List> maps = new ArrayList<>(); + for (YwSceneNetelementWx ywSceneNetelementWx : list1) { + boolean jump = false; + for (Map map : maps) { + if (map.get("sceneName").equalsIgnoreCase(ywSceneNetelementWx.getSceneName()) && + map.get("ci").equalsIgnoreCase(ywSceneNetelementWx.getCi())) { + jump = true; + break; + } + } + if (jump) { + continue; + } + list.add(ywSceneNetelementWx); + Map map = new HashMap<>(); + map.put("sceneName", ywSceneNetelementWx.getSceneName()); + map.put("ci", ywSceneNetelementWx.getCi()); + maps.add(map); + } + + for (YwSceneNetelementWx y : list) { + if (InRedLine.IN_RED_LINE.getLabel().equals(y.getInRedline())) { + y.setInRedline(InRedLine.IN_RED_LINE.getCode()); + } else if (InRedLine.NOT_IN_RED_LINE.getLabel().equals(y.getInRedline())) { + y.setInRedline(InRedLine.NOT_IN_RED_LINE.getCode()); + } else { + y.setInRedline(""); + } + for (YwScene ywScene : ywSceneList) { + if (StringUtils.isNotEmpty(y.getSceneName()) && y.getSceneName().equals(ywScene.getVenueName())) { + y.setSceneId(ywScene.getId()); + break; + } + } + y.setEnodebid(StringUtils.isNotEmpty(y.getEnodebidStr()) ? Integer.parseInt(y.getEnodebidStr()) : null); + y.set小区标识(StringUtils.isNotEmpty(y.get小区标识Str()) ? Integer.parseInt(y.get小区标识Str()) : null); + y.set本地小区标识(StringUtils.isNotEmpty(y.get本地小区标识Str()) ? Integer.parseInt(y.get本地小区标识Str()) : null); + y.set站号(StringUtils.isNotEmpty(y.get站号Str()) ? Integer.parseInt(y.get站号Str()) : null); + y.set频点(StringUtils.isNotEmpty(y.get频点Str()) ? Integer.parseInt(y.get频点Str()) : null); + y.setPci(StringUtils.isNotEmpty(y.getPciStr()) ? Integer.parseInt(y.getPciStr()) : null); + y.setTac(StringUtils.isNotEmpty(y.getTacStr()) ? Integer.parseInt(y.getTacStr()) : null); + y.set带宽(StringUtils.isNotEmpty(y.get带宽Str()) ? Integer.parseInt(y.get带宽Str()) : null); + y.set方位角(StringUtils.isNotEmpty(y.get方位角Str()) ? Float.parseFloat(y.get方位角Str()) : null); + y.set经度(StringUtils.isNotEmpty(y.get经度Str()) ? Double.parseDouble(y.get经度Str()) : null); + y.set纬度(StringUtils.isNotEmpty(y.get纬度Str()) ? Double.parseDouble(y.get纬度Str()) : null); + y.set地市(DictUtils.getDictValue("yw_city", y.getCity())); + y.set县市(DictUtils.getDictValue("yw_county", y.getCounty())); + y.setUpdateBy(SecurityUtils.getUsername()); + y.setUpdateTime(DateUtils.getNowDate()); + } + List collect = list.stream().filter(x -> x.getSceneId() != null).collect(Collectors.toList()); + if (NetElementConstants.SINGLE_SCENE_COVER.equals(importType)) { + Long id = collect.get(0).getSceneId(); + ywSceneNetelementWxMapper.deleteBySceneId(id); + } else { + ywSceneNetelementWxMapper.deleteBySceneBigId(sceneBigId); + } + add(collect, 0L, 100L); + + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/AppMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/AppMapper.java new file mode 100644 index 0000000..9886b32 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/AppMapper.java @@ -0,0 +1,44 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.model.AppEntity; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; + +/** + * @author los + */ +public interface AppMapper extends BaseMapper { + + /** + * findApp + * + * @param appEntity + * @return + */ + @Select("SELECT id AS id ,APP_NAME AS appName, app_id as appId, app_secret as appSecret ,is_flag as isFlag , access_token as accessToken from m_app " + + "where app_id=#{appId} and app_secret=#{appSecret} and ip like concat('%', #{ip}, '%') and is_flag = '0'") + AppEntity findApp(AppEntity appEntity); + +// /** +// * +// * +// * @param appId +// * @return +// */ +// @Select("SELECT ID AS ID ,APP_NAME AS appName, app_id as appId, app_secret as appSecret ,is_flag as isFlag access_token as accessToken from m_app " +// + "where app_id=#{appId} and app_secret=#{appSecret} ") +// AppEntity findAppId(@Param("appId") String appId); + +// /** +// * 更新accessToken +// * +// * @param accessToken +// * @param appId +// * @return +// */ +// @Update(" update m_app set access_token =#{accessToken} where app_id=#{appId} ") +// int updateAccessToken(@Param("accessToken") String accessToken, @Param("appId") String appId); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/AppVersionConfigMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/AppVersionConfigMapper.java new file mode 100644 index 0000000..ce01396 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/AppVersionConfigMapper.java @@ -0,0 +1,10 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.AppVersionConfig; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface AppVersionConfigMapper extends BaseMapper { + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2AgisLink5miMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2AgisLink5miMapper.java new file mode 100644 index 0000000..08f3a7c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2AgisLink5miMapper.java @@ -0,0 +1,27 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.ruoyi.eastcom_yw.domain.Dp2AgisLink5mi; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.vo.Dp2AgisLink5miVO; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author yqf + * @since 2023-08-18 + */ +public interface Dp2AgisLink5miMapper extends BaseMapper { + + + List getAgislinkTop5List(@Param("venueId") Integer venueId, + @Param("starttime") LocalDateTime starttime, + @Param("endtime")LocalDateTime endtime, + @Param("ordertype")String ordertype); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2MmlListMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2MmlListMapper.java new file mode 100644 index 0000000..e2d60dd --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2MmlListMapper.java @@ -0,0 +1,21 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.Dp2MmlList; +import com.ruoyi.eastcom_yw.domain.qo.Dp2MmlListQO; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author ck + * @since 2023-09-12 + */ +public interface Dp2MmlListMapper extends BaseMapper { + + List list(Dp2MmlListQO qo); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2PnNetVenue5miMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2PnNetVenue5miMapper.java new file mode 100644 index 0000000..8e2db29 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2PnNetVenue5miMapper.java @@ -0,0 +1,34 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.Dp2PnNetVenue5mi; +import com.ruoyi.eastcom_yw.domain.vo.Dp2PnNetVenue5miVO; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetAgixStaVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetStaVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetWifiStaVo; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author yqf + * @since 2023-08-21 + */ +public interface Dp2PnNetVenue5miMapper extends BaseMapper { + + List getNetVenueTop5List(@Param("venueId") Integer venueId, + @Param("starttime") LocalDateTime starttime, + @Param("endtime")LocalDateTime endtime, + @Param("ordertype")String ordertype); + + + YwSceneNetStaVo getNetVenueStatis(@Param("id") Long id, + @Param("beginTime") LocalDateTime beginTime, + @Param("endTime") LocalDateTime endTime); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2SpotCellMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2SpotCellMapper.java new file mode 100644 index 0000000..c79e2dd --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2SpotCellMapper.java @@ -0,0 +1,24 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.Dp2SpotCell; +import com.ruoyi.eastcom_yw.domain.qo.Dp2SpotCellQO; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author ck + * @since 2023-08-10 + */ +public interface Dp2SpotCellMapper extends BaseMapper { + + List list(Dp2SpotCellQO qo); + + @InterceptorIgnore(blockAttack = "true") + void deleteAll(); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2SpotConfigMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2SpotConfigMapper.java new file mode 100644 index 0000000..91c2d21 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2SpotConfigMapper.java @@ -0,0 +1,22 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.Dp2SpotConfig; +import com.ruoyi.eastcom_yw.domain.qo.Dp2SpotConfigQO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2SpotConfigVO; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author ck + * @since 2023-08-09 + */ +public interface Dp2SpotConfigMapper extends BaseMapper { + + List list(Dp2SpotConfigQO qo); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2ViewPowerAlarmMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2ViewPowerAlarmMapper.java new file mode 100644 index 0000000..ba04e41 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2ViewPowerAlarmMapper.java @@ -0,0 +1,23 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.Dp2ViewPowerAlarm;; +import com.ruoyi.eastcom_yw.domain.qo.Dp2ViewPowerAlarmQO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2ViewPowerAlarmVO; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author wqx + * @since 2023-08-31 + */ +public interface Dp2ViewPowerAlarmMapper extends BaseMapper { + + List list(Dp2ViewPowerAlarmQO qo); + + int updateDealStatus(Long alarmid); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2ViewWirelessAlarmMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2ViewWirelessAlarmMapper.java new file mode 100644 index 0000000..b05e847 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/Dp2ViewWirelessAlarmMapper.java @@ -0,0 +1,22 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.Dp2ViewWirelessAlarm; +import com.ruoyi.eastcom_yw.domain.qo.Dp2ViewWirelessAlarmQO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2ViewWirelessAlarmVO; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author wqx + * @since 2023-09-01 + */ +public interface Dp2ViewWirelessAlarmMapper extends BaseMapper { + + public List list(Dp2ViewWirelessAlarmQO qo); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/DpSceneConfigMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/DpSceneConfigMapper.java new file mode 100644 index 0000000..0778a94 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/DpSceneConfigMapper.java @@ -0,0 +1,58 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.DpSceneConfig; +import com.ruoyi.eastcom_yw.domain.qo.DpSceneConfigQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiColorQo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + *

+ * Mapper 接口 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Mapper +public interface DpSceneConfigMapper extends BaseMapper { + + String getColorByQo(DpSceneConfigQO qo); + + Map getFourKpiColor(PmKpiColorQo qo); + + Map getkpiColorAndScore(@Param("kpiname") String kpiname, + @Param("kpivalue") Double kpivalue, + @Param("nettype") String nettype, + @Param("freqtype") String freqtype, + @Param("devicetype") String devicetype, + @Param("bandwidth") Long bandwidth); + + String getkpicolor(@Param("kpiname") String kpiname, + @Param("kpivalue") Double kpivalue, + @Param("nettype") String nettype, + @Param("freqtype") String freqtype, + @Param("devicetype") String devicetype, + @Param("bandwidth") Long bandwidth); + + Map getColor(List ids); + + int getkpicolorscore(@Param("kpiname") String kpiname, + @Param("kpivalue") Double kpivalue, + @Param("nettype") String nettype, + @Param("freqtype") String freqtype, + @Param("devicetype") String devicetype, + @Param("bandwidth") Long bandwidth); + + List listColor(); + + List listKpiName(); + + List getList(DpSceneConfigQO qo); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/HmAlarmDeriveMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/HmAlarmDeriveMapper.java new file mode 100644 index 0000000..4671c43 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/HmAlarmDeriveMapper.java @@ -0,0 +1,18 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.ruoyi.eastcom_yw.domain.HmAlarmDerive; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jkj + * @since 2023-08-02 + */ +@Mapper +public interface HmAlarmDeriveMapper extends BaseMapper { + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/LargeScreenMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/LargeScreenMapper.java new file mode 100644 index 0000000..3401f30 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/LargeScreenMapper.java @@ -0,0 +1,24 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.ruoyi.eastcom_yw.domain.vo.*; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface LargeScreenMapper { + + List getTaskManageList(); + + List getMatchList(); + + List getRaceScheduleList(); + + List getMedalList(); + + List getNewsList(); + + List getAlarmTopList(); + + List getAlarmStatisticsList(); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi4gCellMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi4gCellMapper.java new file mode 100644 index 0000000..44e65b8 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi4gCellMapper.java @@ -0,0 +1,74 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.PmKpi4gCell; +import com.ruoyi.eastcom_yw.domain.PmKpiMaxEntity; +import com.ruoyi.eastcom_yw.domain.PmKpiMonitorEntity; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellMonitorQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiVenueQO; +import com.ruoyi.eastcom_yw.domain.vo.DpcSeneControlVo; +import com.ruoyi.eastcom_yw.domain.vo.KpiVenueReportVo; +import com.ruoyi.eastcom_yw.domain.vo.RecordVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +/** + *

+ * 场馆4G小区级15分钟指标 Mapper 接口 + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Mapper +public interface PmKpi4gCellMapper extends BaseMapper { + + PmKpiMaxEntity getMaxKpi(PmKpiCellQO qo); + + List getList(PmKpiCellQO qo); + +// List getMaxUserList(PmKpiCellQO qo); +// +// List getUpPrbList(PmKpiCellQO qo); + + List getKpiDataList(PmKpiCellQO qo); + + +// List getDownPrbList(PmKpiCellQO qo); + +// int getVillageCount(PmKpiVenueQO qo); + + List getKpiList(PmKpiCellMonitorQO qo); + + List getKpiCopyList(PmKpiCellMonitorQO qo); + + Map getLastTime(@Param("sceneid") Integer sceneid,@Param("seatno") String seatno); + + int updateDpcSeneControl(DpcSeneControlVo dpcSeneControlVo); + + KpiVenueReportVo getMaxuserData(@Param("venueId") Integer venueId, @Param("starttime")LocalDateTime starttime, @Param("endtime")LocalDateTime endtime); + KpiVenueReportVo getPrbUpData(@Param("venueId") Integer venueId, @Param("starttime")LocalDateTime starttime, @Param("endtime")LocalDateTime endtime); + KpiVenueReportVo getPrbDownData(@Param("venueId") Integer venueId, @Param("starttime")LocalDateTime starttime, @Param("endtime")LocalDateTime endtime); + + int getUnusualcount(@Param("venueId") Integer venueId, + @Param("starttime")LocalDateTime starttime, + @Param("endtime")LocalDateTime endtime, + @Param("nettype") String nettype); + + int getVillageCount(@Param("venueId") Integer venueId, + @Param("starttime")LocalDateTime starttime, + @Param("endtime")LocalDateTime endtime); + + Map getLastTimeByvenueIds(@Param("venueIds") Long[] venueIds); + + List getTop5List(@Param("venueId") Integer venueId, + @Param("starttime")LocalDateTime starttime, + @Param("endtime")LocalDateTime endtime, + @Param("ordertype")String ordertype); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi4gMinMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi4gMinMapper.java new file mode 100644 index 0000000..db7ced8 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi4gMinMapper.java @@ -0,0 +1,34 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.*; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellMonitorQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiMinQO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + *

+ * 场馆4G小区级1分钟指标 Mapper 接口 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Mapper +public interface PmKpi4gMinMapper extends BaseMapper { + + PmKpiMaxEntity getMaxKpi(PmKpiMinQO qo); + + List getList(PmKpiMinQO qo); + + List getKpiList(PmKpiCellMonitorQO qo); + + Map getLastTime(@Param("sceneid") Integer sceneid,@Param("seatno") String seatno); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi4gVenueMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi4gVenueMapper.java new file mode 100644 index 0000000..423913e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi4gVenueMapper.java @@ -0,0 +1,35 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.PmKpi4gVenue; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiVenueQO; +import com.ruoyi.eastcom_yw.domain.vo.KpiVenueReportVo; +import com.ruoyi.eastcom_yw.domain.vo.RecordVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +/** + * @author yqf + * @date 2023/4/11 + */ +@Mapper +public interface PmKpi4gVenueMapper extends BaseMapper { + + List getList(PmKpiVenueQO qo); + + KpiVenueReportVo getLastData(@Param("venueId") Integer venueId, @Param("starttime")LocalDateTime starttime, @Param("endtime")LocalDateTime endtime); + + BigDecimal getsumbg(@Param("venueId") Integer venueId, @Param("starttime")LocalDateTime starttime, @Param("endtime")LocalDateTime endtime); + + Map getLastTime(@Param("venueId") Integer venueId); + + Map getLastTimeByvenueIds(@Param("venueIds") Integer[] venueIds); + + List getKpiDataList(PmKpiVenueQO qo); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi5gCellMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi5gCellMapper.java new file mode 100644 index 0000000..d7e0ee5 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi5gCellMapper.java @@ -0,0 +1,66 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.PmKpi4gCell; +import com.ruoyi.eastcom_yw.domain.PmKpi5gCell; +import com.ruoyi.eastcom_yw.domain.PmKpiMaxEntity; +import com.ruoyi.eastcom_yw.domain.PmKpiMonitorEntity; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellMonitorQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellQO; +import com.ruoyi.eastcom_yw.domain.vo.KpiVenueReportVo; +import com.ruoyi.eastcom_yw.domain.vo.RecordVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +/** + *

+ * 场馆5G小区级15分钟指标 Mapper 接口 + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Mapper +public interface PmKpi5gCellMapper extends BaseMapper { + +// List getMaxUserList(PmKpiCellQO qo); +// +// List getUpPrbList(PmKpiCellQO qo); +// +// +// List getDownPrbList(PmKpiCellQO qo); + + List getKpiDataList(PmKpiCellQO qo); + + List getList(PmKpiCellQO qo); + + List getKpiList(PmKpiCellMonitorQO qo); + + List getKpiCopyList(PmKpiCellMonitorQO qo); + + Map getLastTime(@Param("sceneid") Integer sceneid,@Param("seatno") String seatno); + + PmKpiMaxEntity getMaxKpi(PmKpiCellQO qo); + + KpiVenueReportVo getMaxuserData(@Param("venueId") Integer venueId, @Param("starttime") LocalDateTime starttime, @Param("endtime")LocalDateTime endtime); + KpiVenueReportVo getPrbUpData(@Param("venueId") Integer venueId, @Param("starttime")LocalDateTime starttime, @Param("endtime")LocalDateTime endtime); + KpiVenueReportVo getPrbDownData(@Param("venueId") Integer venueId, @Param("starttime")LocalDateTime starttime, @Param("endtime")LocalDateTime endtime); + + int getUnusualcount(@Param("venueId") Integer venueId, + @Param("starttime")LocalDateTime starttime, + @Param("endtime")LocalDateTime endtime, + @Param("nettype") String nettype); + + int getVillageCount(@Param("venueId") Integer venueId, + @Param("starttime")LocalDateTime starttime, + @Param("endtime")LocalDateTime endtime); + + List getTop5List(@Param("venueId") Integer venueId, + @Param("starttime")LocalDateTime starttime, + @Param("endtime")LocalDateTime endtime, + @Param("ordertype")String ordertype); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi5gMinMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi5gMinMapper.java new file mode 100644 index 0000000..1d39577 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi5gMinMapper.java @@ -0,0 +1,35 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.PmKpi4gMin; +import com.ruoyi.eastcom_yw.domain.PmKpi5gMin; +import com.ruoyi.eastcom_yw.domain.PmKpiMaxEntity; +import com.ruoyi.eastcom_yw.domain.PmKpiMonitorEntity; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellMonitorQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiMinQO; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + *

+ * 场馆5G小区级1分钟指标 Mapper 接口 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +public interface PmKpi5gMinMapper extends BaseMapper { + + PmKpiMaxEntity getMaxKpi(PmKpiMinQO qo); + + List getList(PmKpiMinQO qo); + + List getKpiList(PmKpiCellMonitorQO qo); + + Map getLastTime(@Param("sceneid") Integer sceneid, @Param("seatno") String seatno); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi5gVenueMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi5gVenueMapper.java new file mode 100644 index 0000000..c461843 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/PmKpi5gVenueMapper.java @@ -0,0 +1,37 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.PmKpi5gVenue; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiVenueQO; +import com.ruoyi.eastcom_yw.domain.vo.KpiVenueReportVo; +import com.ruoyi.eastcom_yw.domain.vo.RecordVo; +import org.apache.ibatis.annotations.Param; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +/** + *

+ * 5G场馆级15分钟指标 Mapper 接口 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +public interface PmKpi5gVenueMapper extends BaseMapper { + + List getList(PmKpiVenueQO qo); + + KpiVenueReportVo getLastData(@Param("venueId") Integer venueId, @Param("starttime")LocalDateTime starttime, @Param("endtime")LocalDateTime endtime); + + BigDecimal getsumbg(@Param("venueId") Integer venueId, @Param("starttime") LocalDateTime starttime, @Param("endtime")LocalDateTime endtime); + + Map getLastTime(@Param("venueId") Integer venueId); + + Map getLastTimeByvenueIds(@Param("venueIds") Integer[] venueIds); + + List getKpiDataList(PmKpiVenueQO qo); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/SysNoticeMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/SysNoticeMapper.java new file mode 100644 index 0000000..0b9a44b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/SysNoticeMapper.java @@ -0,0 +1,40 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.SysNotice; +import com.ruoyi.eastcom_yw.domain.qo.SysNoticeQO; +import com.ruoyi.eastcom_yw.domain.vo.SysNoticeVO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeBriefingVO; + +import java.util.List; + + +/** + *

+ * 通知公告表 Mapper 接口 + *

+ * + * @author ck + * @since 2023-04-14 + */ +public interface SysNoticeMapper extends BaseMapper { + + /** + * 公告已读,不要提醒 + * + * @param noticeIds 公告信息 + * @return 结果 + */ + public int isReadNotice(Long[] noticeIds); + + List selectToDoSMSList(); + + public List selectNoticeListByUser(Long reciveUserId); + + /** + * 查询未发送的简报计划 + */ + List selectToDoBriefingPlan(); + + List getData(SysNoticeQO qo); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmCSMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmCSMapper.java new file mode 100644 index 0000000..9f15537 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmCSMapper.java @@ -0,0 +1,28 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwAlarmCS; +import com.ruoyi.eastcom_yw.domain.YwAlarmView; +import com.ruoyi.eastcom_yw.domain.YwAlarmWX; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmInfoVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmNewNumVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Mapper +public interface YwAlarmCSMapper extends BaseMapper { + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmDHMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmDHMapper.java new file mode 100644 index 0000000..30a7750 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmDHMapper.java @@ -0,0 +1,27 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwAlarmDH; +import com.ruoyi.eastcom_yw.domain.YwAlarmView; +import com.ruoyi.eastcom_yw.domain.YwAlarmWX; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmInfoVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmNewNumVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Mapper +public interface YwAlarmDHMapper extends BaseMapper { + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmHangupLogMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmHangupLogMapper.java new file mode 100644 index 0000000..ed47dcf --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmHangupLogMapper.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.ruoyi.eastcom_yw.domain.YwAlarmHangupLog; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwAlarmHangupReover; +import com.ruoyi.eastcom_yw.domain.YwAlarmView; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jkj + * @since 2023-02-15 + */ +@Mapper +public interface YwAlarmHangupLogMapper extends BaseMapper { + + public List getYwAlarmHangupReoverList(); + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmMapper.java new file mode 100644 index 0000000..dd27cc1 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmMapper.java @@ -0,0 +1,49 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwAlarm; +import com.ruoyi.eastcom_yw.domain.YwAlarmRecover; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.vo.AlarmStaticListVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmNoticeVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmQuestionVo; +import com.ruoyi.eastcom_yw.domain.vo.YwErrorAlarmVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Mapper +public interface YwAlarmMapper extends BaseMapper { + public List getYwAlarmQuestionList(@Param("specialty") String specialty); + + List selectYwAlarmStaticList(@Param("alarmHour") String alarmHour,@Param("venueId") Long venueId); + + + List selectYwAlarmStaticList2(@Param("alarmVar") String alarmVar,@Param("alarmStart") String alarmStart,@Param("alarmEnd") String alarmEnd,@Param("venueId") Long venueId); + + + List selectYwAlarmCouldRecover(); + + List selectYwAlarmCouldNotice(); + + + int updateAlarmClearByAlarmId(YwAlarmDTO ywAlarmDTO); + + int updateAlarmClearByGroupId(YwAlarmDTO ywAlarmDTO); + + List selectAllAlarmWithError(); + + int updateOriginAlarmClose(YwAlarmDTO ywAlarmDTO); + + List revokeAlarm(); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmOprateLogMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmOprateLogMapper.java new file mode 100644 index 0000000..f468351 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmOprateLogMapper.java @@ -0,0 +1,16 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.ruoyi.eastcom_yw.domain.YwAlarmOprateLog; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jkj + * @since 2023-03-06 + */ +public interface YwAlarmOprateLogMapper extends BaseMapper { + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmStatisticsMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmStatisticsMapper.java new file mode 100644 index 0000000..d0146e4 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmStatisticsMapper.java @@ -0,0 +1,33 @@ +package com.ruoyi.eastcom_yw.mapper; +import java.util.Date; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmStatistics; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * (YwAlarmStatistics)表数据库访问层 + * + * @author lee + * @since 2023-04-24 20:22:12 + */ +public interface YwAlarmStatisticsMapper extends BaseMapper { + + /** + * 批量新增数据(MyBatis原生foreach方法) + * + * @param entities List 实例对象列表 + * @return 影响行数 + */ + int insertBatch(@Param("entities") List entities); + + int deleteByCreateTimeBefore(); + + List selectBySceneIdAndCreateTime(@Param("sceneId") Long sceneId, @Param("createTime") Date createTime); + + List selectBySceneIdAndCreateTimeAndProfession(@Param("sceneId") Long sceneId, @Param("createTime") Date createTime, @Param("profession") String profession); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmViewMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmViewMapper.java new file mode 100644 index 0000000..a200f3d --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmViewMapper.java @@ -0,0 +1,63 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwAlarmView; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTONoPage; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmInfoVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmNewNumVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmViewVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Mapper +public interface YwAlarmViewMapper extends BaseMapper { + + public List getYwHandleList(); + + + public List getYwAlarmInfoListByGroup(@Param("groupId") String groupId); + + //20230314 为解决红线外无流程ID的问题,这边查询多个加用关联ID + public List getYwAlarmInfoList(@Param("processId") String processId); + + public List getYwAlarmNewNum(@Param("userId") Long userId,@Param("isAll") Boolean isAll); + + public Long getYwAlarmNewNumByDto(YwAlarmDTO alarmDTO); + + public Long getYwAlarmNewNumByDto2(YwAlarmDTONoPage alarmDTO); + + //查询次告警 + public List getYwAlarmByGroupId(@Param("alarmType") String alarmType,@Param("groupId") String groupId); + + public List getYwAlarmByGroupIds(@Param("alarmType") String alarmType,@Param("groupIds") long [] groupIds); + + //查所有告警 + public List getYwAlarmAll(@Param("alarmType") String alarmType,@Param("venueName") String venueName,@Param("startTime") String startTime,@Param("endTime") String endTime); + + //查询主告警 + public YwAlarmVo getYwAlarmLastByGroupId(@Param("alarmType") String alarmType,@Param("groupId") String groupId); + + public List getYwAlarmByDto(YwAlarmDTO alarmDTO); + + public List selectAlarmContent(@Param("groupId") String groupId); + + @Select("SELECT template_id\n" + + "FROM process_templates\n" + + "WHERE template_name = #{taskType}") + public String getTemplateId(@Param("taskType") String taskType); + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmWXMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmWXMapper.java new file mode 100644 index 0000000..183caff --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwAlarmWXMapper.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwAlarmView; +import com.ruoyi.eastcom_yw.domain.YwAlarmWX; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmInfoVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmNewNumVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Mapper +public interface YwAlarmWXMapper extends BaseMapper { + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwConstrucTeamMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwConstrucTeamMapper.java new file mode 100644 index 0000000..6c7a2c3 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwConstrucTeamMapper.java @@ -0,0 +1,15 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.ruoyi.eastcom_yw.domain.vo.YwConstrucTeamVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface YwConstrucTeamMapper { + + public List getConstrucTeamByVenueId(@Param("venueId") Long venueId); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwDrsConfigMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwDrsConfigMapper.java new file mode 100644 index 0000000..8910b24 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwDrsConfigMapper.java @@ -0,0 +1,22 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwDrsConfig; +import com.ruoyi.eastcom_yw.domain.qo.YwDrsConfigQO; +import com.ruoyi.eastcom_yw.domain.vo.YwDrsConfigVO; + +import java.util.List; + +/** + *

+ * DRS配置表 Mapper 接口 + *

+ * + * @author ck + * @since 2023-06-13 + */ +public interface YwDrsConfigMapper extends BaseMapper { + + List list(YwDrsConfigQO qo); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwDrsTempTaskMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwDrsTempTaskMapper.java new file mode 100644 index 0000000..4543679 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwDrsTempTaskMapper.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwDrsTempTask; +import com.ruoyi.eastcom_yw.domain.qo.YwDrsTempTaskQO; +import com.ruoyi.eastcom_yw.domain.vo.YwDrsTempTaskVO; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDate; +import java.util.List; + +/** + *

+ * DRS临时任务表 Mapper 接口 + *

+ * + * @author ck + * @since 2023-06-13 + */ +public interface YwDrsTempTaskMapper extends BaseMapper { + + List list(YwDrsTempTaskQO qo); + + List selectDrsPreviewByVenueIdAndDate(@Param("venueId") Long venueId, @Param("date") LocalDate date, @Param("commandVenueId") Long commandVenueId); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwKpiConfigMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwKpiConfigMapper.java new file mode 100644 index 0000000..f093f1c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwKpiConfigMapper.java @@ -0,0 +1,17 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwKpiConfig; + +/** + *

+ * 指标字段阈值配置表 Mapper 接口 + *

+ * + * @author yqf + * @since 2023-04-11 + */ +public interface YwKpiConfigMapper extends BaseMapper { + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeBriefingMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeBriefingMapper.java new file mode 100644 index 0000000..3556908 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeBriefingMapper.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwNoticeBriefing; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeBriefingQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeBriefingPlanVO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeBriefingVO; + +import java.util.List; + +/** + *

+ * 通知通告简报计划表 Mapper 接口 + *

+ * + * @author ck + * @since 2023-04-11 + */ +public interface YwNoticeBriefingMapper extends BaseMapper { + + List selectBriefingPlan(); + + List selectNeedSendBriefing(); + + List getDataByPage(YwNoticeBriefingQO qo); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeHandworkMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeHandworkMapper.java new file mode 100644 index 0000000..36ad05e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeHandworkMapper.java @@ -0,0 +1,23 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwNoticeHandwork; + +import java.io.Serializable; +import java.util.List; + +/** + *

+ * 通知通告手工通知计划表 Mapper 接口 + *

+ * + * @author ck + * @since 2023-04-11 + */ +public interface YwNoticeHandworkMapper extends BaseMapper { + + String selectTaskIdByProcessId(String flwProcessid); + + List selectPass(); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeHandworkdetailMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeHandworkdetailMapper.java new file mode 100644 index 0000000..f005354 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeHandworkdetailMapper.java @@ -0,0 +1,16 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwNoticeHandworkdetail; + +/** + *

+ * 通知通告手工通知审核表 Mapper 接口 + *

+ * + * @author ck + * @since 2023-04-11 + */ +public interface YwNoticeHandworkdetailMapper extends BaseMapper { + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeListMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeListMapper.java new file mode 100644 index 0000000..e784723 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeListMapper.java @@ -0,0 +1,17 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwNoticeList; + +/** + *

+ * 通知通告记录表 Mapper 接口 + *

+ * + * @author ck + * @since 2023-04-11 + */ +public interface YwNoticeListMapper extends BaseMapper { + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeModelMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeModelMapper.java new file mode 100644 index 0000000..6fc322b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeModelMapper.java @@ -0,0 +1,17 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwNoticeModel; + +/** + *

+ * 通知通告模板表 Mapper 接口 + *

+ * + * @author ck + * @since 2023-04-07 + */ +public interface YwNoticeModelMapper extends BaseMapper { + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeObjectMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeObjectMapper.java new file mode 100644 index 0000000..ae241ee --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeObjectMapper.java @@ -0,0 +1,20 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwNoticeObject; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 通知通告对象表 Mapper 接口 + *

+ * + * @author ck + * @since 2023-04-11 + */ +public interface YwNoticeObjectMapper extends BaseMapper { + + List selectObjectsByVenueName(@Param("venueNames")List venueNames); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeUserMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeUserMapper.java new file mode 100644 index 0000000..eccff9d --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwNoticeUserMapper.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwNoticeUser; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Mapper +public interface YwNoticeUserMapper extends BaseMapper { + public List getYwNoticeUserList(@Param("flwId") String flwId,@Param("taskId") String taskId,@Param("groupId") String groupId,@Param("type") String type); + + public String getPhoneByGroupId(@Param("groupId") String groupId); + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectConfigMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectConfigMapper.java new file mode 100644 index 0000000..308867f --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectConfigMapper.java @@ -0,0 +1,19 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectConfig; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectConfigParam; + +import java.util.List; + +/** + * @author huamile + * @date 2023/1/18 15:26 + **/ +public interface YwRoutInspectConfigMapper extends BaseMapper { + + List getList(YwRoutInspectConfigParam param); + + Integer insertSelective(YwRoutInspectConfig config); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectLogMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectLogMapper.java new file mode 100644 index 0000000..d6530a3 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectLogMapper.java @@ -0,0 +1,21 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectLog; +import com.ruoyi.eastcom_yw.domain.vo.YwInspectLogVo; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface YwRoutInspectLogMapper extends BaseMapper { + + Integer insertSelective(YwRoutInspectLog ywRoutInspectLog); + + List getRoutInspectInfoList(String processId); + + void updateByflwProcessid(YwRoutInspectLog log); + + List getRoutInspectInfoListByJobNoAndFlowId(String jobNo); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectPlanMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectPlanMapper.java new file mode 100644 index 0000000..5b83cea --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectPlanMapper.java @@ -0,0 +1,77 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectPlan; +import com.ruoyi.eastcom_yw.domain.dto.YwInspectPlanDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwInspectStatDTO; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectConfigParam; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectPlanParam; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectStatParam; +import com.ruoyi.eastcom_yw.domain.vo.YwInspectLogVo; +import com.ruoyi.eastcom_yw.domain.vo.YwInspectPlanVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + * @author huamile + * @date 2023/1/17 16:05 + **/ +@Mapper +public interface YwRoutInspectPlanMapper extends BaseMapper { + + List getExecutablePlanList(@Param("now") String now); + + List getList(YwRoutInspectConfigParam param); + + List getListByJobNo(@Param("jobNo") String jobNo); + + List getPlanList(YwRoutInspectPlanParam param); + + Integer getNumOfAllPlan(YwRoutInspectStatParam param); + + Integer getNumOfCompletedPlan(YwRoutInspectStatParam param); + + Integer getAllNumOfPlan(YwRoutInspectStatParam param); + + Integer getNumOfQuestionPlan(YwRoutInspectStatParam param); + + List getStatListData(YwRoutInspectStatParam param); + + List getResultStatListData(YwRoutInspectStatParam param); + + List getStatListData20231012(YwRoutInspectStatParam param); + + List getResultStatListData20231012(YwRoutInspectStatParam param); + + /** + * 删除不在configIds中的同场馆同专业的配置 + * @param sceneId 场馆ID + * @param specialty 专业 + * @param configIds 配置ID列表 + * @return + */ + Integer delUselessConfig(@Param("sceneId") Long sceneId,@Param("specialty") String specialty, + @Param("configIds") List configIds); + + /** + * 删除不在list中的同工单号的巡检计划 + * @param jobNo 工单号 + * @param list 专业列表 + * @return + */ + Integer delUselessPlan(@Param("jobNo") String jobNo,@Param("list") List list); + + Integer insertSelective(YwInspectPlanDTO ywInspectPlanDTO); + + Integer updateByJobNoSelective(YwInspectPlanDTO ywInspectPlanDTO); + + @Select("SELECT template_id\n" + + "FROM process_templates\n" + + "WHERE template_name = '巡检任务'") + public String getInspectTemplateId(); + + List mergeResultStat(YwRoutInspectStatParam param); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectQuestionConfigMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectQuestionConfigMapper.java new file mode 100644 index 0000000..084f0a1 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwRoutInspectQuestionConfigMapper.java @@ -0,0 +1,23 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectQuestionConfig; +import com.ruoyi.eastcom_yw.domain.param.YwInspectQuestionConfigParam; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * @author huamile + * @date 2023/2/4 17:02 + **/ +@Mapper +public interface YwRoutInspectQuestionConfigMapper extends BaseMapper { + + List getlist(YwInspectQuestionConfigParam param); + + Integer insertSelective(YwRoutInspectQuestionConfig ywRoutInspectQuestionConfig); + + Integer updateByPrimaryKeySelective(YwRoutInspectQuestionConfig ywRoutInspectQuestionConfig); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneAlarmMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneAlarmMapper.java new file mode 100644 index 0000000..bd60944 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneAlarmMapper.java @@ -0,0 +1,27 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwSceneAlarm; +import com.ruoyi.eastcom_yw.domain.param.YwSceneAlarmParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneAlarmVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @author huamile + * @date 2023/2/14 10:33 + **/ +@Mapper +public interface YwSceneAlarmMapper extends BaseMapper { + + List getList(YwSceneAlarmParam param); + + List getListBySceneBigId(@Param("sceneBigId") Long sceneBigId); + + Integer insertSelective(YwSceneAlarm ywSceneAlarm); + + Integer updateByPrimaryKeySelective(YwSceneAlarm ywSceneAlarm); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneBigConfigMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneBigConfigMapper.java new file mode 100644 index 0000000..9802868 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneBigConfigMapper.java @@ -0,0 +1,20 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwSceneBigConfig; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jkj + * @since 2023-01-12 + */ +@Mapper +public interface YwSceneBigConfigMapper extends BaseMapper { + + Long selectCurrentBig(); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneCalendarMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneCalendarMapper.java new file mode 100644 index 0000000..78a3226 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneCalendarMapper.java @@ -0,0 +1,86 @@ +package com.ruoyi.eastcom_yw.mapper; + +import java.util.Date; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwSceneCalendar; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneCalendarDTO; +import com.ruoyi.eastcom_yw.domain.param.YwSceneCalendarParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneCalendar2Vo; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneCalendarVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @author huamile + * @date 2023/2/14 16:06 + **/ +@Mapper +public interface YwSceneCalendarMapper extends BaseMapper { + + /** + * 查询 + * + * @param param param + * @return list + */ + List getList(YwSceneCalendarParam param); + + /** + * 根据大场景id查询 + * + * @param sceneBigId 大场景id + * @return list + */ + List getListBySceneBigId(@Param("sceneBigId") Long sceneBigId); + + /** + * 新增 + * + * @param dto dto + * @return 插入条数 + */ + Integer insertSelective(YwSceneCalendarDTO dto); + + /** + * 根据主键更新 + * + * @param dto dto + * @return 更新条数 + */ + Integer updateByPrimaryKeySelective(YwSceneCalendarDTO dto); + + /** + * 批量插入 + * + * @param collect 数据 + */ + void insertBatch(List collect); + + /** + * 根据大场景id删除 + * + * @param sceneBigId 大场景id + */ + void deleteBySceneBigId(Long sceneBigId); + + /** + * 查询大场景下的id + * + * @param sceneBigId 大场景id + * @return ids + */ + String selectIds(@Param("sceneBigId") Long sceneBigId); + + /** + * 按条件查询 + * + * @param matchDate 比赛日期 + * @param sceneId 场景id + * @param endTime 结束时间 + * @return 符合条件数据 + */ + List selectByMatchDateAndSceneIdAndEndTimeGreaterThanEqualOrderByBeginTime(@Param("matchDate") Date matchDate, @Param("sceneId") Long sceneId, @Param("endTime") Date endTime); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneMapper.java new file mode 100644 index 0000000..642ee4a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneMapper.java @@ -0,0 +1,69 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwSceneBigConfig; +import com.ruoyi.eastcom_yw.domain.YwSceneFile; +import com.ruoyi.eastcom_yw.domain.dto.YwDataDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneDTO; +import com.ruoyi.eastcom_yw.domain.param.YwSceneParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneRedisVO; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jkj + * @since 2023-01-12 + */ +@Mapper +public interface YwSceneMapper extends BaseMapper { + + public List getAllVenues(); + + public List getVenueByUserId(@Param("userId") Long userId); + + public List getVenueByArea(@Param("area") String area); + + public List getVenueByUserIdAndBigId(@Param("userId") Long userId,@Param("sceneBigId") Long sceneBigId); + + public List getVenueByQuery(@Param("userId") Long userId,@Param("venueName") String venueName,@Param("sceneBigId") Long sceneBigId); + + public List getSysUserByVenueAndOther(YwDataDTO ywDataDTO); + + + List getList(YwSceneParam param); + + List getSceneBySceneBigId(@Param("sceneBigId") Long sceneBigId); + + Integer insertSelective(YwSceneDTO dto); + + Integer updateByPrimaryKeySelective(YwSceneDTO dto); + + Long getCurrentSceneBigId(); + + List getFilesBySceneIds(@Param("ids") List ids); + + Integer insertFileSelective(YwSceneFile ywSceneFile); + + Integer updateFileByPrimaryKeySelective(YwSceneFile ywSceneFile); + + Integer delUselessFile(@Param("sceneId") Long id,@Param("ids") List ids); + + List getFileByCondition(@Param("sceneId") Long id,@Param("ids") List ids); + + List getSceneBigById(@Param("sceneBigId") Long id); + + void updateBySceneNameSelective(YwSceneDTO dto); + + void deleteBySceneBigId(Long sceneBigId); + + void insertBatch(List ywScenes); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneMatchMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneMatchMapper.java new file mode 100644 index 0000000..c062b2f --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneMatchMapper.java @@ -0,0 +1,20 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.param.YwSceneMatchParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneMatchVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface YwSceneMatchMapper extends BaseMapper { + void insertBatch(List collect); + + void deleteBySceneBigId(Long sceneBigId); + + List list(YwSceneMatchParam param); + + String selectIds(@Param("sceneBigId") Long sceneBigId); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementAgisMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementAgisMapper.java new file mode 100644 index 0000000..085b97b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementAgisMapper.java @@ -0,0 +1,24 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementAgisParam; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementWxParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementAgis; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementCs; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementWx; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface YwSceneNetelementAgisMapper { + + List listAll(YwSceneNetelementAgisParam para); + + void deleteBySceneBigId(@Param("sceneBigId") Long sceneBigId); + + void insertBatch(@Param("list") List collect); + + int deleteBySceneId(@Param("sceneId") Long sceneId); + + int syncBySceneId(@Param("sceneId") Long sceneId); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementCsMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementCsMapper.java new file mode 100644 index 0000000..ed5830e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementCsMapper.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementCsParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementCs; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementDh; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface YwSceneNetelementCsMapper { + void insertOne(YwSceneNetelementCs cs); + + List listAll(YwSceneNetelementCsParam param); + + void updateBySceneId(YwSceneNetelementCs x); + + int syncBySceneId(@Param("sceneId") Long sceneId); + + List selectBySceneId(YwSceneNetelementCs y); + + void deleteBySceneBigId(@Param("sceneBigId") Long sceneBigId); + + void insertBatch(List ywSceneNetelementWxes1); + + int deleteBySceneId(@Param("sceneId") Long sceneId); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementDhMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementDhMapper.java new file mode 100644 index 0000000..28f9bb6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementDhMapper.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementDhParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementDh; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementWx; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface YwSceneNetelementDhMapper { + void insertOne(YwSceneNetelementDh cs); + + List listAll(YwSceneNetelementDhParam para); + + void updateBySceneId(YwSceneNetelementDh x); + + List selectById(YwSceneNetelementDh y); + + void deleteBySceneBigId(@Param("sceneBigId") Long sceneBigId); + + void insertBatch(List ywSceneNetelementWxes1); + + int deleteBySceneId(@Param("sceneId") Long sceneId); + + int syncBySceneId(@Param("sceneId") Long sceneId); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementMapper.java new file mode 100644 index 0000000..3390f12 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementMapper.java @@ -0,0 +1,30 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwSceneNetelement; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementParam; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @author huamile + * @date 2023/2/14 14:59 + **/ +@Mapper +public interface YwSceneNetelementMapper extends BaseMapper { + + List getList(YwSceneNetelementParam param); + + List getListBySceneBigId(@Param("sceneBigId") Long sceneBigId); + + Integer insertSelective(YwSceneNetelement ywSceneNetelement); + + Integer updateByPrimaryKeySelective(YwSceneNetelement ywSceneNetelement); + + Integer[] getNetelementNum(); + + void dp_2_refresh_materialized_view(); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementWxMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementWxMapper.java new file mode 100644 index 0000000..c994e86 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNetelementWxMapper.java @@ -0,0 +1,31 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementWxParam; +import com.ruoyi.eastcom_yw.domain.vo.WholeAreaAssureCellSheet; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementWx; +import org.apache.ibatis.annotations.Param; + +import java.util.Collection; +import java.util.List; + +public interface YwSceneNetelementWxMapper { + void insertOne(YwSceneNetelementWx cs); + + List listAll(YwSceneNetelementWxParam para); + + List listAll2(YwSceneNetelementWxParam para); + + void updateBySceneId(YwSceneNetelementWx x); + + List selectBySceneId(YwSceneNetelementWx y); + + void deleteBySceneBigId(@Param("sceneBigId") Long sceneBigId); + + int insertBatch(@Param("ywSceneNetelementWxCollection") Collection ywSceneNetelementWxCollection); + + List listSeatId(@Param("sceneId") Long sceneId); + + int deleteBySceneId(@Param("sceneId") Long sceneId); + + int syncBySceneId(@Param("sceneId") Long sceneId); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNoticeinfoMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNoticeinfoMapper.java new file mode 100644 index 0000000..3517aac --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneNoticeinfoMapper.java @@ -0,0 +1,51 @@ +package com.ruoyi.eastcom_yw.mapper; + +import java.util.List; + +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneNoticeinfoSearchDTO; +import org.apache.ibatis.annotations.Param; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNoticeinfo; + +/** + * (YwSceneNoticeinfo)表数据库访问层 + * + * @author lee + * @since 2023-04-27 11:13:51 + */ +public interface YwSceneNoticeinfoMapper extends BaseMapper { + + /** + * 批量新增数据(MyBatis原生foreach方法) + * + * @param entities List 实例对象列表 + * @return 影响行数 + */ + int insertBatch(@Param("entities") List entities); + + /** + * 根据场馆id查询 + * + * @param sceneId 场馆id + * @return 数据 + */ + List selectBySceneId(@Param("sceneId") Long sceneId); + + /** + * 根据条件查询 + * + * @param ywSceneNoticeinfo 条件 + * @return 数据 + */ + List selectBySearch(YwSceneNoticeinfoSearchDTO ywSceneNoticeinfo); + + int insertSelective(YwSceneNoticeinfo ywSceneNoticeinfo); + + int updateSelective(YwSceneNoticeinfo ywSceneNoticeinfo); + + @InterceptorIgnore(blockAttack = "true") + int clear(); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwScenePictureMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwScenePictureMapper.java new file mode 100644 index 0000000..9d784fb --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwScenePictureMapper.java @@ -0,0 +1,88 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.ruoyi.eastcom_yw.domain.PmKpi5gCell; +import com.ruoyi.eastcom_yw.domain.vo.*; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +/** + * @author los + */ +@Mapper +@Component +public interface YwScenePictureMapper { + + /** + * 查询单场馆布线任务总数 + * + * @param id 场馆id + * @return 单场馆布线任务总数 + */ + Integer getNumOfBXALL(Long id); + + /** + * 查询单场馆布线任务已完成数 + * + * @param id 场馆id + * @return 单场馆布线任务已完成数 + */ + Integer getNumOfBXComplete(Long id); + + List getAlarmStatistics(); + + /** + * 查询15分钟场馆级KPI指标 + * + * @param id 场馆id + * @param typeId 45g + * @return 指标 + */ + List getLineChartKpi(@Param("id") Long id, @Param("typeId") String typeId); + + List selectManagerInfoBySceneId(@Param("id") Long id); + + YwSceneNetAgixStaVo getNetAgixStatis(@Param("id") Long id, + @Param("beginTime") LocalDateTime beginTime, + @Param("endTime") LocalDateTime endTime); + + YwSceneNetStaVo getNetStatis(@Param("id") Long id, + @Param("beginTime") LocalDateTime beginTime, + @Param("endTime") LocalDateTime endTime); + + List getNetVelocityStatis(@Param("id") Long id, + @Param("beginTime") LocalDateTime beginTime, + @Param("endTime") LocalDateTime endTime); + + YwSceneNetFixtelStaVo getNetFixtelStatis(@Param("id") Long id, + @Param("beginTime") LocalDateTime beginTime, + @Param("endTime") LocalDateTime endTime); + + List getNetFixtelRegSuccStatis(@Param("id") Long id, + @Param("beginTime") LocalDateTime beginTime, + @Param("endTime") LocalDateTime endTime); + + List getGbtop5List(@Param("id") Long id); + + List getOpticalpowerTop5List(@Param("id") Long id,@Param("size") Integer size, + @Param("beginTime") LocalDateTime beginTime, + @Param("endTime") LocalDateTime endTime); + + List getOutOpticalpowerTop5List(@Param("id") Long id,@Param("size") Integer size, + @Param("beginTime") LocalDateTime beginTime, + @Param("endTime") LocalDateTime endTime); + + YwSceneTransOpticalpowerStaVo getMaxInOpticalpower(@Param("id") Long id, + @Param("beginTime") LocalDateTime beginTime, + @Param("endTime") LocalDateTime endTime); + + YwSceneTransOpticalpowerStaVo getMaxOutOpticalpower(@Param("id") Long id, + @Param("beginTime") LocalDateTime beginTime, + @Param("endTime") LocalDateTime endTime); + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneTestDataInterfaceMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneTestDataInterfaceMapper.java new file mode 100644 index 0000000..355fe6b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneTestDataInterfaceMapper.java @@ -0,0 +1,15 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneTestDataInterface; + +/** + * (YwSceneTestDataInterface)表数据库访问层 + * + * @author lee + * @since 2023-09-07 09:58:03 + */ +public interface YwSceneTestDataInterfaceMapper extends BaseMapper { + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneTestDataMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneTestDataMapper.java new file mode 100644 index 0000000..ae5b145 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneTestDataMapper.java @@ -0,0 +1,38 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwSceneTestData; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * (YwSceneTestData)表数据库访问层 + * + * @author lee + * @since 2023-04-26 18:26:34 + */ +public interface YwSceneTestDataMapper extends BaseMapper { + + /** + * 批量新增数据(MyBatis原生foreach方法) + * + * @param entities List 实例对象列表 + * @return 影响行数 + */ + int insertBatch(@Param("entities") List entities); + + @InterceptorIgnore(blockAttack = "true") + int deleteAll(); + + /** + * 根据场馆id删除 + * + * @param entities idList + * @return + */ + int deleteBySceneIdIn(@Param("entities") List entities); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneUserMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneUserMapper.java new file mode 100644 index 0000000..d010098 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneUserMapper.java @@ -0,0 +1,50 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwSceneUser; +import com.ruoyi.eastcom_yw.domain.vo.SysUserVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneUserVo; +import com.ruoyi.eastcom_yw.domain.param.YwSceneUserParam; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @author huamile + */ +@Mapper +public interface YwSceneUserMapper extends BaseMapper { + + List getList(YwSceneUserParam param); + + List getVenuesByUserId(@Param("userId") Long userId); + + List getVenuesByUserIds(@Param("userIds") List userIds); + + List getListBySceneBigId(@Param("sceneBigId") Long sceneBigId); + + Integer insertSelective(YwSceneUser ywSceneUser); + + Integer updateByPrimaryKeySelective(YwSceneUser ywSceneUser); + + void updateByUserIdAndSceneId(YwSceneUser ywSceneUser); + + List getListByUserIdAndSceneId(YwSceneUser ywSceneUser); + + List listSysUser(Long sceneBigId); + + void deleteBySceneBigId(Long sceneBigId); + + void insertBatch(List list); + + /** + * 清空当前用户当前大场景下的场馆绑定 + * + * @param userId 用户 + * @param sceneBigId 大场景 + * @return 删除条数 + */ + int deleteCurrentBigSceneUserVenue(@Param(value = "userId") Long userId, @Param(value = "sceneBigId") Long sceneBigId); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneViewMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneViewMapper.java new file mode 100644 index 0000000..08955df --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSceneViewMapper.java @@ -0,0 +1,29 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwSceneBigConfig; +import com.ruoyi.eastcom_yw.domain.YwSceneFile; +import com.ruoyi.eastcom_yw.domain.YwSceneView; +import com.ruoyi.eastcom_yw.domain.dto.YwDataDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneDTO; +import com.ruoyi.eastcom_yw.domain.param.YwSceneParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jkj + * @since 2023-01-12 + */ +@Mapper +public interface YwSceneViewMapper extends BaseMapper { + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSignLogMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSignLogMapper.java new file mode 100644 index 0000000..f437973 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSignLogMapper.java @@ -0,0 +1,32 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwSignLog; +import com.ruoyi.eastcom_yw.domain.dto.YwSignInDTO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +@Mapper +public interface YwSignLogMapper extends BaseMapper { + + //签到 + public void SingIn(YwSignInDTO ywSignInDTO); + + //个人签到 + public void sign(@Param("ywSignLog") YwSignLog ywSignLog,@Param("sceneId") Long sceneId); + + //配置签到记录 + public void AssignSignLog(); + + //根据计划ID删除签到记录 + public int deleteSignLogByPlan(@Param("id") Long id); + + + //根据计划ID删除多余的签到记录 + public int deleteSignLogUserByPlan(@Param("id") Long id); + + + //删除当天场馆不存在的签到记录表的人员 + public int deleteSignLogToday(); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSignLogViewMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSignLogViewMapper.java new file mode 100644 index 0000000..d122852 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSignLogViewMapper.java @@ -0,0 +1,21 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwSignLogView; +import com.ruoyi.eastcom_yw.domain.YwSignPlan; +import com.ruoyi.eastcom_yw.domain.dto.YwSignLogDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwSignLogStaticVo; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface YwSignLogViewMapper extends BaseMapper { + + List getSignLogStatic(YwSignLogDTO ywSignLogDTO); + + List getSignLogStatic20231012(YwSignLogDTO ywSignLogDTO); + + List getSignLogStaticForPic(YwSignLogDTO ywSignLogDTO); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSignPlanMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSignPlanMapper.java new file mode 100644 index 0000000..f489f55 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSignPlanMapper.java @@ -0,0 +1,27 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.eastcom_yw.domain.YwSignPlanRemind; +import com.ruoyi.eastcom_yw.domain.YwSignPlanView; +import com.ruoyi.eastcom_yw.domain.dto.YwSignPlanDTO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + + +@Mapper +public interface YwSignPlanMapper extends BaseMapper { + + public List getSignRemindList(); + + public int insertSignPlan(YwSignPlanDTO ywSignPlanDTO); + + public int updateSignPlan(YwSignPlanDTO ywSignPlanDTO); + + public int deleteSignPlan(@Param("id") Long id); + + public List getSignPlanList(@Param("userId") Long userId,@Param("venueId") Long venueId,@Param("signDate") String signDate); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSparePartsMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSparePartsMapper.java new file mode 100644 index 0000000..900403a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwSparePartsMapper.java @@ -0,0 +1,28 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwSpareParts; +import com.ruoyi.eastcom_yw.domain.dto.YwSparePartsDTO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 亚运备件表 Mapper 接口 + *

+ * + * @author yqf + * @since 2023-08-31 + */ +@Mapper +public interface YwSparePartsMapper extends BaseMapper { + + void insertBatch(@Param("list") List list); + + + void deleteAllData(); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwWireTaskLogMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwWireTaskLogMapper.java new file mode 100644 index 0000000..dcdd674 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/YwWireTaskLogMapper.java @@ -0,0 +1,27 @@ +package com.ruoyi.eastcom_yw.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.YwWireTaskLog; +import com.ruoyi.eastcom_yw.domain.vo.FlowContentVo; +import com.ruoyi.eastcom_yw.domain.dto.YwWireTaskLogDTO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface YwWireTaskLogMapper extends BaseMapper { + + public String getWireTaskId(); + + public int insertWireTask(YwWireTaskLogDTO ywWireTaskLogDTO); + + public int updateWireTask(YwWireTaskLogDTO ywWireTaskLogDTO); + + public int updateWireTaskReport(YwWireTaskLogDTO ywWireTaskLogDTO); + + public int deleteWireTask(YwWireTaskLogDTO ywWireTaskLogDTO); + + public List getWireTaskFlowContent(); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/yw_alarm_deal_logMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/yw_alarm_deal_logMapper.java new file mode 100644 index 0000000..67d0c1e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/yw_alarm_deal_logMapper.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneDTO; +import com.ruoyi.eastcom_yw.domain.yw_alarm_deal_log; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Mapper +public interface yw_alarm_deal_logMapper extends BaseMapper { + + + Integer updateHangupSpantime(@Param("minute") double minute,@Param("processId") String processId); + + public Integer updateEndTime(); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/yw_alarm_deal_resMapper.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/yw_alarm_deal_resMapper.java new file mode 100644 index 0000000..f9bbdb0 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/mapper/yw_alarm_deal_resMapper.java @@ -0,0 +1,7 @@ +package com.ruoyi.eastcom_yw.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.eastcom_yw.domain.yw_alarm_deal_res; + +public interface yw_alarm_deal_resMapper extends BaseMapper { +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/AppVersionService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/AppVersionService.java new file mode 100644 index 0000000..24c783a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/AppVersionService.java @@ -0,0 +1,8 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.AppVersionConfig; + +public interface AppVersionService extends IService { + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/CommonService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/CommonService.java new file mode 100644 index 0000000..731a06a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/CommonService.java @@ -0,0 +1,35 @@ +package com.ruoyi.eastcom_yw.service; + +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.core.domain.dto.HandleDataDTO; +import com.ruoyi.common.core.domain.dto.StartProcessInstanceDTO; +import com.ruoyi.common.core.domain.dto.TaskDTO; +import org.apache.poi.ss.formula.functions.T; + +import java.util.List; + +public interface CommonService { + + public String GetProcessDefinitionId(String template_id) throws Exception; + + public String StartProcess(StartProcessInstanceDTO startDTO) throws Exception; + + public Boolean UpdateProcessStatus(HandleDataDTO handleDataDTO) throws Exception; + + public JSONObject getTaskInfo(HandleDataDTO handleDataDTO) throws Exception; + + public Boolean agreeTask(HandleDataDTO handleDataDTO) throws Exception; + + public Boolean revokeTask(HandleDataDTO handleDataDTO) throws Exception; + + public JSONObject toDoList(TaskDTO taskDTO) throws Exception; + + //告警需要传alarmType,巡检布线不用 + public List selectCurrenUserTodoProcessId(String alarmType); + + + public String getToken(String userName,String password); + + public String getTokenByPhone(String phone,String code); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2MmlListService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2MmlListService.java new file mode 100644 index 0000000..de07cc6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2MmlListService.java @@ -0,0 +1,77 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.github.pagehelper.PageInfo; +import com.ruoyi.eastcom_yw.domain.Dp2MmlList; +import com.ruoyi.eastcom_yw.domain.qo.Dp2MmlListQO; + +import java.util.List; + +/** +*

+ * 服务类 + *

+* +* @author ck +* @since 2023-09-12 +*/ +public interface Dp2MmlListService extends IService { + + /** + * 列表 + * @param qo 根据需要进行传值 + * @return + */ + List getData(Dp2MmlListQO qo); + + /** + * 分页列表 + * @param qo 根据需要进行传值 + * @return + */ + PageInfo getDataByPage(Dp2MmlListQO qo); + +// /** +// * 详情 +// * @param id +// * @return +// */ +// Dp2MmlList fetchById(Long id); +// +// /** +// * 新增或修改 +// * @param dto 根据需要进行传值 +// * @return +// */ +// boolean saveOrUpdate(Dp2MmlList dto); +// +// /** +// * 删除(单个条目) +// * @param id +// * @return +// */ +// boolean deleteById(Long id); +// +// /** +// * 批量删除(多个条目) +// * +// * @param ids +// * @return +// */ +// boolean deleteByIdBatch(List ids); + + /** + * 导出 + * @param qo + * @return + */ + void export(Dp2MmlListQO qo); + + /** + * 导入 + * + * @param + * @return + */ +// AjaxResult importData(List list, boolean updateSupport); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2SpotCellService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2SpotCellService.java new file mode 100644 index 0000000..6346593 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2SpotCellService.java @@ -0,0 +1,85 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.Dp2SpotCell; +import com.ruoyi.eastcom_yw.domain.qo.Dp2SpotCellQO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2SpotCellVO; + +import java.util.List; + +/** + *

+ * 服务类 + *

+ * + * @author ck + * @since 2023-08-10 + */ +public interface Dp2SpotCellService extends IService { + + /** + * 列表 + * + * @param qo 根据需要进行传值 + * @return + */ + List getData(Dp2SpotCellQO qo); + + /** + * 分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + PageInfo getDataByPage(Dp2SpotCellQO qo); + + /** + * 详情 + * + * @param id + * @return + */ + Dp2SpotCellVO fetchById(Long id); + + /** + * 新增或修改 + * + * @param entity 根据需要进行传值 + * @return + */ + boolean saveOrUpdated(Dp2SpotCell entity); + + /** + * 删除(单个条目) + * + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * 批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * 导出 + * + * @param qo + * @return + */ + void export(Dp2SpotCellQO qo); + + /** + * 导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2SpotConfigService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2SpotConfigService.java new file mode 100644 index 0000000..f5db53c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2SpotConfigService.java @@ -0,0 +1,88 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.Dp2SpotConfig; +import com.ruoyi.eastcom_yw.domain.dto.Dp2SpotConfigDTO; +import com.ruoyi.eastcom_yw.domain.qo.Dp2SpotConfigQO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2SpotConfigVO; + +import java.util.List; + +; + +/** + *

+ * 服务类 + *

+ * + * @author ck + * @since 2023-08-09 + */ +public interface Dp2SpotConfigService extends IService { + + /** + * 列表 + * + * @param qo 根据需要进行传值 + * @return + */ + List getData(Dp2SpotConfigQO qo); + + /** + * 分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + PageInfo getDataByPage(Dp2SpotConfigQO qo); + + /** + * 详情 + * + * @param id + * @return + */ + Dp2SpotConfigVO fetchById(Long id); + + /** + * 新增或修改 + * + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(Dp2SpotConfigDTO dto); + + /** + * 删除(单个条目) + * + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * 批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * 导出 + * + * @param qo + * @return + */ + void export(Dp2SpotConfigQO qo); + + /** + * 导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2ViewPowerAlarmService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2ViewPowerAlarmService.java new file mode 100644 index 0000000..771c065 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2ViewPowerAlarmService.java @@ -0,0 +1,56 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.Dp2ViewPowerAlarm; +import com.ruoyi.eastcom_yw.domain.dto.Dp2ViewPowerAlarmDTO; +import com.ruoyi.eastcom_yw.domain.qo.Dp2ViewPowerAlarmQO; +import com.ruoyi.eastcom_yw.domain.qo.Dp2ViewWirelessAlarmQO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2ViewPowerAlarmVO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2ViewWirelessAlarmVO; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** +*

+ * 服务类 + *

+* +* @author wqx +* @since 2023-08-31 +*/ +public interface Dp2ViewPowerAlarmService extends IService{ + + /** + * 列表 + * @param qo 根据需要进行传值 + * @return + */ + List getData(Dp2ViewPowerAlarmQO qo); + + /** + * 分页列表 + * @param qo 根据需要进行传值 + * @return + */ + PageInfo getDataByPage(Dp2ViewPowerAlarmQO qo); + + /** + * 详情 + * @param id + * @return + */ + Dp2ViewPowerAlarmVO fetchById(Long id); + + + public void export(Dp2ViewPowerAlarmQO qo) ; + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2ViewWirelessAlarmService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2ViewWirelessAlarmService.java new file mode 100644 index 0000000..fd027ef --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/Dp2ViewWirelessAlarmService.java @@ -0,0 +1,82 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.Dp2ViewWirelessAlarm; +import com.ruoyi.eastcom_yw.domain.dto.Dp2ViewWirelessAlarmDTO; +import com.ruoyi.eastcom_yw.domain.qo.Dp2ViewWirelessAlarmQO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2ViewWirelessAlarmVO; + +import java.util.List; + +/** +*

+ * 服务类 + *

+* +* @author wqx +* @since 2023-09-01 +*/ +public interface Dp2ViewWirelessAlarmService extends IService { + + /** + * 列表 + * @param qo 根据需要进行传值 + * @return + */ + List getData(Dp2ViewWirelessAlarmQO qo); + + /** + * 分页列表 + * @param qo 根据需要进行传值 + * @return + */ + public PageInfo getDataByPage(Dp2ViewWirelessAlarmQO qo); + + /** + * 详情 + * @param id + * @return + */ + Dp2ViewWirelessAlarmVO fetchById(Long id); + + /** + * 新增或修改 + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(Dp2ViewWirelessAlarmDTO dto); + + /** + * 删除(单个条目) + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * 批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * 导出 + * @param qo + * @return + */ + void export(Dp2ViewWirelessAlarmQO qo); + + /** + * 导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/DpSceneConfigService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/DpSceneConfigService.java new file mode 100644 index 0000000..811df21 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/DpSceneConfigService.java @@ -0,0 +1,86 @@ +package com.ruoyi.eastcom_yw.service; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.DpSceneConfig; +import com.ruoyi.eastcom_yw.domain.dto.DpSceneConfigDTO; +import com.ruoyi.eastcom_yw.domain.qo.DpSceneConfigQO; +import com.ruoyi.eastcom_yw.domain.vo.DpSceneConfigVO; + +import java.util.List; + +/** +*

+ * 服务类 + *

+* +* @author yqf +* @since 2023-04-12 +*/ +public interface DpSceneConfigService extends IService { + + /** + * 列表 + * @param qo 根据需要进行传值 + * @return + */ + List getData(DpSceneConfigQO qo); + + /** + * 分页列表 + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(DpSceneConfigQO qo); + + /** + * 详情 + * @param id + * @return + */ + DpSceneConfigVO fetchById(Long id); + + /** + * 新增或修改 + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(DpSceneConfigDTO dto); + + /** + * 删除(单个条目) + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * 批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * 导出 + * @param qo + * @return + */ + void export(DpSceneConfigQO qo); + + /** + * 导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); + + List listColor(); + + List listKpiName(); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/HmAlarmDeriveService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/HmAlarmDeriveService.java new file mode 100644 index 0000000..1657f00 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/HmAlarmDeriveService.java @@ -0,0 +1,23 @@ +package com.ruoyi.eastcom_yw.service; + +import com.ruoyi.eastcom_yw.domain.HmAlarmDerive; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmVo; + +import java.util.List; + +/** + *

+ * 服务类 + *

+ * + * @author jkj + * @since 2023-08-02 + */ +public interface HmAlarmDeriveService extends IService { + + List getAlarmDerive(YwAlarmDTO alarmDTO); + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/LargeScreenService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/LargeScreenService.java new file mode 100644 index 0000000..a07108a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/LargeScreenService.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.service; + +import com.ruoyi.eastcom_yw.domain.model.AppEntity; +import com.ruoyi.eastcom_yw.domain.vo.*; + +import java.util.List; + +public interface LargeScreenService { + List getTaskManageList(); + + List getMatchList(); + + List getRaceScheduleList(); + + List getMedalList(); + + List getNewsList(); + + List getAlarmTopList(); + + List getAlarmStatisticsList(); + + boolean validate(String ip, AppEntity appEntity); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/OpenApiService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/OpenApiService.java new file mode 100644 index 0000000..30c43fb --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/OpenApiService.java @@ -0,0 +1,15 @@ +package com.ruoyi.eastcom_yw.service; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.dto.MmlObjectDTO; + +import java.util.List; + +/** + * @author yqf + * @date 2023/6/5 + */ +public interface OpenApiService { + + public AjaxResult getMsgByMML(MmlObjectDTO mmlObjectDTO); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi4gCellService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi4gCellService.java new file mode 100644 index 0000000..0a03e61 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi4gCellService.java @@ -0,0 +1,42 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.PmKpi4gCell; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellQO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi15MinCellVO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi4gCellVO; + +import java.util.List; +import java.util.Map; + +/** + * @author yqf + * @date 2023/4/11 + */ +public interface PmKpi4gCellService extends IService { + + /** + * 场馆4G小区级15分钟指标列表 + * @param qo 根据需要进行传值 + * @return + */ + List getData(PmKpiCellQO qo); + + /** + * 场馆4G小区级15分钟指标分页列表 + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(PmKpiCellQO qo); + + + /** + * 场馆4G小区级15分钟指标导出 + * @param qo + * @return + */ + void export(PmKpiCellQO qo); + + Map getLastTime(Long[] venueIds); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi4gMinService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi4gMinService.java new file mode 100644 index 0000000..8558a3e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi4gMinService.java @@ -0,0 +1,90 @@ +package com.ruoyi.eastcom_yw.service; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.PmKpi4gMin; +import com.ruoyi.eastcom_yw.domain.dto.PmKpi4gMinDTO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpi4gMinQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiMinQO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi4gMinVO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpiOneMinVO; + +import java.util.List; + +/** + *

+ * 场馆4G小区级1分钟指标 服务类 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +public interface PmKpi4gMinService extends IService { + + /** + * 场馆4G小区级1分钟指标列表 + * + * @param qo 根据需要进行传值 + * @return + */ + List getData(PmKpiMinQO qo); + + /** + * 场馆4G小区级1分钟指标分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(PmKpiMinQO qo); + + /** + * 场馆4G小区级1分钟指标详情 + * + * @param id + * @return + */ + PmKpi4gMinVO fetchById(Long id); + + /** + * 场馆4G小区级1分钟指标新增或修改 + * + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(PmKpi4gMinDTO dto); + + /** + * 场馆4G小区级1分钟指标删除(单个条目) + * + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * 场馆4G小区级1分钟指标批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * 场馆4G小区级1分钟指标导出 + * + * @param qo + * @return + */ + void export(PmKpiMinQO qo); + + /** + * 场馆4G小区级1分钟指标导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi4gVenueService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi4gVenueService.java new file mode 100644 index 0000000..8e6d11e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi4gVenueService.java @@ -0,0 +1,30 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.PmKpi4gVenue; +import com.ruoyi.eastcom_yw.domain.PmKpi5gCell; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiVenueQO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi4gVenueConvertVO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi4gVenueVO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi5gCellVO; + +import java.util.Map; + +/** + * @author yqf + * @date 2023/4/11 + */ +public interface PmKpi4gVenueService extends IService { + + + /** + * 4G场馆级15分钟指标分页列表 + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(PmKpiVenueQO qo); + + Map get4gVenueLastTime(Integer[] venueIds); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi5gCellService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi5gCellService.java new file mode 100644 index 0000000..821ed67 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi5gCellService.java @@ -0,0 +1,42 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.PmKpi5gCell; +import com.ruoyi.eastcom_yw.domain.qo.PmKpi5gCellQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellQO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi15MinCellVO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi4gCellVO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi5gCellVO; + +import java.util.List; + +/** + * @author yqf + * @date 2023/4/11 + */ +public interface PmKpi5gCellService extends IService { + + + /** + * 场馆5G小区级15分钟指标列表 + * @param qo 根据需要进行传值 + * @return + */ + List getData(PmKpiCellQO qo); + + /** + * 场馆5G小区级15分钟指标分页列表 + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(PmKpiCellQO qo); + + + /** + * 场馆5G小区级15分钟指标导出 + * @param qo + * @return + */ + void export(PmKpiCellQO qo); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi5gMinService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi5gMinService.java new file mode 100644 index 0000000..2f30602 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi5gMinService.java @@ -0,0 +1,84 @@ +package com.ruoyi.eastcom_yw.service; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.PmKpi5gMin; +import com.ruoyi.eastcom_yw.domain.dto.PmKpi5gMinDTO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpi5gMinQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiMinQO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi5gMinVO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpiOneMinVO; + +import java.util.List; + +/** +*

+ * 场馆5G小区级1分钟指标 服务类 + *

+* +* @author yqf +* @since 2023-04-12 +*/ +public interface PmKpi5gMinService extends IService { + + /** + * 场馆5G小区级1分钟指标列表 + * @param qo 根据需要进行传值 + * @return + */ + List getData(PmKpiMinQO qo); + + /** + * 场馆5G小区级1分钟指标分页列表 + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(PmKpiMinQO qo); + + /** + * 场馆5G小区级1分钟指标详情 + * @param id + * @return + */ + PmKpi5gMinVO fetchById(Long id); + + /** + * 场馆5G小区级1分钟指标新增或修改 + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(PmKpi5gMinDTO dto); + + /** + * 场馆5G小区级1分钟指标删除(单个条目) + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * 场馆5G小区级1分钟指标批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * 场馆5G小区级1分钟指标导出 + * @param qo + * @return + */ + void export(PmKpiMinQO qo); + + /** + * 场馆5G小区级1分钟指标导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi5gVenueService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi5gVenueService.java new file mode 100644 index 0000000..5417244 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpi5gVenueService.java @@ -0,0 +1,36 @@ +package com.ruoyi.eastcom_yw.service; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.eastcom_yw.domain.PmKpi5gVenue; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiVenueQO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi4gVenueConvertVO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi5gVenueVO; + +import java.util.List; +import java.util.Map; + +/** +*

+ * 5G场馆级15分钟指标 服务类 + *

+* +* @author yqf +* @since 2023-04-12 +*/ +public interface PmKpi5gVenueService extends IService { + + + /** + * 5G场馆级15分钟指标分页列表 + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(PmKpiVenueQO qo); + + Map get5gVenueLastTime(Integer[] venueIds); + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpiMonitorCellService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpiMonitorCellService.java new file mode 100644 index 0000000..5dfaeee --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/PmKpiMonitorCellService.java @@ -0,0 +1,38 @@ +package com.ruoyi.eastcom_yw.service; + +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.github.pagehelper.PageInfo; +import com.ruoyi.eastcom_yw.domain.qo.DpKpiMonitorQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellMonitorQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiMinQO; +import com.ruoyi.eastcom_yw.domain.vo.DpcSeneControlVo; +import com.ruoyi.eastcom_yw.domain.vo.KpiVenueReportVo; +import com.ruoyi.eastcom_yw.domain.vo.MonitorCellVo; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi15MinCellVO; + +import java.time.LocalDateTime; +import java.util.Map; + +/** + * @author yqf + * @date 2023/4/13 + */ +public interface PmKpiMonitorCellService { + + PageInfo getMonitorCellList(PmKpiCellMonitorQO qo); + + + PageInfo getDpMonitorCellList(DpKpiMonitorQO qo); + + int updateDpcSeneControl(DpcSeneControlVo dpcSeneControlVo); + + KpiVenueReportVo getReportKpi(Integer venueid, LocalDateTime starttime, LocalDateTime endtime, Integer minute); + + JSONObject getReportKpiByJson(Integer venueid, LocalDateTime starttime, LocalDateTime endtime, Integer minute); + + void exportMonitorList(PmKpiCellMonitorQO qo); + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/SysNoticeService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/SysNoticeService.java new file mode 100644 index 0000000..7adc604 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/SysNoticeService.java @@ -0,0 +1,106 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.SysNotice; +import com.ruoyi.eastcom_yw.domain.dto.SysNoticeDTO; +import com.ruoyi.eastcom_yw.domain.qo.SysNoticeQO; +import com.ruoyi.eastcom_yw.domain.vo.SysNoticeVO; + +import java.util.List; + +/** + *

+ * 通知公告表 服务类 + *

+ * + * @author ck + * @since 2023-04-14 + */ +public interface SysNoticeService extends IService { + + /** + * 通知公告表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + List getData(SysNoticeQO qo); + + /** + * 通知公告表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(SysNoticeQO qo); + + /** + * 通知公告表详情 + * + * @param id + * @return + */ + SysNoticeVO fetchById(Long id); + + /** + * 通知公告表新增或修改 + * + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(SysNoticeDTO dto); + + /** + * 通知公告表删除(单个条目) + * + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * 通知公告表批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * 通知公告表导出 + * + * @param qo + * @return + */ + void export(SysNoticeQO qo); + + /** + * 通知公告表导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); + + + + public int isReadNotice(Long[] noticeIds); + + /** + * 查询定时任务需要发送的短信 notice_type=3 add_flag=0 currentTime-5minute <=exp_send_time<=currentTime 五分钟之内 + * @return 结果 + */ + List selectToDoSMSList(); + + public void eastcomYwSendSMSSchedule(); + + public void newEastcomYwSendSMSSchedule(); + + public void send(List sysNotices); + + void saveAndSendBriefing(SysNoticeDTO dto); + + public List selectNoticeListByUser(Long reciveUserId); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/WeatherService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/WeatherService.java new file mode 100644 index 0000000..03106ea --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/WeatherService.java @@ -0,0 +1,11 @@ +package com.ruoyi.eastcom_yw.service; + +import com.ruoyi.common.core.domain.AjaxResult; + +public interface WeatherService { + + /** + * 获取场馆天气详情 + */ + public AjaxResult fetchById(Long venueId); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmCSService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmCSService.java new file mode 100644 index 0000000..80c6ada --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmCSService.java @@ -0,0 +1,21 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.eastcom_yw.domain.YwAlarmCS; +import com.ruoyi.eastcom_yw.domain.YwAlarmDH; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; + +/** + *

+ * 服务类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +public interface YwAlarmCSService extends IService { + + public TableDataInfo GetAlarmList(YwAlarmDTO alarmDTO); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmDHService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmDHService.java new file mode 100644 index 0000000..25e9e6e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmDHService.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.eastcom_yw.domain.YwAlarmDH; +import com.ruoyi.eastcom_yw.domain.YwAlarmView; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmInfoVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmNewNumVo; + +import java.util.List; + +/** + *

+ * 服务类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +public interface YwAlarmDHService extends IService { + + public TableDataInfo GetAlarmList(YwAlarmDTO alarmDTO); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmHangupLogService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmHangupLogService.java new file mode 100644 index 0000000..405a6ec --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmHangupLogService.java @@ -0,0 +1,20 @@ +package com.ruoyi.eastcom_yw.service; + +import com.ruoyi.eastcom_yw.domain.YwAlarmHangupLog; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmHangupLogDTO; + +/** + *

+ * 服务类 + *

+ * + * @author jkj + * @since 2023-02-15 + */ +public interface YwAlarmHangupLogService extends IService { + public boolean insertYwAlarmHangupLog(YwAlarmHangupLogDTO ywAlarmHangupLogDTO); + + public void updateAlarmHangupSchedule(); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmOprateLogService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmOprateLogService.java new file mode 100644 index 0000000..6ceda9d --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmOprateLogService.java @@ -0,0 +1,16 @@ +package com.ruoyi.eastcom_yw.service; + +import com.ruoyi.eastcom_yw.domain.YwAlarmOprateLog; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 服务类 + *

+ * + * @author jkj + * @since 2023-03-06 + */ +public interface YwAlarmOprateLogService extends IService { + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmService.java new file mode 100644 index 0000000..0174204 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmService.java @@ -0,0 +1,32 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.YwAlarm; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmQuestionVo; + +import java.util.List; + +/** + *

+ * 服务类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +public interface YwAlarmService extends IService { + public List getYwAlarmQuestionList(String specialty); + + public void YwAlarmAutoRecover(); + + /** + * 定时发送告警简报 + */ + void eastcomYwSendAlarmBriefingSchedule(); + + public boolean YwAlarmClear(YwAlarmDTO alarmDTO); + + public boolean YwAlarmClose(YwAlarmDTO alarmDTO); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmViewService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmViewService.java new file mode 100644 index 0000000..3d54707 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmViewService.java @@ -0,0 +1,55 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.eastcom_yw.domain.YwAlarmView; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTONoPage; +import com.ruoyi.eastcom_yw.domain.vo.*; + +import java.util.List; + +/** + *

+ * 服务类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +public interface YwAlarmViewService extends IService { + + public void insert_alarm_schedule(); + + + public void insert_alarmNotice_schedule(); + + public TableDataInfo GetAlarmList(YwAlarmDTO alarmDTO); + + + public List GetNewAlarmNum(Long userId); + + //管理员的角色不需要场馆的绑定 + public List GetNewAlarmNum(Long userId,Boolean isAdmin); + + public Long getYwAlarmNewNumByDto(YwAlarmDTO alarmDTO); + + public Long getYwAlarmNewNumByDto(YwAlarmDTONoPage alarmDTO); + + public List getYwAlarmByDto(YwAlarmDTO alarmDTO); + + public List GetAlarmInfoList(String processId); + + public List getYwAlarmInfoListByGroup(String groupId); + + public List GetAlarmInfoList(String processId,boolean isApp); + + public List getYwAlarmInfoListByGroup(String groupId,boolean isApp); + + public List getYwAlarmList(String alarmType,String venueName,String startTime,String endTime); + + public List getYwAlarmLessList(String alarmType,String groupId); + + public void updateAlarmLogEnd(String alarmType, Long group_id,Long userId); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmWXService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmWXService.java new file mode 100644 index 0000000..8c6e70c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwAlarmWXService.java @@ -0,0 +1,21 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.eastcom_yw.domain.YwAlarmDH; +import com.ruoyi.eastcom_yw.domain.YwAlarmWX; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; + +/** + *

+ * 服务类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +public interface YwAlarmWXService extends IService { + + public TableDataInfo GetAlarmList(YwAlarmDTO alarmDTO); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwDrsConfigService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwDrsConfigService.java new file mode 100644 index 0000000..08cb82c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwDrsConfigService.java @@ -0,0 +1,86 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.YwDrsConfig; +import com.ruoyi.eastcom_yw.domain.dto.YwDrsConfigDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwDrsConfigQO; +import com.ruoyi.eastcom_yw.domain.vo.YwDrsConfigVO; + +import java.util.List; + +/** + *

+ * DRS配置表 服务类 + *

+ * + * @author ck + * @since 2023-06-13 + */ +public interface YwDrsConfigService extends IService { + + /** + * DRS配置表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + List getData(YwDrsConfigQO qo); + + /** + * DRS配置表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + PageInfo getDataByPage(YwDrsConfigQO qo); + + /** + * DRS配置表详情 + * + * @param id + * @return + */ + YwDrsConfigVO fetchById(Long id); + + /** + * DRS配置表新增或修改 + * + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(YwDrsConfigDTO dto); + + /** + * DRS配置表删除(单个条目) + * + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * DRS配置表批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * DRS配置表导出 + * + * @param qo + * @return + */ + void export(YwDrsConfigQO qo); + + /** + * DRS配置表导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwDrsTempTaskService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwDrsTempTaskService.java new file mode 100644 index 0000000..69ce32a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwDrsTempTaskService.java @@ -0,0 +1,89 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.YwDrsTempTask; +import com.ruoyi.eastcom_yw.domain.dto.YwDrsTempTaskDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwDrsTempTaskQO; +import com.ruoyi.eastcom_yw.domain.vo.YwDrsTempTaskVO; + +import java.time.LocalDate; +import java.util.List; + +/** + *

+ * DRS临时任务表 服务类 + *

+ * + * @author ck + * @since 2023-06-13 + */ +public interface YwDrsTempTaskService extends IService { + + /** + * DRS临时任务表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + List getData(YwDrsTempTaskQO qo); + + /** + * DRS临时任务表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + PageInfo getDataByPage(YwDrsTempTaskQO qo); + + /** + * DRS临时任务表详情 + * + * @param id + * @return + */ + YwDrsTempTaskVO fetchById(Long id); + + /** + * DRS临时任务表新增或修改 + * + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(YwDrsTempTaskDTO dto); + + /** + * DRS临时任务表删除(单个条目) + * + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * DRS临时任务表批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * DRS临时任务表导出 + * + * @param qo + * @return + */ + void export(YwDrsTempTaskQO qo); + + /** + * DRS临时任务表导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); + + List drsPreview(Long venueId, LocalDate date); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwKpiConfigService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwKpiConfigService.java new file mode 100644 index 0000000..6c1435d --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwKpiConfigService.java @@ -0,0 +1,82 @@ +package com.ruoyi.eastcom_yw.service; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.YwKpiConfig; +import com.ruoyi.eastcom_yw.domain.dto.YwKpiConfigDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwKpiConfigQO; +import com.ruoyi.eastcom_yw.domain.vo.YwKpiConfigVO; + +import java.util.List; + +/** +*

+ * 指标字段阈值配置表 服务类 + *

+* +* @author yqf +* @since 2023-04-11 +*/ +public interface YwKpiConfigService extends IService { + + /** + * 指标字段阈值配置表列表 + * @param qo 根据需要进行传值 + * @return + */ + List getData(YwKpiConfigQO qo); + + /** + * 指标字段阈值配置表分页列表 + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(YwKpiConfigQO qo); + + /** + * 指标字段阈值配置表详情 + * @param id + * @return + */ + YwKpiConfigVO fetchById(Long id); + + /** + * 指标字段阈值配置表新增或修改 + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(YwKpiConfigDTO dto); + + /** + * 指标字段阈值配置表删除(单个条目) + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * 指标字段阈值配置表批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * 指标字段阈值配置表导出 + * @param qo + * @return + */ + void export(YwKpiConfigQO qo); + + /** + * 指标字段阈值配置表导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeBriefingService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeBriefingService.java new file mode 100644 index 0000000..f6ddbeb --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeBriefingService.java @@ -0,0 +1,152 @@ +package com.ruoyi.eastcom_yw.service; + + +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.YwNoticeBriefing; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeBriefingDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeBriefingQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeBriefingVO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeModelVO; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知通告简报计划表 服务类 + *

+ * + * @author ck + * @since 2023-04-11 + */ +public interface YwNoticeBriefingService extends IService { + + /** + * 通知通告简报计划表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + List getData(YwNoticeBriefingQO qo); + + /** + * 通知通告简报计划表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(YwNoticeBriefingQO qo); + + /** + * 通知通告简报计划表详情 + * + * @param id + * @return + */ + YwNoticeBriefingVO fetchById(Long id); + + /** + * 通知通告简报计划表新增或修改 + * + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(YwNoticeBriefingDTO dto); + + /** + * 通知通告简报计划表删除(单个条目) + * + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * 通知通告简报计划表批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * 通知通告简报计划表导出 + * + * @param qo + * @return + */ + void export(YwNoticeBriefingQO qo); + + /** + * 通知通告简报计划表导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); + + /** + * 定时发送简报 + * + * @param + * @return + */ + void eastcomYwSendBriefingSchedule(); + + /** + * 自动切换发送方式定时任务 + * + * @param + * @return + */ + void eastcomYwUpdateBriefingSendTypeSchedule(); + + /** + * 保存json到本地 + */ + JSONObject getJson(Long venueId,Integer timeInterval); + + /** + * 组装场馆级简报 + * + * @param + * @return + */ + String assemblyVenueBriefing(LocalDateTime sendTime,Long venueId,Integer timeInterval,Long modelId); + + /** + * 组装场馆级简报JSON + */ + String assemblyVenueJsonToGetURL(LocalDateTime sendTime, Long venueId, Integer timeInterval); + + /** + * 组装区县级简报JSON + */ + String assemblyCountyJsonToGetURL(LocalDateTime sendTime, Long venueId, Integer timeInterval); + + /** + * 组装地市级简报JSON + */ + String assemblyCityJsonToGetURL(LocalDateTime sendTime, Long venueId, Integer timeInterval); + + /** + * 组装地市级简报 + * + * @param + * @return + */ + String assemblyCityBriefing(LocalDateTime sendTime,String city,Integer timeInterval,Long modelId); + + /** + * 组装区县级简报 + * + * @param + * @return + */ + String assemblyCountyBriefing(LocalDateTime sendTime,String city,Integer timeInterval); + + List getModel(Long venueId,String modelSuitType); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeHandworkService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeHandworkService.java new file mode 100644 index 0000000..068692e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeHandworkService.java @@ -0,0 +1,92 @@ +package com.ruoyi.eastcom_yw.service; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.YwNoticeHandwork; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeHandworkDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeHandworkQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeHandworkVO; + +import java.util.List; + +/** + *

+ * 通知通告手工通知计划表 服务类 + *

+ * + * @author ck + * @since 2023-04-11 + */ +public interface YwNoticeHandworkService extends IService { + + /** + * 通知通告手工通知计划表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + List getData(YwNoticeHandworkQO qo); + + /** + * 通知通告手工通知计划表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(YwNoticeHandworkQO qo); + + /** + * 通知通告手工通知计划表详情 + * + * @param id + * @return + */ + YwNoticeHandworkVO fetchById(Long id); + + /** + * 通知通告手工通知计划表新增或修改 + * + * @param dto 根据需要进行传值 + * @return + */ + Long saveOrUpdate(YwNoticeHandworkDTO dto); + + /** + * 通知通告手工通知计划表删除(单个条目) + * + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * 通知通告手工通知计划表批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * 通知通告手工通知计划表导出 + * + * @param qo + * @return + */ + void export(YwNoticeHandworkQO qo); + + /** + * 通知通告手工通知计划表导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); + + /** + * 查询审核通过的手工通知添加到sys_notice等待发送 + */ + void eastcomSelectPassAndAddNoticeSchedule(); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeHandworkdetailService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeHandworkdetailService.java new file mode 100644 index 0000000..83eaef2 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeHandworkdetailService.java @@ -0,0 +1,87 @@ +package com.ruoyi.eastcom_yw.service; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.YwNoticeHandworkdetail; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeHandworkdetailDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeHandworkdetailQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeHandworkdetailVO; + +import java.util.List; + +/** + *

+ * 通知通告手工通知审核表 服务类 + *

+ * + * @author ck + * @since 2023-04-11 + */ +public interface YwNoticeHandworkdetailService extends IService { + + /** + * 通知通告手工通知审核表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + List getData(YwNoticeHandworkdetailQO qo); + + /** + * 通知通告手工通知审核表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(YwNoticeHandworkdetailQO qo); + + /** + * 通知通告手工通知审核表详情 + * + * @param id + * @return + */ + YwNoticeHandworkdetailVO fetchById(Long id); + + /** + * 通知通告手工通知审核表新增或修改 + * + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(YwNoticeHandworkdetailDTO dto); + + /** + * 通知通告手工通知审核表删除(单个条目) + * + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * 通知通告手工通知审核表批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * 通知通告手工通知审核表导出 + * + * @param qo + * @return + */ + void export(YwNoticeHandworkdetailQO qo); + + /** + * 通知通告手工通知审核表导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeListService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeListService.java new file mode 100644 index 0000000..f326dcd --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeListService.java @@ -0,0 +1,87 @@ +package com.ruoyi.eastcom_yw.service; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.YwNoticeList; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeListDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeListQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeListVO; + +import java.util.List; + +/** + *

+ * 通知通告记录表 服务类 + *

+ * + * @author ck + * @since 2023-04-11 + */ +public interface YwNoticeListService extends IService { + + /** + * 通知通告记录表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + List getData(YwNoticeListQO qo); + + /** + * 通知通告记录表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(YwNoticeListQO qo); + + /** + * 通知通告记录表详情 + * + * @param id + * @return + */ + YwNoticeListVO fetchById(Long id); + + /** + * 通知通告记录表新增或修改 + * + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(YwNoticeListDTO dto); + + /** + * 通知通告记录表删除(单个条目) + * + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * 通知通告记录表批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * 通知通告记录表导出 + * + * @param qo + * @return + */ + void export(YwNoticeListQO qo); + + /** + * 通知通告记录表导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeModelService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeModelService.java new file mode 100644 index 0000000..7d64b6b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeModelService.java @@ -0,0 +1,88 @@ +package com.ruoyi.eastcom_yw.service; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.YwNoticeModel; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeModelDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeModelQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeModelVO; + +import java.util.List; + +/** + *

+ * 通知通告模板表 服务类 + *

+ * + * @author ck + * @since 2023-04-07 + */ +public interface YwNoticeModelService extends IService { + + /** + * 通知通告模板表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + List getData(YwNoticeModelQO qo); + + /** + * 通知通告模板表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(YwNoticeModelQO qo); + + /** + * 通知通告模板表详情 + * + * @param id + * @return + */ + YwNoticeModelVO fetchById(Long id); + + /** + * 通知通告模板表新增或修改 + * + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(YwNoticeModelDTO dto); + + /** + * 通知通告模板表删除(单个条目) + * + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * 通知通告模板表批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * 通知通告模板表导出 + * + * @param qo + * @return + */ + void export(YwNoticeModelQO qo); + + /** + * 通知通告模板表导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeObjectService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeObjectService.java new file mode 100644 index 0000000..a71a71a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeObjectService.java @@ -0,0 +1,95 @@ +package com.ruoyi.eastcom_yw.service; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.YwNoticeObject; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeObjectDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeObjectQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeObjectVO; + +import java.util.List; +import java.util.Map; + +/** + *

+ * 通知通告对象表 服务类 + *

+ * + * @author ck + * @since 2023-04-11 + */ +public interface YwNoticeObjectService extends IService { + + /** + * 通知通告对象表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + List getData(YwNoticeObjectQO qo); + + /** + * 通知通告对象表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(YwNoticeObjectQO qo); + + /** + * 通知通告对象表ByIds + */ + List fetchByIds(List ids); + + /** + * 通知通告对象表详情 + * + * @param id + * @return + */ + YwNoticeObjectVO fetchById(Long id); + + /** + * 通知通告对象表新增或修改 + * + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(YwNoticeObjectDTO dto); + + /** + * 通知通告对象表删除(单个条目) + * + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * 通知通告对象表批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * 通知通告对象表导出 + * + * @param qo + * @return + */ + void export(YwNoticeObjectQO qo); + + /** + * 通知通告对象表导入 + * + * @param + * @return + */ + AjaxResult importData(List list, boolean updateSupport); + + Map allObject(); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeUserService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeUserService.java new file mode 100644 index 0000000..5743c5f --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwNoticeUserService.java @@ -0,0 +1,22 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.YwNoticeUser; + +import java.util.List; + +/** + *

+ * 服务类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +public interface YwNoticeUserService extends IService { + + public List getYwNoticeUserList(String flwId,String taskId,String groupId,String type); + + public boolean noticeYW(String flwId,String groupId,String type); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectConfigService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectConfigService.java new file mode 100644 index 0000000..d380e9d --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectConfigService.java @@ -0,0 +1,17 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectConfig; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectConfigParam; + +import java.util.List; + +/** + * @author huamile + * @date 2023/1/18 15:28 + **/ +public interface YwRoutInspectConfigService extends IService { + + List getInspectConfigList(YwRoutInspectConfigParam param); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectLogService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectLogService.java new file mode 100644 index 0000000..84d5e2d --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectLogService.java @@ -0,0 +1,12 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectLog; + +/** + * @author huamile + */ +public interface YwRoutInspectLogService extends IService { + + void updateLog(YwRoutInspectLog log); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectPlanService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectPlanService.java new file mode 100644 index 0000000..c15b689 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectPlanService.java @@ -0,0 +1,93 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectPlan; +import com.ruoyi.eastcom_yw.domain.dto.YwInspectStatDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwInspectTaskDTO; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectConfigParam; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectPlanParam; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectStatParam; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmInfoVo; +import com.ruoyi.eastcom_yw.domain.vo.YwInspectLogVo; +import com.ruoyi.eastcom_yw.domain.vo.YwInspectPlanStaticVo; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.text.ParseException; +import java.util.List; +import java.util.Map; + +/** + * @author huamile + * @date 2023/1/17 16:05 + **/ +public interface YwRoutInspectPlanService extends IService { + + /** + * 将到点的巡检计划加入工作流中 + */ + void insetInspectSchedule(); + + /** + * 根据条件获取巡检计划列表,一个工单号一条记录 + * @param param 场馆,时间 + * @return + */ + List getList(YwRoutInspectConfigParam param); + + TableDataInfo getPlanList(YwRoutInspectPlanParam param); + + /** + * 根据条件获取巡检统计结果 + * @param param 地市,区县,场馆,专业 + * @return + */ + Map getStatData(YwRoutInspectStatParam param); + + /** + * 根据条件获取巡检统计列表 + * @param param 地市,区县,场馆,专业 + * @return + */ + Map getStatListData(YwRoutInspectStatParam param); + + /** + * 根据条件获取巡检统计结果 + * @param param 地市,区县,场馆,专业 + * @return + */ + Map getResultStatData(YwRoutInspectStatParam param); + + /** + * 根据条件获取巡检统计列表 + * @param param 地市,区县,场馆,专业 + * @return + */ + Map getResultStatListData(YwRoutInspectStatParam param); + + public List getRoutInspectInfoList(String processId); + + /** + * 创建巡检任务 + * @param dto + */ + AjaxResult create(YwInspectTaskDTO dto) throws Exception; + + /** + * 编辑巡检任务 + * @param dto + */ + void updatePlan(YwInspectTaskDTO dto) throws Exception; + + void export(YwRoutInspectConfigParam param, HttpServletRequest request, HttpServletResponse response); + + void planExport(YwRoutInspectPlanParam param, HttpServletRequest request, HttpServletResponse response); + + List mergeResultStat(YwRoutInspectStatParam param); + + boolean checkPlanStatus(String dto); + + List getInspectPlanStatic(YwRoutInspectStatParam param); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectQuestionConfigService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectQuestionConfigService.java new file mode 100644 index 0000000..ac07a22 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwRoutInspectQuestionConfigService.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectQuestionConfig; +import com.ruoyi.eastcom_yw.domain.param.YwInspectQuestionConfigParam; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author huamile + * @date 2023/2/4 16:50 + **/ +public interface YwRoutInspectQuestionConfigService extends IService { + + List getlist(YwInspectQuestionConfigParam param); + + Integer create(YwRoutInspectQuestionConfig ywRoutInspectQuestionConfig); + + Integer updateByPrimaryKeySelective(YwRoutInspectQuestionConfig ywRoutInspectQuestionConfig); + + void export(YwInspectQuestionConfigParam param, HttpServletRequest request, HttpServletResponse response); + + List appList(YwInspectQuestionConfigParam param); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneAlarmService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneAlarmService.java new file mode 100644 index 0000000..bfddc21 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneAlarmService.java @@ -0,0 +1,30 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.YwSceneAlarm; +import com.ruoyi.eastcom_yw.domain.param.YwSceneAlarmParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneAlarmVo; +import org.apache.ibatis.annotations.Param; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author huamile + */ +public interface YwSceneAlarmService extends IService { + + List getList(YwSceneAlarmParam param); + + List getListBySceneBigId(Long sceneBigId); + + Integer create(YwSceneAlarm ywSceneAlarm); + + Integer updateByPrimaryKeySelective(YwSceneAlarm ywSceneAlarm); + + Integer delBySceneIds(List ids); + + void export(YwSceneAlarmParam param, HttpServletRequest request, HttpServletResponse response); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneCalendarService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneCalendarService.java new file mode 100644 index 0000000..1a0afdb --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneCalendarService.java @@ -0,0 +1,35 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.YwSceneCalendar; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneCalendarDTO; +import com.ruoyi.eastcom_yw.domain.param.YwSceneCalendarParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneCalendar2Vo; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneCalendarVo; +import org.apache.ibatis.annotations.Param; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.text.ParseException; +import java.util.List; + +/** + * @author huamile + */ +public interface YwSceneCalendarService extends IService { + + List getList(YwSceneCalendarParam param); + + List getListBySceneBigId(Long sceneBigId); + + Integer create(YwSceneCalendarDTO dto); + + Integer updateByPrimaryKeySelective(YwSceneCalendarDTO dto); + + Integer delBySceneIds(List ids); + + void export(YwSceneCalendarParam param, HttpServletRequest request, HttpServletResponse response); + + AjaxResult importSceneCalendar(List vos, Long sceneBigId, String importType) throws Exception; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneMatchService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneMatchService.java new file mode 100644 index 0000000..3dc46ee --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneMatchService.java @@ -0,0 +1,33 @@ +package com.ruoyi.eastcom_yw.service; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.param.YwSceneMatchParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneMatchVo; + +import java.text.ParseException; +import java.util.List; + +/** + * @author los + */ +public interface YwSceneMatchService { + + /** + * 导入赛程 + * + * @param vos + * @param sceneBigId + * @param importType + * @return + * @throws ParseException + */ + AjaxResult importMatch(List vos, Long sceneBigId, String importType) throws Exception; + + /** + * 查询赛程 + * + * @param param + * @return + */ + List list(YwSceneMatchParam param); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementAgisService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementAgisService.java new file mode 100644 index 0000000..0dadc4c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementAgisService.java @@ -0,0 +1,34 @@ +package com.ruoyi.eastcom_yw.service; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementAgisParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementAgis; + +import java.util.List; + +/** + * @author huamile + * @date 2023/2/14 14:54 + **/ +public interface YwSceneNetelementAgisService { + + /** + * 导入 + * + * @param cs 数据 + * @param sceneBigId 大场景id + * @param opType 导入类型 + * @param sceneId + * @return + * @throws Exception + */ + AjaxResult importAgis(List cs, Long sceneBigId, String opType, String sceneId) throws Exception; + + /** + * 列表 + * + * @param para + * @return + */ + List list(YwSceneNetelementAgisParam para); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementCsService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementCsService.java new file mode 100644 index 0000000..5263329 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementCsService.java @@ -0,0 +1,32 @@ +package com.ruoyi.eastcom_yw.service; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementCsParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementCs; + +import java.util.List; + +/** + * @author huamile + * @date 2023/2/14 14:54 + **/ +public interface YwSceneNetelementCsService { + + /** + * 导入 + * + * @param cs + * @param sceneBigId + * @param opType + * @param sceneId + * @return + */ + AjaxResult importCs(List cs, Long sceneBigId, String opType, String sceneId) throws Exception; + + /** + * 列表 + * @param param + * @return + */ + List list(YwSceneNetelementCsParam param); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementDhService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementDhService.java new file mode 100644 index 0000000..eecef4b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementDhService.java @@ -0,0 +1,32 @@ +package com.ruoyi.eastcom_yw.service; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementDhParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementDh; + +import java.util.List; + +/** + * @author huamile + * @date 2023/2/14 14:54 + **/ +public interface YwSceneNetelementDhService { + + /** + * 导入 + * + * @param cs + * @param sceneBigId + * @param opType + * @param sceneId + * @return + */ + AjaxResult importDh(List cs, Long sceneBigId, String opType, String sceneId) throws Exception; + + /** + * 列表 + * @param para + * @return + */ + List list(YwSceneNetelementDhParam para); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementService.java new file mode 100644 index 0000000..ceac8d7 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementService.java @@ -0,0 +1,30 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.YwSceneNetelement; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementParam; +import org.apache.ibatis.annotations.Param; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author huamile + * @date 2023/2/14 14:54 + **/ +public interface YwSceneNetelementService extends IService { + + List getList(YwSceneNetelementParam param); + + List getListBySceneBigId(Long sceneBigId); + + Integer create(YwSceneNetelement ywSceneNetelement); + + Integer updateByPrimaryKeySelective(YwSceneNetelement ywSceneNetelement); + + Integer delBySceneIds(List ids); + + void export(YwSceneNetelementParam param, HttpServletRequest request, HttpServletResponse response); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementWxService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementWxService.java new file mode 100644 index 0000000..2be6f36 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNetelementWxService.java @@ -0,0 +1,39 @@ +package com.ruoyi.eastcom_yw.service; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementWxParam; +import com.ruoyi.eastcom_yw.domain.vo.WholeAreaAssureCellSheet; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementWx; + +import java.util.List; + +/** + * @author huamile + * @date 2023/2/14 14:54 + **/ +public interface YwSceneNetelementWxService { + + /** + * 导入 + * + * @param cs + * @param sceneBigId + * @param optType + * @param sceneId + * @return + */ + AjaxResult importWx(List cs, Long sceneBigId, String optType, String sceneId) throws Exception; + + /** + * 列表 + * @param para + * @return + */ + List list(YwSceneNetelementWxParam para); + + List list2(YwSceneNetelementWxParam para); + + List listCell(YwSceneNetelementWxParam param); + + List listSeat(Long sceneId); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNoticeinfoService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNoticeinfoService.java new file mode 100644 index 0000000..b763d03 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneNoticeinfoService.java @@ -0,0 +1,39 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneNoticeinfoSearchDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNoticeinfo; + +import java.util.List; + +/** + * (YwSceneNoticeinfo)表服务接口 + * + * @author lee + * @since 2023-05-23 10:10:40 + */ +public interface YwSceneNoticeinfoService extends IService { + + /** + * 通过条件查询 + * + * @param ywSceneNoticeinfo 条件 + * @return 数据 + */ + List getNoticeinfoBySearch(YwSceneNoticeinfoSearchDTO ywSceneNoticeinfo); + + /** + * 批量导入 + * + * @param ywSceneNoticeinfos 数据 + * @param importType 导入模式 + * @return 导入结果 + */ + AjaxResult batchImport(List ywSceneNoticeinfos, String importType) throws Exception; + + void reset(Boolean isNet); + + void statisticsNetNum(); +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwScenePictureService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwScenePictureService.java new file mode 100644 index 0000000..786275f --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwScenePictureService.java @@ -0,0 +1,71 @@ +package com.ruoyi.eastcom_yw.service; + +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.core.domain.AjaxResult; + +import java.util.Map; + +/** + * @author los + */ +public interface YwScenePictureService { + + /** + * 任务管理 + * + * @param id 场馆id + * @return 统计数据 + */ + JSONObject listTaskManage(Long id); + + /** + * 人员签到 + * + * @param id 场馆id + * @return 统计数据 + */ + JSONObject listSign(Long id); + + /** + * 场馆基本信息 + * + * @param id 场馆id + * @return 统计数据 + */ + JSONObject listMatchTop3(Long id); + + /** + * 场馆告警 + * + * @param id 场馆id + * @return 统计数据 + */ + JSONObject listAlarm(Long id); + + /** + * 场馆性能(15分粒度) + * + * @param id 场馆id + * @param typeId 45g + * @return 统计数据 + */ + JSONObject listKPI(Long id, String typeId); + + Map listKPIALL(Long id); + + AjaxResult listNetKpi(Long id, Integer type); + + AjaxResult listTransKpi(Long id, Integer type); + + JSONObject getAlarmTopDetail(Long id); + + void generateAlarmStatisticsEvery5Minutes(); + + /** + * 中小屏场馆画像-巡检统计数据 + * + * @param id 场馆id + * @return + */ + JSONObject listTaskManage2(Long id,Boolean taskFlag); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneService.java new file mode 100644 index 0000000..7b7d856 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneService.java @@ -0,0 +1,78 @@ +package com.ruoyi.eastcom_yw.service; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.YwSceneView; +import com.ruoyi.eastcom_yw.domain.dto.YwDataDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneDTO; +import com.ruoyi.eastcom_yw.domain.param.YwSceneParam; +import com.ruoyi.eastcom_yw.domain.vo.SceneBaseStation; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneRedisVO; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneVo; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; +import java.util.List; + +/** + *

+ * 服务类 + *

+ * + * @author jkj + * @since 2023-01-12 + */ +public interface YwSceneService extends IService { + + + void loadingVenueCache(); + + public List selectVenues(); + + Object validateUserVenues(Object o,Class clazz,String targetName); + + /** + * 根据大场景id获取场馆 + * + * @param sceneBigId 大场景id + * @return 场馆 + */ + public List getVenueByBigId(Long sceneBigId); + + public List getVenueByUser(SysUser user); + + public List getVenueByUserCanNoData(SysUser user,Boolean display); + + public List getVenueByUser(SysUser user, Long sceneBigId); + + public List getSysUserByVenueAndOther(YwDataDTO ywDataDTO); + + List msgList(YwSceneParam param); + + void create(YwSceneDTO dto); + + void updateByPrimaryKeySelective(YwSceneDTO dto); + + void delByIds(List ids); + + void export(YwSceneParam param, HttpServletRequest request, HttpServletResponse response); + + void bigSceneExport(Long sceneBigId, HttpServletRequest request, HttpServletResponse response); + + void exportTemplate(HttpServletRequest request, HttpServletResponse response); + + void importSceneBigConfig(MultipartFile file) throws Exception; + + AjaxResult importYWScene(List list, Long sceneBigId, String importType) throws Exception; + + void exportReal(YwSceneParam param, HttpServletRequest request, HttpServletResponse response); + + void importStationByScene(MultipartFile multipartFile, Long sceneBigId, Long sceneId); + + void getJsonBySceneId(Long sceneId,HttpServletResponse response)throws Exception; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneTestDataService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneTestDataService.java new file mode 100644 index 0000000..7a30bed --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneTestDataService.java @@ -0,0 +1,13 @@ +package com.ruoyi.eastcom_yw.service; + +import com.alibaba.fastjson2.JSONObject; + +import java.util.List; + +public interface YwSceneTestDataService { + + void insertTestData(); + + List getList(); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneUserService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneUserService.java new file mode 100644 index 0000000..5ba1bac --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSceneUserService.java @@ -0,0 +1,44 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.SysUserImp; +import com.ruoyi.eastcom_yw.domain.YwSceneUser; +import com.ruoyi.eastcom_yw.domain.param.SysUserParam; +import com.ruoyi.eastcom_yw.domain.vo.SysUserVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneUserVo; +import com.ruoyi.eastcom_yw.domain.param.YwSceneUserParam; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author huamile + */ +public interface YwSceneUserService extends IService { + + List getList(YwSceneUserParam param); + + List getVenuesByUserId(Long userId); + + List getVenuesByUserIds(List userIds); + + List getListBySceneBigId(Long sceneBigId); + + void create(YwSceneUser ywSceneUser); + + void delete(Long userId); + + void updateByPrimaryKeySelective(YwSceneUser ywSceneUser); + + Integer delBySceneIds(List ids); + + void export(YwSceneUserParam param, HttpServletRequest request, HttpServletResponse response); + + AjaxResult importSysUser(List imps, Long sceneBigId, String importType) throws Exception; + + List listSysUser(SysUserParam para); + + void exportForImport(SysUserParam para, HttpServletRequest request, HttpServletResponse response); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSignLogService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSignLogService.java new file mode 100644 index 0000000..689ece6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSignLogService.java @@ -0,0 +1,15 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.YwSignLog; +import com.ruoyi.eastcom_yw.domain.dto.YwSignDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSignInDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwSignVo; + +public interface YwSignLogService extends IService { + void SignIn(YwSignInDTO ywSignInDTO); + YwSignVo couldSign(YwSignDTO ywSignDTO); + Boolean sign(YwSignDTO ywSignDTO); + Boolean signTest(YwSignDTO ywSignDTO); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSignLogViewService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSignLogViewService.java new file mode 100644 index 0000000..2e91c40 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSignLogViewService.java @@ -0,0 +1,24 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.eastcom_yw.domain.YwSignLogView; +import com.ruoyi.eastcom_yw.domain.dto.YwSignLogDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwSignLogStaticVo; + +import java.util.List; + +public interface YwSignLogViewService extends IService { + + TableDataInfo getSignLog(YwSignLogDTO ywSignLogDTO); + + + List getSignLogStatic(YwSignLogDTO ywSignLogDTO); + + List getSignLogAndPlan(Long venueId); + + List getSignLogByPlanId(Long signPlanId); + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSignPlanService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSignPlanService.java new file mode 100644 index 0000000..77d6424 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSignPlanService.java @@ -0,0 +1,30 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.eastcom_yw.domain.YwSignPlanView; +import com.ruoyi.eastcom_yw.domain.dto.YwSignPlanDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwSignPlanVo; + +import java.text.ParseException; +import java.util.List; + +public interface YwSignPlanService extends IService { + + TableDataInfo getSignPlan(YwSignPlanDTO ywSignPlanDTO); + + public boolean insertSignPlan(YwSignPlanDTO ywSignPlanDTO); + + public AjaxResult importSignPlan(List signPlanList, Boolean isUpdateSupport, Long sceneBigId) throws ParseException; + + public boolean updateSignPlan(YwSignPlanDTO ywSignPlanDTO); + + public boolean deleteSignPlan(Long id); + + public YwSignPlanVo handleYwSignPlan(YwSignPlanView ywSignPlanView); + + public List getSignPlan(Long venueId,String signDate); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSparePartsService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSparePartsService.java new file mode 100644 index 0000000..926fd21 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwSparePartsService.java @@ -0,0 +1,88 @@ +package com.ruoyi.eastcom_yw.service; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.YwSpareParts; +import com.ruoyi.eastcom_yw.domain.dto.YwSparePartsDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwSparePartsQO; +import com.ruoyi.eastcom_yw.domain.vo.YwSparePartsVO; + +import java.util.List; + +/** + *

+ * 亚运备件表 服务类 + *

+ * + * @author yqf + * @since 2023-08-31 + */ +public interface YwSparePartsService extends IService { + + /** + * 亚运备件表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + List getData(YwSparePartsQO qo); + + /** + * 亚运备件表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + IPage getDataByPage(YwSparePartsQO qo); + + /** + * 亚运备件表详情 + * + * @param id + * @return + */ + YwSparePartsVO fetchById(Long id); + + /** + * 亚运备件表新增或修改 + * + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(YwSparePartsDTO dto); + + /** + * 亚运备件表删除(单个条目) + * + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * 亚运备件表批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * 亚运备件表导出 + * + * @param qo + * @return + */ + void export(YwSparePartsQO qo); + + /** + * 亚运备件表导入 + * + * @param + * @return + */ + AjaxResult importData(List list) throws Exception ; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwWireTaskLogService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwWireTaskLogService.java new file mode 100644 index 0000000..3c98b7f --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/YwWireTaskLogService.java @@ -0,0 +1,30 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.eastcom_yw.domain.YwWireTaskLog; +import com.ruoyi.eastcom_yw.domain.dto.YwSignInDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSignLogDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwWireTaskLogDTO; + +/** + *

+ * 服务类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +public interface YwWireTaskLogService extends IService { + + Boolean insertWireTaskLog(YwWireTaskLogDTO ywWireTaskLogDTO); + + String insertWireTaskLogReWireTaskId(YwWireTaskLogDTO ywWireTaskLogDTO); + + Boolean updateWireTaskLog(YwWireTaskLogDTO ywWireTaskLogDTO); + + Boolean deleteWireTaskLog(YwWireTaskLogDTO ywWireTaskLogDTO); + + TableDataInfo getWireTaskLog(YwWireTaskLogDTO ywWireTaskLogDTO); + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2SpotCellConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2SpotCellConvert.java new file mode 100644 index 0000000..b0369d6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2SpotCellConvert.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.service.convert; + +import com.ruoyi.eastcom_yw.domain.Dp2SpotCell; +import com.ruoyi.eastcom_yw.domain.dto.Dp2SpotCellDTO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2SpotCellVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface Dp2SpotCellConvert { + +Dp2SpotCellConvert INSTANCE = Mappers.getMapper(Dp2SpotCellConvert.class); + +Dp2SpotCell dtoToEntity(Dp2SpotCellDTO dto); + +Dp2SpotCellVO entityToVo(Dp2SpotCell entity); + +List entityToVoList(List entityList); + +Dp2SpotCellDTO entityToDto(Dp2SpotCell entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2SpotConfigConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2SpotConfigConvert.java new file mode 100644 index 0000000..59bc12b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2SpotConfigConvert.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.service.convert; + +import com.ruoyi.eastcom_yw.domain.Dp2SpotConfig; +import com.ruoyi.eastcom_yw.domain.dto.Dp2SpotConfigDTO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2SpotConfigVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface Dp2SpotConfigConvert { + +Dp2SpotConfigConvert INSTANCE = Mappers.getMapper(Dp2SpotConfigConvert.class); + +Dp2SpotConfig dtoToEntity(Dp2SpotConfigDTO dto); + +Dp2SpotConfigVO entityToVo(Dp2SpotConfig entity); + +List entityToVoList(List entityList); + +Dp2SpotConfigDTO entityToDto(Dp2SpotConfig entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2ViewPowerAlarmConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2ViewPowerAlarmConvert.java new file mode 100644 index 0000000..57e2ea3 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2ViewPowerAlarmConvert.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.service.convert; + +import com.ruoyi.eastcom_yw.domain.Dp2ViewPowerAlarm; +import com.ruoyi.eastcom_yw.domain.dto.Dp2ViewPowerAlarmDTO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2ViewPowerAlarmVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface Dp2ViewPowerAlarmConvert { + +Dp2ViewPowerAlarmConvert INSTANCE = Mappers.getMapper(Dp2ViewPowerAlarmConvert.class); + +Dp2ViewPowerAlarm dtoToEntity(Dp2ViewPowerAlarmDTO dto); + +Dp2ViewPowerAlarmVO entityToVo(Dp2ViewPowerAlarm entity); + +List entityToVoList(List entityList); + +Dp2ViewPowerAlarmDTO entityToDto(Dp2ViewPowerAlarm entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2ViewWirelessAlarmConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2ViewWirelessAlarmConvert.java new file mode 100644 index 0000000..2509278 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/Dp2ViewWirelessAlarmConvert.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.service.convert; + +import com.ruoyi.eastcom_yw.domain.Dp2ViewWirelessAlarm; +import com.ruoyi.eastcom_yw.domain.dto.Dp2ViewWirelessAlarmDTO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2ViewWirelessAlarmVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface Dp2ViewWirelessAlarmConvert { + +Dp2ViewWirelessAlarmConvert INSTANCE = Mappers.getMapper(Dp2ViewWirelessAlarmConvert.class); + +Dp2ViewWirelessAlarm dtoToEntity(Dp2ViewWirelessAlarmDTO dto); + +Dp2ViewWirelessAlarmVO entityToVo(Dp2ViewWirelessAlarm entity); + +List entityToVoList(List entityList); + +Dp2ViewWirelessAlarmDTO entityToDto(Dp2ViewWirelessAlarm entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/DpSceneConfigConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/DpSceneConfigConvert.java new file mode 100644 index 0000000..472b29a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/DpSceneConfigConvert.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.service.convert; + + +import com.ruoyi.eastcom_yw.domain.DpSceneConfig; +import com.ruoyi.eastcom_yw.domain.dto.DpSceneConfigDTO; +import com.ruoyi.eastcom_yw.domain.vo.DpSceneConfigVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface DpSceneConfigConvert { + + DpSceneConfigConvert INSTANCE = Mappers.getMapper(DpSceneConfigConvert.class); + + DpSceneConfig dtoToEntity(DpSceneConfigDTO dto); + + DpSceneConfigVO entityToVo(DpSceneConfig entity); + + List entityToVoList(List entityList); + + DpSceneConfigDTO entityToDto(DpSceneConfig entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi4gCellConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi4gCellConvert.java new file mode 100644 index 0000000..576adf1 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi4gCellConvert.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.service.convert; + +import com.ruoyi.eastcom_yw.domain.PmKpi4gCell; +import com.ruoyi.eastcom_yw.domain.dto.PmKpi4gCellDTO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi4gCellVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface PmKpi4gCellConvert { + + PmKpi4gCellConvert INSTANCE = Mappers.getMapper(PmKpi4gCellConvert.class); + + PmKpi4gCell dtoToEntity(PmKpi4gCellDTO dto); + + PmKpi4gCellVO entityToVo(PmKpi4gCell entity); + + List entityToVoList(List entityList); + + PmKpi4gCellDTO entityToDto(PmKpi4gCell entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi4gMinConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi4gMinConvert.java new file mode 100644 index 0000000..2ce531b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi4gMinConvert.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.service.convert; + + +import com.ruoyi.eastcom_yw.domain.PmKpi4gMin; +import com.ruoyi.eastcom_yw.domain.dto.PmKpi4gMinDTO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi4gMinVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface PmKpi4gMinConvert { + + PmKpi4gMinConvert INSTANCE = Mappers.getMapper(PmKpi4gMinConvert.class); + + PmKpi4gMin dtoToEntity(PmKpi4gMinDTO dto); + + PmKpi4gMinVO entityToVo(PmKpi4gMin entity); + + List entityToVoList(List entityList); + + PmKpi4gMinDTO entityToDto(PmKpi4gMin entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi4gVenueConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi4gVenueConvert.java new file mode 100644 index 0000000..edd2496 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi4gVenueConvert.java @@ -0,0 +1,27 @@ +package com.ruoyi.eastcom_yw.service.convert; + +import com.ruoyi.eastcom_yw.domain.PmKpi4gVenue; +import com.ruoyi.eastcom_yw.domain.dto.PmKpi4gVenueDTO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi4gVenueVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * @author yqf + * @date 2023/4/11 + */ +@Mapper +public interface PmKpi4gVenueConvert { + + PmKpi4gVenueConvert INSTANCE = Mappers.getMapper(PmKpi4gVenueConvert.class); + + PmKpi4gVenue dtoToEntity(PmKpi4gVenueDTO dto); + + PmKpi4gVenueVO entityToVo(PmKpi4gVenue entity); + + List entityToVoList(List entityList); + + PmKpi4gVenueDTO entityToDto(PmKpi4gVenue entity); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi5gCellConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi5gCellConvert.java new file mode 100644 index 0000000..49b9545 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi5gCellConvert.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.service.convert; + + +import com.ruoyi.eastcom_yw.domain.PmKpi5gCell; +import com.ruoyi.eastcom_yw.domain.dto.PmKpi5gCellDTO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi5gCellVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface PmKpi5gCellConvert { + + PmKpi5gCellConvert INSTANCE = Mappers.getMapper(PmKpi5gCellConvert.class); + + PmKpi5gCell dtoToEntity(PmKpi5gCellDTO dto); + + PmKpi5gCellVO entityToVo(PmKpi5gCell entity); + + List entityToVoList(List entityList); + + PmKpi5gCellDTO entityToDto(PmKpi5gCell entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi5gMinConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi5gMinConvert.java new file mode 100644 index 0000000..c75c2fd --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi5gMinConvert.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.service.convert; + + +import com.ruoyi.eastcom_yw.domain.PmKpi5gMin; +import com.ruoyi.eastcom_yw.domain.dto.PmKpi5gMinDTO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi5gMinVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface PmKpi5gMinConvert { + + PmKpi5gMinConvert INSTANCE = Mappers.getMapper(PmKpi5gMinConvert.class); + + PmKpi5gMin dtoToEntity(PmKpi5gMinDTO dto); + + PmKpi5gMinVO entityToVo(PmKpi5gMin entity); + + List entityToVoList(List entityList); + + PmKpi5gMinDTO entityToDto(PmKpi5gMin entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi5gVenueConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi5gVenueConvert.java new file mode 100644 index 0000000..459c057 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/PmKpi5gVenueConvert.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.service.convert; + + +import com.ruoyi.eastcom_yw.domain.PmKpi5gVenue; +import com.ruoyi.eastcom_yw.domain.dto.PmKpi5gVenueDTO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi5gVenueVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface PmKpi5gVenueConvert { + + PmKpi5gVenueConvert INSTANCE = Mappers.getMapper(PmKpi5gVenueConvert.class); + + PmKpi5gVenue dtoToEntity(PmKpi5gVenueDTO dto); + + PmKpi5gVenueVO entityToVo(PmKpi5gVenue entity); + + List entityToVoList(List entityList); + + PmKpi5gVenueDTO entityToDto(PmKpi5gVenue entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/SysNoticeConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/SysNoticeConvert.java new file mode 100644 index 0000000..97838a2 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/SysNoticeConvert.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.service.convert; + +import com.ruoyi.eastcom_yw.domain.SysNotice; +import com.ruoyi.eastcom_yw.domain.dto.SysNoticeDTO; +import com.ruoyi.eastcom_yw.domain.vo.SysNoticeVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface SysNoticeConvert { + + SysNoticeConvert INSTANCE = Mappers.getMapper(SysNoticeConvert.class); + + SysNotice dtoToEntity(SysNoticeDTO dto); + + SysNoticeVO entityToVo(SysNotice entity); + + List entityToVoList(List entityList); + + SysNoticeDTO entityToDto(SysNotice entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwDrsConfigConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwDrsConfigConvert.java new file mode 100644 index 0000000..fa46c35 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwDrsConfigConvert.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.service.convert; + +import com.ruoyi.eastcom_yw.domain.YwDrsConfig; +import com.ruoyi.eastcom_yw.domain.dto.YwDrsConfigDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwDrsConfigVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface YwDrsConfigConvert { + + YwDrsConfigConvert INSTANCE = Mappers.getMapper(YwDrsConfigConvert.class); + + YwDrsConfig dtoToEntity(YwDrsConfigDTO dto); + + YwDrsConfigVO entityToVo(YwDrsConfig entity); + + List entityToVoList(List entityList); + + YwDrsConfigDTO entityToDto(YwDrsConfig entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwDrsTempTaskConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwDrsTempTaskConvert.java new file mode 100644 index 0000000..46a0fcc --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwDrsTempTaskConvert.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.service.convert; + +import com.ruoyi.eastcom_yw.domain.YwDrsTempTask; +import com.ruoyi.eastcom_yw.domain.dto.YwDrsTempTaskDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwDrsTempTaskVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface YwDrsTempTaskConvert { + + YwDrsTempTaskConvert INSTANCE = Mappers.getMapper(YwDrsTempTaskConvert.class); + + YwDrsTempTask dtoToEntity(YwDrsTempTaskDTO dto); + + YwDrsTempTaskVO entityToVo(YwDrsTempTask entity); + + List entityToVoList(List entityList); + + YwDrsTempTaskDTO entityToDto(YwDrsTempTask entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwKpiConfigConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwKpiConfigConvert.java new file mode 100644 index 0000000..e4fe2c0 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwKpiConfigConvert.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.service.convert; + + +import com.ruoyi.eastcom_yw.domain.YwKpiConfig; +import com.ruoyi.eastcom_yw.domain.dto.YwKpiConfigDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwKpiConfigVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface YwKpiConfigConvert { + + YwKpiConfigConvert INSTANCE = Mappers.getMapper(YwKpiConfigConvert.class); + + YwKpiConfig dtoToEntity(YwKpiConfigDTO dto); + + YwKpiConfigVO entityToVo(YwKpiConfig entity); + + List entityToVoList(List entityList); + + YwKpiConfigDTO entityToDto(YwKpiConfig entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeBriefingConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeBriefingConvert.java new file mode 100644 index 0000000..c5b3c52 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeBriefingConvert.java @@ -0,0 +1,30 @@ +package com.ruoyi.eastcom_yw.service.convert; + + +import com.ruoyi.eastcom_yw.domain.YwNoticeBriefing; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeBriefingDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeBriefingVO; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface YwNoticeBriefingConvert { + + YwNoticeBriefingConvert INSTANCE = Mappers.getMapper(YwNoticeBriefingConvert.class); + + @Mapping(target = "noticeType",expression = "java(cn.hutool.json.JSONUtil.toJsonStr(dto.getNoticeType()))") + YwNoticeBriefing dtoToEntity(YwNoticeBriefingDTO dto); + + @Mapping(target = "noticeType",expression = "java(cn.hutool.json.JSONUtil.toList(entity.getNoticeType(),String.class))") + YwNoticeBriefingVO entityToVo(YwNoticeBriefing entity); + + List entityToVoList(List entityList); + + @Mapping(target = "noticeType",expression = "java(cn.hutool.json.JSONUtil.toList(entity.getNoticeType(),String.class))") + YwNoticeBriefingDTO entityToDto(YwNoticeBriefing entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeHandworkConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeHandworkConvert.java new file mode 100644 index 0000000..c684a05 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeHandworkConvert.java @@ -0,0 +1,30 @@ +package com.ruoyi.eastcom_yw.service.convert; + + +import com.ruoyi.eastcom_yw.domain.YwNoticeHandwork; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeHandworkDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeHandworkVO; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface YwNoticeHandworkConvert { + + YwNoticeHandworkConvert INSTANCE = Mappers.getMapper(YwNoticeHandworkConvert.class); + + @Mapping(target = "noticeType",expression = "java(cn.hutool.json.JSONUtil.toJsonStr(dto.getNoticeType()))") + YwNoticeHandwork dtoToEntity(YwNoticeHandworkDTO dto); + + @Mapping(target = "noticeType",expression = "java(cn.hutool.json.JSONUtil.toList(entity.getNoticeType(),String.class))") + YwNoticeHandworkVO entityToVo(YwNoticeHandwork entity); + + List entityToVoList(List entityList); + + @Mapping(target = "noticeType",expression = "java(cn.hutool.json.JSONUtil.toList(entity.getNoticeType(),String.class))") + YwNoticeHandworkDTO entityToDto(YwNoticeHandwork entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeHandworkdetailConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeHandworkdetailConvert.java new file mode 100644 index 0000000..be6aae8 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeHandworkdetailConvert.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.service.convert; + + +import com.ruoyi.eastcom_yw.domain.YwNoticeHandworkdetail; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeHandworkdetailDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeHandworkdetailVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface YwNoticeHandworkdetailConvert { + + YwNoticeHandworkdetailConvert INSTANCE = Mappers.getMapper(YwNoticeHandworkdetailConvert.class); + + YwNoticeHandworkdetail dtoToEntity(YwNoticeHandworkdetailDTO dto); + + YwNoticeHandworkdetailVO entityToVo(YwNoticeHandworkdetail entity); + + List entityToVoList(List entityList); + + YwNoticeHandworkdetailDTO entityToDto(YwNoticeHandworkdetail entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeListConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeListConvert.java new file mode 100644 index 0000000..7f37cc5 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeListConvert.java @@ -0,0 +1,25 @@ +package com.ruoyi.eastcom_yw.service.convert; + +import com.ruoyi.eastcom_yw.domain.YwNoticeList; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeListDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeListVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface YwNoticeListConvert { + + YwNoticeListConvert INSTANCE = Mappers.getMapper(YwNoticeListConvert.class); + + YwNoticeList dtoToEntity(YwNoticeListDTO dto); + + YwNoticeListVO entityToVo(YwNoticeList entity); + + List entityToVoList(List entityList); + + YwNoticeListDTO entityToDto(YwNoticeList entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeModelConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeModelConvert.java new file mode 100644 index 0000000..e7a4a6c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeModelConvert.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.service.convert; + +import com.ruoyi.eastcom_yw.domain.YwNoticeModel; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeModelDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeModelVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + + +@Mapper +public interface YwNoticeModelConvert { + + YwNoticeModelConvert INSTANCE = Mappers.getMapper(YwNoticeModelConvert.class); + + YwNoticeModel dtoToEntity(YwNoticeModelDTO dto); + + YwNoticeModelVO entityToVo(YwNoticeModel entity); + + List entityToVoList(List entityList); + + YwNoticeModelDTO entityToDto(YwNoticeModel entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeObjectConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeObjectConvert.java new file mode 100644 index 0000000..37874d3 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwNoticeObjectConvert.java @@ -0,0 +1,27 @@ +package com.ruoyi.eastcom_yw.service.convert; + + +import com.ruoyi.eastcom_yw.domain.YwNoticeObject; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeObjectDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeObjectVO; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface YwNoticeObjectConvert { + + YwNoticeObjectConvert INSTANCE = Mappers.getMapper(YwNoticeObjectConvert.class); + + YwNoticeObject dtoToEntity(YwNoticeObjectDTO dto); + + YwNoticeObjectVO entityToVo(YwNoticeObject entity); + + List entityToVoList(List entityList); + + YwNoticeObjectDTO entityToDto(YwNoticeObject entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwSparePartsConvert.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwSparePartsConvert.java new file mode 100644 index 0000000..adf60b3 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/convert/YwSparePartsConvert.java @@ -0,0 +1,26 @@ +package com.ruoyi.eastcom_yw.service.convert; + + +import com.ruoyi.eastcom_yw.domain.YwSpareParts; +import com.ruoyi.eastcom_yw.domain.dto.YwSparePartsDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwSparePartsVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface YwSparePartsConvert { + +YwSparePartsConvert INSTANCE = Mappers.getMapper(YwSparePartsConvert.class); + +YwSpareParts dtoToEntity(YwSparePartsDTO dto); + +YwSparePartsVO entityToVo(YwSpareParts entity); + +List entityToVoList(List entityList); + +YwSparePartsDTO entityToDto(YwSpareParts entity); + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/AppVersionServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/AppVersionServiceImpl.java new file mode 100644 index 0000000..0aa3574 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/AppVersionServiceImpl.java @@ -0,0 +1,11 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.eastcom_yw.domain.AppVersionConfig; +import com.ruoyi.eastcom_yw.mapper.AppVersionConfigMapper; +import com.ruoyi.eastcom_yw.service.AppVersionService; +import org.springframework.stereotype.Service; + +@Service +public class AppVersionServiceImpl extends ServiceImpl implements AppVersionService { +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/CommonServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/CommonServiceImpl.java new file mode 100644 index 0000000..1562bda --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/CommonServiceImpl.java @@ -0,0 +1,348 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.poi.excel.ExcelReader; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.core.domain.dto.HandleDataDTO; +import com.ruoyi.common.core.domain.dto.StartProcessInstanceDTO; +import com.ruoyi.common.core.domain.dto.TaskDTO; +import com.ruoyi.common.core.domain.dto.json.UserInfo; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.model.LoginBody; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.utils.RestTemplateUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.service.CommonService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import org.apache.poi.ss.formula.functions.T; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.*; +import org.springframework.stereotype.Component; +import org.springframework.util.MultiValueMap; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@Component +public class CommonServiceImpl implements CommonService { + + @Autowired + private RestTemplateUtils restTemplate; + + + @Autowired + private YwSceneService yw_sceneService; + + @Value("${workFlowUrl}") + private String workFlowUrl; + + //查询ProcessDefinitionId + @Override + public String GetProcessDefinitionId(String template_id) throws Exception { + + String url_detail = workFlowUrl+"/workspace/process/detail?templateId=" + template_id; +// String url_detail = "http://localhost:8093/workspace/process/detail?templateId=" + template_id; + ResponseEntity responseEntityDetail = null; + + try { + responseEntityDetail = restTemplate.get(url_detail, this.getHeaders(),String.class); + } catch (Exception ex) { + throw new Exception("template_id:" + template_id + ",workspace/process/detail请求错误"); + } + + + if (responseEntityDetail == null) { + throw new Exception("workspace/process/detail没有正确的返回值"); + } + + String resDetail = responseEntityDetail.getBody(); + + JSONObject obj_resDetail = JSONObject.parseObject(resDetail); + + //必须要有processDefinitionId才可以创建工作流 + if (obj_resDetail.getBoolean("success")) { + + JSONObject obj_resultDetail = obj_resDetail.getJSONObject("result"); + + return obj_resultDetail.getString("processDefinitionId"); + + } + + throw new Exception("workspace/process/detail返回错误"); + + } + + //启动流程并返回流程ID + @Override + public String StartProcess(StartProcessInstanceDTO startDTO) throws Exception { + + ResponseEntity responseEntityStart =null; + + String url = workFlowUrl+"/workspace/process/start"; +// String url = "http://localhost:8093/workspace/process/start"; + + HttpEntity request = new HttpEntity(JSONObject.toJSONString(startDTO),this.getHeaders()); + + try { + responseEntityStart = restTemplate.exchange(url, HttpMethod.POST, request, String.class); + //延迟2秒请求 +// Thread.sleep(2000L); + } + catch (Exception ex){ + throw new Exception("workspace/process/start请求错误"); + } + + if(responseEntityStart==null) + { + throw new Exception("workspace/process/start没有正确的返回值"); + } + + String resStart = responseEntityStart.getBody(); + + JSONObject obj_resStart = JSONObject.parseObject(resStart); + + + if (obj_resStart.getBoolean("success")) { + return obj_resStart.getString("result"); + } + + throw new Exception("流程启动失败"); + + } + + //自定义当前流程状态 + @Override + public Boolean UpdateProcessStatus(HandleDataDTO handleDataDTO) throws Exception { + + ResponseEntity responseEntityStart =null; + + String url = workFlowUrl+"/workspace/assignee"; + + HttpEntity request = new HttpEntity(JSONObject.toJSONString(handleDataDTO),this.getHeaders()); + + try { + responseEntityStart = restTemplate.exchange(url, HttpMethod.POST, request, String.class); + } + catch (Exception ex){ + throw new Exception("workspace/assignee接口是错误的"); + } + + if(responseEntityStart==null) + { + throw new Exception("workspace/process/assignee没有正确的返回值"); + } + + String resStart = responseEntityStart.getBody(); + + JSONObject obj_resStart = JSONObject.parseObject(resStart); + + return obj_resStart.getBoolean("success"); + + } + + @Override + public JSONObject getTaskInfo(HandleDataDTO handleDataDTO) throws Exception { + ResponseEntity responseEntityStart =null; + + String url = workFlowUrl+"/workspace/process/taskInfo"; + + HttpEntity request = new HttpEntity(JSONObject.toJSONString(handleDataDTO),this.getHeaders()); + + try { + responseEntityStart = restTemplate.exchange(url, HttpMethod.POST, request, String.class); + } + catch (Exception ex){ + throw new Exception("workspace/process/taskInfo请求错误"+ex.getMessage()); + } + + if(responseEntityStart==null) + { + throw new Exception("workspace/process/taskInfo没有正确的返回值"); + } + + String resStart = responseEntityStart.getBody(); + + JSONObject obj_resStart = JSONObject.parseObject(resStart); + + + if (obj_resStart.getBoolean("success")) { + return obj_resStart.getJSONObject("result"); + } + + throw new Exception("节点详情查询失败"); + } + + @Override + public Boolean agreeTask(HandleDataDTO handleDataDTO) throws Exception { + + ResponseEntity responseEntityStart =null; + + String url = workFlowUrl+"/workspace/agree"; + + + HttpEntity request = new HttpEntity(JSONObject.toJSONString(handleDataDTO),this.getHeaders()); + + try { + responseEntityStart = restTemplate.exchange(url, HttpMethod.POST, request, String.class); + //延迟2秒请求 +// Thread.sleep(2000L); + } + catch (Exception ex){ + throw new Exception("请求workspace/agree接口发生错误"); + } + + if(responseEntityStart==null) + { + throw new Exception("workspace/agree没有正确的返回值"); + } + + String resStart = responseEntityStart.getBody(); + + JSONObject obj_resStart = JSONObject.parseObject(resStart); + + return obj_resStart.getBoolean("success"); + + } + + @Override + public Boolean revokeTask(HandleDataDTO handleDataDTO) throws Exception { + + ResponseEntity responseEntityStart =null; + + String url = workFlowUrl+"/workspace/revokeByProcess"; + + + HttpEntity request = new HttpEntity(JSONObject.toJSONString(handleDataDTO),this.getHeaders()); + + try { + responseEntityStart = restTemplate.exchange(url, HttpMethod.POST, request, String.class); + //延迟2秒请求 +// Thread.sleep(2000L); + } + catch (Exception ex){ + throw new Exception("请求接口发生错误"); + } + + if(responseEntityStart==null) + { + throw new Exception("没有正确的返回值"); + } + + String resStart = responseEntityStart.getBody(); + + JSONObject obj_resStart = JSONObject.parseObject(resStart); + + return obj_resStart.getBoolean("success"); + + } + + @Override + public JSONObject toDoList(TaskDTO taskDTO) throws Exception { + ResponseEntity responseEntityStart =null; + + String url = workFlowUrl+"/workspace/process/toDoList"; + + HttpEntity request = new HttpEntity(JSONObject.toJSONString(taskDTO),this.getHeaders()); + + try { + responseEntityStart = restTemplate.exchange(url, HttpMethod.POST, request, String.class); + } + catch (Exception ex){ + throw new Exception("workspace/process/toDoList请求错误"+ex.getMessage()); + } + + if(responseEntityStart==null) + { + throw new Exception("workspace/process/toDoList没有正确的返回值"); + } + + String resStart = responseEntityStart.getBody(); + + JSONObject obj_resStart = JSONObject.parseObject(resStart); + + + if (obj_resStart.getBoolean("success")) { + return obj_resStart.getJSONObject("result"); + } + + throw new Exception("待办查询失败"); + + } + + @Override + public List selectCurrenUserTodoProcessId(String alarmType) { + TaskDTO taskDTO = new TaskDTO(); + taskDTO.setPageNo(1); + taskDTO.setPageSize(10000); + UserInfo user = new UserInfo(); + LoginUser loginUser = SecurityUtils.getLoginUser(); + user.setId(loginUser.getUserId().toString()); + user.setName(loginUser.getUsername()); + List roles = loginUser.getUser().getRoles().stream().map(SysRole::getRoleKey).collect(Collectors.toList()); + user.setRoles(roles); + user.setSpecialty(alarmType); + List venueByUser = yw_sceneService.getVenueByUser(loginUser.getUser()); + user.setVenue(venueByUser.stream().map(l->l.getId().toString()).collect(Collectors.toList())); + taskDTO.setCurrentUserInfo(user); + taskDTO.setSearchInfo(null); + taskDTO.setIsApp("true"); + List processIds=new ArrayList<>(); + try { + JSONObject jsonObject = toDoList(taskDTO); + processIds = jsonObject.getList("records", JSONObject.class).stream().map(l -> l.getString("processInstanceId")).collect(Collectors.toList()); + } catch (Exception e) { + e.printStackTrace(); + } + return processIds; + } + + + //获取登录的token,仅测试用 + @Override + public String getToken(String userName, String password) + { +// String url ="http://192.168.97.212:9010/login"; +// String url ="http://192.168.5.132:8081/login"; + String url ="http://localhost:9010/login"; + LoginBody login =new LoginBody(); + login.setUsername(userName); + login.setPassword(password); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity request = new HttpEntity(JSONObject.toJSONString(login),headers); + ResponseEntity responseEntity = restTemplate.post(url,request,String.class); + String token = JSONObject.parseObject(responseEntity.getBody()).getString("token"); + return token; + } + + @Override + public String getTokenByPhone(String phone, String code) + { +// String url ="http://192.168.97.212:9010/login"; +// String url ="http://192.168.5.132:8081/login"; + String url ="http://localhost:8080/login"; + LoginBody login =new LoginBody(); + login.setPhone(phone); + login.setCode(code); + login.setLoginType("1"); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity request = new HttpEntity(JSONObject.toJSONString(login),headers); + ResponseEntity responseEntity = restTemplate.post(url,request,String.class); + String token = JSONObject.parseObject(responseEntity.getBody()).getString("token"); + return token; + } + + private HttpHeaders getHeaders() + { + HttpHeaders headers = new HttpHeaders(); + headers.add("isSys","true"); + headers.setContentType(MediaType.APPLICATION_JSON); + return headers; + } + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2MmlListServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2MmlListServiceImpl.java new file mode 100644 index 0000000..4588c10 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2MmlListServiceImpl.java @@ -0,0 +1,115 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.Dp2MmlList; +import com.ruoyi.eastcom_yw.domain.qo.Dp2MmlListQO; +import com.ruoyi.eastcom_yw.mapper.Dp2MmlListMapper; +import com.ruoyi.eastcom_yw.service.Dp2MmlListService; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + *

+ * 服务实现类 + *

+ * + * @author ck + * @since 2023-09-12 + */ +@Service +public class Dp2MmlListServiceImpl extends ServiceImpl implements Dp2MmlListService { + + @Resource + private Dp2MmlListMapper dp2MmlListMapper; + + /** + * 列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(Dp2MmlListQO qo) { + qo.setPageNum(null); + qo.setPageSize(null); + return dp2MmlListMapper.list(qo); + } + + /** + * 分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public PageInfo getDataByPage(Dp2MmlListQO qo) { + PageHelper.startPage(qo.getPageNum(),qo.getPageSize()); + List list = getData(qo); + return PageInfo.of(list); + } + +// @Override +// public Dp2MmlList fetchById(Long id) { +// Dp2MmlList entity = dp2MmlListMapper.selectById(id); +// return Dp2MmlListConvert.INSTANCE.entityToVo(entity); +// } +// +// @Override +// public boolean saveOrUpdate(Dp2MmlList dto) { +// Dp2MmlList entity = Dp2MmlListConvert.INSTANCE.dtoToEntity(dto); +// return saveOrUpdate(entity); +// } +// +// @Override +// public boolean deleteById(Long id) { +// return removeById(id); +// } +// +// @Override +// public boolean deleteByIdBatch(List ids) { +// return SqlHelper.retBool(dp2MmlListMapper.deleteBatchIds(ids)); +// } + + @Override + public void export(Dp2MmlListQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + ExcelUtil util = new ExcelUtil<>(Dp2MmlList.class); + try { + util.exportExcel(response, data, "导出结果"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + +// @Override +// public AjaxResult importData(List list, boolean updateSupport) { +// // 核查模板 +// if (CollUtil.isEmpty(list)) { +// return AjaxResult.error("导入模板不正确。"); +// } +// +// // 核查 +// // boolean checkFlag; +// // checkFlag = checkData(cs, ywSceneList); +// // if (checkFlag) { +// // checkFlag = checkUnique(cs); +// // } +// // if (!checkFlag) { +// // ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); +// // String fileName = (String) util.exportExcel(cs, "网元传输导入结果").get(AjaxResult.MSG_TAG); +// // return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); +// // } +// // saveBatch(list); +// return null; +// } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2SpotCellServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2SpotCellServiceImpl.java new file mode 100644 index 0000000..fd20a53 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2SpotCellServiceImpl.java @@ -0,0 +1,312 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.CoordinateConversionUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.Dp2SpotCell; +import com.ruoyi.eastcom_yw.domain.qo.Dp2SpotCellQO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2SpotCellVO; +import com.ruoyi.eastcom_yw.mapper.Dp2SpotCellMapper; +import com.ruoyi.eastcom_yw.service.Dp2SpotCellService; +import com.ruoyi.eastcom_yw.service.convert.Dp2SpotCellConvert; +import com.ruoyi.system.mapper.SysDictDataMapper; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 服务实现类 + *

+ * + * @author ck + * @since 2023-08-10 + */ +@Service +public class Dp2SpotCellServiceImpl extends ServiceImpl implements Dp2SpotCellService { + + @Resource + private Dp2SpotCellMapper dp2SpotCellMapper; + +// @Resource +// private Dp2SpotConfigMapper dp2SpotConfigMapper; + + @Resource + private SysDictDataMapper sysDictDataMapper; + + /** + * 列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(Dp2SpotCellQO qo) { + qo.setPageNum(null); + qo.setPageSize(null); + return dp2SpotCellMapper.list(qo); + } + + /** + * 分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public PageInfo getDataByPage(Dp2SpotCellQO qo) { + PageHelper.startPage(qo.getPageNum(),qo.getPageSize()); + List list = dp2SpotCellMapper.list(qo); + return PageInfo.of(list); + } + + @Override + public Dp2SpotCellVO fetchById(Long id) { + Dp2SpotCell entity = dp2SpotCellMapper.selectById(id); + return Dp2SpotCellConvert.INSTANCE.entityToVo(entity); + } + + @Override + public boolean saveOrUpdated(Dp2SpotCell entity) { +// List dp2SpotConfigs = dp2SpotConfigMapper.selectList(new LambdaQueryWrapper().eq(Dp2SpotConfig::get景区名称, entity.get二级场景())); +// if(dp2SpotConfigs.isEmpty()){ +// throw new ServiceException("【二级场景】未找到匹配的景区名称"); +// }else { +// entity.set景区id(dp2SpotConfigs.get(0).get景区id()); +// } + Double 经度 = entity.get经度(); + Double 纬度 = entity.get纬度(); + // WGS84转GCj02 + String s = CoordinateConversionUtils.wgs84togcj02(经度, 纬度); + double lng02 = Double.parseDouble(s.split(",")[0]); + double lat02 = Double.parseDouble(s.split(",")[1]); + entity.set经度gcj(NumberUtil.round(lng02,6).doubleValue()); + entity.set纬度gcj(NumberUtil.round(lat02,6).doubleValue()); + + entity.set更新时间(LocalDateTime.now()); + + //字典翻译 + if(entity.get县市()!=null) { + String label = sysDictDataMapper.selectDictLabel("yw_county", entity.get县市()); + if(StrUtil.isBlank(label)){ + throw new ServiceException("【县市】不正确"); + } + entity.set县市(label); + } +// if(entity.get网络()!=null) { +// String label = sysDictDataMapper.selectDictLabel("yw_nettype", entity.get网络()); +// if(StrUtil.isBlank(label)){ +// throw new ServiceException("【网络】不正确"); +// } +// entity.set网络(label); +// } +// if(entity.get设备类型()!=null) { +// entity.set设备类型(sysDictDataMapper.selectDictLabel("spot_cell_type", entity.get设备类型())); +// } + return saveOrUpdate(entity); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(dp2SpotCellMapper.deleteBatchIds(ids)); + } + + @Override + public void export(Dp2SpotCellQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + if(CollUtil.isNotEmpty(data)){ + for (Dp2SpotCell datum : data) { + if(datum.get带宽()!=null) { + datum.set带宽str(datum.get带宽().toString() + "M"); + } + } + } + ExcelUtil util = new ExcelUtil<>(Dp2SpotCell.class); + util.hideColumn("reason"); + try { + util.exportExcel(response, data, "信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + + //判断cgi不能重复 +// List cgiList = list.stream().map(Dp2SpotCell::getCgi).collect(Collectors.toList()); +// HashSet set = new HashSet<>(cgiList); +// if(cgiList.size()!=set.size()){ +// return AjaxResult.error("存在cgi相同数据,请保证cgi唯一"); +// } + + List countyDictData = sysDictDataMapper.selectDictDataByType("yw_county"); + List countyList = countyDictData.stream().map(SysDictData::getDictLabel).collect(Collectors.toList()); + +// List nettypeDictData = sysDictDataMapper.selectDictDataByType("yw_nettype"); +// List nettypeList = nettypeDictData.stream().map(SysDictData::getDictLabel).collect(Collectors.toList()); + +// List dp2SpotConfigs = dp2SpotConfigMapper.selectList(null); +// List collect = dp2SpotConfigs.stream().map(Dp2SpotConfig::get景区介绍).distinct().collect(Collectors.toList()); +// List collect2 = dp2SpotConfigs.stream().map(Dp2SpotConfig::get景区名称).distinct().collect(Collectors.toList()); +// collect.addAll(collect2); +// Map map = dp2SpotConfigs.stream().collect(Collectors.toMap(Dp2SpotConfig::get景区名称, Dp2SpotConfig::get景区id)); + + boolean checkFlag = true; + for (Dp2SpotCell vo : list) { + if (StrUtil.isBlank(vo.get基站全称())) { + return AjaxResult.error("导入模板不正确。"); + } + StringBuilder builder = new StringBuilder(); + +// int num=0; +// for (String cgi : cgiList) { +// if(vo.getCgi().equals(cgi)){ +// num++; +// } +// } +// if(num>1){ +// builder.append("【cgi】重复;"); +// checkFlag = false; +// } + if (StrUtil.isBlank(vo.get县市())) { +// builder.append("【县市】为空;"); +// checkFlag = false; + }else { + //判断是否是字典中的值 +// String yw_county = sysDictDataMapper.selectDictValue("yw_county", vo.get县市()); + //去掉县市的区 + vo.set县市(vo.get县市().replace("区","")); + if(!countyList.contains(vo.get县市())){ + builder.append("【县市】不正确;"); + checkFlag = false; + } + } +// if (vo.get站号() == null) { +// builder.append("【站号】为空;"); +// checkFlag = false; +// } + if (StrUtil.isBlank(vo.get基站全称())) { + builder.append("【基站全称】不能为空;"); + } + if (StrUtil.isBlank(vo.get小区名称())) { + builder.append("【小区名称】为空;"); + checkFlag = false; + } +// if (StrUtil.isBlank(vo.get小区频段())) { +// builder.append("【小区频段】为空;"); +// checkFlag = false; +// } + if (vo.get纬度() == null) { + builder.append("【纬度】为空;"); + checkFlag = false; + } + if (vo.get经度() == null) { + builder.append("【经度】为空;"); + checkFlag = false; + } +// if (StrUtil.isBlank(vo.get室内室外())) { +// builder.append("【室内室外】为空;"); +// checkFlag = false; +// } + if (StrUtil.isBlank(vo.get网络())) { + builder.append("【网络】为空;"); + checkFlag = false; + }else { + //判断是否是字典中的值 +// String yw_nettype = sysDictDataMapper.selectDictValue("yw_nettype", vo.get网络()); +// if(!nettypeList.contains(vo.get网络())){ +// builder.append("【网络】不正确;"); +// checkFlag = false; +// } + } +// if (StrUtil.isBlank(vo.get设备类型())) { +// builder.append("【设备类型】为空;"); +// checkFlag = false; +// } +// if (vo.get带宽str() == null) { +// builder.append("【带宽】为空;"); +// checkFlag = false; +// } +// if (vo.get方位角() == null) { +// builder.append("【方位角】为空;"); +// checkFlag = false; +// } +// if (!collect.contains(vo.get一级场景())) { +// builder.append("【一级场景】未找到匹配的景区介绍;"); +// checkFlag = false; +// } +// List dp2SpotConfigs = dp2SpotConfigMapper.selectList(new LambdaQueryWrapper().eq(Dp2SpotConfig::get景区名称, vo.get二级场景())); +// if(!map.containsKey(vo.get二级场景())){ +// //设置景区id,根据二级场景匹配 +// builder.append("【二级场景】未找到匹配的景区名称;"); +// checkFlag = false; +// }else { +// vo.set景区id(map.get(vo.get二级场景())); +// } + vo.setReason(builder.toString()); + } + if (!checkFlag) { + ExcelUtil util = new ExcelUtil<>(Dp2SpotCell.class); + String fileName = (String) util.exportExcel(list, "场馆对应网元导入结果").get(AjaxResult.MSG_TAG); + return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + } else { + dp2SpotCellMapper.deleteAll(); + importList(list); + } + return AjaxResult.success(); + } + + + private void importList(List list) { + for (Dp2SpotCell entity : list) { + Double 经度 = entity.get经度(); + Double 纬度 = entity.get纬度(); + // WGS84转GCj02 + String s = CoordinateConversionUtils.wgs84togcj02(经度, 纬度); + double lng02 = Double.parseDouble(s.split(",")[0]); + double lat02 = Double.parseDouble(s.split(",")[1]); + entity.set经度gcj(NumberUtil.round(lng02,6).doubleValue()); + entity.set纬度gcj(NumberUtil.round(lat02,6).doubleValue()); + //带宽转换 + String 带宽str = entity.get带宽str(); + entity.set带宽(Double.valueOf(带宽str.replace("M",""))); + + entity.set更新时间(LocalDateTime.now()); + +// Dp2SpotCell dp2SpotCell = dp2SpotCellMapper.selectOne(new LambdaQueryWrapper() +// .eq(Dp2SpotCell::getCgi, entity.getCgi()) +// ); +// if (dp2SpotCell!=null) { +// entity.setId(dp2SpotCell.getId()); +// } + } + saveOrUpdateBatch(list); + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2SpotConfigServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2SpotConfigServiceImpl.java new file mode 100644 index 0000000..3ecc528 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2SpotConfigServiceImpl.java @@ -0,0 +1,130 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.Dp2SpotConfig; +import com.ruoyi.eastcom_yw.domain.dto.Dp2SpotConfigDTO; +import com.ruoyi.eastcom_yw.domain.qo.Dp2SpotConfigQO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2SpotConfigVO; +import com.ruoyi.eastcom_yw.mapper.Dp2SpotConfigMapper; +import com.ruoyi.eastcom_yw.service.Dp2SpotConfigService; +import com.ruoyi.eastcom_yw.service.convert.Dp2SpotConfigConvert; +import com.ruoyi.system.mapper.SysDictDataMapper; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + *

+ * 服务实现类 + *

+ * + * @author ck + * @since 2023-08-09 + */ +@Service +public class Dp2SpotConfigServiceImpl extends ServiceImpl implements Dp2SpotConfigService { + + @Resource + private Dp2SpotConfigMapper dp2SpotConfigMapper; + + @Resource + private SysDictDataMapper sysDictDataMapper; + + /** + * 列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(Dp2SpotConfigQO qo) { + return dp2SpotConfigMapper.list(qo); + } + + /** + * 分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public PageInfo getDataByPage(Dp2SpotConfigQO qo) { + PageHelper.startPage(qo.getPageNum(),qo.getPageSize()); + List list = dp2SpotConfigMapper.list(qo); + return PageInfo.of(list); + } + + @Override + public Dp2SpotConfigVO fetchById(Long id) { + Dp2SpotConfig entity = dp2SpotConfigMapper.selectById(id); + return Dp2SpotConfigConvert.INSTANCE.entityToVo(entity); + } + + @Override + public boolean saveOrUpdate(Dp2SpotConfigDTO dto) { + Dp2SpotConfig entity = Dp2SpotConfigConvert.INSTANCE.dtoToEntity(dto); + //翻译字典值 + if(entity.get行政区域()!=null) { + entity.set行政区域(sysDictDataMapper.selectDictLabel("yw_county", entity.get行政区域())); + } + if(entity.get景区大类()!=null) { + entity.set景区大类(sysDictDataMapper.selectDictLabel("spot_type", entity.get景区大类())); + } + return saveOrUpdate(entity); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(dp2SpotConfigMapper.deleteBatchIds(ids)); + } + + @Override + public void export(Dp2SpotConfigQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + ExcelUtil util = new ExcelUtil<>(Dp2SpotConfigVO.class); + try { + util.exportExcel(response, data, "信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + + // 核查 + // boolean checkFlag; + // checkFlag = checkData(cs, ywSceneList); + // if (checkFlag) { + // checkFlag = checkUnique(cs); + // } + // if (!checkFlag) { + // ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); + // String fileName = (String) util.exportExcel(cs, "网元传输导入结果").get(AjaxResult.MSG_TAG); + // return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + // } + // saveBatch(list); + return null; + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2ViewPowerAlarmServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2ViewPowerAlarmServiceImpl.java new file mode 100644 index 0000000..ef6d958 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2ViewPowerAlarmServiceImpl.java @@ -0,0 +1,86 @@ +package com.ruoyi.eastcom_yw.service.impl; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.domain.AjaxResult; + +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.Dp2ViewPowerAlarm; +import com.ruoyi.eastcom_yw.domain.qo.Dp2ViewPowerAlarmQO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2ViewPowerAlarmVO; +import com.ruoyi.eastcom_yw.mapper.Dp2ViewPowerAlarmMapper; +import com.ruoyi.eastcom_yw.service.Dp2ViewPowerAlarmService; +import com.ruoyi.eastcom_yw.service.convert.Dp2ViewPowerAlarmConvert; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** +*

+ * 服务实现类 + *

+* +* @author wqx +* @since 2023-08-31 +*/ +@Service +@RequiredArgsConstructor +public class Dp2ViewPowerAlarmServiceImpl extends ServiceImpl implements Dp2ViewPowerAlarmService { + + @Resource + private Dp2ViewPowerAlarmMapper dp2ViewPowerAlarmMapper; + + + /** + * 列表 + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(Dp2ViewPowerAlarmQO qo) { + qo.setPageNum(null); + qo.setPageSize(null); + List list = dp2ViewPowerAlarmMapper.list(qo); + return list; + } + + /** + * 分页列表 + * @param qo 根据需要进行传值 + * @return + */ + @Override + public PageInfo getDataByPage(Dp2ViewPowerAlarmQO qo) { + PageHelper.startPage(qo.getPageNum(),qo.getPageSize()); + List list = dp2ViewPowerAlarmMapper.list(qo); + return PageInfo.of(list); + } + + + + @Override + public Dp2ViewPowerAlarmVO fetchById(Long id) { + Dp2ViewPowerAlarm entity = dp2ViewPowerAlarmMapper.selectById(id); + return Dp2ViewPowerAlarmConvert.INSTANCE.entityToVo(entity); + } + + @Override + public void export(Dp2ViewPowerAlarmQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + ExcelUtil util = new ExcelUtil<>(Dp2ViewPowerAlarmVO.class); + try { + util.exportExcel(response, data, "场馆和城市侧动环告警"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2ViewWirelessAlarmServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2ViewWirelessAlarmServiceImpl.java new file mode 100644 index 0000000..cea0325 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/Dp2ViewWirelessAlarmServiceImpl.java @@ -0,0 +1,129 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.Dp2ViewWirelessAlarm; +import com.ruoyi.eastcom_yw.domain.dto.Dp2ViewWirelessAlarmDTO; +import com.ruoyi.eastcom_yw.domain.qo.Dp2ViewWirelessAlarmQO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2ViewPowerAlarmVO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2ViewWirelessAlarmVO; +import com.ruoyi.eastcom_yw.mapper.Dp2ViewWirelessAlarmMapper; +import com.ruoyi.eastcom_yw.service.Dp2ViewWirelessAlarmService; +import com.ruoyi.eastcom_yw.service.convert.Dp2ViewWirelessAlarmConvert; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** +*

+ * 服务实现类 + *

+* +* @author wqx +* @since 2023-09-01 +*/ +@Service +public class Dp2ViewWirelessAlarmServiceImpl extends ServiceImpl implements Dp2ViewWirelessAlarmService { + + @Resource + private Dp2ViewWirelessAlarmMapper dp2ViewWirelessAlarmMapper; + + /** + * 列表 + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(Dp2ViewWirelessAlarmQO qo) { + qo.setPageNum(null); + qo.setPageSize(null); + List list = dp2ViewWirelessAlarmMapper.list(qo); + return list; + } + + /** + * 分页列表 + * @param qo 根据需要进行传值 + * @return + */ + @Override + public PageInfo getDataByPage(Dp2ViewWirelessAlarmQO qo) { + PageHelper.startPage(qo.getPageNum(),qo.getPageSize()); + List list = dp2ViewWirelessAlarmMapper.list(qo); + return PageInfo.of(list); + } + + @Override + public Dp2ViewWirelessAlarmVO fetchById(Long id) { + Dp2ViewWirelessAlarm entity = dp2ViewWirelessAlarmMapper.selectById(id); + return Dp2ViewWirelessAlarmConvert.INSTANCE.entityToVo(entity); + } + + @Override + public boolean saveOrUpdate(Dp2ViewWirelessAlarmDTO dto) { + Dp2ViewWirelessAlarm entity = Dp2ViewWirelessAlarmConvert.INSTANCE.dtoToEntity(dto); + return saveOrUpdate(entity); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(dp2ViewWirelessAlarmMapper.deleteBatchIds(ids)); + } + + @Override + public void export(Dp2ViewWirelessAlarmQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + ExcelUtil util = new ExcelUtil<>(Dp2ViewWirelessAlarmVO.class); + try { + util.exportExcel(response, data, "场馆和城市侧无线告警"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + + // 核查 + // boolean checkFlag; + // checkFlag = checkData(cs, ywSceneList); + // if (checkFlag) { + // checkFlag = checkUnique(cs); + // } + // if (!checkFlag) { + // ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); + // String fileName = (String) util.exportExcel(cs, "网元传输导入结果").get(AjaxResult.MSG_TAG); + // return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + // } + // saveBatch(list); + return null; + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/DpSceneConfigServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/DpSceneConfigServiceImpl.java new file mode 100644 index 0000000..e787142 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/DpSceneConfigServiceImpl.java @@ -0,0 +1,166 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.common.constant.KpiConstants; +import com.ruoyi.eastcom_yw.domain.DpSceneConfig; +import com.ruoyi.eastcom_yw.domain.dto.DpSceneConfigDTO; +import com.ruoyi.eastcom_yw.domain.qo.DpSceneConfigQO; +import com.ruoyi.eastcom_yw.domain.vo.DpSceneConfigVO; +import com.ruoyi.eastcom_yw.mapper.DpSceneConfigMapper; +import com.ruoyi.eastcom_yw.service.DpSceneConfigService; +import com.ruoyi.eastcom_yw.service.convert.DpSceneConfigConvert; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + *

+ * 服务实现类 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Service +public class DpSceneConfigServiceImpl extends ServiceImpl implements DpSceneConfigService { + + @Resource + private DpSceneConfigMapper dpSceneConfigMapper; + + /** + * 列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(DpSceneConfigQO qo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + .like(StrUtil.isNotBlank(qo.getName()), DpSceneConfig::getName, qo.getName()) + .eq(StrUtil.isNotBlank(qo.getNettype()), DpSceneConfig::getNettype, qo.getNettype()) + .eq(StrUtil.isNotBlank(qo.getType()), DpSceneConfig::getType, qo.getType()) + .orderByAsc(DpSceneConfig::getId); + List list = dpSceneConfigMapper.selectList(queryWrapper); + return DpSceneConfigConvert.INSTANCE.entityToVoList(list); + } + + /** + * 分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public IPage getDataByPage(DpSceneConfigQO qo) { +// LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); +// queryWrapper +// .like(StrUtil.isNotBlank(qo.getName()), DpSceneConfig::getName, qo.getName()) +// .like(StrUtil.isNotBlank(qo.getCelltype()), DpSceneConfig::getCelltype, qo.getCelltype()) +// .eq(StrUtil.isNotBlank(qo.getNettype()), DpSceneConfig::getNettype, qo.getNettype()) +// .eq(StrUtil.isNotBlank(qo.getType()), DpSceneConfig::getType, qo.getType()) +// .orderByAsc(DpSceneConfig::getNettype,DpSceneConfig::getType,DpSceneConfig::getName,DpSceneConfig::getCelltype,DpSceneConfig::getLevel); + + Page voPage = new Page<>(); + List list = dpSceneConfigMapper.getList(qo); + List voList = new ArrayList<>(); + for (DpSceneConfig dpSceneConfig : list) { + DpSceneConfigVO dpSceneConfigVO = new DpSceneConfigVO(); + BeanUtil.copyProperties(dpSceneConfig,dpSceneConfigVO); + voList.add(dpSceneConfigVO); + } + voPage.setRecords(voList); + voPage.setTotal(PageInfo.of(list).getTotal()); + return voPage; + } + + @Override + public DpSceneConfigVO fetchById(Long id) { + DpSceneConfig entity = dpSceneConfigMapper.selectById(id); + return DpSceneConfigConvert.INSTANCE.entityToVo(entity); + } + + @Override + public boolean saveOrUpdate(DpSceneConfigDTO dto) { + DpSceneConfig entity = DpSceneConfigConvert.INSTANCE.dtoToEntity(dto); + return saveOrUpdate(entity); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(dpSceneConfigMapper.deleteBatchIds(ids)); + } + + @Override + public void export(DpSceneConfigQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + ExcelUtil util = new ExcelUtil<>(DpSceneConfigVO.class); + try { + util.exportExcel(response, data, "信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + + // 核查 + // boolean checkFlag; + // checkFlag = checkData(cs, ywSceneList); + // if (checkFlag) { + // checkFlag = checkUnique(cs); + // } + // if (!checkFlag) { + // ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); + // String fileName = (String) util.exportExcel(cs, "网元传输导入结果").get(AjaxResult.MSG_TAG); + // return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + // } + // saveBatch(list); + return null; + } + + @Override + public List listColor(){ + return dpSceneConfigMapper.listColor(); + } + + @Override + public List listKpiName(){ + List list = dpSceneConfigMapper.listKpiName(); + list.removeIf(s -> s.equals(KpiConstants.YW_FIELD_ALL)); + list.add(KpiConstants.YW_FIELD_ALL); + return list; + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/HmAlarmDeriveServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/HmAlarmDeriveServiceImpl.java new file mode 100644 index 0000000..4e21bc4 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/HmAlarmDeriveServiceImpl.java @@ -0,0 +1,192 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.domain.HmAlarmDerive; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmVo; +import com.ruoyi.eastcom_yw.mapper.HmAlarmDeriveMapper; +import com.ruoyi.eastcom_yw.service.HmAlarmDeriveService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 服务实现类 + *

+ * + * @author jkj + * @since 2023-08-02 + */ +@Service +public class HmAlarmDeriveServiceImpl extends ServiceImpl implements HmAlarmDeriveService { + + @Resource + HmAlarmDeriveMapper hmAlarmDeriveMapper; + + @Resource + YwSceneService ywSceneService; + + @Override + public List getAlarmDerive(YwAlarmDTO alarmDTO) { + SysUser user = SecurityUtils.getLoginUser().getUser(); + //如果没有传入场馆就用当前登录用户的配置的场馆 + List lstVenue = new ArrayList<>(); + if (alarmDTO.getVenues() == null) { + + //管理员不需要设置场馆 + if (!user.isAdmin(user)) { + + ywSceneService.getVenueByUser(user).forEach( + venue -> { + lstVenue.add(venue.getVenueName()); + } + ); + alarmDTO.setVenueNames(lstVenue); + } + } + if (alarmDTO.getVenues() != null) { + + if(alarmDTO.getVenues().size() == 0) { + //管理员不需要设置场馆 + if (!user.isAdmin(user)) { + + ywSceneService.getVenueByUser(user).forEach( + venue -> { + lstVenue.add(venue.getVenueName()); + } + ); + alarmDTO.setVenueNames(lstVenue); + } + } + if(alarmDTO.getVenues().size() > 0) { + + LambdaQueryWrapper queryScene =new LambdaQueryWrapper<>(); + + queryScene.in(YwScene::getId,alarmDTO.getVenues()); + + List lstScene = ywSceneService.getBaseMapper().selectList(queryScene); + + for(YwScene scene : lstScene) + { + lstVenue.add(scene.getVenueName()); + } + + } + alarmDTO.setVenueNames(lstVenue); + } + + LambdaQueryWrapper query =new LambdaQueryWrapper<>(); + + if(StringUtils.isNotEmpty(alarmDTO.getVenueType())) + { + query.apply("场馆名称 in (SELECT venue_name FROM yw_scene where match_type = {0})",alarmDTO.getVenueType()); + } + + if(StringUtils.isNotEmpty(alarmDTO.getMaintainType())) + { + query.apply("场馆名称 in (SELECT venue_name FROM yw_scene where maintain_type = {0})",alarmDTO.getMaintainType()); + + } + + if(StringUtils.isNotEmpty(alarmDTO.getCounty())) { + + if("0571".equals(alarmDTO.getCounty())) + { + query.eq(HmAlarmDerive::get分公司,"杭州"); + } + else + { + alarmDTO.setCounty(DictUtils.getDictLabel("yw_county", alarmDTO.getCounty())); + query.eq(HmAlarmDerive::get分公司,alarmDTO.getCounty()); + } + + } + + if(StringUtils.isNotEmpty(alarmDTO.getCity())) { + + List datas = DictUtils.getDictCache("yw_county"); + + List lstCounty = datas.stream().filter(x->x.getDictValue().contains(alarmDTO.getCity())).map(SysDictData::getDictLabel).collect(Collectors.toList()); + + //分公司字段存在杭州的值 + if("0571".equals(alarmDTO.getCity())) + { + lstCounty.add("杭州"); + } + + query.in(HmAlarmDerive::get分公司, lstCounty); + } + + query.in(ObjectUtils.isNotEmpty(alarmDTO.getCountys()),HmAlarmDerive::get分公司,alarmDTO.getCountys()); + + query.in(!alarmDTO.getVenueNames().isEmpty(),HmAlarmDerive::get场馆名称,alarmDTO.getVenueNames()); + + if(StringUtils.isNotEmpty(alarmDTO.getSearchBox())) + { + query.and( + queryLess -> queryLess.like(HmAlarmDerive::get网元名称,alarmDTO.getSearchBox()).or(). + like(HmAlarmDerive::get告警名称,alarmDTO.getSearchBox()) + ); + + } + + if (StringUtils.isNotEmpty(alarmDTO.getStartTime())&&StringUtils.isNotEmpty(alarmDTO.getEndTime())) + { + try + { + if(alarmDTO.getStartTime().length()==10) { + alarmDTO.setStartTime(alarmDTO.getStartTime()+"T00:00:00"); + } + if(alarmDTO.getEndTime().length()==10) { + alarmDTO.setEndTime(alarmDTO.getEndTime()+"T23:59:59"); + } + if(alarmDTO.getStartTime().length()==19 && alarmDTO.getEndTime().length()==19) { + alarmDTO.setStart(LocalDateTime.parse(alarmDTO.getStartTime().replace(" ","T"))); + alarmDTO.setEnd(LocalDateTime.parse(alarmDTO.getEndTime().replace(" ","T"))); + } + } + catch (Exception ex) + { + throw new ServiceException(ex.getMessage()); + } + + } + + query.between(ObjectUtils.isNotEmpty(alarmDTO.getStart())&&ObjectUtils.isNotEmpty(alarmDTO.getEnd()),HmAlarmDerive::get告警时间,alarmDTO.getStart(),alarmDTO.getEnd()); + + query.orderByDesc(HmAlarmDerive::get恢复时间); + + List lstDerive = hmAlarmDeriveMapper.selectList(query); + + for(HmAlarmDerive derive : lstDerive) + { + derive.setAlarmId(derive.getId()); + derive.setAlarmKey(derive.getAlarmId()+"||0"); + if(ObjectUtils.isNotEmpty(derive.get恢复时间())) + { + derive.setAlarmKey(derive.getAlarmId()+"||1"); + } + } + + return lstDerive; + + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/LargeScreenServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/LargeScreenServiceImpl.java new file mode 100644 index 0000000..b1849ea --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/LargeScreenServiceImpl.java @@ -0,0 +1,62 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.ruoyi.eastcom_yw.domain.model.AppEntity; +import com.ruoyi.eastcom_yw.domain.vo.*; +import com.ruoyi.eastcom_yw.mapper.AppMapper; +import com.ruoyi.eastcom_yw.mapper.LargeScreenMapper; +import com.ruoyi.eastcom_yw.service.LargeScreenService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class LargeScreenServiceImpl implements LargeScreenService { + + private final LargeScreenMapper largeScreenMapper; + + private final AppMapper appMapper; + + @Override + public List getTaskManageList() { + return largeScreenMapper.getTaskManageList(); + } + + @Override + public List getMatchList() { + return largeScreenMapper.getMatchList(); + } + + @Override + public List getRaceScheduleList() { + return largeScreenMapper.getRaceScheduleList(); + } + + @Override + public List getMedalList() { + return largeScreenMapper.getMedalList(); + } + + @Override + public List getNewsList() { + return largeScreenMapper.getNewsList(); + } + + @Override + public List getAlarmTopList() { + return largeScreenMapper.getAlarmTopList(); + } + + @Override + public List getAlarmStatisticsList() { + return largeScreenMapper.getAlarmStatisticsList(); + } + + @Override + public boolean validate(String ip, AppEntity appEntity) { + appEntity.setIp(ip); + return appMapper.findApp(appEntity) != null ? true : false; + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/OpenApiServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/OpenApiServiceImpl.java new file mode 100644 index 0000000..fc727d2 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/OpenApiServiceImpl.java @@ -0,0 +1,41 @@ +package com.ruoyi.eastcom_yw.service.impl; + + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.http.HttpUtils; +import com.ruoyi.eastcom_yw.domain.dto.MmlObjectDTO; +import com.ruoyi.eastcom_yw.service.OpenApiService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +/** + * @author yqf + * @date 2023/6/5 + */ +@Service +@RequiredArgsConstructor +public class OpenApiServiceImpl implements OpenApiService { + + private static final String url = "http://10.71.80.224:53335/datasnap/rest/tmml/sitemml"; + + @Override + public AjaxResult getMsgByMML(MmlObjectDTO mmlObjectDTO) { + String json = JSON.toJSONString(mmlObjectDTO); + System.out.println(json); + String result = HttpUtils.postJosnContent(url, json); +// String result = geetStr(); + JSONObject jsonObject = JSONObject.parseObject(result); + + System.out.println(result); + if (jsonObject.get("code").equals("1")) { + return AjaxResult.success(jsonObject.get("message")); + } else { + return AjaxResult.error("调用远程接口错误",jsonObject.get("message")); + } + + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi4gCellServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi4gCellServiceImpl.java new file mode 100644 index 0000000..1c73da2 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi4gCellServiceImpl.java @@ -0,0 +1,208 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.common.constant.KpiConstants; +import com.ruoyi.eastcom_yw.domain.PmKpi4gCell; +import com.ruoyi.eastcom_yw.domain.PmKpiMaxEntity; +import com.ruoyi.eastcom_yw.domain.param.YwSceneCalendarParam; +import com.ruoyi.eastcom_yw.domain.qo.DpSceneConfigQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiColorQo; +import com.ruoyi.eastcom_yw.domain.qo.YwKpiConfigQO; +import com.ruoyi.eastcom_yw.domain.vo.*; +import com.ruoyi.eastcom_yw.mapper.DpSceneConfigMapper; +import com.ruoyi.eastcom_yw.mapper.PmKpi4gCellMapper; +import com.ruoyi.eastcom_yw.service.DpSceneConfigService; +import com.ruoyi.eastcom_yw.service.PmKpi4gCellService; +import com.ruoyi.eastcom_yw.service.YwKpiConfigService; +import com.ruoyi.eastcom_yw.service.convert.PmKpi4gCellConvert; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletResponse; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author yqf + * @date 2023/4/11 + */ +@Service +public class PmKpi4gCellServiceImpl extends ServiceImpl implements PmKpi4gCellService { + + @Autowired + private PmKpi4gCellMapper pmKpi4gCellMapper; + + @Autowired + private DpSceneConfigService dpSceneConfigService; + + @Autowired + private DpSceneConfigMapper dpSceneConfigMapper; + + /** + * 场馆4G小区级15分钟指标列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(PmKpiCellQO qo) { + qo.setPageSize(0); + List list = pmKpi4gCellMapper.getList(qo); + return PmKpi4gCellConvert.INSTANCE.entityToVoList(list); + } + + + /** + * 场馆4G小区级15分钟指标分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public IPage getDataByPage(PmKpiCellQO qo) { + + PageUtils.startPage(qo, PmKpiCellQO.class); + List records = pmKpi4gCellMapper.getList(qo); + List list = new ArrayList<>(); + + if (!records.isEmpty()) { + qo.setPageSize(0); + PmKpiMaxEntity maxKpi = pmKpi4gCellMapper.getMaxKpi(qo); + BigDecimal maxuserNum = maxKpi.getMaxuserNum(); + BigDecimal prbupNum = maxKpi.getPrbupNum(); + BigDecimal prbdownNum = maxKpi.getPrbdownNum(); + BigDecimal avgNum = maxKpi.getAvgNum(); + BigDecimal succesNum = maxKpi.getSuccesNum(); + BigDecimal failNum = maxKpi.getFailNum(); + BigDecimal avgDisturb = maxKpi.getAvgDisturb(); + + for (PmKpi4gCell pmKpi4gCell : records) { + PmKpi15MinCellVO vo = new PmKpi15MinCellVO(); + BeanUtil.copyProperties(pmKpi4gCell, vo); + + DpSceneConfigQO configQO = new DpSceneConfigQO(); + configQO.setNettype(qo.getNetType()); + + vo.setNetType(qo.getNetType()); + + BigDecimal defaultNum = new BigDecimal(0); + PmKpiColorQo kpiColorQo = new PmKpiColorQo(); + kpiColorQo.setPrbupvalue(null != pmKpi4gCell.get上行prb利用率() ? pmKpi4gCell.get上行prb利用率() : defaultNum); + kpiColorQo.setPrbdownvalue(null != pmKpi4gCell.get下行prb利用率() ? pmKpi4gCell.get下行prb利用率() : defaultNum); + kpiColorQo.setAvgdisvalue(null != pmKpi4gCell.get上行平均干扰() ? pmKpi4gCell.get上行平均干扰() : defaultNum); + kpiColorQo.setMaxuservalue(null != pmKpi4gCell.get最大用户数() ? pmKpi4gCell.get最大用户数() : defaultNum); + kpiColorQo.setFreqtype(pmKpi4gCell.get小区频段()); + kpiColorQo.setDevicetype(pmKpi4gCell.get设备类型()); + kpiColorQo.setBandwidth(pmKpi4gCell.get带宽()); + kpiColorQo.setNettype(qo.getNetType()); + + Map fourKpiColor = dpSceneConfigMapper.getFourKpiColor(kpiColorQo); + + //平均用户 + PmKpiVO avgUser = new PmKpiVO(avgNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gCell.get平均用户数()) { + avgUser.setValue(pmKpi4gCell.get平均用户数()); + } + vo.set平均用户数(avgUser); + + //干扰值 + PmKpiVO disb = new PmKpiVO(avgDisturb, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gCell.get上行平均干扰()) { + disb.setValue(pmKpi4gCell.get上行平均干扰()); + disb.setColor(fourKpiColor.get("avgdiscolor").toString()); + } + vo.set上行平均干扰(disb); + + //无线接通率 + PmKpiVO success = new PmKpiVO(succesNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gCell.get无线接通率()) { + success.setValue(pmKpi4gCell.get无线接通率()); + } + vo.set无线接通率(success); + + //无线掉线率 + PmKpiVO failrate = new PmKpiVO(failNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gCell.get无线掉线率()) { + failrate.setValue(pmKpi4gCell.get无线掉线率()); + } + vo.set无线掉线率(failrate); + + //最大用户数 + LocalDateTime starttime = qo.getStarttime().minusHours(6); + qo.setQuerystarttime(starttime); + qo.setQueryvenueid(pmKpi4gCell.getVenueId()); + qo.setVillageIds(new String[]{pmKpi4gCell.getCellcodeci()}); + List dataList = pmKpi4gCellMapper.getKpiDataList(qo); + vo.setKpi6HourData(dataList); + + PmKpiVO maxUserVo = new PmKpiVO(maxuserNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gCell.get最大用户数()) { + maxUserVo.setValue(pmKpi4gCell.get最大用户数()); + maxUserVo.setColor(fourKpiColor.get("maxusercolor").toString()); + } + maxUserVo.setData(dataList); + vo.set最大用户数(maxUserVo); + + //上行prb利用率 + PmKpiVO upPrbVo = new PmKpiVO(prbupNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gCell.get上行prb利用率()) { + upPrbVo.setValue(pmKpi4gCell.get上行prb利用率()); + upPrbVo.setColor(fourKpiColor.get("prbupcolor").toString()); + } + upPrbVo.setData(dataList); + vo.set上行prb利用率(upPrbVo); + + //下行prb利用率 + PmKpiVO downPrbVo = new PmKpiVO(prbdownNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gCell.get下行prb利用率()) { + downPrbVo.setValue(pmKpi4gCell.get下行prb利用率()); + downPrbVo.setColor(fourKpiColor.get("prbdowncolor").toString()); + } + downPrbVo.setData(dataList); + vo.set下行prb利用率(downPrbVo); + list.add(vo); + } + + } + + IPage voPage = new Page<>(); + voPage.setRecords(list); + voPage.setTotal(PageInfo.of(records).getTotal()); + return voPage; + } + + + @Override + public void export(PmKpiCellQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + ExcelUtil util = new ExcelUtil<>(PmKpi4gCellVO.class); + try { + util.exportExcel(response, data, "场馆4G小区级15分钟指标信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public Map getLastTime(Long[] venueIds){ + return pmKpi4gCellMapper.getLastTimeByvenueIds(venueIds); + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi4gMinServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi4gMinServiceImpl.java new file mode 100644 index 0000000..4ae91c4 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi4gMinServiceImpl.java @@ -0,0 +1,269 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; + +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.common.constant.KpiConstants; +import com.ruoyi.eastcom_yw.domain.PmKpi4gCell; +import com.ruoyi.eastcom_yw.domain.PmKpi4gMin; +import com.ruoyi.eastcom_yw.domain.PmKpi5gCell; +import com.ruoyi.eastcom_yw.domain.PmKpiMaxEntity; +import com.ruoyi.eastcom_yw.domain.dto.PmKpi4gMinDTO; +import com.ruoyi.eastcom_yw.domain.param.YwSceneCalendarParam; +import com.ruoyi.eastcom_yw.domain.qo.DpSceneConfigQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpi4gMinQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiColorQo; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiMinQO; +import com.ruoyi.eastcom_yw.domain.vo.*; +import com.ruoyi.eastcom_yw.mapper.DpSceneConfigMapper; +import com.ruoyi.eastcom_yw.mapper.PmKpi4gMinMapper; +import com.ruoyi.eastcom_yw.service.PmKpi4gMinService; +import com.ruoyi.eastcom_yw.service.convert.PmKpi4gMinConvert; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + *

+ * 场馆4G小区级1分钟指标 服务实现类 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Service +public class PmKpi4gMinServiceImpl extends ServiceImpl implements PmKpi4gMinService { + + @Resource + private PmKpi4gMinMapper pmKpi4gMinMapper; + + @Autowired + private DpSceneConfigMapper dpSceneConfigMapper; + + /** + * 场馆4G小区级1分钟指标列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(PmKpiMinQO qo) { + qo.setPageSize(0); + List list = pmKpi4gMinMapper.getList(qo); + return PmKpi4gMinConvert.INSTANCE.entityToVoList(list); + } + + /** + * 场馆4G小区级1分钟指标分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public IPage getDataByPage(PmKpiMinQO qo) { + + PageUtils.startPage(qo, PmKpiMinQO.class); + List records = pmKpi4gMinMapper.getList(qo); + List list = new ArrayList<>(); + + if (!records.isEmpty()) { + qo.setPageSize(0); + PmKpiMaxEntity maxKpi = pmKpi4gMinMapper.getMaxKpi(qo); + BigDecimal maxuserNum = maxKpi.getMaxuserNum(); + BigDecimal prbupNum = maxKpi.getPrbupNum(); + BigDecimal prbdownNum = maxKpi.getPrbdownNum(); + BigDecimal avgNum = maxKpi.getAvgNum(); + BigDecimal succesNum = maxKpi.getSuccesNum(); + BigDecimal failNum = maxKpi.getFailNum(); + BigDecimal avgDisturb = maxKpi.getAvgDisturb(); + + for (PmKpi4gMin pmKpi4gMin : records) { + PmKpiOneMinVO vo = new PmKpiOneMinVO(); + BeanUtil.copyProperties(pmKpi4gMin, vo); + + DpSceneConfigQO configQO = new DpSceneConfigQO(); + configQO.setCelltype(qo.getNetType()); + + vo.setNetType(qo.getNetType()); + + BigDecimal defaultNum = new BigDecimal(0); + PmKpiColorQo kpiColorQo = new PmKpiColorQo(); + kpiColorQo.setPrbupvalue(null != pmKpi4gMin.getPrbUp() ? pmKpi4gMin.getPrbUp() : defaultNum); + kpiColorQo.setPrbdownvalue(null != pmKpi4gMin.getPrbDown() ? pmKpi4gMin.getPrbDown() : defaultNum); + kpiColorQo.setAvgdisvalue(null != pmKpi4gMin.getAvgDisturb() ? BigDecimal.valueOf(pmKpi4gMin.getAvgDisturb()) : defaultNum); + kpiColorQo.setMaxuservalue(null != pmKpi4gMin.getMaxUser() ? BigDecimal.valueOf(pmKpi4gMin.getMaxUser()) : defaultNum); + kpiColorQo.setFreqtype(pmKpi4gMin.get小区频段()); + kpiColorQo.setDevicetype(pmKpi4gMin.get设备类型()); + kpiColorQo.setBandwidth(pmKpi4gMin.get带宽()); + kpiColorQo.setNettype(qo.getNetType()); + + Map fourKpiColor = dpSceneConfigMapper.getFourKpiColor(kpiColorQo); + + //平均用户 + PmKpiVO avgUser = new PmKpiVO(avgNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gMin.getAvgUser()) { + avgUser.setValue(pmKpi4gMin.getAvgUser()); + } + vo.set平均用户数(avgUser); + + //干扰值 + PmKpiVO disb = new PmKpiVO(avgDisturb, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gMin.getAvgDisturb()) { + disb.setValue(BigDecimal.valueOf(pmKpi4gMin.getAvgDisturb())); +// configQO.setValue(BigDecimal.valueOf(pmKpi4gMin.getAvgDisturb())); +// configQO.setName(KpiConstants.YW_FIELD_AVG_DIS); +// String avgdisbColor = dpSceneConfigMapper.getColorByQo(configQO); +// if (null != avgdisbColor) { +// disb.setColor(avgdisbColor); +// } + disb.setColor(fourKpiColor.get("avgdiscolor").toString()); + } + vo.set上行平均干扰(disb); + + //无线接通率 + PmKpiVO success = new PmKpiVO(succesNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gMin.getCallSuccRate()) { + success.setValue(pmKpi4gMin.getCallSuccRate()); + } + vo.set无线接通率(success); + + //无线掉线率 + PmKpiVO failrate = new PmKpiVO(failNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gMin.getCallDropRate()) { + failrate.setValue(pmKpi4gMin.getCallDropRate()); + } + vo.set无线掉线率(failrate); + + //最大用户数 + PmKpiVO maxUserVo = new PmKpiVO(maxuserNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gMin.getMaxUser()) { + maxUserVo.setValue(BigDecimal.valueOf(pmKpi4gMin.getMaxUser())); +// configQO.setName(KpiConstants.YW_FIELD_MAX_USER); +// configQO.setValue(BigDecimal.valueOf(pmKpi4gMin.getMaxUser())); +// String maxUserColor = dpSceneConfigMapper.getColorByQo(configQO); +// if (null != maxUserColor) { +// maxUserVo.setColor(maxUserColor); +// } + maxUserVo.setColor(fourKpiColor.get("maxusercolor").toString()); + } + vo.set最大用户数(maxUserVo); + + //上行prb利用率 + PmKpiVO upPrbVo = new PmKpiVO(prbupNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gMin.getPrbUp()) { + upPrbVo.setValue(pmKpi4gMin.getPrbUp()); +// configQO.setName(KpiConstants.YW_FIELD_RPB_DOWN); +// configQO.setValue(pmKpi4gMin.getPrbUp()); +// String upPrbVoColor = dpSceneConfigMapper.getColorByQo(configQO); +// if (null != upPrbVoColor) { +// upPrbVo.setColor(upPrbVoColor); +// } + upPrbVo.setColor(fourKpiColor.get("prbupcolor").toString()); + } + vo.set上行prb利用率(upPrbVo); + + //下行prb利用率 + PmKpiVO downPrbVo = new PmKpiVO(prbdownNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gMin.getPrbDown()) { + downPrbVo.setValue(pmKpi4gMin.getPrbDown()); +// configQO.setName(KpiConstants.YW_FIELD_RPB_DOWN); +// configQO.setValue(pmKpi4gMin.getPrbDown()); +// String downPrbVoColor = dpSceneConfigMapper.getColorByQo(configQO); +// if (null != downPrbVoColor) { +// downPrbVo.setColor(downPrbVoColor); +// } + downPrbVo.setColor(fourKpiColor.get("prbdowncolor").toString()); + } + vo.set下行prb利用率(downPrbVo); + + list.add(vo); + } + } + + IPage voPage = new Page<>(); + voPage.setRecords(list); + voPage.setTotal(PageInfo.of(records).getTotal()); + return voPage; + } + + @Override + public PmKpi4gMinVO fetchById(Long id) { + PmKpi4gMin entity = pmKpi4gMinMapper.selectById(id); + return PmKpi4gMinConvert.INSTANCE.entityToVo(entity); + } + + @Override + public boolean saveOrUpdate(PmKpi4gMinDTO dto) { + PmKpi4gMin entity = PmKpi4gMinConvert.INSTANCE.dtoToEntity(dto); + return saveOrUpdate(entity); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(pmKpi4gMinMapper.deleteBatchIds(ids)); + } + + @Override + public void export(PmKpiMinQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + ExcelUtil util = new ExcelUtil<>(PmKpi4gMinVO.class); + try { + util.exportExcel(response, data, "场馆4G小区级1分钟指标信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + + // 核查 + // boolean checkFlag; + // checkFlag = checkData(cs, ywSceneList); + // if (checkFlag) { + // checkFlag = checkUnique(cs); + // } + // if (!checkFlag) { + // ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); + // String fileName = (String) util.exportExcel(cs, "网元传输导入结果").get(AjaxResult.MSG_TAG); + // return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + // } + // saveBatch(list); + return null; + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi4gVenueServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi4gVenueServiceImpl.java new file mode 100644 index 0000000..cf4a170 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi4gVenueServiceImpl.java @@ -0,0 +1,117 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.eastcom_yw.common.constant.KpiConstants; +import com.ruoyi.eastcom_yw.domain.PmKpi4gCell; +import com.ruoyi.eastcom_yw.domain.PmKpi4gVenue; +import com.ruoyi.eastcom_yw.domain.PmKpi5gCell; +import com.ruoyi.eastcom_yw.domain.qo.DpSceneConfigQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiVenueQO; +import com.ruoyi.eastcom_yw.domain.vo.*; +import com.ruoyi.eastcom_yw.mapper.DpSceneConfigMapper; +import com.ruoyi.eastcom_yw.mapper.PmKpi4gCellMapper; +import com.ruoyi.eastcom_yw.mapper.PmKpi4gVenueMapper; +import com.ruoyi.eastcom_yw.service.PmKpi4gCellService; +import com.ruoyi.eastcom_yw.service.PmKpi4gVenueService; +import com.ruoyi.eastcom_yw.service.YwKpiConfigService; +import com.ruoyi.eastcom_yw.service.convert.PmKpi4gCellConvert; +import com.ruoyi.eastcom_yw.service.convert.PmKpi4gVenueConvert; +import com.ruoyi.eastcom_yw.service.convert.PmKpi5gCellConvert; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author yqf + * @date 2023/4/11 + */ +@Service +public class PmKpi4gVenueServiceImpl extends ServiceImpl implements PmKpi4gVenueService { + @Autowired + private PmKpi4gVenueMapper pmKpi4gVenueMapper; + + @Autowired + private PmKpi4gCellMapper pmKpi4gCellMapper; + + @Autowired + private DpSceneConfigMapper dpSceneConfigMapper; + + + + @Override + public IPage getDataByPage(PmKpiVenueQO qo) { + PageUtils.startPage(qo, PmKpiVenueQO.class); + List records = pmKpi4gVenueMapper.getList(qo); + List list = new ArrayList<>(); + + + DpSceneConfigQO configQO = new DpSceneConfigQO(); + configQO.setNettype(qo.getNetType()); + + for (PmKpi4gVenue pmKpi4gVenue : records) { + BigDecimal num = new BigDecimal("0"); + + PmKpi4gVenueConvertVO vo = new PmKpi4gVenueConvertVO(); + BeanUtil.copyProperties(pmKpi4gVenue, vo); + + //异常小区数 + int count = pmKpi4gCellMapper.getUnusualcount(pmKpi4gVenue.get场馆id(), qo.getStarttime(), qo.getEndtime(), qo.getNetType()); + PmKpiVO unusualcount = new PmKpiVO(KpiConstants.YW_KPI_COLOR_DEFAULT); + unusualcount.setValue(BigDecimal.valueOf(count)); + vo.setUnusualcount(unusualcount); + + //上行prb利用率 + PmKpiVO prbUpVo = new PmKpiVO( KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gVenue.get上行prb利用率()) { + prbUpVo.setValue(pmKpi4gVenue.get上行prb利用率()); + prbUpVo.setColor(pmKpi4gVenue.getPrbupColor()); + } + vo.set上行prb利用率(prbUpVo); + + //下行prb利用率 + PmKpiVO prbdownVo = new PmKpiVO(KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gVenue.get下行prb利用率()) { + prbdownVo.setValue(pmKpi4gVenue.get下行prb利用率()); + prbdownVo.setColor(pmKpi4gVenue.getPrbdownColor()); + } + vo.set下行prb利用率(prbdownVo); + + //小区总数 + int villageCount = pmKpi4gCellMapper.getVillageCount(pmKpi4gVenue.get场馆id(),qo.getStarttime(),qo.getEndtime()); + PmKpiVO countVO = new PmKpiVO(KpiConstants.YW_KPI_COLOR_DEFAULT); + countVO.setValue(BigDecimal.valueOf(villageCount)); + vo.setVillagecount(countVO); + + // 计算最大用户最大值 + PmKpiVO maxUserVo = new PmKpiVO(KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi4gVenue.get最大用户数()) { + maxUserVo.setValue(BigDecimal.valueOf(pmKpi4gVenue.get最大用户数())); + } + vo.setMaxusercount(maxUserVo); + + list.add(vo); + } + + IPage voPage = new Page<>(); + voPage.setRecords(list); + voPage.setTotal(PageInfo.of(records).getTotal()); + return voPage; + } + + @Override + public Map get4gVenueLastTime(Integer[] venueIds){ + return pmKpi4gVenueMapper.getLastTimeByvenueIds(venueIds); + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi5gCellServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi5gCellServiceImpl.java new file mode 100644 index 0000000..c1e337e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi5gCellServiceImpl.java @@ -0,0 +1,229 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.common.constant.KpiConstants; +import com.ruoyi.eastcom_yw.domain.PmKpi4gCell; +import com.ruoyi.eastcom_yw.domain.PmKpi5gCell; +import com.ruoyi.eastcom_yw.domain.PmKpiMaxEntity; +import com.ruoyi.eastcom_yw.domain.param.YwSceneCalendarParam; +import com.ruoyi.eastcom_yw.domain.qo.DpSceneConfigQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpi5gCellQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiColorQo; +import com.ruoyi.eastcom_yw.domain.vo.*; +import com.ruoyi.eastcom_yw.mapper.DpSceneConfigMapper; +import com.ruoyi.eastcom_yw.mapper.PmKpi4gCellMapper; +import com.ruoyi.eastcom_yw.mapper.PmKpi5gCellMapper; +import com.ruoyi.eastcom_yw.service.PmKpi5gCellService; +import com.ruoyi.eastcom_yw.service.convert.PmKpi4gCellConvert; +import com.ruoyi.eastcom_yw.service.convert.PmKpi5gCellConvert; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletResponse; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author yqf + * @date 2023/4/11 + */ +@Service +public class PmKpi5gCellServiceImpl extends ServiceImpl implements PmKpi5gCellService { + + @Autowired + private PmKpi5gCellMapper pmKpi5gCellMapper; + + + @Autowired + private DpSceneConfigMapper dpSceneConfigMapper; + + + /** + * 场馆5G小区级15分钟指标列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(PmKpiCellQO qo) { + qo.setPageSize(0); + List list = pmKpi5gCellMapper.getList(qo); + return PmKpi5gCellConvert.INSTANCE.entityToVoList(list); + } + + /** + * 场馆5G小区级15分钟指标分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public IPage getDataByPage(PmKpiCellQO qo) { + PageUtils.startPage(qo, PmKpiCellQO.class); + List records = pmKpi5gCellMapper.getList(qo); + List list = new ArrayList<>(); + + if (!records.isEmpty()) { + qo.setPageSize(0); + PmKpiMaxEntity maxKpi = pmKpi5gCellMapper.getMaxKpi(qo); + BigDecimal maxuserNum = maxKpi.getMaxuserNum(); + BigDecimal prbupNum = maxKpi.getPrbupNum(); + BigDecimal prbdownNum = maxKpi.getPrbdownNum(); + BigDecimal avgNum = maxKpi.getAvgNum(); + BigDecimal succesNum = maxKpi.getSuccesNum(); + BigDecimal failNum = maxKpi.getFailNum(); + BigDecimal avgDisturb = maxKpi.getAvgDisturb(); + + + for (PmKpi5gCell pmKpi5gCell : records) { + PmKpi15MinCellVO vo = new PmKpi15MinCellVO(); + BeanUtil.copyProperties(pmKpi5gCell, vo); + vo.setCellcodeci(pmKpi5gCell.getCi()); + + DpSceneConfigQO configQO = new DpSceneConfigQO(); + configQO.setCelltype(qo.getNetType()); + + vo.setNetType(qo.getNetType()); + + BigDecimal defaultNum = new BigDecimal(0); + PmKpiColorQo kpiColorQo = new PmKpiColorQo(); + kpiColorQo.setPrbupvalue(null != pmKpi5gCell.get上行prb利用率() ? pmKpi5gCell.get上行prb利用率() : defaultNum); + kpiColorQo.setPrbdownvalue(null != pmKpi5gCell.get下行prb利用率() ? pmKpi5gCell.get下行prb利用率() : defaultNum); + kpiColorQo.setAvgdisvalue(null != pmKpi5gCell.get上行干扰值() ? BigDecimal.valueOf(pmKpi5gCell.get上行干扰值()) : defaultNum); + kpiColorQo.setMaxuservalue(null != pmKpi5gCell.get最大用户数() ? pmKpi5gCell.get最大用户数() : defaultNum); + kpiColorQo.setFreqtype(pmKpi5gCell.get小区频段()); + kpiColorQo.setDevicetype(pmKpi5gCell.get设备类型()); + kpiColorQo.setBandwidth(pmKpi5gCell.get带宽()); + kpiColorQo.setNettype(qo.getNetType()); + + Map fourKpiColor = dpSceneConfigMapper.getFourKpiColor(kpiColorQo); + + //平均用户 + PmKpiVO avgUser = new PmKpiVO(avgNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gCell.get平均用户数()) { + avgUser.setValue(pmKpi5gCell.get平均用户数()); + } + vo.set平均用户数(avgUser); + + //干扰值 + PmKpiVO disb = new PmKpiVO(avgDisturb, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gCell.get上行干扰值()) { + disb.setValue(BigDecimal.valueOf(pmKpi5gCell.get上行干扰值())); +// configQO.setValue(BigDecimal.valueOf(pmKpi5gCell.get上行干扰值())); +// configQO.setName(KpiConstants.YW_FIELD_AVG_DIS); +// String avgdisbColor = dpSceneConfigMapper.getColorByQo(configQO); +// if (null != avgdisbColor) { +// disb.setColor(avgdisbColor); +// } + disb.setColor(fourKpiColor.get("avgdiscolor").toString()); + } + vo.set上行平均干扰(disb); + + //无线接通率 + PmKpiVO success = new PmKpiVO(succesNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gCell.get无线接通率()) { + success.setValue(pmKpi5gCell.get无线接通率()); + } + vo.set无线接通率(success); + + //无线掉线率 + PmKpiVO failrate = new PmKpiVO(failNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gCell.get无线掉线率()) { + failrate.setValue(pmKpi5gCell.get无线掉线率()); + } + vo.set无线掉线率(failrate); + + //最大用户数 + LocalDateTime starttime = qo.getStarttime().minusHours(6); + qo.setQuerystarttime(starttime); + qo.setQueryvenueid(pmKpi5gCell.getVenueId()); + qo.setVillageIds(new String[]{pmKpi5gCell.getCi()}); + List dataList = pmKpi5gCellMapper.getKpiDataList(qo); + vo.setKpi6HourData(dataList); + + PmKpiVO maxUserVo = new PmKpiVO(maxuserNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gCell.get最大用户数()) { + maxUserVo.setValue(pmKpi5gCell.get最大用户数()); +// configQO.setValue(pmKpi5gCell.get最大用户数()); +// configQO.setName(KpiConstants.YW_FIELD_MAX_USER); +// String maxUserColor = dpSceneConfigMapper.getColorByQo(configQO); +// if (null != maxUserColor) { +// maxUserVo.setColor(maxUserColor); +// } + maxUserVo.setColor(fourKpiColor.get("maxusercolor").toString()); + } + maxUserVo.setData(dataList); + vo.set最大用户数(maxUserVo); + + //上行prb利用率 +// List upPrbList = pmKpi5gCellMapper.getUpPrbList(qo); + PmKpiVO upPrbVo = new PmKpiVO(prbupNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gCell.get上行prb利用率()) { + upPrbVo.setValue(pmKpi5gCell.get上行prb利用率()); +// configQO.setName(KpiConstants.YW_FIELD_RPB_UP); +// configQO.setValue(pmKpi5gCell.get上行prb利用率()); +// String upPrbVoColor = dpSceneConfigMapper.getColorByQo(configQO); +// if (null != upPrbVoColor) { +// upPrbVo.setColor(upPrbVoColor); +// } + upPrbVo.setColor(fourKpiColor.get("prbupcolor").toString()); + } + upPrbVo.setData(dataList); + vo.set上行prb利用率(upPrbVo); + + //下行prb利用率 +// List downPrbList = pmKpi5gCellMapper.getDownPrbList(qo); + PmKpiVO downPrbVo = new PmKpiVO(prbdownNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gCell.get下行prb利用率()) { + downPrbVo.setValue(pmKpi5gCell.get下行prb利用率()); +// configQO.setName(KpiConstants.YW_FIELD_RPB_DOWN); +// configQO.setValue(pmKpi5gCell.get下行prb利用率()); +// String downPrbVoColor = dpSceneConfigMapper.getColorByQo(configQO); +// if (null != downPrbVoColor) { +// downPrbVo.setColor(downPrbVoColor); +// } + downPrbVo.setColor(fourKpiColor.get("prbdowncolor").toString()); + + } + downPrbVo.setData(dataList); + vo.set下行prb利用率(downPrbVo); + + list.add(vo); + } + } + IPage voPage = new Page<>(); + voPage.setRecords(list); + voPage.setTotal(PageInfo.of(records).getTotal()); + return voPage; + } + + + @Override + public void export(PmKpiCellQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + ExcelUtil util = new ExcelUtil<>(PmKpi5gCellVO.class); + try { + util.exportExcel(response, data, "场馆5G小区级15分钟指标信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi5gMinServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi5gMinServiceImpl.java new file mode 100644 index 0000000..fe97bac --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi5gMinServiceImpl.java @@ -0,0 +1,271 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.common.constant.KpiConstants; +import com.ruoyi.eastcom_yw.domain.PmKpi4gMin; +import com.ruoyi.eastcom_yw.domain.PmKpi5gMin; +import com.ruoyi.eastcom_yw.domain.PmKpiMaxEntity; +import com.ruoyi.eastcom_yw.domain.dto.PmKpi5gMinDTO; +import com.ruoyi.eastcom_yw.domain.param.YwSceneCalendarParam; +import com.ruoyi.eastcom_yw.domain.qo.DpSceneConfigQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpi5gMinQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiColorQo; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiMinQO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi5gMinVO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpiOneMinVO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpiVO; +import com.ruoyi.eastcom_yw.domain.vo.RecordVo; +import com.ruoyi.eastcom_yw.mapper.DpSceneConfigMapper; +import com.ruoyi.eastcom_yw.mapper.PmKpi5gMinMapper; +import com.ruoyi.eastcom_yw.service.PmKpi5gMinService; +import com.ruoyi.eastcom_yw.service.convert.PmKpi5gMinConvert; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + *

+ * 场馆5G小区级1分钟指标 服务实现类 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Service +public class PmKpi5gMinServiceImpl extends ServiceImpl implements PmKpi5gMinService { + + @Resource + private PmKpi5gMinMapper pmKpi5gMinMapper; + + @Autowired + private DpSceneConfigMapper dpSceneConfigMapper; + + /** + * 场馆5G小区级1分钟指标列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(PmKpiMinQO qo) { + qo.setPageSize(0); + List list = pmKpi5gMinMapper.getList(qo); + return PmKpi5gMinConvert.INSTANCE.entityToVoList(list); + } + + /** + * 场馆5G小区级1分钟指标分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public IPage getDataByPage(PmKpiMinQO qo) { + PageUtils.startPage(qo, PmKpiMinQO.class); + List records = pmKpi5gMinMapper.getList(qo); + List list = new ArrayList<>(); + + if (!records.isEmpty()) { + qo.setPageSize(0); + PmKpiMaxEntity maxKpi = pmKpi5gMinMapper.getMaxKpi(qo); + BigDecimal maxuserNum = maxKpi.getMaxuserNum(); + BigDecimal prbupNum = maxKpi.getPrbupNum(); + BigDecimal prbdownNum = maxKpi.getPrbdownNum(); + BigDecimal avgNum = maxKpi.getAvgNum(); + BigDecimal succesNum = maxKpi.getSuccesNum(); + BigDecimal failNum = maxKpi.getFailNum(); + BigDecimal avgDisturb = maxKpi.getAvgDisturb(); + + for (PmKpi5gMin pmKpi5gMin : records) { + PmKpiOneMinVO vo = new PmKpiOneMinVO(); + BeanUtil.copyProperties(pmKpi5gMin, vo); + + + DpSceneConfigQO configQO = new DpSceneConfigQO(); + configQO.setCelltype(qo.getNetType()); + vo.setNetType(qo.getNetType()); + + BigDecimal defaultNum = new BigDecimal(0); + PmKpiColorQo kpiColorQo = new PmKpiColorQo(); + kpiColorQo.setPrbupvalue(null != pmKpi5gMin.getPrbUp() ? BigDecimal.valueOf(pmKpi5gMin.getPrbUp()) : defaultNum); + kpiColorQo.setPrbdownvalue(null != pmKpi5gMin.getPrbDown() ? BigDecimal.valueOf(pmKpi5gMin.getPrbDown()) : defaultNum); + kpiColorQo.setAvgdisvalue(null != pmKpi5gMin.getUpDisturb() ? BigDecimal.valueOf(pmKpi5gMin.getUpDisturb()) : defaultNum); + kpiColorQo.setMaxuservalue(null != pmKpi5gMin.getRrcMaxUser() ? BigDecimal.valueOf(pmKpi5gMin.getRrcMaxUser()) : defaultNum); + kpiColorQo.setFreqtype(pmKpi5gMin.get小区频段()); + kpiColorQo.setDevicetype(pmKpi5gMin.get设备类型()); + kpiColorQo.setBandwidth(pmKpi5gMin.get带宽()); + kpiColorQo.setNettype(qo.getNetType()); + + Map fourKpiColor = dpSceneConfigMapper.getFourKpiColor(kpiColorQo); + + //平均用户 + PmKpiVO avgUser = new PmKpiVO(avgNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gMin.getRrcAvgUser()) { + avgUser.setValue(pmKpi5gMin.getRrcAvgUser()); + } + + vo.set平均用户数(avgUser); + + //干扰值 + PmKpiVO upDisturb = new PmKpiVO(avgDisturb, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gMin.getUpDisturb()) { + upDisturb.setValue(BigDecimal.valueOf(pmKpi5gMin.getUpDisturb())); +// configQO.setValue(BigDecimal.valueOf(pmKpi5gMin.getUpDisturb())); +// configQO.setName(KpiConstants.YW_FIELD_AVG_DIS); +// String avgdisbColor = dpSceneConfigMapper.getColorByQo(configQO); +// if (null != avgdisbColor) { +// upDisturb.setColor(avgdisbColor); +// } + upDisturb.setColor(fourKpiColor.get("avgdiscolor").toString()); + } + vo.set上行平均干扰(upDisturb); + + //无线接通率 + PmKpiVO success = new PmKpiVO(succesNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gMin.getCallSuccRate()) { + success.setValue(pmKpi5gMin.getCallSuccRate()); + } + vo.set无线接通率(success); + + //无线掉线率 + PmKpiVO failrate = new PmKpiVO(failNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gMin.getDropCallRate()) { + failrate.setValue(pmKpi5gMin.getDropCallRate()); + } + vo.set无线掉线率(failrate); + + //最大用户数 + PmKpiVO maxUserVo = new PmKpiVO(maxuserNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gMin.getRrcMaxUser()) { + maxUserVo.setValue(BigDecimal.valueOf(pmKpi5gMin.getRrcMaxUser())); +// configQO.setName(KpiConstants.YW_FIELD_MAX_USER); +// configQO.setValue(BigDecimal.valueOf(pmKpi5gMin.getRrcMaxUser())); +// String maxUserColor = dpSceneConfigMapper.getColorByQo(configQO); +// if (null != maxUserColor) { +// maxUserVo.setColor(maxUserColor); +// } + maxUserVo.setColor(fourKpiColor.get("maxusercolor").toString()); + } + vo.set最大用户数(maxUserVo); + + //上行prb利用率 + PmKpiVO upPrbVo = new PmKpiVO(prbupNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gMin.getPrbUp()) { + upPrbVo.setValue(BigDecimal.valueOf((pmKpi5gMin.getPrbUp()))); +// configQO.setValue(BigDecimal.valueOf(pmKpi5gMin.getPrbUp())); +// configQO.setName(KpiConstants.YW_FIELD_RPB_UP); +// String upPrbVoColor = dpSceneConfigMapper.getColorByQo(configQO); +// if (null != upPrbVoColor) { +// upPrbVo.setColor(upPrbVoColor); +// } + upPrbVo.setColor(fourKpiColor.get("prbupcolor").toString()); + } + + vo.set上行prb利用率(upPrbVo); + + //下行prb利用率 + PmKpiVO downPrbVo = new PmKpiVO(prbdownNum, KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gMin.getPrbDown()) { + downPrbVo.setValue(BigDecimal.valueOf(pmKpi5gMin.getPrbDown())); +// configQO.setValue(BigDecimal.valueOf(pmKpi5gMin.getPrbDown())); +// configQO.setName(KpiConstants.YW_FIELD_RPB_DOWN); +// String downPrbVoColor = dpSceneConfigMapper.getColorByQo(configQO); +// if (null != downPrbVoColor) { +// downPrbVo.setColor(downPrbVoColor); +// } + downPrbVo.setColor(fourKpiColor.get("prbdowncolor").toString()); + } + vo.set下行prb利用率(downPrbVo); + + list.add(vo); + } + } + + IPage voPage = new Page<>(); + voPage.setRecords(list); + voPage.setTotal(PageInfo.of(records).getTotal()); + return voPage; + } + + @Override + public PmKpi5gMinVO fetchById(Long id) { + PmKpi5gMin entity = pmKpi5gMinMapper.selectById(id); + return PmKpi5gMinConvert.INSTANCE.entityToVo(entity); + } + + @Override + public boolean saveOrUpdate(PmKpi5gMinDTO dto) { + PmKpi5gMin entity = PmKpi5gMinConvert.INSTANCE.dtoToEntity(dto); + return saveOrUpdate(entity); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(pmKpi5gMinMapper.deleteBatchIds(ids)); + } + + @Override + public void export(PmKpiMinQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + ExcelUtil util = new ExcelUtil<>(PmKpi5gMinVO.class); + try { + util.exportExcel(response, data, "场馆5G小区级1分钟指标信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + + // 核查 + // boolean checkFlag; + // checkFlag = checkData(cs, ywSceneList); + // if (checkFlag) { + // checkFlag = checkUnique(cs); + // } + // if (!checkFlag) { + // ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); + // String fileName = (String) util.exportExcel(cs, "网元传输导入结果").get(AjaxResult.MSG_TAG); + // return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + // } + // saveBatch(list); + return null; + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi5gVenueServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi5gVenueServiceImpl.java new file mode 100644 index 0000000..2dd5ec3 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpi5gVenueServiceImpl.java @@ -0,0 +1,127 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.eastcom_yw.common.constant.KpiConstants; +import com.ruoyi.eastcom_yw.domain.PmKpi4gCell; +import com.ruoyi.eastcom_yw.domain.PmKpi4gVenue; +import com.ruoyi.eastcom_yw.domain.PmKpi5gCell; +import com.ruoyi.eastcom_yw.domain.PmKpi5gVenue; +import com.ruoyi.eastcom_yw.domain.param.YwSceneCalendarParam; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiVenueQO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi4gVenueConvertVO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpi5gVenueVO; +import com.ruoyi.eastcom_yw.domain.vo.PmKpiVO; +import com.ruoyi.eastcom_yw.mapper.PmKpi4gCellMapper; +import com.ruoyi.eastcom_yw.mapper.PmKpi5gCellMapper; +import com.ruoyi.eastcom_yw.mapper.PmKpi5gVenueMapper; +import com.ruoyi.eastcom_yw.service.PmKpi5gVenueService; +import com.ruoyi.eastcom_yw.service.convert.PmKpi5gVenueConvert; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.RequestContextHolder; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + *

+ * 5G场馆级15分钟指标 服务实现类 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Service +public class PmKpi5gVenueServiceImpl extends ServiceImpl implements PmKpi5gVenueService { + + @Resource + private PmKpi5gVenueMapper pmKpi5gVenueMapper; + + @Autowired + private PmKpi5gCellMapper pmKpi5gCellMapper; + + + /** + * 5G场馆级15分钟指标分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public IPage getDataByPage(PmKpiVenueQO qo) { + PageUtils.startPage(qo, PmKpiVenueQO.class); + List records = pmKpi5gVenueMapper.getList(qo); + + List list = new ArrayList<>(); + + BigDecimal num = new BigDecimal("0"); + for (PmKpi5gVenue pmKpi5gVenue : records) { + PmKpi4gVenueConvertVO vo = new PmKpi4gVenueConvertVO(); + BeanUtil.copyProperties(pmKpi5gVenue, vo); + + //异常小区数 + int count = pmKpi5gCellMapper.getUnusualcount(pmKpi5gVenue.get场馆id(), qo.getStarttime(), qo.getEndtime(), qo.getNetType()); + PmKpiVO unusualcount = new PmKpiVO(KpiConstants.YW_KPI_COLOR_DEFAULT); + unusualcount.setValue(BigDecimal.valueOf(count)); + vo.setUnusualcount(unusualcount); + + //上行prb利用率 + PmKpiVO prbUpVo = new PmKpiVO( KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gVenue.get上行prb利用率()) { + prbUpVo.setValue(pmKpi5gVenue.get上行prb利用率()); + prbUpVo.setColor(pmKpi5gVenue.getPrbupColor()); + } + vo.set上行prb利用率(prbUpVo); + + //下行prb利用率 + PmKpiVO prbdownVo = new PmKpiVO(KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gVenue.get下行prb利用率()) { + prbdownVo.setValue(pmKpi5gVenue.get下行prb利用率()); + prbdownVo.setColor(pmKpi5gVenue.getPrbdownColor()); + } + vo.set下行prb利用率(prbdownVo); + + //小区总数 + int villageCount = pmKpi5gCellMapper.getVillageCount(pmKpi5gVenue.get场馆id(),qo.getStarttime(),qo.getEndtime()); + PmKpiVO countVO = new PmKpiVO(KpiConstants.YW_KPI_COLOR_DEFAULT); + countVO.setValue(BigDecimal.valueOf(villageCount)); + vo.setVillagecount(countVO); + + + // 计算最大用户最大值 + PmKpiVO maxUserVo = new PmKpiVO(KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != pmKpi5gVenue.get最大用户数()) { + maxUserVo.setValue(BigDecimal.valueOf(pmKpi5gVenue.get最大用户数())); + } + vo.setMaxusercount(maxUserVo); + + list.add(vo); + } + IPage voPage = new Page<>(); + voPage.setRecords(list); + voPage.setTotal(PageInfo.of(records).getTotal()); + return voPage; + } + + @Override + public Map get5gVenueLastTime(Integer[] venueIds){ + return pmKpi5gVenueMapper.getLastTimeByvenueIds(venueIds); + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpiMonitorCellServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpiMonitorCellServiceImpl.java new file mode 100644 index 0000000..5d00af1 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/PmKpiMonitorCellServiceImpl.java @@ -0,0 +1,747 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.common.constant.KpiConstants; +import com.ruoyi.eastcom_yw.domain.PmKpi4gCell; +import com.ruoyi.eastcom_yw.domain.PmKpi4gMin; +import com.ruoyi.eastcom_yw.domain.PmKpi5gMin; +import com.ruoyi.eastcom_yw.domain.PmKpiMonitorEntity; +import com.ruoyi.eastcom_yw.domain.param.YwSceneCalendarParam; +import com.ruoyi.eastcom_yw.domain.qo.*; +import com.ruoyi.eastcom_yw.domain.vo.*; +import com.ruoyi.eastcom_yw.mapper.*; +import com.ruoyi.eastcom_yw.service.PmKpiMonitorCellService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletResponse; +import java.math.BigDecimal; +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author yqf + * @date 2023/4/13 + */ +@Service +public class PmKpiMonitorCellServiceImpl implements PmKpiMonitorCellService { + + @Autowired + private PmKpi4gCellMapper pmKpi4gCellMapper; + + @Autowired + private PmKpi5gCellMapper pmKpi5gCellMapper; + + @Autowired + private Dp2AgisLink5miMapper agisLink5miMapper; + + @Autowired + private Dp2PnNetVenue5miMapper netVenue5miMapper; + + @Autowired + private DpSceneConfigMapper dpSceneConfigMapper; + + + @Autowired + private PmKpi4gMinMapper pmKpi4gMinMapper; + + + @Autowired + private PmKpi5gMinMapper pmKpi5gMinMapper; + + @Autowired + private PmKpi4gVenueMapper pmKpi4gVenueMapper; + + @Autowired + private PmKpi5gVenueMapper pmKpi5gVenueMapper; + + @Autowired + private YwScenePictureMapper ywScenePictureMapper; + + @Autowired + private Dp2PnNetVenue5miMapper dp2PnNetVenue5miMapper; + + @Autowired + private RedisCache redisCache; + + private String cell_key = CacheConstants.YW_KPIMONITORCELL_INFO; + private String min_key = CacheConstants.YW_KPIMONITORMIN_INFO; + + @Override + public PageInfo getMonitorCellList(PmKpiCellMonitorQO qo) { + PageInfo pageInfo = new PageInfo(); + Integer pageNum = qo.getPageNum(); + Integer pageSize = qo.getPageSize(); + List allList = new ArrayList<>(); + if (qo.getIscache()) { + if (qo.getDatatype().equals(KpiConstants.YW_DATATYPE_15)) { + allList = redisCache.getCacheObject(cell_key); + } else { + allList = redisCache.getCacheObject(min_key); + } + } else { + List voList = getMonitorVoList(qo); + + Map> map = voList.stream().collect(Collectors.groupingBy(e -> e.get坐席编号() + "|" + e.getVenueid())); + for (String key : map.keySet()) { + List list = map.get(key); + BigDecimal num = new BigDecimal("0.00"); + float score = 0; + MonitorCellVo monitorCellVo = new MonitorCellVo(); + monitorCellVo.setSeatid(key.substring(0, key.indexOf("|"))); + monitorCellVo.setCelllist(map.get(key)); + monitorCellVo.setVenuename(map.get(key).get(0).getVenuename()); + monitorCellVo.setVenueid(map.get(key).get(0).getVenueid()); + monitorCellVo.setPointid(map.get(key).get(0).getPointid()); + monitorCellVo.setStationno(map.get(key).get(0).getStationno()); + monitorCellVo.setPointname(map.get(key).get(0).getPointname()); + monitorCellVo.setLongitude(map.get(key).get(0).getLongitude()); + monitorCellVo.setLatitude(map.get(key).get(0).getLatitude()); + + //根据坐席分值判断颜色 + DpSceneConfigQO sceneConfigQO = new DpSceneConfigQO(); + sceneConfigQO.setNettype(qo.getNettype()); + + String seatcolor = ""; + int seatscore = 0; + String frequency = null; + String devicetype = null; + Long bandwidth = null; + + if (qo.getKpiname().equals(KpiConstants.YW_FIELD_ALL)) { + for (PmKpi15CellMonitorVO vo : map.get(key)) { + if (null != vo.get综合得分().getValue()) { + if (vo.get综合得分().getValue().compareTo(num) > 0) { + num = vo.get综合得分().getValue(); + } +// num = num.add(vo.get综合得分().getValue()); + } + } + + } else if (qo.getKpiname().equals(KpiConstants.YW_FIELD_RPB_UP)) { + //坐席指标值按所有小区最差的,上行prb利用率越大越差 +// num = list.stream().map(s -> s.get上行prb利用率().getValue().intValue()).max(Integer::compareTo).get(); + for (PmKpi15CellMonitorVO vo : map.get(key)) { + if (null != vo.get上行prb利用率().getValue()) { + if (score <= vo.get上行prb利用率().getScore()) { + score = vo.get上行prb利用率().getScore(); + num = vo.get上行prb利用率().getValue(); + } + } + } + + + } else if (qo.getKpiname().equals(KpiConstants.YW_FIELD_RPB_DOWN)) { +// num = list.stream().map(s -> s.get下行prb利用率().getValue().intValue()).max(Integer::compareTo).get(); + for (PmKpi15CellMonitorVO vo : map.get(key)) { + if (null != vo.get下行prb利用率().getValue()) { + if (score <= vo.get下行prb利用率().getScore()) { + score = vo.get下行prb利用率().getScore(); + num = vo.get下行prb利用率().getValue(); + } + } + } + + } else if (qo.getKpiname().equals(KpiConstants.YW_FIELD_MAX_USER)) { + //分设备类型 +// num = list.stream().map(s -> s.get最大用户数().getValue().intValue()).max(Integer::compareTo).get(); + for (PmKpi15CellMonitorVO vo : map.get(key)) { + if (null != vo.get最大用户数().getValue()) { + if (score <= vo.get最大用户数().getScore()) { + score = vo.get最大用户数().getScore(); + num = vo.get最大用户数().getValue(); + frequency = vo.get小区频段(); + devicetype = vo.get设备类型(); + bandwidth = vo.get带宽(); + } + } + } + + } else if (qo.getKpiname().equals(KpiConstants.YW_FIELD_AVG_DIS)) { +// num = list.stream().map(s -> s.get上行平均干扰().getValue().intValue()).max(Integer::compareTo).get(); + for (PmKpi15CellMonitorVO vo : map.get(key)) { + if (null != vo.get上行平均干扰().getValue()) { + if (score <= vo.get上行平均干扰().getScore()) { + score = vo.get上行平均干扰().getScore(); + num = vo.get上行平均干扰().getValue(); + } + } + } + } + + sceneConfigQO.setName(qo.getKpiname()); + sceneConfigQO.setValue(num); + Map colorAndScore = dpSceneConfigMapper.getkpiColorAndScore(qo.getKpiname(), num.doubleValue(), qo.getNettype(), + frequency, devicetype, bandwidth); +// seatcolor = dpSceneConfigMapper.getkpicolor(qo.getKpiname(), num.doubleValue(), qo.getNettype(), +// frequency, devicetype, bandwidth); +// seatscore = dpSceneConfigMapper.getkpicolorscore(qo.getKpiname(), num.doubleValue(), qo.getNettype(), +// frequency, devicetype, bandwidth); + monitorCellVo.setColor(colorAndScore.get("color").toString()); + monitorCellVo.setScore(Float.valueOf(colorAndScore.get("score").toString())); + + monitorCellVo.setKpiname(qo.getKpiname()); + monitorCellVo.setDatatype(qo.getDatatype()); + monitorCellVo.setNettype(qo.getNettype()); + + allList.add(monitorCellVo); + } + + //把多次查询组装查询 + + + if (null != qo.getSeatcolor() && !qo.getSeatcolor().equals("")) { + allList = allList.stream().filter(e -> e.getColor().equals(qo.getSeatcolor())).collect(Collectors.toList()); + } + + if (null != qo.getSortcol() && null != qo.getSort()) { + if (qo.getSort().equals(KpiConstants.YW_SORT_DESC)) { + allList = allList.stream().sorted(Comparator.comparing(MonitorCellVo::getScore).reversed()).collect(Collectors.toList()); + } else { + allList = allList.stream().sorted(Comparator.comparing(MonitorCellVo::getScore)).collect(Collectors.toList()); + } + + } + + int orderid = 1; + for (MonitorCellVo monitorCellVo : allList) { + monitorCellVo.setOrderid(orderid); + orderid++; + } + + + if (qo.getDatatype().equals(KpiConstants.YW_DATATYPE_15)) { + redisCache.deleteObject(cell_key); + redisCache.setCacheObject(cell_key, allList); + } else { + redisCache.deleteObject(min_key); + redisCache.setCacheObject(min_key, allList); + } + + } + pageInfo = getPageInfo(pageNum, pageSize, allList); + return pageInfo; + } + + private List getMonitorVoList(PmKpiCellMonitorQO qo) { + List voList = new ArrayList<>(); + List kpiList = new ArrayList<>(); + if (qo.getDatatype().equals(KpiConstants.YW_DATATYPE_15)) { + if (qo.getNettype().equals(KpiConstants.YW_NETTYPE_4G)) { + qo.setPageSize(0); + if (qo.getSceneruntype() == KpiConstants.YW_SCENE_RUNTYPE) { + kpiList = pmKpi4gCellMapper.getKpiCopyList(qo); + } else { + kpiList = pmKpi4gCellMapper.getKpiList(qo); + } + + } else { + qo.setPageSize(0); + if (qo.getSceneruntype() == KpiConstants.YW_SCENE_RUNTYPE) { + kpiList = pmKpi5gCellMapper.getKpiCopyList(qo); + } else { + kpiList = pmKpi5gCellMapper.getKpiList(qo); + } + + } + } else { + if (qo.getNettype().equals(KpiConstants.YW_NETTYPE_4G)) { + qo.setPageSize(0); + kpiList = pmKpi4gMinMapper.getKpiList(qo); + } else { + qo.setPageSize(0); + kpiList = pmKpi5gMinMapper.getKpiList(qo); + } + } + kpiList = kpiList.stream().filter(e -> null != e.get坐席编号()).collect(Collectors.toList()); + if (qo.getKpiname().equals(KpiConstants.YW_FIELD_RPB_UP)) { + kpiList = kpiList.stream().filter(e -> null != e.get上行prb利用率() && !e.get上行prb利用率().equals(new BigDecimal("0.00"))).collect(Collectors.toList()); + } else if (qo.getKpiname().equals(KpiConstants.YW_FIELD_RPB_DOWN)) { + kpiList = kpiList.stream().filter(e -> null != e.get下行prb利用率() && !e.get下行prb利用率().equals(new BigDecimal("0.00"))).collect(Collectors.toList()); + } else if (qo.getKpiname().equals(KpiConstants.YW_FIELD_AVG_DIS)) { + kpiList = kpiList.stream().filter(e -> null != e.get上行平均干扰() && !e.get上行平均干扰().equals(new BigDecimal("0.00"))).collect(Collectors.toList()); + } else if (qo.getKpiname().equals(KpiConstants.YW_FIELD_MAX_USER)) { + kpiList = kpiList.stream().filter(e -> null != e.get最大用户数() && !e.get最大用户数().equals(BigDecimal.ZERO)).collect(Collectors.toList()); + } + for (PmKpiMonitorEntity monitorEntity : kpiList) { + PmKpi15CellMonitorVO vo = new PmKpi15CellMonitorVO(); + BeanUtil.copyProperties(monitorEntity, vo); + + DpSceneConfigQO configQO = new DpSceneConfigQO(); + configQO.setNettype(qo.getNettype()); + + //根据各指标值查出对应的颜色 + //上行prb利用率 + PmKpiVO prbUp = new PmKpiVO(KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != monitorEntity.get上行prb利用率()) { + prbUp.setValue(monitorEntity.get上行prb利用率()); + prbUp.setColor(monitorEntity.getPrbupColor()); + prbUp.setScore(monitorEntity.getPrbupScore()); + } + vo.set上行prb利用率(prbUp); + + //下行prb利用率 + PmKpiVO prbDown = new PmKpiVO(KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != monitorEntity.get下行prb利用率()) { + prbDown.setValue(monitorEntity.get下行prb利用率()); + prbDown.setColor(monitorEntity.getPrbdownColor()); + prbDown.setScore(monitorEntity.getPrbdownScore()); + } + vo.set下行prb利用率(prbDown); + + //上行平均干扰 + PmKpiVO avgDisturb = new PmKpiVO(KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != monitorEntity.get上行平均干扰()) { + avgDisturb.setValue(monitorEntity.get上行平均干扰()); + avgDisturb.setColor(monitorEntity.getAvgdisColor()); + avgDisturb.setScore(monitorEntity.getAvgdisScore()); + } + vo.set上行平均干扰(avgDisturb); + + //最大用户数 + PmKpiVO maxUser = new PmKpiVO(KpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != monitorEntity.get最大用户数()) { + maxUser.setValue(monitorEntity.get最大用户数()); + maxUser.setColor(monitorEntity.getMaxuserColor()); + maxUser.setScore(monitorEntity.getMaxuserScore()); + } + vo.set最大用户数(maxUser); + + + ////综合得分 + PmKpiVO allkpi = new PmKpiVO(KpiConstants.YW_KPI_COLOR_DEFAULT); +// allkpi.setValue(BigDecimal.valueOf(getMaxScore(prbUp.getScore(), prbDown.getScore(), avgDisturb.getScore(), maxUser.getScore()))); + allkpi.setValue(BigDecimal.valueOf(prbUp.getScore() + prbDown.getScore() + maxUser.getScore())); + configQO.setName(KpiConstants.YW_FIELD_ALL); + configQO.setValue(allkpi.getValue()); + Map colorAndScore = dpSceneConfigMapper.getkpiColorAndScore(KpiConstants.YW_FIELD_ALL, + allkpi.getValue().doubleValue(), qo.getNettype(), null, null, null); +// String allcolor = dpSceneConfigMapper.getkpicolor(KpiConstants.YW_FIELD_ALL, +// allkpi.getValue().doubleValue(), qo.getNettype(), null, null, null); +// int allscore = dpSceneConfigMapper.getkpicolorscore(KpiConstants.YW_FIELD_ALL, +// allkpi.getValue().doubleValue(), qo.getNettype(), null, null, null); + allkpi.setColor(colorAndScore.get("color").toString()); + allkpi.setScore(Float.parseFloat(colorAndScore.get("score").toString())); + vo.set综合得分(allkpi); + + + vo.setNettype(qo.getNettype()); + voList.add(vo); + } + + return voList; + } + + private float getMaxScore(float prbUp, float prbDown, float avgDisturb, float maxUser) { + float score = 0; + if (prbUp > score) { + score = prbUp; + } + if (prbDown > score) { + score = prbDown; + } + if (avgDisturb > score) { + score = avgDisturb; + } + if (maxUser > score) { + score = maxUser; + } + return score; + } + + public static PageInfo getPageInfo(int currentPage, int pageSize, List list) { + int total = list.size(); + if (total > pageSize) { + int toIndex = pageSize * currentPage; + if (toIndex > total) { + toIndex = total; + } + int totalPage = total % pageSize == 0 ? (total / pageSize) : (total / pageSize) + 1; + if (totalPage < currentPage) { + list = new ArrayList<>(); + } else { + list = list.subList(pageSize * (currentPage - 1), toIndex); + } + } + Page page = new Page<>(currentPage, pageSize); + page.addAll(list); + page.setPages((total + pageSize - 1) / pageSize); + page.setTotal(total); + return new PageInfo<>(page); + } + + @Override + public PageInfo getDpMonitorCellList(DpKpiMonitorQO qo) { + Map map = new HashMap<>(); + if (qo.getDatatype().equals(KpiConstants.YW_DATATYPE_15)) { + if (qo.getNettype().equals(KpiConstants.YW_NETTYPE_4G)) { + map = pmKpi4gCellMapper.getLastTime(qo.getSceneid(), qo.getSeatno()); + } else { + map = pmKpi5gCellMapper.getLastTime(qo.getSceneid(), qo.getSeatno()); + } + } else { + if (qo.getNettype().equals(KpiConstants.YW_NETTYPE_4G)) { + map = pmKpi4gMinMapper.getLastTime(qo.getSceneid(), qo.getSeatno()); + } else { + map = pmKpi5gMinMapper.getLastTime(qo.getSceneid(), qo.getSeatno()); + } + } + + PageInfo pageInfo = new PageInfo(); + if (null != map && map.size() > 0) { + LocalDateTime starttime = ((Timestamp) map.get("starttime")).toLocalDateTime(); + LocalDateTime endtime = ((Timestamp) map.get("endtime")).toLocalDateTime(); + qo.setStarttime(starttime); + qo.setEndtime(endtime); + PmKpiCellMonitorQO monitorQO = new PmKpiCellMonitorQO(); + monitorQO.setIscache(false); + BeanUtil.copyProperties(qo, monitorQO); + monitorQO.setPageNum(1); + monitorQO.setPageSize(20000); + //用于演示版本 + if (qo.getSceneruntype() == KpiConstants.YW_SCENE_RUNTYPE) { + monitorQO.setEndtime(qo.getMaxtime()); + monitorQO.setStarttime(qo.getMaxtime().minusMinutes(15)); //提前15分钟 + monitorQO.setSceneruntype(qo.getSceneruntype()); + } + pageInfo = getMonitorCellList(monitorQO); + } + + return pageInfo; + } + + @Override + public int updateDpcSeneControl(DpcSeneControlVo dpcSeneControlVo) { + return pmKpi4gCellMapper.updateDpcSeneControl(dpcSeneControlVo); + } + + @Override + public KpiVenueReportVo getReportKpi(Integer venueid, LocalDateTime starttime, LocalDateTime endtime, Integer minute) { + KpiVenueReportVo reportVo = new KpiVenueReportVo(); + if (null == starttime || null == endtime) { + Map lastTimeMap = pmKpi5gVenueMapper.getLastTime(venueid); + if (null == lastTimeMap) { + return null; + } + starttime = ((Timestamp) lastTimeMap.get("endtime")).toLocalDateTime().minusMinutes(minute); + endtime = ((Timestamp) lastTimeMap.get("endtime")).toLocalDateTime(); + } + + BigDecimal sumbg5g = pmKpi5gVenueMapper.getsumbg(venueid, starttime, endtime); + if (null != sumbg5g) { + reportVo.set流量GB5g(sumbg5g); + } + + + BigDecimal sumbg4g = pmKpi4gVenueMapper.getsumbg(venueid, starttime, endtime); + if (null == sumbg4g) { + Map lastTimeMap = pmKpi4gVenueMapper.getLastTime(venueid); + if (null == lastTimeMap) { + return null; + } + starttime = ((Timestamp) lastTimeMap.get("starttime")).toLocalDateTime(); + endtime = ((Timestamp) lastTimeMap.get("endtime")).toLocalDateTime(); + } + sumbg4g = pmKpi4gVenueMapper.getsumbg(venueid, starttime, endtime); + LocalDateTime laststarttime = endtime.minusMinutes(15); + KpiVenueReportVo lastData4g = pmKpi4gVenueMapper.getLastData(venueid, laststarttime, endtime); + KpiVenueReportVo maxuserData4g = pmKpi4gCellMapper.getMaxuserData(venueid, laststarttime, endtime); + KpiVenueReportVo prbUpData4g = pmKpi4gCellMapper.getPrbUpData(venueid, laststarttime, endtime); + KpiVenueReportVo prbDownData4g = pmKpi4gCellMapper.getPrbDownData(venueid, laststarttime, endtime); + + reportVo.set开始时间(starttime); + reportVo.set结束时间(endtime); + + if (null != sumbg4g) { + reportVo.set流量GB4g(sumbg4g); + } + if (null != lastData4g) { + reportVo.set场馆id(lastData4g.get场馆id()); + reportVo.set无线掉线率4g(lastData4g.get无线掉线率4g()); + reportVo.set无线接通率4g(lastData4g.get无线接通率4g()); + reportVo.set上行平均干扰4g(lastData4g.get上行平均干扰4g()); + reportVo.set最大用户数4g(lastData4g.get最大用户数4g()); + } + if (null != maxuserData4g) { + reportVo.set最大用户数小区4g(maxuserData4g.get最大用户数小区4g()); + } + if (null != prbUpData4g) { + reportVo.set上行prb利用率4g(prbUpData4g.get上行prb利用率4g()); + reportVo.set上行prb利用率小区4g(prbUpData4g.get上行prb利用率小区4g()); + } + + if (null != prbDownData4g) { + reportVo.set下行prb利用率4g(prbDownData4g.get下行prb利用率4g()); + reportVo.set下行prb利用率小区4g(prbDownData4g.get下行prb利用率小区4g()); + } + + + if (null == sumbg5g) { + Map lastTimeMap = pmKpi4gVenueMapper.getLastTime(venueid); + if (null == lastTimeMap) { + return null; + } + starttime = ((Timestamp) lastTimeMap.get("endtime")).toLocalDateTime().minusMinutes(minute); + endtime = ((Timestamp) lastTimeMap.get("endtime")).toLocalDateTime(); + } + laststarttime = endtime.minusMinutes(15); + KpiVenueReportVo lastData5g = pmKpi5gVenueMapper.getLastData(venueid, laststarttime, endtime); + KpiVenueReportVo maxuserData5g = pmKpi5gCellMapper.getMaxuserData(venueid, laststarttime, endtime); + KpiVenueReportVo prbUpData5g = pmKpi5gCellMapper.getPrbUpData(venueid, laststarttime, endtime); + KpiVenueReportVo prbDownData5g = pmKpi5gCellMapper.getPrbDownData(venueid, laststarttime, endtime); + + + if (null != lastData5g) { + reportVo.set平均用户数5g(lastData5g.get平均用户数5g()); + reportVo.set最大用户数5g(lastData5g.get最大用户数5g()); + reportVo.setSn异常释放率5g(lastData5g.getSn异常释放率5g()); + reportVo.set无线接通率5g(lastData5g.get无线接通率5g()); + reportVo.set无线掉线率5g(lastData5g.get无线掉线率5g()); + reportVo.set切换成功率5g(lastData5g.get切换成功率5g()); + reportVo.set上行干扰值5g(lastData5g.get上行干扰值5g()); + reportVo.setSgnb添加成功率5g(lastData5g.getSgnb添加成功率5g()); + } + if (null != maxuserData5g) { + reportVo.set小区最大用户数5g(maxuserData5g.get小区最大用户数5g()); + reportVo.set小区最大用户数小区5g(maxuserData5g.get小区最大用户数小区5g()); + } + if (null != prbUpData5g) { + reportVo.set上行prb利用率5g(prbUpData5g.get上行prb利用率5g()); + reportVo.set上行prb利用率小区5g(prbUpData5g.get上行prb利用率小区5g()); + } + if (null != prbDownData5g) { + reportVo.set下行prb利用率5g(prbDownData5g.get下行prb利用率5g()); + reportVo.set下行prb利用率小区5g(prbDownData5g.get下行prb利用率小区5g()); + } + return reportVo; + } + + @Override + public JSONObject getReportKpiByJson(Integer venueid, LocalDateTime starttime, LocalDateTime endtime, Integer minute) { + if (null == starttime || null == endtime) { + Map lastTimeMap = pmKpi5gVenueMapper.getLastTime(venueid); + if (null == lastTimeMap) { + return null; + } + starttime = ((Timestamp) lastTimeMap.get("endtime")).toLocalDateTime().minusMinutes(minute); + endtime = ((Timestamp) lastTimeMap.get("endtime")).toLocalDateTime(); + } + BigDecimal sumbg5g = pmKpi5gVenueMapper.getsumbg(venueid, starttime, endtime); + + if (null == sumbg5g) { + Map lastTimeMap = pmKpi4gVenueMapper.getLastTime(venueid); + if (null == lastTimeMap) { + return null; + } + starttime = ((Timestamp) lastTimeMap.get("endtime")).toLocalDateTime().minusMinutes(minute); + endtime = ((Timestamp) lastTimeMap.get("endtime")).toLocalDateTime(); + } + + JSONObject jsonObject = new JSONObject(); + + KpiVenueReportVo venueReportVo = getReportKpi(venueid, starttime, endtime, minute); + + KpiReport4gVo kpiReport4gVo = new KpiReport4gVo(); + if (venueReportVo == null) { + return null; + } + BeanUtil.copyProperties(venueReportVo, kpiReport4gVo); + + + PmKpiVenueQO kpiVenueQO = new PmKpiVenueQO(); + kpiVenueQO.setVenueId(venueid); + kpiVenueQO.setStarttime(endtime.minusHours(24)); + kpiVenueQO.setEndtime(endtime); + + kpiVenueQO.setPageSize(0); + List data4gList = pmKpi4gVenueMapper.getKpiDataList(kpiVenueQO); + + DateTimeFormatter fmt = DateTimeFormatter.ofPattern("HH:mm"); + List gb4gList = data4gList.stream().map( + red -> new KpiTrendVo("总流量", red.getGbcount(), fmt.format(red.getTime()))).collect(Collectors.toList()); + List avgdisturb4gList = data4gList.stream().map( + red -> new KpiTrendVo("上行平均干扰", red.getAvgdisturbcount(), fmt.format(red.getTime()))).collect(Collectors.toList()); + List mauser4gList = data4gList.stream().map( + red -> new KpiTrendVo("最大用户数", red.getMaxusercount(), fmt.format(red.getTime()))).collect(Collectors.toList()); + List prbup4gList = data4gList.stream().map( + red -> new KpiTrendVo("上行prb利用率", red.getPrbupcount(), fmt.format(red.getTime()))).collect(Collectors.toList()); + List prbdown4gList = data4gList.stream().map( + red -> new KpiTrendVo("下行prb利用率", red.getPrbdowncount(), fmt.format(red.getTime()))).collect(Collectors.toList()); + + kpiReport4gVo.setGbList(gb4gList); + kpiReport4gVo.setAvgdisturbList(avgdisturb4gList); + kpiReport4gVo.setPrbupList(prbup4gList); + kpiReport4gVo.setPrbdownList(prbdown4gList); + kpiReport4gVo.setMauserList(mauser4gList); + + List gb4gTop5ist = pmKpi4gCellMapper.getTop5List(venueid, starttime, endtime, KpiConstants.FIELD_4G_GB).stream() + .map(i -> new KpiTrendVo(i.get小区名称(), i.get上行流量mb())).collect(Collectors.toList()); + List avgdisturb4gTop5ist = pmKpi4gCellMapper.getTop5List(venueid, starttime, endtime, KpiConstants.FIELD_4G_DISTURB).stream() + .map(i -> new KpiTrendVo(i.get小区名称(), i.get上行平均干扰())).collect(Collectors.toList()); + List mauser4gTop5ist = pmKpi4gCellMapper.getTop5List(venueid, starttime, endtime, KpiConstants.FIELD_4G_MAXUSER).stream() + .map(i -> new KpiTrendVo(i.get小区名称(), i.get最大用户数())).collect(Collectors.toList()); + List prbup4gTop5ist = pmKpi4gCellMapper.getTop5List(venueid, starttime, endtime, KpiConstants.FIELD_4G_PRBUP).stream() + .map(i -> new KpiTrendVo(i.get小区名称(), i.get上行prb利用率())).collect(Collectors.toList()); + List prbdown4gTop5ist = pmKpi4gCellMapper.getTop5List(venueid, starttime, endtime, KpiConstants.FIELD_4G_PRBDOWN).stream() + .map(i -> new KpiTrendVo(i.get小区名称(), i.get下行prb利用率())).collect(Collectors.toList()); + + kpiReport4gVo.setGbTop5List(gb4gTop5ist); + kpiReport4gVo.setAvgdisturbTop5List(avgdisturb4gTop5ist); + kpiReport4gVo.setMauserTop5List(mauser4gTop5ist); + kpiReport4gVo.setPrbupTop5List(prbup4gTop5ist); + kpiReport4gVo.setPrbdownTop5List(prbdown4gTop5ist); + + + KpiReport5gVo kpiReport5gVo = new KpiReport5gVo(); + BeanUtil.copyProperties(venueReportVo, kpiReport5gVo); + + List data5gList = pmKpi5gVenueMapper.getKpiDataList(kpiVenueQO); + + List gb5gList = data5gList.stream().map( + red -> new KpiTrendVo("总流量", red.getGbcount(), fmt.format(red.getTime()))).collect(Collectors.toList()); + List avgdisturb5gList = data5gList.stream().map( + red -> new KpiTrendVo("上行平均干扰", red.getAvgdisturbcount(), fmt.format(red.getTime()))).collect(Collectors.toList()); + List mauser5gList = data5gList.stream().map( + red -> new KpiTrendVo("最大用户数", red.getMaxusercount(), fmt.format(red.getTime()))).collect(Collectors.toList()); + List prbup5gList = data5gList.stream().map( + red -> new KpiTrendVo("上行prb利用率", red.getPrbupcount(), fmt.format(red.getTime()))).collect(Collectors.toList()); + List prbdown5gList = data5gList.stream().map( + red -> new KpiTrendVo("下行prb利用率", red.getPrbdowncount(), fmt.format(red.getTime()))).collect(Collectors.toList()); + kpiReport5gVo.setGbList(gb5gList); + kpiReport5gVo.setAvgdisturbList(avgdisturb5gList); + kpiReport5gVo.setPrbupList(prbup5gList); + kpiReport5gVo.setPrbdownList(prbdown5gList); + kpiReport5gVo.setMauserList(mauser5gList); + + List gb5gTop5ist = pmKpi5gCellMapper.getTop5List(venueid, starttime, endtime, KpiConstants.FIELD_5G_GB).stream() + .map(i -> new KpiTrendVo(i.get小区名称(), i.get上行5g流量())).collect(Collectors.toList()); + List avgdisturb5gTop5ist = pmKpi5gCellMapper.getTop5List(venueid, starttime, endtime, KpiConstants.FIELD_5G_DISTURB).stream() + .map(i -> new KpiTrendVo(i.get小区名称(), BigDecimal.valueOf(i.get上行干扰值()))).collect(Collectors.toList()); + List mauser5gTop5ist = pmKpi5gCellMapper.getTop5List(venueid, starttime, endtime, KpiConstants.FIELD_5G_MAXUSER).stream() + .map(i -> new KpiTrendVo(i.get小区名称(), i.get最大用户数())).collect(Collectors.toList()); + List prbup5gTop5ist = pmKpi5gCellMapper.getTop5List(venueid, starttime, endtime, KpiConstants.FIELD_5G_PRBUP).stream() + .map(i -> new KpiTrendVo(i.get小区名称(), i.get上行prb利用率())).collect(Collectors.toList()); + List prbdown5gTop5ist = pmKpi5gCellMapper.getTop5List(venueid, starttime, endtime, KpiConstants.FIELD_5G_PRBDOWN).stream() + .map(i -> new KpiTrendVo(i.get小区名称(), i.get下行prb利用率())).collect(Collectors.toList()); + + kpiReport5gVo.setGbTop5List(gb5gTop5ist); + kpiReport5gVo.setAvgdisturbTop5List(avgdisturb5gTop5ist); + kpiReport5gVo.setMauserTop5List(mauser5gTop5ist); + kpiReport5gVo.setPrbupTop5List(prbup5gTop5ist); + kpiReport5gVo.setPrbdownTop5List(prbdown5gTop5ist); + + jsonObject.put("kpiReport4gVo", kpiReport4gVo); + jsonObject.put("kpiReport5gVo", kpiReport5gVo); + + + YwSceneNetAgixStaVo agixStaVo = ywScenePictureMapper.getNetAgixStatis(venueid.longValue(), starttime, endtime); + jsonObject.put("kpiReportAgix", agixStaVo); + + DateTimeFormatter dft = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + if (null != agixStaVo) { + + List flowTop5List = agisLink5miMapper.getAgislinkTop5List(venueid, starttime, endtime, KpiConstants.FIELD_AGIS_FLOWCOUNT).stream() + .map(i -> new KpiLinkTrendVo(i.getLinkName(), i.getADeviceName(), i.getFlowcount(), i.getStatDate().format(dft))).collect(Collectors.toList()); + List ullocityTop5List = agisLink5miMapper.getAgislinkTop5List(venueid, starttime, endtime, KpiConstants.FIELD_AGIS_UL_VELOCITY).stream() + .map(i -> new KpiLinkTrendVo(i.getLinkName(), i.getADeviceName(), i.getUlVelocity(), i.getStatDate().format(dft))).collect(Collectors.toList()); + List dllocityTop5List = agisLink5miMapper.getAgislinkTop5List(venueid, starttime, endtime, KpiConstants.FIELD_AGIS_DL_VELOCITY).stream() + .map(i -> new KpiLinkTrendVo(i.getLinkName(), i.getADeviceName(), i.getDlVelocity(), i.getStatDate().format(dft))).collect(Collectors.toList()); + List ulbandratioTop5List = agisLink5miMapper.getAgislinkTop5List(venueid, starttime, endtime, KpiConstants.FIELD_AGIS_UL_BAND_RATIO).stream() + .map(i -> new KpiLinkTrendVo(i.getLinkName(), i.getADeviceName(), i.getUlBandRatio(), i.getStatDate().format(dft))).collect(Collectors.toList()); + List dlbandratioTop5List = agisLink5miMapper.getAgislinkTop5List(venueid, starttime, endtime, KpiConstants.FIELD_AGIS_DL_BAND_RATIO).stream() + .map(i -> new KpiLinkTrendVo(i.getLinkName(), i.getADeviceName(), i.getDlBandRatio(), i.getStatDate().format(dft))).collect(Collectors.toList()); + + agixStaVo.setFlowTop5List(flowTop5List); + agixStaVo.setUllocityTop5List(ullocityTop5List); + agixStaVo.setDllocityTop5List(dllocityTop5List); + agixStaVo.setUlbandratioTop5List(ulbandratioTop5List); + agixStaVo.setDlbandratioTop5List(dlbandratioTop5List); + + } + YwSceneNetStaVo netStatis = ywScenePictureMapper.getNetStatis(venueid.longValue(), starttime, endtime); + jsonObject.put("kpiReportNet", netStatis); + + + YwSceneNetFixtelStaVo fixtelStaVo = ywScenePictureMapper.getNetFixtelStatis(venueid.longValue(), starttime, endtime); + if(null == fixtelStaVo){ + fixtelStaVo = ywScenePictureMapper.getNetFixtelStatis(venueid.longValue(), null, null); + } + jsonObject.put("kpiReportFixtel", fixtelStaVo); + + + YwSceneTransStaVo transStaVo = new YwSceneTransStaVo(); + + List opticalpowerTop5 = ywScenePictureMapper.getOpticalpowerTop5List(venueid.longValue(), 3, starttime, endtime); + jsonObject.put("kpiReportOpticalpowerTop5", opticalpowerTop5); + + String maxInOpticalpower = ""; + YwSceneTransOpticalpowerStaVo maxInOpticalpowerVo = ywScenePictureMapper.getMaxInOpticalpower(venueid.longValue(), starttime, endtime); + if (null != maxInOpticalpowerVo) { + maxInOpticalpower = maxInOpticalpowerVo.getInOpticalpower() + ""; + }else { + maxInOpticalpowerVo = ywScenePictureMapper.getMaxInOpticalpower(venueid.longValue(), null, null); + maxInOpticalpower = maxInOpticalpowerVo.getInOpticalpower() + ""; + starttime = LocalDateTime.parse(maxInOpticalpowerVo.getDateTime(),dft); + endtime = LocalDateTime.parse(maxInOpticalpowerVo.getDateTime(),dft).plusMinutes(minute); + opticalpowerTop5 = ywScenePictureMapper.getOpticalpowerTop5List(venueid.longValue(), 3, starttime, endtime); + } + + String maxOutOpticalpower = ""; + + + + List outopticalpowerTop5 = ywScenePictureMapper.getOutOpticalpowerTop5List(venueid.longValue(), 3, starttime, endtime); + + YwSceneTransOpticalpowerStaVo maxOutOpticalpowerVo = ywScenePictureMapper.getMaxOutOpticalpower(venueid.longValue(), starttime, endtime); + if(null != maxOutOpticalpowerVo){ + maxOutOpticalpower = maxOutOpticalpowerVo.getOutOpticalpower() + ""; + }else { + maxOutOpticalpowerVo = ywScenePictureMapper.getMaxOutOpticalpower(venueid.longValue(), null, null); + maxOutOpticalpower = maxOutOpticalpowerVo.getOutOpticalpower() + ""; + starttime = LocalDateTime.parse(maxOutOpticalpowerVo.getDateTime(),dft); + endtime = LocalDateTime.parse(maxOutOpticalpowerVo.getDateTime(),dft).plusMinutes(minute); + outopticalpowerTop5 = ywScenePictureMapper.getOutOpticalpowerTop5List(venueid.longValue(), 3, starttime, endtime); + } + + + transStaVo.setOpticalpowerTop5(opticalpowerTop5); + transStaVo.setOutopticalpowerTop5(outopticalpowerTop5); + transStaVo.setMaxInOpticalpower(maxInOpticalpower); + transStaVo.setMaxOutOpticalpower(maxOutOpticalpower); + + jsonObject.put("kpiReportOpticalpower", transStaVo); + + + return jsonObject; + } + + @Override + public void exportMonitorList(PmKpiCellMonitorQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getMonitorVoList(qo); + ExcelUtil util = new ExcelUtil<>(PmKpi15CellMonitorVO.class); + try { + util.exportExcel(response, data, "性能监控数据信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/SysNoticeServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/SysNoticeServiceImpl.java new file mode 100644 index 0000000..2a31b08 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/SysNoticeServiceImpl.java @@ -0,0 +1,341 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.SysNotice; +import com.ruoyi.eastcom_yw.domain.YwNoticeBriefing; +import com.ruoyi.eastcom_yw.domain.dto.SysNoticeDTO; +import com.ruoyi.eastcom_yw.domain.qo.SysNoticeQO; +import com.ruoyi.eastcom_yw.domain.vo.SysNoticeVO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeModelVO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeObjectVO; +import com.ruoyi.eastcom_yw.mapper.SysNoticeMapper; +import com.ruoyi.eastcom_yw.mapper.YwNoticeBriefingMapper; +import com.ruoyi.eastcom_yw.service.SysNoticeService; +import com.ruoyi.eastcom_yw.service.YwNoticeModelService; +import com.ruoyi.eastcom_yw.service.YwNoticeObjectService; +import com.ruoyi.eastcom_yw.service.convert.SysNoticeConvert; +import com.ruoyi.framework.web.domain.dto.MobileOfficesDTO; +import com.ruoyi.framework.web.service.sms.MessageService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 通知公告表 服务实现类 + *

+ * + * @author ck + * @since 2023-04-14 + */ +@Service +@Slf4j +public class SysNoticeServiceImpl extends ServiceImpl implements SysNoticeService { + + @Resource + private SysNoticeMapper sysNoticeMapper; + + @Resource + private YwNoticeModelService ywNoticeModelService; + + @Resource + private YwNoticeObjectService ywNoticeObjectService; + + @Resource + private YwNoticeBriefingMapper ywNoticeBriefingMapper; + + @Resource + private MessageService messageService; + + + /** + * 通知公告表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(SysNoticeQO qo) { + if(qo.getExpSendTime()!=null){ + LocalDateTime expSendTime = qo.getExpSendTime(); + qo.setBeginTime(LocalDateTimeUtil.beginOfDay(expSendTime)); + qo.setEndTime(LocalDateTimeUtil.endOfDay(expSendTime)); + } + qo.setPageNum(null); + qo.setPageSize(null); + List data = sysNoticeMapper.getData(qo); + for (SysNoticeVO vo : data) { + translate(vo); + } + return data; + } + + /** + * 通知公告表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public IPage getDataByPage(SysNoticeQO qo) { + + if (qo.getExpSendTime() != null) { + LocalDateTime begin = LocalDateTimeUtil.beginOfDay(qo.getExpSendTime()); + LocalDateTime end = LocalDateTimeUtil.endOfDay(qo.getExpSendTime()); + qo.setBeginTime(begin); + qo.setEndTime(end); + } + List vos = sysNoticeMapper.getData(qo); + //翻译场馆和用户名 + for (SysNoticeVO vo : vos) { + translate(vo); + Long userId = SecurityUtils.getUserId(); + vo.setCanUpdate("0"); + if (vo.getSendUser() != null && userId.equals(vo.getSendUser()) && "3".equals(vo.getModelSuitType()) && "2".equals(vo.getAddFlag())) { + if (vo.getHandworkId() != null) { + YwNoticeBriefing briefing = ywNoticeBriefingMapper.selectById(vo.getHandworkId()); + if (briefing != null) { + if ("0".equals(briefing.getSysNormalDisable())) { + vo.setCanUpdate("1"); + } + } + } + } + } + IPage voPage = new Page<>(); + voPage.setRecords(vos); + voPage.setTotal(PageInfo.of(vos).getTotal()); + return voPage; + } + + @Override + public SysNoticeVO fetchById(Long id) { + SysNotice entity = sysNoticeMapper.selectById(id); + SysNoticeVO vo = SysNoticeConvert.INSTANCE.entityToVo(entity); + translate(vo); + return vo; + } + + @Override + public boolean saveOrUpdate(SysNoticeDTO dto) { + SysNotice entity = SysNoticeConvert.INSTANCE.dtoToEntity(dto); + return saveOrUpdate(entity); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(sysNoticeMapper.deleteBatchIds(ids)); + } + + @Override + public void export(SysNoticeQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + for (int i = 1; i < data.size() + 1; i++) { + SysNoticeVO sysNoticeVO = data.get(i - 1); + sysNoticeVO.setNoticeId(i); + } + ExcelUtil util = new ExcelUtil<>(SysNoticeVO.class); + try { + util.exportExcel(response, data, "通知记录"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + + // 核查 + // boolean checkFlag; + // checkFlag = checkData(cs, ywSceneList); + // if (checkFlag) { + // checkFlag = checkUnique(cs); + // } + // if (!checkFlag) { + // ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); + // String fileName = (String) util.exportExcel(cs, "网元传输导入结果").get(AjaxResult.MSG_TAG); + // return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + // } + // saveBatch(list); + return null; + } + + @Override + public int isReadNotice(Long[] noticeIds) { + return sysNoticeMapper.isReadNotice(noticeIds); + } + + /** + * 查询所有需要发送的短信 + */ + @Override + public List selectToDoSMSList() { + return sysNoticeMapper.selectToDoSMSList(); + } + + @Override + public void eastcomYwSendSMSSchedule() { + List sysNotices = this.selectToDoSMSList(); + for (SysNotice sysNotice : sysNotices) { + sysNotice.setAddFlag("1"); + this.updateById(sysNotice); + } + + for (SysNotice sysNotice : sysNotices) { + JSONObject res = null; + //实际发送短信 + res = messageService.sendSMS(sysNotice.getNoticeContent(), sysNotice.getReciveUserPhone()); + //保存发送结果 + sysNotice.setSendTime(LocalDateTime.now()); + if ("1".equals(res.getString("code"))) { + sysNotice.setSendStatus("1"); + } else { + sysNotice.setSendStatus("0"); + } + sysNotice.setRemark(res.getString("message")); + this.updateById(sysNotice); + } + } + + @Override + @Transactional + public void newEastcomYwSendSMSSchedule() { + List sysNotices = this.selectToDoSMSList(); + if(CollUtil.isEmpty(sysNotices)){ + return; + } + send(sysNotices); + } + + @Override + @Transactional + public void send(List sysNotices) { + for (SysNotice sysNotice : sysNotices) { + sysNotice.setAddFlag("1"); + this.updateById(sysNotice); + } + + for (SysNotice sysNotice : sysNotices) { + JSONObject res = null; + if ("3".equals(sysNotice.getNoticeType()) && ("1".equals(sysNotice.getModelSuitType()) || "2".equals(sysNotice.getModelSuitType()))) { + log.info("发送短信++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + res = messageService.sendSMS(sysNotice.getNoticeContent(), sysNotice.getReciveUserPhone()); + } else if ("5".equals(sysNotice.getNoticeType())) { + MobileOfficesDTO dto = new MobileOfficesDTO(); + dto.setMobileoffices(sysNotice.getGroupId()); + dto.setMobileoffice_user(null); + dto.setFile(null); + dto.setFilename(null); + dto.setImg(null); + dto.setImgname(null); + dto.setContent(sysNotice.getNoticeContent()); + res = messageService.sendMobileOffice(dto); + } else if ("7".equals(sysNotice.getNoticeType()) && ("1".equals(sysNotice.getModelSuitType()) || "2".equals(sysNotice.getModelSuitType()))) { + res = messageService.sendIvr(sysNotice.getNoticeContent(), sysNotice.getReciveUserPhone()); + } else { + log.info("发送短信++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + res = messageService.sendSMS(sysNotice.getNoticeContent(), sysNotice.getReciveUserPhone()); + } + + //保存发送结果 + sysNotice.setSendTime(LocalDateTime.now()); + if (res != null) { + if ("1".equals(res.getString("code"))) { + sysNotice.setSendStatus("1"); + } else { + sysNotice.setSendStatus("0"); + } + sysNotice.setRemark(res.getString("message")); + this.updateById(sysNotice); + } else { + sysNotice.setRemark("三方短信无反馈"); + log.error("三方短信无反馈"); + sysNotice.setSendStatus("0"); + this.updateById(sysNotice); + } + } + } + + + @Override + public void saveAndSendBriefing(SysNoticeDTO dto) { +// saveOrUpdate(dto); + SysNotice byId = getById(dto.getNoticeId()); + if (byId != null) { + if ("1".equals(byId.getAddFlag())) { + throw new ServiceException("手工简报已发送"); + } + if (byId.getHandworkId() != null) { + YwNoticeBriefing briefing = ywNoticeBriefingMapper.selectById(byId.getHandworkId()); + if (briefing == null) { + throw new ServiceException("简报计划不存在"); + } else { + if ("1".equals(briefing.getSysNormalDisable())) { + throw new ServiceException("简报计划已停用"); + } + } + } + byId.setNoticeContent(dto.getNoticeContent()); + byId.setNoticeContent(byId.getNoticeContent().replaceAll("<.*?>", "").replace("\n(在此输入其他性能数据)","").replace("(","").replace("(","").replace(")","").replace(")","").replaceAll("(\\s*)", "").replaceAll("\\(\\s*\\)", "")); + + ArrayList sysNotices = new ArrayList<>(); + + sysNotices.add(byId); + send(sysNotices); +// byId.setAddFlag("0"); +// byId.setExpSendTime(LocalDateTime.now()); +// sysNoticeMapper.updateById(byId); + } + } + + @Override + public List selectNoticeListByUser(Long reciveUserId) { + return sysNoticeMapper.selectNoticeListByUser(reciveUserId); + } + + private void translate(SysNoticeVO vo) { + YwNoticeModelVO modelVO = ywNoticeModelService.fetchById(vo.getNoticeModelId()); + vo.setNoticeModelIdStr(modelVO); + if (modelVO != null) { + vo.setNoticeModelName(modelVO.getModelName()); + } + + List objectIds = vo.getNoticeObjectId(); + if (CollUtil.isNotEmpty(objectIds)) { + List objectVOS = ywNoticeObjectService.fetchByIds(objectIds); + vo.setNoticeObjectIdStr(objectVOS); + vo.setNoticeObject(objectVOS.stream().map(YwNoticeObjectVO::getObjectName).collect(Collectors.joining(","))); + } + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/WeatherServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/WeatherServiceImpl.java new file mode 100644 index 0000000..21978dc --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/WeatherServiceImpl.java @@ -0,0 +1,102 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.http.HttpUtil; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.service.WeatherService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.Iterator; + +@Service +@Slf4j +public class WeatherServiceImpl implements WeatherService { + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private YwSceneService ywSceneService; + + @Override + public AjaxResult fetchById(Long venueId) { + YwScene venue = ywSceneService.getById(venueId); + if (venue == null) { + throw new ServiceException("场馆不存在"); + } + String venueName = venue.getVenueName(); + String url = "https://szqx.hzqx.com/getUrl?cache=1&url=/hzcitybrain/homepage/GetAllStadiumInfo_v1"; + String response = HttpUtil.get(url); + JsonNode jsonNode = null; + try { + jsonNode = objectMapper.readTree(response); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + HashMap map = extractDataFromJson(jsonNode); + if (!map.containsKey(venueName)) { + throw new ServiceException("未取到匹配的场馆名:" + venueName); + } + String stationCode = map.get(venueName); + String queryTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + String queryUrl = "https://szqx.hzqx.com/getUrl?url=/hzcitybrain/zdz/complex/GetNearDataByStationCodeAndWeatherKeys_v3?" + + "dataRate=fiveminute%26stationCode="+stationCode+"%26weatherKeys=rain_sum_1h,airtemp_current,rh_current,wind_current,stapressure_current,vis_current,comfort_current" + + "%26queryTime="+queryTime+"%26isNeedStationInfo=false%26blackType=-1"; + String response1 = HttpUtil.get(queryUrl); + JsonNode dataNode = null; + try { + dataNode = objectMapper.readTree(response1); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + JsonNode rows1 = dataNode.withArray("Rows").get(0); + HashMap resMap = new HashMap<>(); + resMap.put("近一小时降水", rows1.get(4).asText()); + resMap.put("温度", rows1.get(6).asText()); + resMap.put("湿度", rows1.get(8).asText()); + resMap.put("风速", rows1.get(11).asText()); + resMap.put("气压", rows1.get(14).asText()); + resMap.put("能见度", rows1.get(16).asText()); + return AjaxResult.success(resMap); + } + + // 提取方法,解析JsonNode并返回HashMap + private HashMap extractDataFromJson(JsonNode jsonNode) { + Iterator rows = jsonNode.withArray("Rows").iterator(); + HashMap map = new HashMap<>(); + while (rows.hasNext()) { + JsonNode next = rows.next(); + map.put(next.get(1).asText(), next.get(23).asText()); + } + return map; + } + + public static void main(String[] args) { + String s = HttpUtil.get("https://szqx.hzqx.com/getUrl?cache=1&url=/hzcitybrain/homepage/GetAllStadiumInfo_v1"); + JsonNode jsonNode = null; + ObjectMapper objectMapper = new ObjectMapper(); + try { + jsonNode = objectMapper.readTree(s); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + Iterator rows = jsonNode.withArray("Rows").iterator(); + HashMap map = new HashMap<>(); + while (rows.hasNext()) { + JsonNode next = rows.next(); + map.put(next.get(23).asText(), next.get(1).asText()); + } + + + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmCSServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmCSServiceImpl.java new file mode 100644 index 0000000..730259c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmCSServiceImpl.java @@ -0,0 +1,225 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.constant.AlarmConstants; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.constant.TaskConstants; +import com.ruoyi.common.core.domain.dto.StartProcessInstanceDTO; +import com.ruoyi.common.core.domain.dto.json.UserInfo; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.eastcom_yw.domain.*; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSearchDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmInfoVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmLastVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmNewNumVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmVo; +import com.ruoyi.eastcom_yw.mapper.*; +import com.ruoyi.eastcom_yw.mapper.YwAlarmCSMapper; +import com.ruoyi.eastcom_yw.service.CommonService; +import com.ruoyi.eastcom_yw.service.YwAlarmCSService; +import com.ruoyi.eastcom_yw.service.YwAlarmOprateLogService; +import com.ruoyi.eastcom_yw.service.YwAlarmCSService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +/** + *

+ * 服务实现类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Service +public class YwAlarmCSServiceImpl extends ServiceImpl implements YwAlarmCSService { + + @Autowired + private YwAlarmCSMapper ywAlarmCSMapper; + + @Autowired + private YwAlarmViewMapper ywAlarmViewMapper; + + @Autowired + private YwAlarmOprateLogService ywAlarmOprateLogService; + + @Autowired + private CommonService commonService; + + @Override + public TableDataInfo GetAlarmList(YwAlarmDTO alarmDTO) { + + LambdaQueryWrapper lambdaQueryWrapper=new LambdaQueryWrapper<>(); + + //告警当前的处理状态 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getDealStatus()),YwAlarmView::getDealStatus, alarmDTO.getDealStatus()); + + //告警的状态 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getAlarmStatus())&&"0".equals(alarmDTO.getAlarmStatus()), YwAlarmView::getAlarmStatus, alarmDTO.getAlarmStatus()); + + //告警名称模糊查询 + lambdaQueryWrapper.like(StringUtils.isNotEmpty(alarmDTO.getAlarmName()),YwAlarmView::get告警名称, alarmDTO.getAlarmName()); + + //告警的区县 + //20230303区县改为AreaCountyId查询 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getCounty()), YwAlarmView::getAreaCountyId, alarmDTO.getCounty()); + + //告警的场馆 + lambdaQueryWrapper.in(CollUtil.isNotEmpty(alarmDTO.getVenues()), YwAlarmView::get场馆id, alarmDTO.getVenues()); + + //告警的类型 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getAlarmType()), YwAlarmView::getAlarmType, alarmDTO.getAlarmType()); + + //告警的专业 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getAlarmGroup()), YwAlarmView::getAlarmType, alarmDTO.getAlarmGroup()); + + //告警的专业 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getInRedLine()), YwAlarmView::get红线内, alarmDTO.getInRedLine()); + + //告警的时间 + lambdaQueryWrapper.between(ObjectUtils.isNotEmpty(alarmDTO.getStartTime()) && ObjectUtils.isNotEmpty(alarmDTO.getEndTime()), YwAlarmView::get告警时间, alarmDTO.getStartTime(), alarmDTO.getEndTime()+" 23:59:59"); + + //告警搜索框 + if(StrUtil.isNotBlank(alarmDTO.getSearchBox())){ + lambdaQueryWrapper.and(i->i.like(YwAlarmView::get告警名称,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::getDealUser,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::get基站号,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::get基站名,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::get网元名称,alarmDTO.getSearchBox())); + } + + + Page page= ywAlarmCSMapper.selectPage(new Page<>(alarmDTO.getPageNum(), alarmDTO.getPageSize()),lambdaQueryWrapper); + + TableDataInfo rspData = new TableDataInfo(); + + rspData.setTotal(page.getTotal()); + + List listVo=new ArrayList<>(); + + for(YwAlarmView ywAlarmsLast: page.getRecords()) + { + + int clearNum=0; + + YwAlarmLastVo ywAlarmLastVo=new YwAlarmLastVo(); + + LambdaQueryWrapper lambdaQueryWrapperOper=new LambdaQueryWrapper<>(); + lambdaQueryWrapperOper.eq(YwAlarmOprateLog::getAlarmGroup, ywAlarmsLast.get关联组号()); + lambdaQueryWrapperOper.eq(YwAlarmOprateLog::getUserId,alarmDTO.getUserId()); + ywAlarmLastVo.setOpId(0L); + //查询告警用户是否点击 + ywAlarmOprateLogService.list(lambdaQueryWrapperOper).forEach( + ywAlarmOprateLog -> { + ywAlarmLastVo.setOpId(ywAlarmOprateLog.getId()); + } + ); + + ywAlarmLastVo.setKey(ywAlarmsLast.getId()); + if(ObjectUtils.isEmpty(ywAlarmsLast.get场馆id())) + { + continue; + } + ywAlarmLastVo.setVenue_id(ywAlarmsLast.get场馆id().toString()); + ywAlarmLastVo.setCg(ywAlarmsLast.get场馆名称()); + //工单号 +// ywAlarmLastVo.setGd(""); + ywAlarmLastVo.setSite_id(ywAlarmsLast.get基站号()); + ywAlarmLastVo.setSite_name(ywAlarmsLast.get基站名()); + ywAlarmLastVo.setNet_name(ywAlarmsLast.get网元名称()); + ywAlarmLastVo.setGroupId(ywAlarmsLast.get关联组号()); + ywAlarmLastVo.setName(ywAlarmsLast.get告警名称()); + ywAlarmLastVo.setStart(ywAlarmsLast.get告警时间()); + ywAlarmLastVo.setEnd(ywAlarmsLast.get恢复时间()); + if(StringUtils.isNotEmpty(ywAlarmsLast.get恢复时间())) + { + clearNum++; + } + ywAlarmLastVo.setInRedLine(ywAlarmsLast.get红线内()); + ywAlarmLastVo.setUserId(ywAlarmsLast.getDealUserId()); + ywAlarmLastVo.setPerson(ywAlarmsLast.getDealUser()); + //冗余state + ywAlarmLastVo.setState(ywAlarmsLast.getDealStatus()); + ywAlarmLastVo.setAlarmStatus(ywAlarmsLast.getAlarmStatus()); + ywAlarmLastVo.setDealStatus(ywAlarmsLast.getDealStatus()); + ywAlarmLastVo.setState(ywAlarmsLast.getDealStatus()); + ywAlarmLastVo.setProcessId(ywAlarmsLast.getProcessId()); + ywAlarmLastVo.setTaskId(ywAlarmsLast.getTaskId()); + //20230308增加了反馈人的红蓝白区标签 + ywAlarmLastVo.setBelongArea(ywAlarmsLast.getBelongArea()); + //用户判断主告警和次告警是否全部恢复了,空表示没有,全部恢复显示最新的恢复时间 + ywAlarmLastVo.setLastClearTime(ywAlarmsLast.getLastClearTime()); + + ywAlarmLastVo.setIsHangup(ywAlarmsLast.getIsHangup()); + + //查询次要告警 + List ywAlarmListLess = ywAlarmViewMapper.getYwAlarmByGroupId(ywAlarmsLast.getAlarmType(),ywAlarmsLast.get关联组号()); + //当前告警总数 + int alarmNum = ywAlarmListLess.size()+1; + + List ywAlarmVoList=new ArrayList(); + if(ywAlarmListLess.size()>0) + { + for(YwAlarmVo ywAlarmLess: ywAlarmListLess) + { + +// 设计问题导致前端用了Net_name和Site_name + YwAlarmVo ywAlarmVo = new YwAlarmVo(); + + BeanUtils.copyBeanProp(ywAlarmVo,ywAlarmLess); + + ywAlarmVo.setNet_name(ywAlarmLess.getNetName()); + + ywAlarmVo.setSite_name(ywAlarmLess.getSiteName()); + + if(StringUtils.isNotEmpty(ywAlarmLess.getEnd())) + { + clearNum++; + } + + ywAlarmVoList.add(ywAlarmVo); + + } + } + ywAlarmLastVo.setAlarmchildren(ywAlarmVoList); + ywAlarmLastVo.setClearNum(clearNum); + ywAlarmLastVo.setClearNumDisplay(clearNum+"/"+alarmNum); + + // //查询工作流,比较是否是当前登录用户的待办 + //APP端 + if(alarmDTO.getIsAPP()) { + List processIds = commonService.selectCurrenUserTodoProcessId(alarmDTO.getAlarmType()); + if (CollUtil.isNotEmpty(processIds)) { + for (String processId : processIds) { + if (processId.equals(ywAlarmLastVo.getProcessId())) { + ywAlarmLastVo.setIsTodo(1); + } + } + } + } + + listVo.add(ywAlarmLastVo); + } + + rspData.setRows(listVo); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setMsg("查询成功"); + return rspData; + + } + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmDHServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmDHServiceImpl.java new file mode 100644 index 0000000..d8034c1 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmDHServiceImpl.java @@ -0,0 +1,216 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.eastcom_yw.domain.*; +import com.ruoyi.eastcom_yw.domain.YwAlarmDH; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmLastVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmVo; +import com.ruoyi.eastcom_yw.mapper.YwAlarmDHMapper; +import com.ruoyi.eastcom_yw.mapper.YwAlarmDHMapper; +import com.ruoyi.eastcom_yw.mapper.YwAlarmMapper; +import com.ruoyi.eastcom_yw.mapper.YwAlarmViewMapper; +import com.ruoyi.eastcom_yw.service.CommonService; +import com.ruoyi.eastcom_yw.service.YwAlarmDHService; +import com.ruoyi.eastcom_yw.service.YwAlarmDHService; +import com.ruoyi.eastcom_yw.service.YwAlarmOprateLogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + *

+ * 服务实现类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Service +public class YwAlarmDHServiceImpl extends ServiceImpl implements YwAlarmDHService { + + @Autowired + private YwAlarmDHMapper ywAlarmDHMapper; + @Autowired + private YwAlarmViewMapper ywAlarmViewMapper; + @Autowired + private YwAlarmOprateLogService ywAlarmOprateLogService; + + @Autowired + private CommonService commonService; + + @Override + public TableDataInfo GetAlarmList(YwAlarmDTO alarmDTO) { + + LambdaQueryWrapper lambdaQueryWrapper=new LambdaQueryWrapper<>(); + + //告警当前的处理状态 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getDealStatus()),YwAlarmView::getDealStatus, alarmDTO.getDealStatus()); + + //告警的状态 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getAlarmStatus())&&"0".equals(alarmDTO.getAlarmStatus()), YwAlarmView::getAlarmStatus, alarmDTO.getAlarmStatus()); + + //告警名称模糊查询 + lambdaQueryWrapper.like(StringUtils.isNotEmpty(alarmDTO.getAlarmName()),YwAlarmView::get告警名称, alarmDTO.getAlarmName()); + + //告警的区县 + //20230303区县改为AreaCountyId查询 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getCounty()), YwAlarmView::getAreaCountyId, alarmDTO.getCounty()); + + //告警的场馆 + lambdaQueryWrapper.in(CollUtil.isNotEmpty(alarmDTO.getVenues()), YwAlarmView::get场馆id, alarmDTO.getVenues()); + + //告警的类型 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getAlarmType()), YwAlarmView::getAlarmType, alarmDTO.getAlarmType()); + + //告警的专业 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getAlarmGroup()), YwAlarmView::getAlarmType, alarmDTO.getAlarmGroup()); + + //告警的专业 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getInRedLine()), YwAlarmView::get红线内, alarmDTO.getInRedLine()); + + //告警的时间 + lambdaQueryWrapper.between(ObjectUtils.isNotEmpty(alarmDTO.getStartTime()) && ObjectUtils.isNotEmpty(alarmDTO.getEndTime()), YwAlarmView::get告警时间, alarmDTO.getStartTime(), alarmDTO.getEndTime()+" 23:59:59"); + + //告警搜索框 + if(StrUtil.isNotBlank(alarmDTO.getSearchBox())){ + lambdaQueryWrapper.and(i->i.like(YwAlarmView::get告警名称,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::getDealUser,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::get基站号,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::get基站名,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::get网元名称,alarmDTO.getSearchBox())); + } + + + Page page= ywAlarmDHMapper.selectPage(new Page<>(alarmDTO.getPageNum(), alarmDTO.getPageSize()),lambdaQueryWrapper); + + TableDataInfo rspData = new TableDataInfo(); + + rspData.setTotal(page.getTotal()); + + List listVo=new ArrayList<>(); + + for(YwAlarmView ywAlarmsLast: page.getRecords()) + { + + int clearNum=0; + + YwAlarmLastVo ywAlarmLastVo=new YwAlarmLastVo(); + + LambdaQueryWrapper lambdaQueryWrapperOper=new LambdaQueryWrapper<>(); + lambdaQueryWrapperOper.eq(YwAlarmOprateLog::getAlarmGroup, ywAlarmsLast.get关联组号()); + lambdaQueryWrapperOper.eq(YwAlarmOprateLog::getUserId,alarmDTO.getUserId()); + ywAlarmLastVo.setOpId(0L); + //查询告警用户是否点击 + ywAlarmOprateLogService.list(lambdaQueryWrapperOper).forEach( + ywAlarmOprateLog -> { + ywAlarmLastVo.setOpId(ywAlarmOprateLog.getId()); + } + ); + + ywAlarmLastVo.setKey(ywAlarmsLast.getId()); + if(ObjectUtils.isEmpty(ywAlarmsLast.get场馆id())) + { + continue; + } + ywAlarmLastVo.setVenue_id(ywAlarmsLast.get场馆id().toString()); + ywAlarmLastVo.setCg(ywAlarmsLast.get场馆名称()); + //工单号 +// ywAlarmLastVo.setGd(""); + ywAlarmLastVo.setSite_id(ywAlarmsLast.get基站号()); + ywAlarmLastVo.setSite_name(ywAlarmsLast.get基站名()); + ywAlarmLastVo.setNet_name(ywAlarmsLast.get网元名称()); + ywAlarmLastVo.setGroupId(ywAlarmsLast.get关联组号()); + ywAlarmLastVo.setName(ywAlarmsLast.get告警名称()); + ywAlarmLastVo.setStart(ywAlarmsLast.get告警时间()); + ywAlarmLastVo.setEnd(ywAlarmsLast.get恢复时间()); + if(StringUtils.isNotEmpty(ywAlarmsLast.get恢复时间())) + { + clearNum++; + } + ywAlarmLastVo.setInRedLine(ywAlarmsLast.get红线内()); + ywAlarmLastVo.setUserId(ywAlarmsLast.getDealUserId()); + ywAlarmLastVo.setPerson(ywAlarmsLast.getDealUser()); + //冗余state + ywAlarmLastVo.setState(ywAlarmsLast.getDealStatus()); + ywAlarmLastVo.setAlarmStatus(ywAlarmsLast.getAlarmStatus()); + ywAlarmLastVo.setDealStatus(ywAlarmsLast.getDealStatus()); + ywAlarmLastVo.setState(ywAlarmsLast.getDealStatus()); + ywAlarmLastVo.setProcessId(ywAlarmsLast.getProcessId()); + ywAlarmLastVo.setTaskId(ywAlarmsLast.getTaskId()); + //20230308增加了反馈人的红蓝白区标签 + ywAlarmLastVo.setBelongArea(ywAlarmsLast.getBelongArea()); + //用户判断主告警和次告警是否全部恢复了,空表示没有,全部恢复显示最新的恢复时间 + ywAlarmLastVo.setLastClearTime(ywAlarmsLast.getLastClearTime()); + + ywAlarmLastVo.setIsHangup(ywAlarmsLast.getIsHangup()); + + //查询次要告警 + List ywAlarmListLess = ywAlarmViewMapper.getYwAlarmByGroupId(ywAlarmsLast.getAlarmType(),ywAlarmsLast.get关联组号()); + //当前告警总数 + int alarmNum = ywAlarmListLess.size()+1; + + List ywAlarmVoList=new ArrayList(); + if(ywAlarmListLess.size()>0) + { + for(YwAlarmVo ywAlarmLess: ywAlarmListLess) + { + +// 设计问题导致前端用了Net_name和Site_name + YwAlarmVo ywAlarmVo = new YwAlarmVo(); + + BeanUtils.copyBeanProp(ywAlarmVo,ywAlarmLess); + + ywAlarmVo.setNet_name(ywAlarmLess.getNetName()); + + ywAlarmVo.setSite_name(ywAlarmLess.getSiteName()); + + if(StringUtils.isNotEmpty(ywAlarmLess.getEnd())) + { + clearNum++; + } + + ywAlarmVoList.add(ywAlarmVo); + + } + } + ywAlarmLastVo.setAlarmchildren(ywAlarmVoList); + ywAlarmLastVo.setClearNum(clearNum); + ywAlarmLastVo.setClearNumDisplay(clearNum+"/"+alarmNum); + + // //查询工作流,比较是否是当前登录用户的待办 + //APP端 + if(alarmDTO.getIsAPP()) { + List processIds = commonService.selectCurrenUserTodoProcessId(alarmDTO.getAlarmType()); + if (CollUtil.isNotEmpty(processIds)) { + for (String processId : processIds) { + if (processId.equals(ywAlarmLastVo.getProcessId())) { + ywAlarmLastVo.setIsTodo(1); + } + } + } + } + + listVo.add(ywAlarmLastVo); + } + + rspData.setRows(listVo); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setMsg("查询成功"); + return rspData; + + } + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmHangupLogServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmHangupLogServiceImpl.java new file mode 100644 index 0000000..5bf997f --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmHangupLogServiceImpl.java @@ -0,0 +1,161 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.ruoyi.common.constant.AlarmConstants; +import com.ruoyi.common.core.domain.dto.HandleDataDTO; +import com.ruoyi.common.core.domain.dto.json.UserInfo; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.domain.YwAlarmHangupLog; +import com.ruoyi.eastcom_yw.domain.YwAlarmHangupReover; +import com.ruoyi.eastcom_yw.domain.YwAlarmView; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmHangupLogDTO; +import com.ruoyi.eastcom_yw.domain.yw_alarm_deal_log; +import com.ruoyi.eastcom_yw.mapper.YwAlarmHangupLogMapper; +import com.ruoyi.eastcom_yw.mapper.yw_alarm_deal_logMapper; +import com.ruoyi.eastcom_yw.service.CommonService; +import com.ruoyi.eastcom_yw.service.YwAlarmHangupLogService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; +import java.util.List; + +/** + *

+ * 服务实现类 + *

+ * + * @author jkj + * @since 2023-02-15 + */ +@Service +public class YwAlarmHangupLogServiceImpl extends ServiceImpl implements YwAlarmHangupLogService { + + @Autowired + private YwAlarmHangupLogMapper ywAlarmHangupLogMapper; + + + @Autowired + private yw_alarm_deal_logMapper yw_alarm_deal_logMapper; + + + @Autowired + private CommonService commonService; + + @Transactional(rollbackFor = Exception.class) + @Override + public boolean insertYwAlarmHangupLog(YwAlarmHangupLogDTO ywAlarmHangupLogDTO) { + + if(StringUtils.isEmpty(ywAlarmHangupLogDTO.getFlwProcessid())) + { + throw new ServiceException("挂起的流程号不允许为空"); + } + + Date hangupEnd = DateUtils.parseDate(ywAlarmHangupLogDTO.getHangupTime()); + + YwAlarmHangupLog ywAlarmHangupLog=new YwAlarmHangupLog(); + ywAlarmHangupLog.setHangupUserId(ywAlarmHangupLogDTO.getHangupUserId()); + ywAlarmHangupLog.setHangupTime(hangupEnd); + ywAlarmHangupLog.setHangupReason(ywAlarmHangupLogDTO.getHangupReason()); + ywAlarmHangupLog.setFlwProcessid(ywAlarmHangupLogDTO.getFlwProcessid()); + ywAlarmHangupLog.setFlwTaskid(ywAlarmHangupLogDTO.getFlwTaskid()); + ywAlarmHangupLog.setHangupStatus(ywAlarmHangupLogDTO.getHangupStatus()); + + //如果是取消挂起,需要计算这次挂起的时长累加到deal_log表 + if("0".equals(ywAlarmHangupLogDTO.getHangupStatus())) + { + QueryWrapper queryWrapper=new QueryWrapper<>(); + queryWrapper.eq("hangup_status","2"); + queryWrapper.eq("flw_processid",ywAlarmHangupLogDTO.getFlwProcessid()); + queryWrapper.eq("flw_taskid",ywAlarmHangupLogDTO.getFlwTaskid()); + queryWrapper.orderByDesc("hangup_time"); + YwAlarmHangupLog hangupLog = ywAlarmHangupLogMapper.selectList(queryWrapper).get(0); + Date hangupBegin =hangupLog.getHangupTime(); + + //这里用的是分钟,不满一分钟按一分钟算 + double durMinute = Math.ceil((double) ((DateUtils.getNowDate().getTime() - hangupBegin.getTime()) / (1000*60))); + + if(yw_alarm_deal_logMapper.updateHangupSpantime(durMinute,ywAlarmHangupLogDTO.getFlwProcessid())==0) + { + throw new ServiceException("取消挂起失败,挂起时长更新出错,请联系管理员"); + } + } + if(StringUtils.isNotEmpty(ywAlarmHangupLogDTO.getRecoveryTime())) + { + ywAlarmHangupLog.setRecoveryTime(DateUtils.parseDate(ywAlarmHangupLogDTO.getRecoveryTime())); + } + if(ywAlarmHangupLogMapper.insert(ywAlarmHangupLog)>0) + { + return true; + } + if("2".equals(ywAlarmHangupLogDTO.getHangupStatus())) { + throw new ServiceException("挂起失败,请联系管理员"); + } + if("0".equals(ywAlarmHangupLogDTO.getHangupStatus())) { + throw new ServiceException("取消挂起失败,请联系管理员"); + } + return false; + } + + @Override + @Deprecated + public void updateAlarmHangupSchedule() { + + List list = ywAlarmHangupLogMapper.getYwAlarmHangupReoverList(); + + for (YwAlarmHangupReover ywAlarmHangupReover : list) + { + try { + + boolean res=false; + + + HandleDataDTO handleDataDTO = new HandleDataDTO(); + UserInfo user = new UserInfo(); + user.setId(ywAlarmHangupReover.getHangupUserId().toString()); + handleDataDTO.setProcessInstanceId(ywAlarmHangupReover.getFlwProcessid()); + handleDataDTO.setTaskId(ywAlarmHangupReover.getFlwTaskid()); + handleDataDTO.setCurrentUserInfo(user); + //这2个在agreeTask没有用 + handleDataDTO.setTransferUserInfo(user); + handleDataDTO.setTransferType(1); + + //0表示告警没有全部恢复,需要退回重新处理,1表示告警全部恢复了,这个告警就不用处理,自动完结 + if (AlarmConstants.NoRecover.equals(ywAlarmHangupReover.getIsRecover())) { + + res = commonService.UpdateProcessStatus(handleDataDTO); + + } + + if (AlarmConstants.Recover.equals(ywAlarmHangupReover.getIsRecover())) { + + res = commonService.agreeTask(handleDataDTO); + } + + if(res) + { + //回填挂起记录表的恢复结果 + YwAlarmHangupLog ywAlarmHangupLog=new YwAlarmHangupLog(); + ywAlarmHangupLog.setId(ywAlarmHangupReover.getId()); + ywAlarmHangupLog.setRecoveryResult(ywAlarmHangupReover.getIsRecover()); + ywAlarmHangupLogMapper.updateById(ywAlarmHangupLog); + + } + + } + catch (Exception e) { + System.out.println(e.getMessage()); + continue; + } + } + + } + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmOprateLogServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmOprateLogServiceImpl.java new file mode 100644 index 0000000..e4abe27 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmOprateLogServiceImpl.java @@ -0,0 +1,20 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.ruoyi.eastcom_yw.domain.YwAlarmOprateLog; +import com.ruoyi.eastcom_yw.mapper.YwAlarmOprateLogMapper; +import com.ruoyi.eastcom_yw.service.YwAlarmOprateLogService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 服务实现类 + *

+ * + * @author jkj + * @since 2023-03-06 + */ +@Service +public class YwAlarmOprateLogServiceImpl extends ServiceImpl implements YwAlarmOprateLogService { + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmServiceImpl.java new file mode 100644 index 0000000..c9d42a8 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmServiceImpl.java @@ -0,0 +1,402 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ArrayUtil; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.domain.dto.HandleDataDTO; +import com.ruoyi.common.core.domain.dto.json.UserInfo; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.common.constant.AlarmConstants; +import com.ruoyi.eastcom_yw.domain.*; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmInfoVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmQuestionVo; +import com.ruoyi.eastcom_yw.domain.vo.YwErrorAlarmVO; +import com.ruoyi.eastcom_yw.mapper.*; +import com.ruoyi.eastcom_yw.service.CommonService; +import com.ruoyi.eastcom_yw.service.SysNoticeService; +import com.ruoyi.eastcom_yw.service.YwAlarmService; +import com.ruoyi.eastcom_yw.service.YwAlarmViewService; +import com.ruoyi.framework.web.domain.dto.MobileOfficesDTO; +import com.ruoyi.framework.web.service.sms.MessageService; +import com.ruoyi.system.mapper.SysDictDataMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.stream.Collectors; + +/** + *

+ * 服务实现类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Service +@Slf4j +public class YwAlarmServiceImpl extends ServiceImpl implements YwAlarmService { + + + @Autowired + private YwAlarmMapper ywAlarmMapper; + + @Autowired + private YwAlarmViewMapper ywAlarmViewMapper; + + @Autowired + private CommonService commonService; + + @Autowired + private YwNoticeModelMapper ywNoticeModelMapper; + + @Autowired + private YwSceneMapper ywSceneMapper; + + @Autowired + private YwNoticeObjectMapper ywNoticeObjectMapper; + + @Autowired + private SysDictDataMapper sysDictDataMapper; + + @Resource + private MessageService messageService; + + @Resource + private SysNoticeService sysNoticeService; + + @Resource + private ThreadPoolTaskExecutor threadPool; + + @Resource + private YwAlarmViewService ywAlarmViewService; + + + @Override + public List getYwAlarmQuestionList(String specialty) { + return ywAlarmMapper.getYwAlarmQuestionList(specialty); + } + + @Override + public void YwAlarmAutoRecover() { + + List list = ywAlarmMapper.selectYwAlarmCouldRecover(); + HandleDataDTO handleDataDTO = new HandleDataDTO(); + UserInfo user = new UserInfo(); +// 恢复人的ID,比如某个用户叫自动恢复 + user.setId("2"); + handleDataDTO.setCurrentUserInfo(user); + for (YwAlarmRecover recover : list) { + handleDataDTO.setProcessInstanceId(recover.getFlwProcessid()); + handleDataDTO.setTaskId(recover.getFlwTaskid()); + + List infoList = ywAlarmViewMapper.getYwAlarmInfoList(recover.getFlwProcessid()); + + if (infoList.isEmpty()) { + continue; + } + + JSONObject json = new JSONObject(); + json.put("input_cleartime", recover.getLastClearTime()); + json.put("input_user", "自动恢复"); + + if (StringUtils.isNotEmpty(infoList.get(0).getAlarmContent())) { + json.put("textarea_gjxx", infoList.get(0).getAlarmContent().replace("##", "\r\n")); + } + + + handleDataDTO.setFormData(json); + handleDataDTO.setOldFromData("need"); + try { + boolean res = commonService.agreeTask(handleDataDTO); + if(res) + { + YwAlarmDTO alarmDTO =new YwAlarmDTO(); + alarmDTO.setAlarmId(recover.getAlarmId()); + alarmDTO.setAlarmType(recover.getAlarmType()); + //更新源数据的状态为关闭,后面相同场馆的groupid另起一个新的 + ywAlarmMapper.updateOriginAlarmClose(alarmDTO); + } + } catch (Exception ex) { + log.error(ex.getMessage()); + break; + } + } + + } + + @Override + @Transactional + public boolean YwAlarmClear(YwAlarmDTO alarmDTO) { + if (StringUtils.isNotEmpty(alarmDTO.getAlarmType())) { + if ("tel".equals(alarmDTO.getAlarmType())) { + alarmDTO.setAlarmType("voip"); + } + + if (ArrayUtil.contains(AlarmConstants.ALARMS, alarmDTO.getAlarmType())) { + + boolean isOk = false; + + if (StringUtils.isNotEmpty(alarmDTO.getProcessId())) { + + if (ObjectUtils.isNotEmpty(alarmDTO.getGroupId())) { + if (alarmDTO.getGroupId() > 0) { + isOk = true; + } + } + + if(isOk) { + HandleDataDTO dto = new HandleDataDTO(); + UserInfo user = new UserInfo(); + user.setId(SecurityUtils.getUserId().toString()); + user.setName(SecurityUtils.getLoginUser().getNickName()); + dto.setTaskName("alarm"); + dto.setCurrentUserInfo(user); + dto.setProcessInstanceId(alarmDTO.getProcessId()); + try { + boolean res = commonService.revokeTask(dto); + if (res) { + int num = ywAlarmMapper.updateAlarmClearByGroupId(alarmDTO); + if(num>0) { + ywAlarmViewService.updateAlarmLogEnd(alarmDTO.getAlarmType(), alarmDTO.getGroupId(),SecurityUtils.getUserId()); + } + ywAlarmMapper.updateOriginAlarmClose(alarmDTO); + } +// else { +// throw new ServiceException("闭环失败"); +// return true; +// } + return true; + } catch (Exception e) { + throw new ServiceException(e.getMessage()); + } + } + + } else { + + if (ObjectUtils.isNotEmpty(alarmDTO.getAlarmId())&&alarmDTO.getAlarmId() > 0) { + + isOk = true; + + } + + if(isOk) { + + if(ObjectUtils.isNotEmpty(alarmDTO.getGroupId()) && alarmDTO.getGroupId() > 0) + { + if(alarmDTO.getGroupId().equals(alarmDTO.getAlarmId())) { + int num = ywAlarmMapper.updateAlarmClearByGroupId(alarmDTO); + if (num > 0) { + ywAlarmViewService.updateAlarmLogEnd(alarmDTO.getAlarmType(), alarmDTO.getGroupId(),SecurityUtils.getUserId()); + } + ywAlarmMapper.updateOriginAlarmClose(alarmDTO); + } + else + { + ywAlarmMapper.updateAlarmClearByAlarmId(alarmDTO); + } + } + else + { + ywAlarmMapper.updateAlarmClearByAlarmId(alarmDTO); + } + return true; + + } + } + throw new ServiceException("参数缺失,告警未处理"); + } + throw new ServiceException("告警类型未接入"); + } + throw new ServiceException("告警类型不允许为空"); + } + + @Override + public boolean YwAlarmClose(YwAlarmDTO alarmDTO) { + if (StringUtils.isNotEmpty(alarmDTO.getAlarmType())) { + if ("tel".equals(alarmDTO.getAlarmType())) { + alarmDTO.setAlarmType("voip"); + } + if (ArrayUtil.contains(AlarmConstants.ALARMS, alarmDTO.getAlarmType())) { + int res = ywAlarmMapper.updateOriginAlarmClose(alarmDTO); + if(res>0) + { + return true; + } + } + throw new ServiceException("告警类型未接入"); + } + throw new ServiceException("告警类型不允许为空"); + } + + @Override + public void eastcomYwSendAlarmBriefingSchedule() { + long startTime = System.currentTimeMillis(); + //查询所有未恢复告警 + List vos = ywAlarmMapper.selectAllAlarmWithError(); + if (CollUtil.isEmpty(vos)) { + log.info("没有需要发送的告警"); + } + //查询模板 + YwNoticeModel model = ywNoticeModelMapper.selectById(22); + if (model == null) { + throw new ServiceException("告警简报模板未配置"); + } + //查询需要发送的对象 + List venueNames = vos.stream().map(YwErrorAlarmVO::get场馆名称).collect(Collectors.toList()); + List objects = ywNoticeObjectMapper.selectObjectsByVenueName(venueNames); + if (CollUtil.isEmpty(objects)) { + throw new ServiceException("对象未配置"); + } + Map> objectMap = objects.stream().collect(Collectors.groupingBy(YwNoticeObject::getVenueName)); + //当前时间 + LocalDateTime now = LocalDateTime.now(); + String time = now.format(DateTimeFormatter.ofPattern("MM月dd日HH时")); + //告警专业 + List yw_alarm_specialty = sysDictDataMapper.selectDictDataByType("yw_alarm_specialty"); + //统计 + Map> map = vos.stream().collect(Collectors.groupingBy(YwErrorAlarmVO::get场馆名称)); + Set keys = map.keySet(); + + // 使用线程池中线程分批处理业务逻辑,并行处理任务提高终端响应速度 + CountDownLatch latch = new CountDownLatch(keys.size()); + for (String key : keys) { + threadPool.submit(() -> { + try { + extracted(model, objectMap, time, yw_alarm_specialty, map, key); + } catch (Exception e) { + log.error("调用下游系统出现错误,异常逻辑处理......"); + } finally { + // 业务逻辑处理完毕,计数器减一【当前线程处理任务完毕,线程释放进入线程池,等待处理下一个任务】 + latch.countDown(); + } + }); + } + try { + latch.await(); + } catch (Exception e) { + log.error("等待超时", e); + throw new RuntimeException("系统处理超时,请稍后再试"); + } +// threadPool.shutdown(); + long endTime = System.currentTimeMillis(); + long executionTime = endTime - startTime; + System.out.println("发送告警简报执行时间:" + executionTime + " 毫秒"); + } + + private void extracted(YwNoticeModel model, Map> objectMap, String time, List yw_alarm_specialty, Map> map, String key) { + System.out.println(Thread.currentThread().getName() + "开始执行"); + List list = map.get(key); + if (CollUtil.isEmpty(list)) { + return; + } + String venueName = list.get(0).get场馆名称(); + + String allNum = String.valueOf(list.size()); + + String modelContent = model.getModelContent(); + for (SysDictData sysDictData : yw_alarm_specialty) { + String num = String.valueOf(list.stream().filter(l -> sysDictData.getDictValue().equals(l.get类型())).count()); + //8.17 名称去重 + String name = list.stream().filter(l -> sysDictData.getDictValue().equals(l.get类型())).map(YwErrorAlarmVO::get名称).distinct().collect(Collectors.joining(",\n")); + modelContent = modelContent.replace("${" + sysDictData.getDictValue() + "Num}", num).replace("${" + sysDictData.getDictValue() + "Name}", name); + } + String content = modelContent.replace("${时间}", time).replace("${场馆名}", venueName).replace("${总告警数}", allNum); + + log.info(venueName+"告警简报原内容"+content); + String regex = "(?m)^(.*共计0条.*)*$\r\n"; // 正则表达式匹配0条的行,并包括换行符 + String res = content.replaceAll(regex, ""); + log.info(venueName+"告警简报去除0条后最终发送内容"+res); + + List objectList = objectMap.get(venueName); + if (CollUtil.isEmpty(objectList)) { + log.error(venueName + "场馆未配置发送对象"); + return; + } + boolean flag = true; + StringBuilder code = new StringBuilder(); + StringBuilder message = new StringBuilder(); + for (YwNoticeObject object : objectList) { + + MobileOfficesDTO dto = new MobileOfficesDTO(); + dto.setMobileoffices(object.getGroupId()); + dto.setMobileoffice_user(null); + dto.setFile(null); + dto.setFilename(null); + dto.setImg(null); + dto.setImgname(null); + dto.setContent(res); + + JSONObject jsonObject = null; + try { + log.info(object.getVenueName() + ":开始发送移动办公告警简报"); + jsonObject = messageService.sendMobileOffice(dto); + } catch (Exception e) { + log.error(object.getVenueName() + ":发送移动办公失败"); + } + //sys_notice新增已发送记录 + if (jsonObject == null) { + flag = false; + log.error(object.getVenueName() + ":三方移动办公无反馈"); + } else { + log.info("code:" + jsonObject.getString("code") + ",message:" + jsonObject.getString("message")); + message.append(jsonObject.getString("message")).append(","); + } + + } + List objectIds = objectList.stream().map(YwNoticeObject::getId).collect(Collectors.toList()); + String objectNames = objectList.stream().map(YwNoticeObject::getObjectName).collect(Collectors.joining(",")); + String groupId = objectList.stream().map(YwNoticeObject::getGroupId).collect(Collectors.joining(",")); + SysNotice sysNotice = new SysNotice(); + sysNotice.setNoticeContent(content); + sysNotice.setStatus("0"); + sysNotice.setCreateBy("sys"); + sysNotice.setCreateTime(LocalDateTime.now()); + sysNotice.setUpdateBy("sys"); + sysNotice.setUpdateTime(LocalDateTime.now()); + sysNotice.setReciveUser(null); + sysNotice.setFlwProcessid(null); + sysNotice.setFlwTaskid(null); + sysNotice.setReciveUserPhone(null); + sysNotice.setExpSendTime(LocalDateTime.now()); + sysNotice.setNoticeObjectId(objectIds); + sysNotice.setNoticeModelId(model.getId()); + sysNotice.setModelScene("17"); + sysNotice.setObjectProto("0"); + sysNotice.setModelSuitType("3"); + sysNotice.setHandworkId(null); + sysNotice.setGroupId(groupId); + sysNotice.setNoticeType("5"); + sysNotice.setNoticeObject(venueName + ":" + groupId); + sysNotice.setNoticeContent(res); + sysNotice.setAddFlag("1"); + sysNotice.setSendTime(LocalDateTime.now()); + if (flag) { + sysNotice.setRemark(message.toString()); + sysNotice.setSendStatus("1"); + } else { + sysNotice.setRemark("三方移动办公无反馈"); + sysNotice.setSendStatus("0"); + } + + sysNotice.setNoticeObjectNameStr(objectNames); + sysNotice.setNoticeTitle(venueName + "告警简报"); + sysNoticeService.save(sysNotice); + System.out.println(Thread.currentThread().getName() + "结束执行"); + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmViewServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmViewServiceImpl.java new file mode 100644 index 0000000..fd3f70b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmViewServiceImpl.java @@ -0,0 +1,819 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.toolkit.ArrayUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.constant.AlarmConstants; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.constant.TaskConstants; +import com.ruoyi.common.core.domain.dto.StartProcessInstanceDTO; +import com.ruoyi.common.core.domain.dto.json.UserInfo; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.*; +import com.ruoyi.eastcom_yw.domain.*; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTONoPage; +import com.ruoyi.eastcom_yw.domain.dto.YwSearchDTO; +import com.ruoyi.eastcom_yw.domain.vo.*; +import com.ruoyi.eastcom_yw.mapper.*; +import com.ruoyi.eastcom_yw.service.*; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.poifs.crypt.dsig.services.TimeStampService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + *

+ * 服务实现类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Service +@Slf4j +public class YwAlarmViewServiceImpl extends ServiceImpl implements YwAlarmViewService { + + @Autowired + private YwAlarmViewMapper ywAlarmViewMapper; + + @Autowired + private YwAlarmMapper ywAlarmMapper; + + @Autowired + private yw_alarm_deal_logMapper alarm_deal_logMapper; + + @Autowired + private CommonService commonService; + + @Autowired + private YwAlarmOprateLogService ywAlarmOprateLogService; + + @Autowired + private YwNoticeUserService ywNoticeUserService; + + @Override + public void insert_alarm_schedule() { + + List list = ywAlarmViewMapper.getYwHandleList(); + + if(list.size()>0) { + + + //需要通过template_id从钉钉的workspace/process/detail取ProcessDefinitionId + //查询告警处理的工作流模板ID + String template_id = ""; + try { + template_id = ywAlarmViewMapper.getTemplateId(TaskConstants.ALARM); + } catch (Exception e) { + log.error(e.getMessage()); + return; + } + + if (StringUtils.isEmpty(template_id)) + { + //todo:有空需要让异常入数据库,方便查询 + log.error("没有找到告警工作流template_id"); + return; + } + + + String processDefinitionId = ""; + try { + processDefinitionId = commonService.GetProcessDefinitionId(template_id); + } catch (Exception e) { + log.error(e.getMessage()); + return; + } + + if (StringUtils.isEmpty(processDefinitionId)) + { + log.error("没有正确的工作流processDefinitionId"); + return; + } + + + UserInfo user = new UserInfo(); + user.setId("2"); + user.setName("系统"); + user.setType("user"); + user.setSex("1"); + user.setSelected(true); + + for (YwAlarmView alarm_handle : list) { + + //从数据库取下内容 + List alarmContent = ywAlarmViewMapper.selectAlarmContent(alarm_handle.get关联组号()); + if(alarmContent.isEmpty()) + { + continue; + } + + //保存数据到yw_alarm_deal_log + yw_alarm_deal_log alarm_deal = new yw_alarm_deal_log(); + alarm_deal.setAlarmCode(alarm_handle.get告警编号()); + alarm_deal.setAlarmType(alarm_handle.getAlarmType()); + alarm_deal.setGroupColnum(alarm_handle.get关联组号()); + alarm_deal.setGroupId(Long.parseLong(alarm_handle.get关联组号())); + alarm_deal.setBeginTime(DateUtils.getNowDate()); + alarm_deal.setPrimaryId(alarm_handle.getId()); + alarm_deal.setIsRed(alarm_handle.get红线内()); + alarm_deal.setSceneId(alarm_handle.get场馆id()); + alarm_deal.setAlarmTime(DateUtils.parseDate(alarm_handle.get告警时间())); + alarm_deal.setSiteType(alarm_handle.get类型()); + //定时器更新endTime,暂时先不用 +// if(StringUtils.isNotEmpty(alarm_handle.get恢复时间())) { +// alarm_deal.setEndTime(DateUtils.parseDate(alarm_handle.get恢复时间())); +// } + if (StringUtils.isNotEmpty(alarm_handle.get红线内())) { + //20230303只有在红线内的告警才需要生成工作流 + if (AlarmConstants.RedInLine.equals(alarm_handle.get红线内())) { + YwSearchDTO ywSearchDTO = new YwSearchDTO(); + ywSearchDTO.setArea_county_id(alarm_handle.getAreaCountyId()); + ywSearchDTO.setVenue_id(alarm_handle.get场馆id().toString()); + ywSearchDTO.setVenue_name(alarm_handle.get场馆名称()); + ywSearchDTO.setCity(alarm_handle.getCity()); + ywSearchDTO.setCounty(alarm_handle.getCounty()); + ywSearchDTO.setTask_type(TaskConstants.ALARM); + ywSearchDTO.setAlarm_name(alarm_handle.get告警名称()); + ywSearchDTO.setNet_name(alarm_handle.get网元名称()); + ywSearchDTO.setSite_name(alarm_handle.get基站名()); + + //20230303工作流增加任务名称 + ywSearchDTO.setTask_name(alarm_handle.get基站号() + " " + alarm_handle.get告警名称()); + //20230307工作流增加专业 + ywSearchDTO.setSpecialty(alarm_handle.get告警类型()); + + StartProcessInstanceDTO startDTO = new StartProcessInstanceDTO(); + startDTO.setStartUserInfo(user); + startDTO.setProcessDefinitionId(processDefinitionId); + + JSONObject json = new JSONObject(); + + String groupId = ""; + + //20230327 agis和其它的工作流都指派到专网zw的专业下 + + + + if("agis".equals(alarm_handle.getAlarmType())||"wifi".equals(alarm_handle.getAlarmType())||"voip".equals(alarm_handle.getAlarmType())) + { + alarm_handle.setAlarmType("zw"); +// alarm_handle.set告警类型("专网"); + } + + groupId = MessageFormat.format("{0}|{1}|gz", alarm_handle.get场馆id().toString().replace(",",""), alarm_handle.getAlarmType()); + + json.put("input_cg_zy_id", groupId); + json.put("input_gjbh", alarm_handle.get关联组号()); + json.put("input_zyfl", alarm_handle.get告警类型()); + + +// json.put("textarea_gjxx", MessageFormat.format("----------杭州奥体中心游泳馆----------##告警网元:{0},告警名称:{1},告警时间:{2}", alarm_handle.get网元名称(), alarm_handle.get告警名称(), alarm_handle.get告警时间())); + json.put("textarea_gjxx", alarmContent.get(0).replace("##","\r\n")); + json.put("textarea_gzyy", ""); + json.put("pictureupload_sczp", null); + //20230217 增加查询条件 + json.put("input_search", JSONObject.toJSONString(ywSearchDTO)); + + startDTO.setFormData(json); + try { + String res_flwprocessid = commonService.StartProcess(startDTO); + if (StringUtils.isNotEmpty(res_flwprocessid)) { + alarm_deal.setFlwProcessid(res_flwprocessid); + + alarm_deal_logMapper.insert(alarm_deal); + + //20230510告警太多,加了新的逻辑,5分钟后如果没有全部恢复就发 +// boolean res = ywNoticeUserService.noticeYW(res_flwprocessid,groupId,TaskConstants.ALARM); +// if(!res) +// { +// log.error("告警工作流已生成,提醒没有发送成功"); +// } + + } + } catch (Exception e) { + log.error(e.getMessage()); + break; + } + } + + if (AlarmConstants.RedOutLine.equals(alarm_handle.get红线内())) { + //非红线内的直接进入记录表,用于查看 + try { + alarm_deal_logMapper.insert(alarm_deal); + } catch (Exception e) { + log.error(e.getMessage()); + break; + } + } + } + + if (StringUtils.isEmpty(alarm_handle.get红线内())) { + //非红线内的直接进入记录表,用于查看 + try { + alarm_deal_logMapper.insert(alarm_deal); + } catch (Exception e) { + log.error(e.getMessage()); + break; + } + } + + + } + + } + + } + + @Override + public void insert_alarmNotice_schedule() { + List list = ywAlarmMapper.selectYwAlarmCouldNotice(); + for (YwAlarmNoticeVo alarmNotice : list) { + ywNoticeUserService.noticeYW(alarmNotice.getProcessId(),alarmNotice.getGroupId(),TaskConstants.ALARM); + } + } + + @Override + public TableDataInfo GetAlarmList(YwAlarmDTO alarmDTO) { + + //特殊要求,传2时代表dealStatus为2,与alarmStatus无关 + if("2".equals(alarmDTO.getAlarmStatus())){ + alarmDTO.setDealStatus("2"); + alarmDTO.setAlarmStatus(""); + } + + LambdaQueryWrapper lambdaQueryWrapper=new LambdaQueryWrapper<>(); + + //告警当前的处理状态 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getDealStatus()),YwAlarmView::getDealStatus, alarmDTO.getDealStatus()); + + //告警的状态 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getAlarmStatus())&&"0".equals(alarmDTO.getAlarmStatus()), YwAlarmView::getAlarmStatus, alarmDTO.getAlarmStatus()); + + //告警名称模糊查询 + lambdaQueryWrapper.like(StringUtils.isNotEmpty(alarmDTO.getAlarmName()),YwAlarmView::get告警名称, alarmDTO.getAlarmName()); + + //告警的区县 + //20230303区县改为AreaCountyId查询 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getCounty()), YwAlarmView::getAreaCountyId, alarmDTO.getCounty()); + + //告警的场馆 + lambdaQueryWrapper.in(CollUtil.isNotEmpty(alarmDTO.getVenues()), YwAlarmView::get场馆id, alarmDTO.getVenues()); + + //告警的类型 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getAlarmType()), YwAlarmView::getAlarmType, alarmDTO.getAlarmType()); + + //告警的专业 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getAlarmGroup()), YwAlarmView::getAlarmType, alarmDTO.getAlarmGroup()); + + //告警是否红线内 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getInRedLine()), YwAlarmView::get红线内, alarmDTO.getInRedLine()); + + //告警的时间 + lambdaQueryWrapper.between(ObjectUtils.isNotEmpty(alarmDTO.getStartTime()) && ObjectUtils.isNotEmpty(alarmDTO.getEndTime()), YwAlarmView::get告警时间, alarmDTO.getStartTime(), alarmDTO.getEndTime()+" 23:59:59"); + + //告警搜索框 + if(StrUtil.isNotBlank(alarmDTO.getSearchBox())){ + lambdaQueryWrapper.and(i->i.like(YwAlarmView::get告警名称,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::getDealUser,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::get基站号,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::get基站名,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::get网元名称,alarmDTO.getSearchBox())); + } + + + Page page= ywAlarmViewMapper.selectPage(new Page<>(alarmDTO.getPageNum(), alarmDTO.getPageSize()),lambdaQueryWrapper); + + TableDataInfo rspData = new TableDataInfo(); + + rspData.setTotal(page.getTotal()); + + List listVo=new ArrayList<>(); + + for(YwAlarmView ywAlarmsLast: page.getRecords()) + { + + int clearNum=0; + + YwAlarmLastVo ywAlarmLastVo=new YwAlarmLastVo(); + + LambdaQueryWrapper lambdaQueryWrapperOper=new LambdaQueryWrapper<>(); + lambdaQueryWrapperOper.eq(YwAlarmOprateLog::getAlarmGroup, ywAlarmsLast.get关联组号()); + lambdaQueryWrapperOper.eq(YwAlarmOprateLog::getUserId,alarmDTO.getUserId()); + ywAlarmLastVo.setOpId(0L); + //查询告警用户是否点击 + ywAlarmOprateLogService.list(lambdaQueryWrapperOper).forEach( + ywAlarmOprateLog -> { + ywAlarmLastVo.setOpId(ywAlarmOprateLog.getId()); + } + ); + + ywAlarmLastVo.setKey(ywAlarmsLast.getId()); + if(ObjectUtils.isEmpty(ywAlarmsLast.get场馆id())) + { + continue; + } + ywAlarmLastVo.setVenue_id(ywAlarmsLast.get场馆id().toString()); + ywAlarmLastVo.setCg(ywAlarmsLast.get场馆名称()); + //工单号 +// ywAlarmLastVo.setGd(""); + ywAlarmLastVo.setSite_id(ywAlarmsLast.get基站号()); + ywAlarmLastVo.setSite_name(ywAlarmsLast.get基站名()); + ywAlarmLastVo.setNet_name(ywAlarmsLast.get网元名称()); + ywAlarmLastVo.setGroupId(ywAlarmsLast.get关联组号()); + ywAlarmLastVo.setName(ywAlarmsLast.get告警名称()); + ywAlarmLastVo.setStart(ywAlarmsLast.get告警时间()); +// ywAlarmLastVo.setEnd(ywAlarmsLast.get恢复时间()); +//告警:主告警记录中恢复时间是呈现该组告警最后一条恢复子告警的恢复时间,在子告警中恢复时间是呈现该条告警的恢复时间 + Date newDate = DateUtils.parseDate(ywAlarmsLast.get恢复时间()); + if(StringUtils.isNotEmpty(ywAlarmsLast.get恢复时间())) + { + clearNum++; + } + ywAlarmLastVo.setInRedLine(ywAlarmsLast.get红线内()); + ywAlarmLastVo.setUserId(ywAlarmsLast.getDealUserId()); + ywAlarmLastVo.setPerson(ywAlarmsLast.getDealUser()); + //冗余state + ywAlarmLastVo.setState(ywAlarmsLast.getDealStatus()); + ywAlarmLastVo.setAlarmStatus(ywAlarmsLast.getAlarmStatus()); + ywAlarmLastVo.setDealStatus(ywAlarmsLast.getDealStatus()); + ywAlarmLastVo.setState(ywAlarmsLast.getDealStatus()); + ywAlarmLastVo.setProcessId(ywAlarmsLast.getProcessId()); + ywAlarmLastVo.setTaskId(ywAlarmsLast.getTaskId()); + //20230308增加了反馈人的红蓝白区标签 + ywAlarmLastVo.setBelongArea(ywAlarmsLast.getBelongArea()); + //用户判断主告警和次告警是否全部恢复了,空表示没有,全部恢复显示最新的恢复时间 + ywAlarmLastVo.setLastClearTime(ywAlarmsLast.getLastClearTime()); + + ywAlarmLastVo.setIsHangup(ywAlarmsLast.getIsHangup()); + + //查询次要告警 + List ywAlarmListLess = ywAlarmViewMapper.getYwAlarmByGroupId(ywAlarmsLast.getAlarmType(),ywAlarmsLast.get关联组号()); + //当前告警总数 + int alarmNum = ywAlarmListLess.size()+1; + + List ywAlarmVoList=new ArrayList(); + if(ywAlarmListLess.size()>0) + { + for(YwAlarmVo ywAlarmLess: ywAlarmListLess) + { + +// 设计问题导致前端用了Net_name和Site_name + ywAlarmLess.setNet_name(ywAlarmLess.getNetName()); + + ywAlarmLess.setSite_name(ywAlarmLess.getSiteName()); + + if(StringUtils.isNotEmpty(ywAlarmLess.getEnd())) + { + clearNum++; + } + + Date lessEnd = DateUtils.parseDate(ywAlarmLess.getEnd()); + + if(lessEnd.after(newDate)) + { + newDate.setTime(lessEnd.getTime()); + } + + ywAlarmVoList.add(ywAlarmLess); + + } + } + + if(alarmNum == clearNum) + { + + } + + ywAlarmLastVo.setAlarmchildren(ywAlarmVoList); + ywAlarmLastVo.setClearNum(clearNum); + ywAlarmLastVo.setClearNumDisplay(clearNum+"/"+alarmNum); + + // //查询工作流,比较是否是当前登录用户的待办 + //APP端 + if(alarmDTO.getIsAPP()) { + List processIds = commonService.selectCurrenUserTodoProcessId(alarmDTO.getAlarmType()); + if (CollUtil.isNotEmpty(processIds)) { + for (String processId : processIds) { + if (processId.equals(ywAlarmLastVo.getProcessId())) { + ywAlarmLastVo.setIsTodo(1); + } + } + } + } + + + listVo.add(ywAlarmLastVo); + } + + rspData.setRows(listVo); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setMsg("查询成功"); + return rspData; + + } + + + + @Override + public List GetNewAlarmNum(Long userId) { + return ywAlarmViewMapper.getYwAlarmNewNum(userId,false); + } + + @Override + public List GetNewAlarmNum(Long userId,Boolean isAdmin) { + return ywAlarmViewMapper.getYwAlarmNewNum(userId,isAdmin); + } + + @Override + public Long getYwAlarmNewNumByDto(YwAlarmDTO alarmDTO) { + + //传1为全量告警,显示全部告警,所以不用设置AlarmStatus的值 + if("1".equals(alarmDTO.getAlarmStatus())){ + alarmDTO.setAlarmStatus(""); + } + + if(alarmDTO.getIsAPP()) { + //特殊要求,传2时代表dealStatus为2,与alarmStatus无关 + if ("2".equals(alarmDTO.getAlarmStatus())) { + alarmDTO.setDealStatus("2"); + alarmDTO.setAlarmStatus(""); + } + } + return ywAlarmViewMapper.getYwAlarmNewNumByDto(alarmDTO); + } + + @Override + public Long getYwAlarmNewNumByDto(YwAlarmDTONoPage alarmDTO) { + + //传1为全量告警,显示全部告警,所以不用设置AlarmStatus的值 + if("1".equals(alarmDTO.getAlarmStatus())){ + alarmDTO.setAlarmStatus(""); + } + + if(alarmDTO.getIsAPP()) { + //特殊要求,传2时代表dealStatus为2,与alarmStatus无关 + if ("2".equals(alarmDTO.getAlarmStatus())) { + alarmDTO.setDealStatus("2"); + alarmDTO.setAlarmStatus(""); + } + } + return ywAlarmViewMapper.getYwAlarmNewNumByDto2(alarmDTO); + } + + @Override + public List getYwAlarmByDto(YwAlarmDTO alarmDTO) { + //传1为全量告警,显示全部告警,所以不用设置AlarmStatus的值 + if("1".equals(alarmDTO.getAlarmStatus())){ + alarmDTO.setAlarmStatus(""); + } + //APP特殊要求,传2时代表dealStatus为2,与alarmStatus无关 + if("2".equals(alarmDTO.getAlarmStatus())){ + alarmDTO.setDealStatus("2"); + alarmDTO.setAlarmStatus(""); + } + + List lstAlarmlasts = ywAlarmViewMapper.getYwAlarmByDto(alarmDTO); + + List processIds = new ArrayList<>(); + +// if(lstAlarmlasts.size()>0&&alarmDTO.getIsAPP()) { +// processIds = commonService.selectCurrenUserTodoProcessId(alarmDTO.getAlarmType()); +// } + + long [] groupIds = lstAlarmlasts.stream().map(YwAlarmViewVo::getGroupId).mapToLong(num -> Long.parseLong(num)).toArray(); + + List ywAlarmListLesses = null; + + List ywAlarmOprateLogList = null; + + if(groupIds.length > 0) + { + ywAlarmListLesses = ywAlarmViewMapper.getYwAlarmByGroupIds(alarmDTO.getAlarmType(),groupIds); + + //查询告警用户是否点击 + LambdaQueryWrapper lambdaQueryWrapperOper = new LambdaQueryWrapper<>(); + lambdaQueryWrapperOper.in(YwAlarmOprateLog::getAlarmGroup, lstAlarmlasts.stream().map(YwAlarmViewVo::getGroupId).toArray()); + lambdaQueryWrapperOper.eq(YwAlarmOprateLog::getUserId, alarmDTO.getUserId()); + ywAlarmOprateLogList = ywAlarmOprateLogService.list(lambdaQueryWrapperOper); + } + + for(YwAlarmViewVo ywAlarmsLast: lstAlarmlasts) + { + int clearNum=0; + + String last_clear_time = ""; + + //主告警ID就是关联组号 + ywAlarmsLast.setKey(ywAlarmsLast.getGroupId()); + + ywAlarmsLast.setVenue_id(ywAlarmsLast.getVenueId().toString()); + + ywAlarmsLast.setSite_id(ywAlarmsLast.getSiteId()); + + ywAlarmsLast.setSite_name(ywAlarmsLast.getSiteName()); + + ywAlarmsLast.setNet_name(ywAlarmsLast.getNetName()); + + if(!alarmDTO.getIsExport()) { + //查询告警用户是否点击 +// LambdaQueryWrapper lambdaQueryWrapperOper = new LambdaQueryWrapper<>(); +// lambdaQueryWrapperOper.eq(YwAlarmOprateLog::getAlarmGroup, ywAlarmsLast.getGroupId()); +// lambdaQueryWrapperOper.eq(YwAlarmOprateLog::getUserId, alarmDTO.getUserId()); + ywAlarmsLast.setOpId(0L); + if(ywAlarmOprateLogList!=null) + { + List ywAlarmOperateLog = ywAlarmOprateLogList.stream().filter(x->x.getAlarmGroup().equals(ywAlarmsLast.getGroupId())).collect(Collectors.toList()); + //设置是否点击 +// ywAlarmOprateLogService.list(lambdaQueryWrapperOper).forEach( +// ywAlarmOprateLog -> { +// ywAlarmsLast.setOpId(ywAlarmOprateLog.getId()); +// } +// ); + + if(!ywAlarmOperateLog.isEmpty()) + { + ywAlarmsLast.setOpId(ywAlarmOperateLog.get(0).getId()); + } + } + } + + //查询次要告警 +// List ywAlarmListLess = ywAlarmViewMapper.getYwAlarmByGroupId(ywAlarmsLast.getAlarmType(),ywAlarmsLast.getGroupId()); + List ywAlarmListLess = ywAlarmListLesses.stream().filter(x->x.getGroupId().equals(ywAlarmsLast.getGroupId())).collect(Collectors.toList()); + + if(ObjectUtils.isEmpty(ywAlarmListLess)) + { + ywAlarmListLess = ywAlarmViewMapper.getYwAlarmByGroupId(ywAlarmsLast.getAlarmType(),ywAlarmsLast.getGroupId()); + } + + //当前告警总数 + int alarmNum = ywAlarmListLess.size(); + + if(ywAlarmListLess.size()>0) + { + for(YwAlarmVo ywAlarmLess: ywAlarmListLess) + { + +// 设计问题导致前端用了Net_name和Site_name + ywAlarmLess.setNet_name(ywAlarmLess.getNetName()); + + ywAlarmLess.setSite_name(ywAlarmLess.getSiteName()); + + ywAlarmLess.setInRedLine(ywAlarmsLast.getInRedLine()); + +// 设置最早的告警时间 + if(ywAlarmLess.getGroupId().equals(ywAlarmLess.getAlarmId().toString())) + { + //主告警的告警等级从子告警的主告警上取 + // ywAlarmsLast.setAlarmLevel(ywAlarmLess.getAlarmLevel()); + ywAlarmsLast.setStart(ywAlarmLess.getStart()); + } + + if(StringUtils.isNotEmpty(ywAlarmLess.getEnd())) + { + clearNum++; + + if(last_clear_time.isEmpty()) { + + last_clear_time=ywAlarmLess.getEnd(); + + } + + if(!last_clear_time.isEmpty()) + { + Date dateLast = DateUtils.parseDate(last_clear_time); + Date dateCompare = DateUtils.parseDate(ywAlarmLess.getEnd()); + if(dateCompare.after(dateLast)) + { + last_clear_time = ywAlarmLess.getEnd(); + } + } + } + } + } + + //APP端不需要子告警的列表,但是需要子告警的数量 + if(!alarmDTO.getIsAPP()) { + + ywAlarmsLast.setAlarmchildren(ywAlarmListLess); + + } + + //查询工作流,比较是否是当前登录用户的待办 + //APP端 +// if(alarmDTO.getIsAPP()) { +// if (CollUtil.isNotEmpty(processIds)) { +// for (String processId : processIds) { +// if (processId.equals(ywAlarmsLast.getProcessId())) { +// ywAlarmsLast.setIsTodo(1); +// } +// } +// } +// } + ywAlarmsLast.setAlarmKey(ywAlarmsLast.getGroupId()+"|"+ywAlarmsLast.getProcessId()+"|0"); + ywAlarmsLast.setEnd(null); + //必须是全部恢复了才给最后的恢复时间 + if(clearNum == alarmNum) + { + ywAlarmsLast.setLastClearTime(last_clear_time); + ywAlarmsLast.setEnd(last_clear_time); + ywAlarmsLast.setAlarmKey(ywAlarmsLast.getGroupId()+"|"+ywAlarmsLast.getProcessId()+"|1"); + } + + ywAlarmsLast.setClearNum(clearNum); + ywAlarmsLast.setClearNumDisplay(clearNum+"/"+alarmNum); + } + + return lstAlarmlasts; + } + + @Override + public List GetAlarmInfoList(String processId) { + + List list = ywAlarmViewMapper.getYwAlarmInfoList(processId); + return handleAlarmInfo(list); + + } + + @Override + public List getYwAlarmInfoListByGroup(String groupId) { + List list = ywAlarmViewMapper.getYwAlarmInfoListByGroup(groupId); + return handleAlarmInfo(list); + } + + @Override + public List GetAlarmInfoList(String processId, boolean isApp) { + List list = ywAlarmViewMapper.getYwAlarmInfoList(processId); + return handleAlarmInfo(list,isApp); + } + + @Override + public List getYwAlarmInfoListByGroup(String groupId, boolean isApp) { + List list = ywAlarmViewMapper.getYwAlarmInfoListByGroup(groupId); + return handleAlarmInfo(list,isApp); + } + + @Override + public List getYwAlarmList(String alarmType, String venueName, String startTime, String endTime) { + if(StringUtils.isEmpty(alarmType)) + { + throw new ServiceException("告警类型不为空"); + } + if(StringUtils.isEmpty(venueName)) + { + throw new ServiceException("场馆不为空"); + } + if(StringUtils.isEmpty(startTime)) + { + throw new ServiceException("告警开始时间不为空"); + } + if(StringUtils.isEmpty(endTime)) + { + throw new ServiceException("告警结束时间不为空"); + } + return ywAlarmViewMapper.getYwAlarmAll(alarmType,venueName,startTime,endTime); + } + + @Override + public List getYwAlarmLessList(String alarmType, String groupId) { + return ywAlarmViewMapper.getYwAlarmByGroupId(alarmType,groupId); + } + + private List handleAlarmInfo(List list) + { + list.forEach( + + ywAlarmInfoVo -> { + + +// LambdaQueryWrapper lambdaQueryWrapper2=new LambdaQueryWrapper<>(); +// +// lambdaQueryWrapper2.ne(YwAlarm::getId, ywAlarmInfoVo.getPrimaryId()); +// +// lambdaQueryWrapper2.eq(YwAlarm::get关联组号,ywAlarmInfoVo.getGroupId()); +// +// //202030315 修复了不同告警类型ID可能重复的BUG,需要多关联告警类型 +// //info的alarmType变成了value +// lambdaQueryWrapper2.eq(YwAlarm::getAlarmType,ywAlarmInfoVo.getAlarmType()); +// +// YwAlarm mainAlarm = ywAlarmMapper.selectOne(new LambdaQueryWrapper().eq(YwAlarm::getId, ywAlarmInfoVo.getPrimaryId()).eq(YwAlarm::getAlarmType,ywAlarmInfoVo.getAlarmType())); + + //20230327 + //根据不同告警类型查询不同的告警表的数据,效率上会快些 + YwAlarmVo mainAlarm = ywAlarmViewMapper.getYwAlarmLastByGroupId(ywAlarmInfoVo.getAlarmType(),ywAlarmInfoVo.getGroupId()); + + if(mainAlarm!=null){ + ywAlarmInfoVo.setCg(mainAlarm.getCg()); + ywAlarmInfoVo.setNet_name(mainAlarm.getNetName()); + ywAlarmInfoVo.setSite_name(mainAlarm.getSiteName()); + ywAlarmInfoVo.setName(mainAlarm.getName()); + ywAlarmInfoVo.setStart(mainAlarm.getStart()); + ywAlarmInfoVo.setEnd(mainAlarm.getEnd()); + ywAlarmInfoVo.setSiteType(mainAlarm.getSiteType()); + } + + //20230320 + //查询次要告警 + List ywAlarmListLess = ywAlarmViewMapper.getYwAlarmByGroupId(ywAlarmInfoVo.getAlarmType(),ywAlarmInfoVo.getGroupId()); + String alarmZWType = DictUtils.getDictLabel("yw_alarm_specialty",ywAlarmInfoVo.getAlarmType()); + ywAlarmInfoVo.setAlarmTypeCode(ywAlarmInfoVo.getAlarmType()); + ywAlarmInfoVo.setAlarmType(alarmZWType); + ywAlarmInfoVo.setAlarmchildren(ywAlarmListLess); + + //老的获取子告警的方法 +// if(ywAlarmMapper.selectList(lambdaQueryWrapper2).size()>0) +// { +// List ywAlarmVoList=new ArrayList(); +// +// ywAlarmMapper.selectList(lambdaQueryWrapper2).forEach( +// ywAlarm -> { +// YwAlarmVo ywAlarmVo=new YwAlarmVo(); +// ywAlarmVo.setCg(ywAlarm.get场馆名称()); +// ywAlarmVo.setSite_id(ywAlarm.get基站号()); +// ywAlarmVo.setNet_name(ywAlarm.get网元名称()); +// ywAlarmVo.setSite_name(ywAlarm.get基站名()); +// ywAlarmVo.setName(ywAlarm.get告警名称()); +// ywAlarmVo.setStart(ywAlarm.get告警时间()); +// ywAlarmVo.setEnd(ywAlarm.get恢复时间()); +// ywAlarmVoList.add(ywAlarmVo); +// } +// ); +// +// ywAlarmInfoVo.setAlarmchildren(ywAlarmVoList); +// +// } + + } + ); + + return list; + } + + private List handleAlarmInfo(List list,boolean isApp) + { + list.forEach( + + ywAlarmInfoVo -> { + + //20230327 + //根据不同告警类型查询不同的告警表的数据,效率上会快些 + YwAlarmVo mainAlarm = ywAlarmViewMapper.getYwAlarmLastByGroupId(ywAlarmInfoVo.getAlarmType(),ywAlarmInfoVo.getGroupId()); + + if(mainAlarm!=null){ + ywAlarmInfoVo.setCg(mainAlarm.getCg()); + ywAlarmInfoVo.setNet_name(mainAlarm.getNetName()); + ywAlarmInfoVo.setSite_name(mainAlarm.getSiteName()); + ywAlarmInfoVo.setName(mainAlarm.getName()); + ywAlarmInfoVo.setStart(mainAlarm.getStart()); + ywAlarmInfoVo.setEnd(mainAlarm.getEnd()); + ywAlarmInfoVo.setSiteType(mainAlarm.getSiteType()); + } + + if(isApp) { + //20230320 + //查询次要告警 + List ywAlarmListLess = ywAlarmViewMapper.getYwAlarmByGroupId(ywAlarmInfoVo.getAlarmType(), ywAlarmInfoVo.getGroupId()); + String alarmZWType = DictUtils.getDictLabel("yw_alarm_specialty", ywAlarmInfoVo.getAlarmType()); + ywAlarmInfoVo.setAlarmType(alarmZWType); + ywAlarmInfoVo.setAlarmchildren(ywAlarmListLess); + } + + } + ); + + return list; + } + + @Override + public void updateAlarmLogEnd(String alarmType,Long group_id,Long userId) + { + //更新告警记录的恢复时间 + yw_alarm_deal_log alarm_deal = new yw_alarm_deal_log(); + alarm_deal.setEndTime(DateUtils.parseDate(DateUtils.getTime())); + alarm_deal.setDealUser(userId.toString()); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("alarm_type", alarmType); + updateWrapper.eq("group_id", group_id); + alarm_deal_logMapper.update(alarm_deal,updateWrapper); + + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmWXServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmWXServiceImpl.java new file mode 100644 index 0000000..7afab1c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwAlarmWXServiceImpl.java @@ -0,0 +1,216 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.eastcom_yw.domain.*; +import com.ruoyi.eastcom_yw.domain.YwAlarmWX; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmLastVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmVo; +import com.ruoyi.eastcom_yw.mapper.YwAlarmViewMapper; +import com.ruoyi.eastcom_yw.mapper.YwAlarmWXMapper; +import com.ruoyi.eastcom_yw.mapper.YwAlarmMapper; +import com.ruoyi.eastcom_yw.mapper.YwAlarmWXMapper; +import com.ruoyi.eastcom_yw.service.CommonService; +import com.ruoyi.eastcom_yw.service.YwAlarmWXService; +import com.ruoyi.eastcom_yw.service.YwAlarmOprateLogService; +import com.ruoyi.eastcom_yw.service.YwAlarmWXService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + *

+ * 服务实现类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Service +public class YwAlarmWXServiceImpl extends ServiceImpl implements YwAlarmWXService { + + @Autowired + private YwAlarmWXMapper ywAlarmWXMapper; + + @Autowired + private YwAlarmViewMapper ywAlarmViewMapper; + @Autowired + private YwAlarmOprateLogService ywAlarmOprateLogService; + + @Autowired + private CommonService commonService; + + @Override + public TableDataInfo GetAlarmList(YwAlarmDTO alarmDTO) { + + LambdaQueryWrapper lambdaQueryWrapper=new LambdaQueryWrapper<>(); + + //告警当前的处理状态 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getDealStatus()),YwAlarmView::getDealStatus, alarmDTO.getDealStatus()); + + //告警的状态 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getAlarmStatus())&&"0".equals(alarmDTO.getAlarmStatus()), YwAlarmView::getAlarmStatus, alarmDTO.getAlarmStatus()); + + //告警名称模糊查询 + lambdaQueryWrapper.like(StringUtils.isNotEmpty(alarmDTO.getAlarmName()),YwAlarmView::get告警名称, alarmDTO.getAlarmName()); + + //告警的区县 + //20230303区县改为AreaCountyId查询 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getCounty()), YwAlarmView::getAreaCountyId, alarmDTO.getCounty()); + + //告警的场馆 + lambdaQueryWrapper.in(CollUtil.isNotEmpty(alarmDTO.getVenues()), YwAlarmView::get场馆id, alarmDTO.getVenues()); + + //告警的类型 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getAlarmType()), YwAlarmView::getAlarmType, alarmDTO.getAlarmType()); + + //告警的专业 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getAlarmGroup()), YwAlarmView::getAlarmType, alarmDTO.getAlarmGroup()); + + //告警的专业 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(alarmDTO.getInRedLine()), YwAlarmView::get红线内, alarmDTO.getInRedLine()); + + //告警的时间 + lambdaQueryWrapper.between(ObjectUtils.isNotEmpty(alarmDTO.getStartTime()) && ObjectUtils.isNotEmpty(alarmDTO.getEndTime()), YwAlarmView::get告警时间, alarmDTO.getStartTime(), alarmDTO.getEndTime()+" 23:59:59"); + + //告警搜索框 + if(StrUtil.isNotBlank(alarmDTO.getSearchBox())){ + lambdaQueryWrapper.and(i->i.like(YwAlarmView::get告警名称,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::getDealUser,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::get基站号,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::get基站名,alarmDTO.getSearchBox()) + .or().like(YwAlarmView::get网元名称,alarmDTO.getSearchBox())); + } + + + Page page= ywAlarmWXMapper.selectPage(new Page<>(alarmDTO.getPageNum(), alarmDTO.getPageSize()),lambdaQueryWrapper); + + TableDataInfo rspData = new TableDataInfo(); + + rspData.setTotal(page.getTotal()); + + List listVo=new ArrayList<>(); + + for(YwAlarmView ywAlarmsLast: page.getRecords()) + { + + int clearNum=0; + + YwAlarmLastVo ywAlarmLastVo=new YwAlarmLastVo(); + + LambdaQueryWrapper lambdaQueryWrapperOper=new LambdaQueryWrapper<>(); + lambdaQueryWrapperOper.eq(YwAlarmOprateLog::getAlarmGroup, ywAlarmsLast.get关联组号()); + lambdaQueryWrapperOper.eq(YwAlarmOprateLog::getUserId,alarmDTO.getUserId()); + ywAlarmLastVo.setOpId(0L); + //查询告警用户是否点击 + ywAlarmOprateLogService.list(lambdaQueryWrapperOper).forEach( + ywAlarmOprateLog -> { + ywAlarmLastVo.setOpId(ywAlarmOprateLog.getId()); + } + ); + + ywAlarmLastVo.setKey(ywAlarmsLast.getId()); + if(ObjectUtils.isEmpty(ywAlarmsLast.get场馆id())) + { + continue; + } + ywAlarmLastVo.setVenue_id(ywAlarmsLast.get场馆id().toString()); + ywAlarmLastVo.setCg(ywAlarmsLast.get场馆名称()); + //工单号 +// ywAlarmLastVo.setGd(""); + ywAlarmLastVo.setSite_id(ywAlarmsLast.get基站号()); + ywAlarmLastVo.setSite_name(ywAlarmsLast.get基站名()); + ywAlarmLastVo.setNet_name(ywAlarmsLast.get网元名称()); + ywAlarmLastVo.setGroupId(ywAlarmsLast.get关联组号()); + ywAlarmLastVo.setName(ywAlarmsLast.get告警名称()); + ywAlarmLastVo.setStart(ywAlarmsLast.get告警时间()); + ywAlarmLastVo.setEnd(ywAlarmsLast.get恢复时间()); + if(StringUtils.isNotEmpty(ywAlarmsLast.get恢复时间())) + { + clearNum++; + } + ywAlarmLastVo.setInRedLine(ywAlarmsLast.get红线内()); + ywAlarmLastVo.setUserId(ywAlarmsLast.getDealUserId()); + ywAlarmLastVo.setPerson(ywAlarmsLast.getDealUser()); + //冗余state + ywAlarmLastVo.setState(ywAlarmsLast.getDealStatus()); + ywAlarmLastVo.setAlarmStatus(ywAlarmsLast.getAlarmStatus()); + ywAlarmLastVo.setDealStatus(ywAlarmsLast.getDealStatus()); + ywAlarmLastVo.setState(ywAlarmsLast.getDealStatus()); + ywAlarmLastVo.setProcessId(ywAlarmsLast.getProcessId()); + ywAlarmLastVo.setTaskId(ywAlarmsLast.getTaskId()); + //20230308增加了反馈人的红蓝白区标签 + ywAlarmLastVo.setBelongArea(ywAlarmsLast.getBelongArea()); + //用户判断主告警和次告警是否全部恢复了,空表示没有,全部恢复显示最新的恢复时间 + ywAlarmLastVo.setLastClearTime(ywAlarmsLast.getLastClearTime()); + + ywAlarmLastVo.setIsHangup(ywAlarmsLast.getIsHangup()); + + //查询次要告警 + List ywAlarmListLess = ywAlarmViewMapper.getYwAlarmByGroupId(ywAlarmsLast.getAlarmType(),ywAlarmsLast.get关联组号()); + //当前告警总数 + int alarmNum = ywAlarmListLess.size()+1; + + List ywAlarmVoList=new ArrayList(); + if(ywAlarmListLess.size()>0) + { + for(YwAlarmVo ywAlarmLess: ywAlarmListLess) + { + +// 设计问题导致前端用了Net_name和Site_name + YwAlarmVo ywAlarmVo = new YwAlarmVo(); + + BeanUtils.copyBeanProp(ywAlarmVo,ywAlarmLess); + + ywAlarmVo.setNet_name(ywAlarmLess.getNetName()); + + ywAlarmVo.setSite_name(ywAlarmLess.getSiteName()); + + if(StringUtils.isNotEmpty(ywAlarmLess.getEnd())) + { + clearNum++; + } + + ywAlarmVoList.add(ywAlarmVo); + + } + } + ywAlarmLastVo.setAlarmchildren(ywAlarmVoList); + ywAlarmLastVo.setClearNum(clearNum); + ywAlarmLastVo.setClearNumDisplay(clearNum+"/"+alarmNum); + + // //查询工作流,比较是否是当前登录用户的待办 + //APP端 + if(alarmDTO.getIsAPP()) { + List processIds = commonService.selectCurrenUserTodoProcessId(alarmDTO.getAlarmType()); + if (CollUtil.isNotEmpty(processIds)) { + for (String processId : processIds) { + if (processId.equals(ywAlarmLastVo.getProcessId())) { + ywAlarmLastVo.setIsTodo(1); + } + } + } + } + + listVo.add(ywAlarmLastVo); + } + + rspData.setRows(listVo); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setMsg("查询成功"); + return rspData; + + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwDrsConfigServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwDrsConfigServiceImpl.java new file mode 100644 index 0000000..c47f638 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwDrsConfigServiceImpl.java @@ -0,0 +1,119 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwDrsConfig; +import com.ruoyi.eastcom_yw.domain.dto.YwDrsConfigDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwDrsConfigQO; +import com.ruoyi.eastcom_yw.domain.vo.YwDrsConfigVO; +import com.ruoyi.eastcom_yw.mapper.YwDrsConfigMapper; +import com.ruoyi.eastcom_yw.service.YwDrsConfigService; +import com.ruoyi.eastcom_yw.service.convert.YwDrsConfigConvert; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + *

+ * DRS配置表 服务实现类 + *

+ * + * @author ck + * @since 2023-06-13 + */ +@Service +public class YwDrsConfigServiceImpl extends ServiceImpl implements YwDrsConfigService { + + @Resource + private YwDrsConfigMapper ywDrsConfigMapper; + + /** + * DRS配置表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(YwDrsConfigQO qo) { + return ywDrsConfigMapper.list(qo); + } + + /** + * DRS配置表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public PageInfo getDataByPage(YwDrsConfigQO qo) { + PageHelper.startPage(qo.getPageNum(),qo.getPageSize()); + List list = getData(qo); + return PageInfo.of(list); + } + + @Override + public YwDrsConfigVO fetchById(Long id) { + YwDrsConfig entity = ywDrsConfigMapper.selectById(id); + return YwDrsConfigConvert.INSTANCE.entityToVo(entity); + } + + @Override + public boolean saveOrUpdate(YwDrsConfigDTO dto) { + YwDrsConfig entity = YwDrsConfigConvert.INSTANCE.dtoToEntity(dto); + return saveOrUpdate(entity); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(ywDrsConfigMapper.deleteBatchIds(ids)); + } + + @Override + public void export(YwDrsConfigQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + ExcelUtil util = new ExcelUtil<>(YwDrsConfigVO.class); + try { + util.exportExcel(response, data, "DRS配置表信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + + // 核查 + // boolean checkFlag; + // checkFlag = checkData(cs, ywSceneList); + // if (checkFlag) { + // checkFlag = checkUnique(cs); + // } + // if (!checkFlag) { + // ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); + // String fileName = (String) util.exportExcel(cs, "网元传输导入结果").get(AjaxResult.MSG_TAG); + // return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + // } + // saveBatch(list); + return null; + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwDrsTempTaskServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwDrsTempTaskServiceImpl.java new file mode 100644 index 0000000..d9cf4ea --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwDrsTempTaskServiceImpl.java @@ -0,0 +1,410 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.*; +import com.ruoyi.eastcom_yw.domain.dto.YwDrsTempTaskDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwDrsTempTaskTimeDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwDrsTempTaskQO; +import com.ruoyi.eastcom_yw.domain.vo.YwDrsTempTaskVO; +import com.ruoyi.eastcom_yw.mapper.*; +import com.ruoyi.eastcom_yw.service.YwDrsTempTaskService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.eastcom_yw.service.convert.YwDrsTempTaskConvert; +import com.ruoyi.system.mapper.SysUserRoleMapper; +import com.ruoyi.system.service.ISysDictDataService; +import com.ruoyi.system.service.ISysDictTypeService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * DRS临时任务表 服务实现类 + *

+ * + * @author ck + * @since 2023-06-13 + */ +@Service +public class YwDrsTempTaskServiceImpl extends ServiceImpl implements YwDrsTempTaskService { + + @Resource + private YwDrsTempTaskMapper ywDrsTempTaskMapper; + + @Resource + private YwSceneMapper ywSceneMapper; + + @Resource + private YwSceneUserMapper ywSceneUserMapper; + + @Resource + private SysUserRoleMapper sysUserRoleMapper; + + @Resource + private YwSceneService ywSceneService; + + @Resource + private YwSignPlanMapper ywSignPlanMapper; + + @Resource + private YwSignLogMapper ywSignLogMapper; + + @Resource + private ISysDictTypeService sysDictTypeService; + + @Resource + private ISysDictDataService dictDataService; + + /** + * DRS临时任务表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(YwDrsTempTaskQO qo) { + Long userId = SecurityUtils.getUserId(); + SysUser user = SecurityUtils.getLoginUser().getUser(); + if (!user.isAdmin(user)) { + List ywSceneUsers = ywSceneUserMapper.selectList(new LambdaQueryWrapper().eq(YwSceneUser::getUserId, userId)); + List venueIds = ywSceneUsers.stream().map(YwSceneUser::getSceneId).collect(Collectors.toList()); + if (CollUtil.isEmpty(venueIds)) { + throw new ServiceException("当前登录用户未绑定场馆"); + } + qo.setVenueIds(venueIds); + } + qo.setPageNum(null); + qo.setPageSize(null); + List list = ywDrsTempTaskMapper.list(qo); + translate(list); + return list; + } + + private void translate(List list) { + if (CollUtil.isNotEmpty(list)) { + for (YwDrsTempTaskVO vo : list) { + YwScene scene = ywSceneMapper.selectById(vo.getVenueId()); + if (scene != null) { + vo.setVenueName(scene.getVenueName()); + } + if ("0".equals(vo.getDrsAutoUpdate()) && vo.getTaskTime() != null && vo.getTaskEndTime() != null) { + LocalDateTime now = LocalDateTime.now(); + if (now.isBefore(vo.getTaskTime())) { + vo.setDrsTaskStatus("0"); + } else if (now.isAfter(vo.getTaskEndTime())) { + vo.setDrsTaskStatus("2"); + } else if (now.isBefore(vo.getTaskEndTime()) && now.isAfter(vo.getTaskTime())) { + vo.setDrsTaskStatus("1"); + } else { + throw new ServiceException("任务开始时间与结束时间有错误"); + } + } + if ("1".equals(vo.getDrsAutoUpdate())) { + vo.setTaskEndTime(null); + } + } + } + } + + /** + * DRS临时任务表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public PageInfo getDataByPage(YwDrsTempTaskQO qo) { + Long userId = SecurityUtils.getUserId(); + SysUser user = SecurityUtils.getLoginUser().getUser(); + if (!user.isAdmin(user)) { + List ywSceneUsers = ywSceneUserMapper.selectList(new LambdaQueryWrapper().eq(YwSceneUser::getUserId, userId)); + List venueIds = ywSceneUsers.stream().map(YwSceneUser::getSceneId).collect(Collectors.toList()); + if (CollUtil.isEmpty(venueIds)) { + throw new ServiceException("当前登录用户未绑定场馆"); + } + qo.setVenueIds(venueIds); + } + + if (qo.getVenueId() == null && (StrUtil.isNotBlank(qo.getVenueType()) || StrUtil.isNotBlank(qo.getMaintainType()))) { + List ywSceneList = ywSceneMapper.selectList(new LambdaQueryWrapper().eq(StrUtil.isNotBlank(qo.getVenueType()), YwScene::getVenueType, qo.getVenueType()) + .eq(StrUtil.isNotBlank(qo.getMaintainType()), YwScene::getMaintainType, qo.getMaintainType())); + if (CollUtil.isNotEmpty(ywSceneList)) { + List venueIds = ywSceneList.stream().map(YwScene::getId).collect(Collectors.toList()); + qo.setVenueIds(venueIds); + } + } + + PageHelper.startPage(qo.getPageNum(), qo.getPageSize()); + List list = ywDrsTempTaskMapper.list(qo); + translate(list); + return PageInfo.of(list); + } + + @Override + public YwDrsTempTaskVO fetchById(Long id) { + YwDrsTempTask entity = ywDrsTempTaskMapper.selectById(id); + YwDrsTempTaskVO vo = YwDrsTempTaskConvert.INSTANCE.entityToVo(entity); + YwScene scene = ywSceneMapper.selectById(vo.getVenueId()); + if (scene != null) { + vo.setVenueName(scene.getVenueName()); + } + if ("0".equals(vo.getDrsAutoUpdate()) && vo.getTaskTime() != null && vo.getTaskEndTime() != null) { + LocalDateTime now = LocalDateTime.now(); + if (now.isBefore(vo.getTaskTime())) { + vo.setDrsTaskStatus("0"); + } else if (now.isAfter(vo.getTaskEndTime())) { + vo.setDrsTaskStatus("2"); + } else if (now.isBefore(vo.getTaskEndTime()) && now.isAfter(vo.getTaskTime())) { + vo.setDrsTaskStatus("1"); + } else { + throw new ServiceException("任务开始时间与结束时间有错误"); + } + } + return vo; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean saveOrUpdate(YwDrsTempTaskDTO dto) { + List ywDrsTempTaskTimes = dto.getYwDrsTempTaskTimes(); + for (YwDrsTempTaskTimeDTO ywDrsTempTaskTime : ywDrsTempTaskTimes) { + if(StrUtil.isBlank(ywDrsTempTaskTime.getTaskName())){ + throw new ServiceException("任务名称必填"); + } + YwDrsTempTask entity = YwDrsTempTaskConvert.INSTANCE.dtoToEntity(dto); + entity.setTaskTime(ywDrsTempTaskTime.getTaskTime()); + entity.setTaskEndTime(ywDrsTempTaskTime.getTaskEndTime()); + entity.setDrsAutoUpdate(ywDrsTempTaskTime.getDrsAutoUpdate()); + entity.setDrsTaskStatus(ywDrsTempTaskTime.getDrsTaskStatus()); + entity.setTaskName(ywDrsTempTaskTime.getTaskName()); + + YwDrsTempTask one = getOne(new LambdaQueryWrapper() + .eq(YwDrsTempTask::getVenueId, entity.getVenueId()) + .eq(YwDrsTempTask::getTaskDate, entity.getTaskDate()) + .eq(YwDrsTempTask::getTaskTime, entity.getTaskTime()) + .eq(YwDrsTempTask::getTaskName, entity.getTaskName())); + if (one != null && !one.getId().equals(dto.getId())) { + throw new ServiceException("数据重复(场馆、任务日期、任务开始时间、任务名称)"); + } + + entity.setDrsTaskType(null); + if ("1".equals(entity.getDrsAutoUpdate())) { + entity.setTaskEndTime(null); + } + if ("0".equals(entity.getDrsAutoUpdate()) && entity.getTaskEndTime() == null) { + throw new ServiceException("状态变更为自动时需要输入任务结束时间"); + } + saveOrUpdate(entity); + } + return true; + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(ywDrsTempTaskMapper.deleteBatchIds(ids)); + } + + @Override + public void export(YwDrsTempTaskQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + ExcelUtil util = new ExcelUtil<>(YwDrsTempTaskVO.class); + util.hideColumn("reason"); + try { + util.exportExcel(response, data, "DRS临时任务表信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + boolean checkFlag = true; + for (YwDrsTempTaskVO vo : list) { + if (StrUtil.isBlank(vo.getTaskName())) { + return AjaxResult.error("导入模板不正确。任务名称为空"); + } + + StringBuilder builder = new StringBuilder(); + if (StrUtil.isBlank(vo.getVenueName())) { + builder.append("【场馆名称】为空;"); + checkFlag = false; + } else { + String venueName = vo.getVenueName(); + List scenes = ywSceneService.list(new LambdaQueryWrapper().eq(YwScene::getVenueName, venueName)); + if (CollUtil.isEmpty(scenes)) { + builder.append("【场馆名】不存在;"); + checkFlag = false; + } + } + if (vo.getTaskTime() == null) { + builder.append("【开始时间】为空;"); + checkFlag = false; + } + if (StrUtil.isBlank(vo.getDrsAutoUpdate())) { + builder.append("【派发方式】不能为空;"); + checkFlag = false; + } else if ("0".equals(vo.getDrsAutoUpdate()) && vo.getTaskEndTime() == null) { + builder.append("【派发方式】为自动时,【结束时间】不能为空;"); + checkFlag = false; + } else if ("0".equals(vo.getDrsAutoUpdate()) && vo.getTaskEndTime().isBefore(vo.getTaskTime())) { + builder.append("结束时间应晚于开始时间;"); + checkFlag = false; + } + if (StrUtil.isBlank(vo.getTaskName())) { + builder.append("【任务名称】为空;"); + checkFlag = false; + } + if (!"0".equals(vo.getDrsAutoUpdate())) { + if (StrUtil.isBlank(vo.getDrsTaskStatus())) { + builder.append("【派发方式】为手动时,【任务状态】不能为空;"); + checkFlag = false; + } else { + List drs_task_status = sysDictTypeService.selectDictDataByType("drs_task_status").stream().map(SysDictData::getDictValue).collect(Collectors.toList()); + if (!drs_task_status.contains(vo.getDrsTaskStatus())) { + builder.append("【任务状态】不存在;"); + checkFlag = false; + } + } + } + vo.setReason(builder.toString()); + } + if (!checkFlag) { + ExcelUtil util = new ExcelUtil<>(YwDrsTempTaskVO.class); + util.hideColumn("taskDate"); + String fileName = (String) util.exportExcel(list, "DRS临时任务导入结果").get(AjaxResult.MSG_TAG); + return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + } else { + importList(list); + } + + return AjaxResult.success(); + } + + private void importList(List list) { + List entityList = new ArrayList<>(); + for (YwDrsTempTaskVO vo : list) { + YwDrsTempTask entity = new YwDrsTempTask(); + String venueName = vo.getVenueName(); + List scenes = ywSceneService.list(new LambdaQueryWrapper().eq(YwScene::getVenueName, venueName)); + if (CollUtil.isNotEmpty(scenes)) { + YwScene scene = scenes.get(0); + entity.setVenueId(scene.getId()); + } + + LocalDate taskDate = vo.getTaskDate(); + LocalTime taskTime = LocalTime.from(vo.getTaskTime()); + LocalDateTime binTime = LocalDateTime.of(taskDate, taskTime); + entity.setTaskDate(taskDate); + entity.setTaskTime(binTime); + if (vo.getTaskEndTime() != null) { + LocalTime taskEndTime = LocalTime.from(vo.getTaskEndTime()); + LocalDateTime endTime = LocalDateTime.of(taskDate, taskEndTime); + entity.setTaskEndTime(endTime); + } + + entity.setTaskName(vo.getTaskName()); + entity.setDrsTaskType(null); + entity.setDrsTaskStatus(vo.getDrsTaskStatus()); + entity.setDrsAutoUpdate(vo.getDrsAutoUpdate()); + entity.setRemark(""); + + List ywDrsTempTasks = ywDrsTempTaskMapper.selectList(new LambdaQueryWrapper() + .eq(YwDrsTempTask::getVenueId, entity.getVenueId()) + .eq(YwDrsTempTask::getTaskDate, entity.getTaskDate()) + .eq(YwDrsTempTask::getTaskTime, entity.getTaskTime()) + .eq(YwDrsTempTask::getTaskName, entity.getTaskName()) + ); + if (CollUtil.isNotEmpty(ywDrsTempTasks)) { + YwDrsTempTask ywDrsTempTask = ywDrsTempTasks.get(0); + entity.setId(ywDrsTempTask.getId()); + } + entityList.add(entity); + } + saveOrUpdateBatch(entityList); + } + + @Override + public List drsPreview(Long venueId, LocalDate date) { + YwScene scene = ywSceneMapper.selectOne(new LambdaQueryWrapper().eq(YwScene::getVenueName, "杭州亚运会运行保障指挥部")); + if (scene == null) { + throw new ServiceException("名为'杭州亚运会运行保障指挥部'的场馆不存在"); + } + List vos = ywDrsTempTaskMapper.selectDrsPreviewByVenueIdAndDate(venueId, date, scene.getId()); + if (venueId.equals(scene.getId())) { + List configIds = vos.stream().map(YwDrsTempTaskVO::getConfigId).collect(Collectors.toList()); + if (configIds.contains(1L) && configIds.contains(2L)) { + vos.removeIf(l -> l.getConfigId() == 2L); + } + if (configIds.contains(4L) && configIds.contains(5L)) { + vos.removeIf(l -> l.getConfigId() == 4L); + } + } + List handlerSign = vos.stream().filter(l -> "1".equals(l.getDrsTaskType()) && l.getTaskName().contains("签到")).collect(Collectors.toList()); + for (YwDrsTempTaskVO signVo : handlerSign) { + Long sceneId = signVo.getVenueId(); + LocalDateTime binTime = signVo.getTaskTime(); + YwSignPlanView ywSignPlanView = ywSignPlanMapper.selectOne(new LambdaQueryWrapper() + .eq(YwSignPlanView::getSceneId, sceneId) + .eq(YwSignPlanView::getBeginTime, binTime) + .eq(YwSignPlanView::getIsOpen, "1") + ); + //应签到数 + Long all = ywSignLogMapper.selectCount(new LambdaQueryWrapper() + .eq(YwSignLog::getSignPlanId, ywSignPlanView.getId()) + .eq(YwSignLog::getSignType, 0) + ); + //已签到数 + Long complate = ywSignLogMapper.selectCount(new LambdaQueryWrapper() + .eq(YwSignLog::getSignPlanId, ywSignPlanView.getId()) + .eq(YwSignLog::getSignType, 0) + .isNotNull(YwSignLog::getSignTime) + ); + signVo.setRemark(complate + "/" + all); + } + for (YwDrsTempTaskVO vo : vos) { + String tasktypevalue = dictDataService.selectDictLabel("drs_task_type", vo.getDrsTaskType()); + if (null != tasktypevalue) { + vo.setDrsTaskTypeStr(tasktypevalue); + } + + String taskstatusvalue = dictDataService.selectDictLabel("drs_task_status", vo.getDrsTaskStatus()); + if (null != taskstatusvalue) { + vo.setDrsTaskStatusStr(taskstatusvalue); + } + } + return vos; + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwKpiConfigServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwKpiConfigServiceImpl.java new file mode 100644 index 0000000..bff2a00 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwKpiConfigServiceImpl.java @@ -0,0 +1,149 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwKpiConfig; +import com.ruoyi.eastcom_yw.domain.dto.YwKpiConfigDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwKpiConfigQO; +import com.ruoyi.eastcom_yw.domain.vo.YwKpiConfigVO; +import com.ruoyi.eastcom_yw.mapper.YwKpiConfigMapper; +import com.ruoyi.eastcom_yw.service.YwKpiConfigService; +import com.ruoyi.eastcom_yw.service.convert.YwKpiConfigConvert; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** + *

+ * 指标字段阈值配置表 服务实现类 + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Service +public class YwKpiConfigServiceImpl extends ServiceImpl implements YwKpiConfigService { + + @Resource + private YwKpiConfigMapper ywKpiConfigMapper; + + /** + * 指标字段阈值配置表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(YwKpiConfigQO qo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + // 序号 + .eq(qo.getId() != null, YwKpiConfig::getId, qo.getId()) + // 专业(1-无线) + .eq(qo.getSubject() != null, YwKpiConfig::getSubject, qo.getSubject()) + // 网络模式(1-4G,2-5G) + .eq(qo.getNetType() != null, YwKpiConfig::getNetType, qo.getNetType()) + // 指标字段 + .eq(qo.getKpiField() != null, YwKpiConfig::getKpiField, qo.getKpiField()) + ; + List list = ywKpiConfigMapper.selectList(queryWrapper); + return YwKpiConfigConvert.INSTANCE.entityToVoList(list); + } + + /** + * 指标字段阈值配置表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public IPage getDataByPage(YwKpiConfigQO qo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + // 序号 + .eq(qo.getId() != null, YwKpiConfig::getId, qo.getId()) + // 专业(1-无线) + .eq(qo.getSubject() != null, YwKpiConfig::getSubject, qo.getSubject()) + // 网络模式(1-4G,2-5G) + .eq(qo.getNetType() != null, YwKpiConfig::getNetType, qo.getNetType()) + // 指标字段 + .eq(qo.getKpiField() != null, YwKpiConfig::getKpiField, qo.getKpiField()) + ; + + Page page = page(new Page<>(qo.getPageNum(), qo.getPageSize()), queryWrapper); + IPage voPage = page.convert(YwKpiConfigConvert.INSTANCE::entityToVo); + return voPage; + } + + @Override + public YwKpiConfigVO fetchById(Long id) { + YwKpiConfig entity = ywKpiConfigMapper.selectById(id); + return YwKpiConfigConvert.INSTANCE.entityToVo(entity); + } + + @Override + public boolean saveOrUpdate(YwKpiConfigDTO dto) { + YwKpiConfig entity = YwKpiConfigConvert.INSTANCE.dtoToEntity(dto); + return saveOrUpdate(entity); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(ywKpiConfigMapper.deleteBatchIds(ids)); + } + + @Override + public void export(YwKpiConfigQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + ExcelUtil util = new ExcelUtil<>(YwKpiConfigVO.class); + try { + util.exportExcel(response, data, "指标字段阈值配置表信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + + // 核查 + // boolean checkFlag; + // checkFlag = checkData(cs, ywSceneList); + // if (checkFlag) { + // checkFlag = checkUnique(cs); + // } + // if (!checkFlag) { + // ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); + // String fileName = (String) util.exportExcel(cs, "网元传输导入结果").get(AjaxResult.MSG_TAG); + // return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + // } + // saveBatch(list); + return null; + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeBriefingServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeBriefingServiceImpl.java new file mode 100644 index 0000000..833f110 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeBriefingServiceImpl.java @@ -0,0 +1,1598 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson2.JSONObject; +import com.alibaba.fastjson2.JSONWriter; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.*; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeBriefingDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeBriefingQO; +import com.ruoyi.eastcom_yw.domain.vo.*; +import com.ruoyi.eastcom_yw.mapper.YwAlarmMapper; +import com.ruoyi.eastcom_yw.mapper.YwNoticeBriefingMapper; +import com.ruoyi.eastcom_yw.mapper.YwSceneMapper; +import com.ruoyi.eastcom_yw.mapper.YwSceneMatchMapper; +import com.ruoyi.eastcom_yw.service.*; +import com.ruoyi.eastcom_yw.service.convert.YwNoticeBriefingConvert; +import com.ruoyi.eastcom_yw.service.convert.YwNoticeModelConvert; +import com.ruoyi.framework.web.domain.dto.MobileOfficesDTO; +import com.ruoyi.framework.web.service.sms.MessageService; +import com.ruoyi.system.mapper.SysUserMapper; +import com.ruoyi.system.service.ISysDictDataService; +import com.ruoyi.system.service.ISysDictTypeService; +import com.ruoyi.system.service.ISysUserService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileItemFactory; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.concurrent.CountDownLatch; +import java.util.stream.Collectors; + +/** + *

+ * 通知通告简报计划表 服务实现类 + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Service +@Slf4j +public class YwNoticeBriefingServiceImpl extends ServiceImpl implements YwNoticeBriefingService { + + @Resource + private YwNoticeBriefingMapper ywNoticeBriefingMapper; + + @Resource + private YwSceneService ywSceneService; + + @Resource + private YwSceneMatchMapper ywSceneMatchMapper; + + @Resource + private YwScenePictureService ywScenePictureService; + + @Resource + private YwNoticeModelService ywNoticeModelService; + + @Resource + private YwNoticeObjectService ywNoticeObjectService; + + @Resource + private MessageService messageService; + + @Resource + private ISysDictDataService dictDataService; + + @Resource + private SysNoticeService sysNoticeService; + + @Resource + private ISysUserService sysUserService; + + @Resource + private SysUserMapper sysUserMapper; + + @Resource + private ISysDictTypeService sysDictTypeService; + + @Resource + private ISysDictDataService sysDictDataService; + + @Resource + private YwAlarmMapper ywAlarmMapper; + + @Resource + private PmKpiMonitorCellService pmKpiMonitorCellService; + + @Resource + private YwSceneMapper ywSceneMapper; + + @Resource + private ThreadPoolTaskExecutor threadPool; + + @Value("${file.briefingJsonPath}") + private String briefingJsonPath; + + @Value("${file.briefingShortUrl}") + private String briefingShortUrl; + + /** + * 通知通告简报计划表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(YwNoticeBriefingQO qo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + // 地市 + .eq(StrUtil.isNotBlank(qo.getCity()), YwNoticeBriefing::getCity, qo.getCity()) + // 场馆id + .in(CollUtil.isNotEmpty(qo.getVenueId()), YwNoticeBriefing::getVenueId, qo.getVenueId()) + // 对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层) + .eq(StrUtil.isNotBlank(qo.getObjectProto()), YwNoticeBriefing::getObjectProto, qo.getObjectProto()) + // 通知方式sys_notice_type + .eq(StrUtil.isNotBlank(qo.getNoticeType()), YwNoticeBriefing::getNoticeType, qo.getNoticeType()) + // 发送日期 + .eq(qo.getSendDate() != null, YwNoticeBriefing::getSendDate, qo.getSendDate()) + // 开始时间 + .eq(qo.getBeginTime() != null, YwNoticeBriefing::getBeginTime, qo.getBeginTime()) + // 结束时间 + .eq(qo.getEndTime() != null, YwNoticeBriefing::getEndTime, qo.getEndTime()) + // 区县 + .eq(StrUtil.isNotBlank(qo.getCounty()), YwNoticeBriefing::getCounty, qo.getCounty()) + // 对象ids数组 +// .eq(StrUtil.isNotBlank(qo.getObjectIds()), YwNoticeBriefing::getObjectIds, qo.getObjectIds()) + // 模板id + .eq(qo.getModelId() != null, YwNoticeBriefing::getModelId, qo.getModelId()) + // 排序号 + .eq(qo.getOrderNum() != null, YwNoticeBriefing::getOrderNum, qo.getOrderNum()) + // 时间间隔(单位分) + .eq(qo.getTimeInterval() != null, YwNoticeBriefing::getTimeInterval, qo.getTimeInterval()) + // 通知名称 + .like(StrUtil.isNotBlank(qo.getNoticeName()), YwNoticeBriefing::getNoticeName, qo.getNoticeName()) + .orderBy(true, false, YwNoticeBriefing::getId) + ; + List list = ywNoticeBriefingMapper.selectList(queryWrapper); + if (CollUtil.isEmpty(list)) { + return new ArrayList<>(); + } + List vos = YwNoticeBriefingConvert.INSTANCE.entityToVoList(list); + //翻译场馆、对象数组、模板 + for (YwNoticeBriefingVO vo : vos) { + translate(vo); + } + if (StrUtil.isNotBlank(qo.getKeyWord())) { + vos = vos.stream().filter(l -> l.getObjectNameStr().contains(qo.getKeyWord()) || l.getNoticeName().contains(qo.getKeyWord())).collect(Collectors.toList()); + } + return vos; + } + + + /** + * 通知通告简报计划表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public IPage getDataByPage(YwNoticeBriefingQO qo) { + + if (CollUtil.isEmpty(qo.getVenueId()) && (StrUtil.isNotBlank(qo.getVenueType()) || StrUtil.isNotBlank(qo.getMaintainType()))) { + List ywSceneList = ywSceneMapper.selectList(new LambdaQueryWrapper().eq(StrUtil.isNotBlank(qo.getVenueType()), YwScene::getVenueType, qo.getVenueType()) + .eq(StrUtil.isNotBlank(qo.getMaintainType()), YwScene::getMaintainType, qo.getMaintainType())); + if (CollUtil.isNotEmpty(ywSceneList)) { + List venueIds = ywSceneList.stream().map(YwScene::getId).collect(Collectors.toList()); + qo.setVenueId(venueIds); + } + } + +// List data = ywNoticeBriefingMapper.getDataByPage(qo); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + // 地市 + .eq(StrUtil.isNotBlank(qo.getCity()), YwNoticeBriefing::getCity, qo.getCity()) + // 场馆id + .in(CollUtil.isNotEmpty(qo.getVenueId()), YwNoticeBriefing::getVenueId, qo.getVenueId()) + // 对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层) + .eq(StrUtil.isNotBlank(qo.getObjectProto()), YwNoticeBriefing::getObjectProto, qo.getObjectProto()) + // 通知方式sys_notice_type + .eq(StrUtil.isNotBlank(qo.getNoticeType()), YwNoticeBriefing::getNoticeType, qo.getNoticeType()) + //简报类型briefing_type + .eq(StrUtil.isNotBlank(qo.getModelSuitType()), YwNoticeBriefing::getModelSuitType, qo.getModelSuitType()) + //发送方式send_type + .eq(StrUtil.isNotBlank(qo.getSendType()), YwNoticeBriefing::getSendType, qo.getSendType()) + //发送用户send_user + .eq(qo.getSendUser() != null, YwNoticeBriefing::getSendUser, qo.getSendUser()) + // 发送日期 + .eq(qo.getSendDate() != null, YwNoticeBriefing::getSendDate, qo.getSendDate()) + // 开始时间 + .eq(qo.getBeginTime() != null, YwNoticeBriefing::getBeginTime, qo.getBeginTime()) + // 结束时间 + .eq(qo.getEndTime() != null, YwNoticeBriefing::getEndTime, qo.getEndTime()) + // 区县 + .eq(StrUtil.isNotBlank(qo.getCounty()), YwNoticeBriefing::getCounty, qo.getCounty()) + // 对象ids数组 +// .in(StrUtil.isNotBlank(qo.getObjectIds()), YwNoticeBriefing::getObjectIds, qo.getObjectIds()) + // 模板id + .eq(qo.getModelId() != null, YwNoticeBriefing::getModelId, qo.getModelId()) + // 时间间隔(单位分) + .eq(qo.getTimeInterval() != null, YwNoticeBriefing::getTimeInterval, qo.getTimeInterval()) + // 通知名称 + .like(StrUtil.isNotBlank(qo.getNoticeName()), YwNoticeBriefing::getNoticeName, qo.getNoticeName()) + .orderBy(true, false, YwNoticeBriefing::getId) + ; + + Page page = page(new Page<>(qo.getPageNum(), qo.getPageSize()), queryWrapper); + IPage voPage = page.convert(YwNoticeBriefingConvert.INSTANCE::entityToVo); + List vos = voPage.getRecords(); + if (CollUtil.isEmpty(vos)) { + return new Page<>(); + } + for (YwNoticeBriefingVO vo : vos) { + translate(vo); + } + voPage.setRecords(vos); + return voPage; + } + + @Override + public YwNoticeBriefingVO fetchById(Long id) { + YwNoticeBriefing entity = ywNoticeBriefingMapper.selectById(id); + YwNoticeBriefingVO vo = YwNoticeBriefingConvert.INSTANCE.entityToVo(entity); + translate(vo); + return vo; + } + + @Override + public boolean saveOrUpdate(YwNoticeBriefingDTO dto) { + if (dto.getId() != null) { + YwNoticeBriefing entity = ywNoticeBriefingMapper.selectById(dto.getId()); + if (entity == null) { + throw new ServiceException("未查询到可修改数据"); + } + if (entity.getSysNormalDisable() == null || "0".equals(entity.getSysNormalDisable())) { + throw new ServiceException("请先停用该简报后再修改"); + } + } + YwNoticeBriefing entity = YwNoticeBriefingConvert.INSTANCE.dtoToEntity(dto); + + if ("3".equals(dto.getModelSuitType()) && StrUtil.isBlank(entity.getNoticeType())) { + throw new ServiceException("请至少选择一种通知方式"); + } + if ("2".equals(dto.getSendType()) && dto.getSendUser() == null) { + throw new ServiceException("选择手工发送时需要选择发送人员"); + } + //发送方式根据模板中动态配置框是否有内容判断 + Long modelId = dto.getModelId(); + YwNoticeModel model = ywNoticeModelService.getById(modelId); + String modelContent = model.getModelContent(); + if ("3".equals(dto.getModelSuitType()) && hasContent(modelContent)) { + entity.setSendType("2"); + } else { + entity.setSendType("1"); + } + if ("0".equals(entity.getObjectProto())) { + YwScene scene = ywSceneService.getById(dto.getVenueId()); + //根据场馆查地市区域 + entity.setCity(scene.getCityId()); + entity.setCounty(scene.getAreaCountyId()); + entity.setNoticeName(scene.getVenueName() + "简报"); + } + if ("1".equals(entity.getObjectProto())) { + //根据区域查地市 + entity.setCity(entity.getCounty().substring(0, 4)); + String name = dictDataService.selectDictLabel("yw_county", dto.getCounty()); + entity.setNoticeName(name + "简报"); + } + if ("2".equals(entity.getObjectProto())) { + String name = dictDataService.selectDictLabel("yw_city", dto.getCity()); + entity.setNoticeName(name + "简报"); + } + //通知通报-简报定制-新建简报确定后,后台自动启动该条记录(页面操作列呈现“已启动”,点击“已启动”将停用该条计划->“未启动”)。 + //通知通报-简报定制只有现将“已启动”停用为“未启动”,才可以支持修改该条计划(即修改功能才可用),修改完确定后,后台自动启动该条记录 + entity.setSysNormalDisable("0"); + if (CollUtil.isNotEmpty(dto.getObjectIds())) { + List objectIds = dto.getObjectIds().stream().map(Long::parseLong).collect(Collectors.toList()); + List objectVOS = ywNoticeObjectService.fetchByIds(objectIds); + if (CollUtil.isNotEmpty(objectVOS)) { + entity.setNoticeObjectNameStr(objectVOS.stream().map(YwNoticeObjectVO::getObjectName).collect(Collectors.joining(","))); + } + } + if (dto.getSendUser() == null) { + Long userId = SecurityUtils.getUserId(); + entity.setSendUser(userId); + } + + if (entity.getId() == null) { + List ywNoticeBriefings = ywNoticeBriefingMapper.selectList(new LambdaQueryWrapper() + .eq(YwNoticeBriefing::getCity, entity.getCity()) + .eq(StrUtil.isNotBlank(entity.getCounty()), YwNoticeBriefing::getCounty, entity.getCounty()) + .eq(entity.getVenueId() != null, YwNoticeBriefing::getVenueId, entity.getVenueId()) + .eq(YwNoticeBriefing::getObjectProto, entity.getObjectProto()) + .eq(YwNoticeBriefing::getTimeInterval, entity.getTimeInterval()) + .eq(entity.getSendDate() != null, YwNoticeBriefing::getSendDate, entity.getSendDate()) + .eq(entity.getModelId() != null, YwNoticeBriefing::getModelId, entity.getModelId())); + + if (CollUtil.isNotEmpty(ywNoticeBriefings)) { + throw new ServiceException("已制定当天计划,无需重复制定"); + } + } + return saveOrUpdate(entity); + } + + + private boolean hasContent(String modelContent) { + String s = StrUtil.cleanBlank(modelContent); + boolean flag = false; + int startIndex = 0; + int endIndex; + while ((startIndex = s.indexOf("(", startIndex)) != -1) { + endIndex = s.indexOf(")", startIndex + 1); + if (endIndex != -1) { + String s2 = s.substring(startIndex + 1, endIndex).trim(); + if (!"在此输入其他性能数据".equals(s2)) { + flag = true; + break; + } + startIndex = endIndex + 1; + } else { + break; + } + } + return flag; + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(ywNoticeBriefingMapper.deleteBatchIds(ids)); + } + + @Override + public void export(YwNoticeBriefingQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + for (YwNoticeBriefingVO vo : data) { + if (vo.getModelId() != null) { + YwNoticeModel model = ywNoticeModelService.getById(vo.getModelId()); + if (model != null) { + vo.setModelName(model.getModelName()); + } + } + List objectIds = vo.getObjectIds(); + if (CollUtil.isNotEmpty(objectIds)) { + List objectVOS = ywNoticeObjectService.fetchByIds(objectIds); + if (CollUtil.isNotEmpty(objectVOS)) { + String names = objectVOS.stream().map(YwNoticeObjectVO::getObjectName).collect(Collectors.joining(",")); + vo.setObjectName(names); + } + } + } + for (int i = 1; i < data.size() + 1; i++) { + YwNoticeBriefingVO ywNoticeBriefingVO = data.get(i - 1); + ywNoticeBriefingVO.setId((long) i); + } + ExcelUtil util = new ExcelUtil<>(YwNoticeBriefingVO.class); + util.hideColumn("reason"); + try { + util.exportExcel(response, data, "简报定制"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + @Transactional + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + for (YwNoticeBriefingVO vo : list) { + if (vo == null) { + return AjaxResult.error("导入模板不正确。"); + } + if (vo.getTimeInterval() == null) { + return AjaxResult.error("导入模板不正确。通报间隔为空"); + } + } + boolean checkFlag = true; + + for (int i = 0; i < list.size(); i++) { + StringBuilder builder = new StringBuilder(); + YwNoticeBriefingVO vo = list.get(i); + + List ywNoticeBriefings = ywNoticeBriefingMapper.selectList(new LambdaQueryWrapper() + .eq(YwNoticeBriefing::getCity, vo.getCity()) + .eq(StrUtil.isNotBlank(vo.getCounty()), YwNoticeBriefing::getCounty, vo.getCounty()) + .eq(vo.getVenueId() != null, YwNoticeBriefing::getVenueId, vo.getVenueId()) + .eq(YwNoticeBriefing::getObjectProto, vo.getObjectProto()) + .eq(YwNoticeBriefing::getTimeInterval, vo.getTimeInterval()) + .eq(vo.getSendDate() != null, YwNoticeBriefing::getSendDate, vo.getSendDate()) + .eq(vo.getModelId() != null, YwNoticeBriefing::getModelId, vo.getModelId())); + if (CollUtil.isNotEmpty(ywNoticeBriefings)) { + YwNoticeBriefing briefing = ywNoticeBriefings.get(0); + if (briefing != null && "0".equals(briefing.getSysNormalDisable())) { + builder.append("已经启用的模板不允许导入修改;"); + checkFlag = false; + } + } + + if (StrUtil.isBlank(vo.getModelSuitType())) { + builder.append("【简报类型】为空;"); + checkFlag = false; + } else { + List model_suit_type = sysDictTypeService.selectDictDataByType("model_suit_type").stream().map(SysDictData::getDictValue).collect(Collectors.toList()); + if (!model_suit_type.contains(vo.getModelSuitType())) { + builder.append("【简报类型】不存在;"); + checkFlag = false; + } + } + if ("3".equals(vo.getModelSuitType())) { + List send_type = sysDictTypeService.selectDictDataByType("send_type").stream().map(SysDictData::getDictValue).collect(Collectors.toList()); + if (StrUtil.isBlank(vo.getSendType())) { + builder.append("【发送方式】为空;"); + checkFlag = false; + } else if (!send_type.contains(vo.getSendType())) { + builder.append("【发送方式】不存在;"); + checkFlag = false; + } else if ("2".equals(vo.getSendType()) && (StrUtil.isBlank(vo.getSendUserStr()) || StrUtil.isBlank(vo.getSendUserPhoneStr()))) { + builder.append("【发送方式】为手工发送时需填发送人员;"); + checkFlag = false; + } else { + List sysUsers = sysUserMapper.selectUserByRoleKey("noticemaster"); + List nameAndPhone = sysUsers.stream().map(l -> l.getNickName() + l.getPhonenumber()).collect(Collectors.toList()); + String s = vo.getSendUserStr() + vo.getSendUserPhoneStr(); + SysUser sysUser = sysUserMapper.selectUserById(1L); + String admin = sysUser.getNickName() + sysUser.getPhonenumber(); + nameAndPhone.add(admin); + if (!nameAndPhone.contains(s)) { + builder.append("该发送人员姓名手机号有误或无通知审核员角色"); + checkFlag = false; + } + } + } + + if (StrUtil.isBlank(vo.getNoticeTypeStr())) { + throw new ServiceException("请至少选择一种通知方式"); + } else { + vo.setNoticeTypeStr("[\"移动办公\"]"); + try { + vo.setNoticeType(JSONUtil.toList(vo.getNoticeTypeStr(), String.class)); + } catch (Exception e) { + builder.append("【通知方式】不存在;"); + checkFlag = false; + } + } + if (StrUtil.isBlank(vo.getObjectProto())) { + builder.append("【对象属性】为空或不存在;"); + checkFlag = false; + } + List scenes = new ArrayList<>(); + if ("0".equals(vo.getObjectProto())) { + if (StrUtil.isBlank(vo.getVenueName())) { + builder.append("【场馆名】不能为空;"); + checkFlag = false; + } else { + String venueName = vo.getVenueName(); + scenes = ywSceneService.list(new LambdaQueryWrapper().eq(YwScene::getVenueName, venueName)); + if (CollUtil.isEmpty(scenes)) { + builder.append("【场馆名】不存在;"); + checkFlag = false; + } + } + } + if ("1".equals(vo.getObjectProto())) { + if (StrUtil.isBlank(vo.getCounty())) { + builder.append("【区县】为空;"); + checkFlag = false; + } else { + List yw_county = sysDictTypeService.selectDictDataByType("yw_county").stream().map(SysDictData::getDictValue).collect(Collectors.toList()); + if (!yw_county.contains(vo.getCounty())) { + builder.append("【区县】不存在;"); + checkFlag = false; + } + } + } + if ("2".equals(vo.getObjectProto())) { + if (StrUtil.isBlank(vo.getCity())) { + builder.append("【地市】为空;"); + checkFlag = false; + } else { + List yw_city = sysDictTypeService.selectDictDataByType("yw_city").stream().map(SysDictData::getDictValue).collect(Collectors.toList()); + if (!yw_city.contains(vo.getCity())) { + builder.append("【地市】不存在;"); + checkFlag = false; + } + } + } + if (vo.getTimeInterval() == null) { + builder.append("【通报间隔】为空;"); + checkFlag = false; + } else { + if (vo.getTimeInterval() != 15 && vo.getTimeInterval() != 60 && vo.getTimeInterval() != 120) { + builder.append("【通报间隔】不存在;"); + checkFlag = false; + } + } + if (StrUtil.isBlank(vo.getSysNormalDisable())) { + builder.append("【启用状态】为空;"); + checkFlag = false; + } else { + List sys_normal_disable = sysDictTypeService.selectDictDataByType("sys_normal_disable").stream().map(SysDictData::getDictValue).collect(Collectors.toList()); + if (!sys_normal_disable.contains(vo.getSysNormalDisable())) { + builder.append("【启用状态】不存在;"); + checkFlag = false; + } + } + + if (StrUtil.isNotBlank(vo.getObjectName())) { + ArrayList objectNames = CollUtil.toList(vo.getObjectName().split(",")); + for (String objectName : objectNames) { + YwNoticeObject object = ywNoticeObjectService.getOne(new LambdaQueryWrapper().eq(YwNoticeObject::getObjectName, objectName)); + if (object == null) { + builder.append("【对象名称】").append("不存在;"); + checkFlag = false; + } else { + if (!vo.getObjectProto().equals(object.getObjectProto())) { + builder.append("对象属性不正确;"); + checkFlag = false; + } + if ("0".equals(vo.getObjectProto())) { + if (CollUtil.isNotEmpty(scenes)) { + List venueIds = scenes.stream().map(YwScene::getId).collect(Collectors.toList()); + if (!venueIds.contains(object.getVenueId())) { + builder.append("【场馆名称】与【通知对象】未对应;"); + checkFlag = false; + } + } + } + } + + } + } + if (StrUtil.isNotBlank(vo.getModelName())) { + YwNoticeModel model = ywNoticeModelService.getOne(new LambdaQueryWrapper().eq(YwNoticeModel::getModelName, vo.getModelName())); + if (model == null) { + builder.append("【通知模板】").append("不存在;"); + checkFlag = false; + } else { + if (!vo.getModelSuitType().equals(model.getModelSuitType())) { + builder.append("【简报类型】与【通知模板】未对应;"); + checkFlag = false; + } + } + } + if (vo.getSendDate() == null) { + builder.append("【发送日期】不能为空;"); + checkFlag = false; + } else { + if (vo.getSendDate().isBefore(LocalDate.now())) { + builder.append("发送日期不能早于当前时间;"); + checkFlag = false; + } + } + if (vo.getBeginTime() == null || vo.getEndTime() == null) { + builder.append("【开始时间】与【结束时间】不能为空;"); + checkFlag = false; + } else { + if (vo.getBeginTime().isBefore(LocalDateTime.now())) { + builder.append("开始时间不能早于当前时间;"); + checkFlag = false; + } + if (vo.getEndTime().isBefore(vo.getBeginTime())) { + builder.append("结束时间不能早于开始时间;"); + checkFlag = false; + } + if (vo.getSendDate() != null && !(vo.getSendDate().equals(vo.getBeginTime().toLocalDate()) && vo.getSendDate().equals(vo.getEndTime().toLocalDate()))) { + builder.append("结束时间与开始时间应与发送日期为同一天;"); + checkFlag = false; + } + } + + vo.setReason(builder.toString()); + } +// if (checkFlag) { +// checkFlag = checkUnique(list); +// } + if (!checkFlag) { + ExcelUtil util = new ExcelUtil<>(YwNoticeBriefingVO.class); + util.hideColumn("id"); + String fileName = (String) util.exportExcel(list, "简报定制导入结果").get(AjaxResult.MSG_TAG); + return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + } else { + importList(list); + } + + return AjaxResult.success(); + } + + private void importList(List list) { + ArrayList ywNoticeBriefings = new ArrayList<>(); + for (YwNoticeBriefingVO vo : list) { + YwNoticeBriefing entity = new YwNoticeBriefing(); + + List split = vo.getNoticeType(); + ArrayList strings = new ArrayList<>(); + for (String s : split) { + String value = dictDataService.selectDictValue("sys_notice_type", s); + strings.add(value); + } + entity.setNoticeType(JSONUtil.toJsonStr(strings)); + + entity.setCity(vo.getCity()); + entity.setCounty(vo.getCounty()); + if ("0".equals(vo.getObjectProto())) { + String venueName = vo.getVenueName(); + List scenes = ywSceneService.list(new LambdaQueryWrapper().eq(YwScene::getVenueName, venueName)); + if (CollUtil.isNotEmpty(scenes)) { + YwScene scene = scenes.get(0); + entity.setVenueId(scene.getId()); + entity.setCounty(scene.getAreaCountyId()); + entity.setCity(scene.getAreaCountyId().substring(0, 4)); + entity.setNoticeName(scene.getVenueName() + "简报"); + } + } + if ("1".equals(vo.getObjectProto())) { + entity.setCity(vo.getCounty().substring(0, 4)); + String name = dictDataService.selectDictLabel("yw_county", vo.getCounty()); + entity.setNoticeName(name + "简报"); + } + if ("2".equals(entity.getObjectProto())) { + String name = dictDataService.selectDictLabel("yw_city", vo.getCity()); + entity.setNoticeName(name + "简报"); + } + entity.setObjectProto(vo.getObjectProto()); + if (StrUtil.isNotBlank(vo.getObjectName())) { + ArrayList objectNames = CollUtil.toList(vo.getObjectName().split(",")); + List objects = ywNoticeObjectService.list + (new LambdaQueryWrapper().in(YwNoticeObject::getObjectName, objectNames)); + if (CollUtil.isNotEmpty(objects)) { + List objectIds = objects.stream().map(YwNoticeObject::getId).collect(Collectors.toList()); + entity.setObjectIds(objectIds); + List objectVOS = ywNoticeObjectService.fetchByIds(objectIds); + if (CollUtil.isNotEmpty(objectVOS)) { + entity.setNoticeObjectNameStr(objectVOS.stream().map(YwNoticeObjectVO::getObjectName).collect(Collectors.joining(","))); + } + } + } + if (StrUtil.isNotBlank(vo.getModelName())) { + YwNoticeModel model = ywNoticeModelService.getOne(new LambdaQueryWrapper().eq(YwNoticeModel::getModelName, vo.getModelName())); + entity.setModelId(model.getId()); + if (hasContent(model.getModelContent())) { + entity.setSendType("2"); + } else { + entity.setSendType("1"); + } + } + entity.setTimeInterval(vo.getTimeInterval()); + entity.setSendDate(vo.getSendDate()); + entity.setBeginTime(vo.getBeginTime()); + entity.setEndTime(vo.getEndTime()); + entity.setSysNormalDisable(vo.getSysNormalDisable()); + entity.setModelSuitType(vo.getModelSuitType()); + + SysUser sysUser = sysUserService.selectUserByPhone(vo.getSendUserPhoneStr()); + if (sysUser != null) { + entity.setSendUser(sysUser.getUserId()); + } + //查询是否存在对象名称相同的数据,如果存在则更新 + List briefingList = ywNoticeBriefingMapper.selectList(new LambdaQueryWrapper() + .eq(YwNoticeBriefing::getCity, entity.getCity()) + .eq(StrUtil.isNotBlank(entity.getCounty()), YwNoticeBriefing::getCounty, entity.getCounty()) + .eq(entity.getVenueId() != null, YwNoticeBriefing::getVenueId, entity.getVenueId()) + .eq(YwNoticeBriefing::getObjectProto, entity.getObjectProto()) + .eq(YwNoticeBriefing::getTimeInterval, entity.getTimeInterval()) + .eq(entity.getSendDate() != null, YwNoticeBriefing::getSendDate, entity.getSendDate()) + .eq(entity.getModelId() != null, YwNoticeBriefing::getModelId, entity.getModelId()) + .eq(StrUtil.isNotBlank(entity.getNoticeObjectNameStr()), YwNoticeBriefing::getNoticeObjectNameStr, entity.getNoticeObjectNameStr())); + if (CollUtil.isNotEmpty(briefingList)) { + YwNoticeBriefing briefing = briefingList.get(0); + entity.setId(briefing.getId()); + ywNoticeBriefingMapper.updateById(entity); + } else { + ywNoticeBriefings.add(entity); + } + } + saveBatch(ywNoticeBriefings); + + } + + private boolean checkUnique(List vos) { + boolean checkFlag = true; + List matchNameList = new ArrayList<>(); + for (YwNoticeBriefingVO imp : vos) { + StringBuilder reason = new StringBuilder(); + if (matchNameList.contains(imp.getObjectName())) { + checkFlag = false; + reason.append("表格中多条记录对象名称有重复。"); + } + matchNameList.add(imp.getObjectName()); + imp.setReason(reason.toString()); + } + return checkFlag; + } + + @Override + public void eastcomYwSendBriefingSchedule() { + long startTime = System.currentTimeMillis(); + log.info("开始执行简报发送任务"); + List vos = ywNoticeBriefingMapper.selectNeedSendBriefing(); + if (CollUtil.isEmpty(vos)) { + return; + } + // 使用线程池中线程分批处理业务逻辑,并行处理任务提高终端响应速度 + CountDownLatch latch = new CountDownLatch(vos.size()); + for (YwNoticeBriefingPlanVO vo : vos) { + threadPool.submit(() -> { + try { + extracted(vo); + } catch (Exception e) { + log.error("调用下游系统出现错误,异常逻辑处理......"); + } finally { + // 业务逻辑处理完毕,计数器减一【当前线程处理任务完毕,线程释放进入线程池,等待处理下一个任务】 + latch.countDown(); + } + }); + } + try { + latch.await(); + } catch (Exception e) { + log.error("等待超时", e); + throw new RuntimeException("系统处理超时,请稍后再试"); + } +// threadPool.shutdown(); + long endTime = System.currentTimeMillis(); + long executionTime = endTime - startTime; + log.info("结束执行简报发送任务,任务耗时"+executionTime+ " 毫秒"); + } + + private void extracted(YwNoticeBriefingPlanVO vo) { + if (StrUtil.isBlank(vo.getObjectProto())) { + log.error(vo.getId() + "未指定对象属性是哪层"); + return; + } + String content = ""; + String urlContent = ""; + if ("0".equals(vo.getObjectProto())) { + if (vo.getVenueId() == null) { + log.error(vo.getId() + "场馆级简报未指定场馆id"); + return; + } + try { + if (vo.getModelId() != null && "3".equals(vo.getModelSuitType())) { + log.info("开始组装场馆级简报"); + content = assemblyVenueBriefing(vo.getSendTime(), vo.getVenueId(), vo.getTimeInterval(), vo.getModelId()); + log.info("结束组装场馆级简报"); + } else if (vo.getModelId() != null && "4".equals(vo.getModelSuitType())) { + log.info("开始组装H5简报"); + content = assemblyVenueJsonToGetURL(vo.getSendTime(), vo.getVenueId(), vo.getTimeInterval()); + log.info("结束组装H5简报"); + } + } catch (Exception e) { + log.error("组装场馆级简报失败:" + e.getMessage()); + content = "组装场馆级简报失败:" + e.getMessage(); + } + } else if ("1".equals(vo.getObjectProto())) { + if (StrUtil.isBlank(vo.getCounty())) { + log.error(vo.getId() + "区县级简报未指定区县"); + return; + } + try { + if (vo.getModelId() != null && 22 == vo.getModelId()) { + content = assemblyCountyBriefing(vo.getSendTime(), vo.getCounty(), vo.getTimeInterval()); + } else if (vo.getModelId() != null && 23 == vo.getModelId()) { + content = assemblyCountyJsonToGetURL(vo.getSendTime(), vo.getVenueId(), vo.getTimeInterval()); + } + } catch (Exception e) { + log.error("组装区县级简报失败:" + e.getMessage()); + return; + } + } else if ("2".equals(vo.getObjectProto())) { + if (StrUtil.isBlank(vo.getCity())) { + log.error(vo.getId() + "地市级简报未指定市"); + return; + } + try { + if (vo.getModelId() != null && "3".equals(vo.getModelSuitType())) { + content = assemblyCityBriefing(vo.getSendTime(), vo.getCity(), vo.getTimeInterval(), vo.getModelId()); + } else if (vo.getModelId() != null && "4".equals(vo.getModelSuitType())) { + content = assemblyCityJsonToGetURL(vo.getSendTime(), vo.getVenueId(), vo.getTimeInterval()); + } + } catch (Exception e) { + log.error("组装地市级简报失败:" + e.getMessage()); + content = "组装地市级简报失败:" + e.getMessage(); + } + } + String objectIdsStr = vo.getObjectIdsStr(); + List objectIds = JSONUtil.toList(objectIdsStr, Long.class); + if (CollUtil.isEmpty(objectIds)) { + log.error(vo.getId() + "简报未配置发送对象"); + return; + } + List objectVOS = ywNoticeObjectService.fetchByIds(objectIds); + if (CollUtil.isEmpty(objectVOS)) { + log.error(vo.getId() + "简报配置发送对象错误,该对象id已失效"); + return; + } + + String noticeType = vo.getNoticeType(); + List strings = JSONUtil.toList(noticeType, String.class); + for (YwNoticeObjectVO object : objectVOS) { + log.info("开始对象发送:"+object.getObjectName()); + //群 + if (strings.contains("5") && StrUtil.isNotBlank(object.getGroupId())) { + SysNotice sysNotice = getSysNotice(content, vo, objectIds, object); + sysNotice.setGroupId(object.getGroupId()); + sysNotice.setNoticeType("5"); + sysNotice.setNoticeObject(sysNotice.getNoticeObject() + ":" + object.getGroupName()); + if ("2".equals(vo.getSendType()) && "3".equals(vo.getModelSuitType())) { + //手工通知 + sysNotice.setAddFlag("2"); + sysNotice.setExpSendTime(vo.getSendTime()); + sysNotice.setSendUser(vo.getSendUser()); + sysNoticeService.save(sysNotice); + } else { + MobileOfficesDTO dto = new MobileOfficesDTO(); + dto.setMobileoffices(object.getGroupId()); + dto.setMobileoffice_user(null); + dto.setFile(null); + dto.setFilename(null); + dto.setImg(null); + dto.setImgname(null); + + String res = content.replaceAll("<.*?>", "").replace("\n(在此输入其他性能数据)", "").replaceAll("(\\s*)", "").replaceAll("\\(\\s*\\)", "").replace("(", "").replace("(", "").replace(")", "").replace(")", ""); + System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" + res); + dto.setContent(res); + + JSONObject jsonObject = null; + try { + jsonObject = messageService.sendMobileOffice(dto); + } catch (Exception e) { + log.error("发送移动办公失败"); + } + //sys_notice新增已发送记录 + if (jsonObject != null) { + sysNotice.setRemark(jsonObject.getString("message")); + sysNotice.setSendStatus(jsonObject.getString("code")); + } + sysNotice.setNoticeContent(res); + sysNotice.setAddFlag("1"); + sysNotice.setSendTime(LocalDateTime.now()); + sysNoticeService.save(sysNotice); + } + } + //短信 + if (strings.contains("3") && CollUtil.isNotEmpty(object.getMessageUsers())) { + List messageUsers = object.getMessageUsers(); + + List sysUsers = getSysUsers(messageUsers); + + String phone = sysUsers.stream().map(SysUser::getPhonenumber).collect(Collectors.joining(",")); + SysNotice sysNotice = getSysNotice(content, vo, objectIds, object); + sysNotice.setNoticeType("3"); + sysNotice.setReciveUserPhone(phone); + sysNotice.setNoticeObject(sysNotice.getNoticeObject() + ":" + object.getMessageName()); + if ("2".equals(vo.getSendType())) { + //手工通知 + sysNotice.setAddFlag("0"); + sysNotice.setExpSendTime(vo.getSendTime().plusMinutes(10)); + sysNoticeService.save(sysNotice); + } else { + JSONObject jsonObject = null; + try { + jsonObject = messageService.sendSMS(content, phone); + } catch (Exception e) { + log.error("发送短信群失败"); + } + //sys_notice新增已发送记录 + if (jsonObject != null) { + sysNotice.setRemark(jsonObject.getString("message")); + sysNotice.setSendStatus(jsonObject.getString("code")); + } + sysNotice.setAddFlag("1"); + sysNotice.setSendTime(LocalDateTime.now()); + sysNoticeService.save(sysNotice); + } + } + //IVR + if (strings.contains("7") && CollUtil.isNotEmpty(object.getIvrUsers())) { + List ivrUsers = object.getIvrUsers(); + + List sysUsers = getSysUsers(ivrUsers); + + String phone = sysUsers.stream().map(SysUser::getPhonenumber).collect(Collectors.joining(",")); + SysNotice sysNotice = getSysNotice(content, vo, objectIds, object); + sysNotice.setNoticeType("7"); + sysNotice.setReciveUserPhone(phone); + sysNotice.setNoticeObject(sysNotice.getNoticeObject() + ":" + object.getIvrName()); + + + if ("2".equals(vo.getSendType())) { + //手工通知 + sysNotice.setAddFlag("0"); + sysNotice.setExpSendTime(vo.getSendTime().plusMinutes(10)); + sysNoticeService.save(sysNotice); + } else { + JSONObject jsonObject = null; + try { + jsonObject = messageService.sendIvr(content, phone); + } catch (Exception e) { + log.error("发送IVR失败"); + } + //sys_notice新增已发送记录 + if (jsonObject != null) { + sysNotice.setRemark(jsonObject.getString("message")); + sysNotice.setSendStatus(jsonObject.getString("code")); + } + sysNotice.setAddFlag("1"); + sysNotice.setSendTime(LocalDateTime.now()); + sysNoticeService.save(sysNotice); + } + } + log.info("结束对象发送:"+object.getObjectName()); + } + } + + @Override + public void eastcomYwUpdateBriefingSendTypeSchedule() { + List list = ywNoticeModelService.list(new LambdaQueryWrapper().eq(YwNoticeModel::getModelSuitType, "3")); + for (YwNoticeModel model : list) { + String modelContent = model.getModelContent(); + if (hasContent(modelContent)) { + ywNoticeBriefingMapper.update(null, new LambdaUpdateWrapper() + .eq(YwNoticeBriefing::getModelId, model.getId()).set(YwNoticeBriefing::getSendType, "2")); + } else { + ywNoticeBriefingMapper.update(null, new LambdaUpdateWrapper() + .eq(YwNoticeBriefing::getModelId, model.getId()).set(YwNoticeBriefing::getSendType, "1")); + } + } + } + + private List getSysUsers(List ivrUsers) { + List sysUsers = sysUserService.selectUserByIds(ivrUsers); + if (CollUtil.isEmpty(sysUsers)) { + log.error("用户不存在"); + } + if (ivrUsers.size() != sysUsers.size()) { + log.error("未找到全部需发送用户"); + } + return sysUsers; + } + + private SysNotice getSysNotice(String content, YwNoticeBriefingPlanVO vo, List objectIds, YwNoticeObjectVO object) { + SysNotice sysNotice = new SysNotice(); + + sysNotice.setNoticeContent(content); + sysNotice.setStatus("0"); + sysNotice.setCreateBy("sys"); + sysNotice.setCreateTime(LocalDateTime.now()); + sysNotice.setUpdateBy("sys"); + sysNotice.setUpdateTime(LocalDateTime.now()); + sysNotice.setReciveUser(null); + sysNotice.setFlwProcessid(null); + sysNotice.setFlwTaskid(null); + sysNotice.setReciveUserPhone(null); + sysNotice.setExpSendTime(vo.getSendTime()); + sysNotice.setNoticeObjectId(objectIds); + sysNotice.setNoticeModelId(vo.getModelId()); + sysNotice.setModelScene("17"); + sysNotice.setObjectProto(vo.getObjectProto()); + sysNotice.setModelSuitType(vo.getModelSuitType()); + sysNotice.setHandworkId(vo.getId()); + + List objectVOS = ywNoticeObjectService.fetchByIds(objectIds); + if (CollUtil.isNotEmpty(objectVOS)) { + sysNotice.setNoticeObjectNameStr(objectVOS.stream().map(YwNoticeObjectVO::getObjectName).collect(Collectors.joining(","))); + } + + String name = ""; + if ("0".equals(vo.getObjectProto())) { + Long venueId = object.getVenueId(); + YwScene scene = ywSceneService.getById(venueId); + name = scene.getVenueName(); + } + if ("2".equals(vo.getObjectProto())) { + name = dictDataService.selectDictLabel("yw_city", object.getCity()); + } + sysNotice.setNoticeObject(name); + sysNotice.setNoticeTitle(name + "简报"); + return sysNotice; + } + + @Override + public JSONObject getJson(Long venueId, Integer timeInterval) { + JSONObject pm = null; + JSONObject mm = null; + JSONObject am = null; + try { + pm = pmKpiMonitorCellService.getReportKpiByJson(venueId.intValue(), null, null, timeInterval); + } catch (Exception e) { + e.printStackTrace(); + log.error("获取pm组装简报数据出错:" + e.getMessage()); + } + try { + mm = ywScenePictureService.listMatchTop3(venueId); + } catch (Exception e) { + e.printStackTrace(); + log.error("获取mm组装简报数据出错:" + e.getMessage()); + } + try { + am = ywScenePictureService.getAlarmTopDetail(venueId); + } catch (Exception e) { + e.printStackTrace(); + log.error("获取am组装简报数据出错:" + e.getMessage()); + } + JSONObject object = new JSONObject(); + YwScene scene = ywSceneService.getById(venueId); + object.put("venueId", scene.getId()); + object.put("venueName", scene.getVenueName()); + object.put("maintainType", scene.getMaintainType()); + String end = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm")); + String bin = LocalDateTime.now().minusMinutes(timeInterval).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")); + object.put("sendTime", bin + "~" + end); + object.put("MM", mm); + object.put("AM", am); + object.put("PM", pm); + log.info("开始保存json文件到本地"); + String fileName = saveFile(object); + log.info("结束保存json文件到本地"); + object.put("fileName", fileName); + return object; + } + + private String saveFile(JSONObject object) { + String json = object.toJSONString(JSONWriter.Feature.PrettyFormat,JSONWriter.Feature.WriteMapNullValue); + String venueName = (String) object.get("venueName"); + String fileName = "test_" + UUID.randomUUID() + ".json"; + File file = new File(briefingJsonPath + fileName); + BufferedWriter writer = null; + if (!file.exists()) { + try { + file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + try { + writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, false), StandardCharsets.UTF_8)); + writer.write(json); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (writer != null) { + writer.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + System.out.println("文件写入成功!"); + return fileName; + } + + @Override + public String assemblyVenueJsonToGetURL(LocalDateTime sendTime, Long venueId, Integer timeInterval) { + JSONObject json = getJson(venueId, timeInterval); + String fileName = json.getString("fileName"); +// File file = new File(briefingJsonPath + fileName); +// FileItem fileItem = this.getMultipartFile(file, "templFileItem"); +// MultipartFile multipartFile = new CommonsMultipartFile(fileItem); + Map map = new HashMap<>(); + map.put("confvalue", "asiagame"); + map.put("file", FileUtil.file(briefingJsonPath + fileName)); + log.info("开始上传json文件"); + String post = HttpUtil.post(briefingShortUrl, map); + log.info("结束上传json文件"); + return post; + } + + /** + * 将file转换成fileItem + * + * @param file + * @param fieldName + * @return + */ + private FileItem getMultipartFile(File file, String fieldName) { + FileItemFactory factory = new DiskFileItemFactory(16, null); + FileItem item = factory.createItem(fieldName, "text/plain", true, file.getName()); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + try { + FileInputStream fis = new FileInputStream(file); + OutputStream os = item.getOutputStream(); + while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return item; + } + + @Override + public String assemblyCountyJsonToGetURL(LocalDateTime sendTime, Long venueId, Integer timeInterval) { + KpiVenueReportVo reportKpi = pmKpiMonitorCellService.getReportKpi(venueId.intValue(), null, null, timeInterval); + if (reportKpi == null) { + log.info("当前没有性能数据"); + reportKpi = new KpiVenueReportVo(); + reportKpi.set开始时间(sendTime.minusMinutes(timeInterval)); + reportKpi.set结束时间(sendTime); + } + return "区县级h5简报"; + } + + @Override + public String assemblyCityJsonToGetURL(LocalDateTime sendTime, Long venueId, Integer timeInterval) { + return "地市级h5简报"; + } + + + @Override + public String assemblyVenueBriefing(LocalDateTime sendTime, Long venueId, Integer timeInterval, Long modelId) { + + JSONObject data = getJson(venueId, timeInterval); + YwNoticeModelVO modelVO = ywNoticeModelService.fetchById(modelId); + if (modelVO == null) { + throw new ServiceException("模板id" + modelId + "不存在"); + } + String modelContent = modelVO.getModelContent(); + YwScene scene = ywSceneService.getById(venueId); + + if ("A".equals(scene.getMaintainType())) { + String s = modelA(modelContent, data); + log.info("A类场馆简报:" + s); + return s; + } else if ("B".equals(scene.getMaintainType())) { + String s = modelB(modelContent, data); + log.info("B类场馆简报:" + s); + return s; + } + return "场馆未分AB类"; + } + + public String replacePlaceholder(String content, JsonNode jsonNode, Map map) { + for (Map.Entry entry : map.entrySet()) { + JsonNode valueNode = jsonNode.get(entry.getValue()); + String value = (valueNode != null) ? valueNode.asText() : "0"; + content = content.replace("${" + entry.getKey() + "}", value); + } + return content; + } + + private String modelA(String modelContent, JSONObject data) { + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonNode = null; + try { + jsonNode = objectMapper.readTree(data.toJSONString()); + } catch (JsonProcessingException e) { + e.printStackTrace(); + log.error("json树转化错误:" + e.getMessage()); + } + if (jsonNode != null) { + JsonNode mm = jsonNode.get("MM"); + JsonNode am = jsonNode.get("AM"); + + Map map1 = new HashMap<>(); + map1.put("A类场馆名称", "venueName"); + map1.put("系统日期", "sendTime"); + + modelContent = replacePlaceholder(modelContent, jsonNode, map1); + if (mm != null) { + Map map = new HashMap<>(); + map.put("现场保障人员", "frontUser"); + map.put("后台保障人员", "backUser"); + map.put("场馆部署应急车", "emergencyCarNum"); + map.put("应急仓", "emergencyWarehouse"); + + map.put("AGIS专网网元总数", "agisNetNum"); + map.put("AGIS专网当前未恢复告警数", "agisAlarm"); + map.put("WIFI互联网网元总数", "internetNetNum"); + map.put("WIFI互联网当前未恢复告警数", "wifiAlarm"); + map.put("公网无线网元个数", "wxNetNum"); + map.put("无线当前未恢复告警数", "wxAlarm"); + map.put("专网传输设备套数", "privateTransportEquipNum"); + map.put("专网传输接入环个数", "privateInterfaceRingNum"); + map.put("专网传输当前未恢复告警数", "privateAlarm"); + map.put("公网传输设备套数", "publicTransportEquipNum"); + map.put("公网传输接入环个数", "publicInterfaceRingNum"); + map.put("公网传输当前未恢复告警数", "publicAlarm"); + + modelContent = replacePlaceholder(modelContent, mm, map); + } + + if (jsonNode.get("PM") != null) { + JsonNode pm4g = jsonNode.get("PM").get("kpiReport4gVo"); + JsonNode pm5g = jsonNode.get("PM").get("kpiReport5gVo"); + JsonNode kpiReportAgix = jsonNode.get("PM").get("kpiReportAgix"); + JsonNode kpiReportNet = jsonNode.get("PM").get("kpiReportNet"); + JsonNode kpiReportOpticalpowerTop5 = jsonNode.get("PM").get("kpiReportOpticalpower").get("opticalpowerTop5"); + if (pm4g != null) { + Map map = new HashMap<>(); + map.put("场馆总流量4G", "流量GB4g"); + map.put("上行平均干扰4G", "上行平均干扰4g"); + map.put("上行PRB利用率4G", "上行prb利用率4g"); + map.put("下行PRB利用率4G", "下行prb利用率4g"); + map.put("最大用户数4G", "最大用户数4g"); + map.put("无线接通率4G", "无线接通率4g"); + map.put("无线掉线率4G", "无线掉线率4g"); + + modelContent = replacePlaceholder(modelContent, pm4g, map); + } + if (pm5g != null) { + Map map = new HashMap<>(); + map.put("场馆总流量5G", "流量GB5g"); + map.put("小区RLC层下行丢包率5G", "小区RLC层下行丢包率5g"); + map.put("上行PRB利用率5G", "上行prb利用率5g"); + map.put("下行PRB利用率5G", "下行prb利用率5g"); + map.put("最大用户数5G", "最大用户数5g"); + map.put("平均用户数5G", "平均用户数5g"); + map.put("SN异常释放率5G", "sn异常释放率5g"); + map.put("SgNB添加成功率5G", "sgnb添加成功率5g"); + map.put("切换成功率5G", "切换成功率5g"); + map.put("无线接通率5G", "无线接通率5g"); + map.put("无线掉线率5G", "无线掉线率5g"); + + modelContent = replacePlaceholder(modelContent, pm5g, map); + } + if (kpiReportAgix != null) { + Map map = new HashMap<>(); + map.put("汇聚-核心链路平均时延", "convcoreavgdelay"); + map.put("汇聚-核心链路平均抖动", "convcoreavgjitter"); + map.put("汇聚-核心链路平均丢包", "convcoreavglpackratio"); + map.put("AGIS下行总流量", "dlconvcoreflow"); + map.put("AGIS上行总流量", "ulconvcoreflow"); + map.put("场馆出口下行流速", "dlvenuevelocity"); + map.put("场馆出口上行流速", "ulvenuevelocity"); + map.put("AGIS下行带宽利用率", "dlvenuebandratio"); + map.put("AGIS上行带宽利用率", "ulvenuebandratio"); + map.put("AGIS汇聚_CPU利用率", "conswitchcpuratio"); + map.put("AGIS汇聚_内存利用率", "convswitchramratio"); + map.put("AGIS接入_CPU利用率", "accessswitchcpuratio"); + map.put("AGIS接入_内存利用率", "accessswitchraratio"); + + modelContent = replacePlaceholder(modelContent, kpiReportAgix, map); + } + if (kpiReportNet != null) { + Map map = new HashMap<>(); + map.put("互联网场馆出口_下行流速", "dlvenuevelocity"); + map.put("互联网出口_上行流速", "ulvenuevelocity"); + map.put("互联网下行带宽利用率", "dlvenuebandratio"); + map.put("互联网上行带宽利用率", "ulvenuebandratio"); + + modelContent = replacePlaceholder(modelContent, kpiReportNet, map); + } + if (kpiReportOpticalpowerTop5 != null) { + //实时收光功率前五 + Iterator iterator = kpiReportOpticalpowerTop5.iterator(); + StringBuilder stringBuilder = new StringBuilder(); + while (iterator.hasNext()) { + JsonNode next = iterator.next(); + String mename = next.get("mename").asText(); + String portname = next.get("portname").asText(); + String inOpticalpower = next.get("inOpticalpower").asText(); + stringBuilder.append(mename).append("(").append(portname).append("):").append(inOpticalpower).append("\r\n"); + } + modelContent = modelContent.replace("${toplist}", stringBuilder.toString()); + } + } + } + + //去掉空数据 + if (modelContent.contains("场馆现有杭州移动现场保障人员0人,后台保障人员0人,场馆部署应急车0辆,应急仓0个")) { + modelContent = modelContent.replace("场馆现有杭州移动现场保障人员0人,后台保障人员0人,场馆部署应急车0辆,应急仓0个 。", ""); + } + if (modelContent.contains("现场保障人员0人")) { + modelContent = modelContent.replace("现场保障人员0人,", ""); + } + if (modelContent.contains("后台保障人员0人")) { + modelContent = modelContent.replace("后台保障人员0人,", ""); + } + if (modelContent.contains("场馆部署应急车0辆")) { + modelContent = modelContent.replace("场馆部署应急车0辆,", ""); + } + if (modelContent.contains("应急仓0个")) { + modelContent = modelContent.replace(",应急仓0个", ""); + } + if (modelContent.contains("汇聚交换机CPU占用率0.0%以内")) { + modelContent = modelContent.replace("汇聚交换机CPU占用率0.0%以内", "汇聚交换机CPU占用率0.0%"); + } + if (modelContent.contains("内存使用率0.0%以内")) { + modelContent = modelContent.replace("内存使用率0.0%以内", "内存使用率0.0%"); + } + + modelContent = modelContent.replaceAll("\\$\\{([^}]+)}", "0"); + return modelContent; + } + + private String modelB(String modelContent, JSONObject data) { + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonNode = null; + try { + jsonNode = objectMapper.readTree(data.toJSONString()); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + if (jsonNode != null) { + JsonNode mm = jsonNode.get("MM"); + JsonNode am = jsonNode.get("AM"); + Map map1 = new HashMap<>(); + map1.put("B类场馆名称", "venueName"); + map1.put("系统日期", "sendTime"); + + modelContent = replacePlaceholder(modelContent, jsonNode, map1); + if (mm != null) { + Map map = new HashMap<>(); + map.put("现场保障人员", "frontUser"); + map.put("后台保障人员", "backUser"); + + map.put("公网无线网元个数", "wxNetNum"); + map.put("无线当前未恢复告警数", "wxAlarm"); + map.put("传输设备套数", "publicTransportEquipNum"); + map.put("传输接入环个数", "publicInterfaceRingNum"); + map.put("传输当前未恢复告警数", "publicAlarm"); + + modelContent = replacePlaceholder(modelContent, mm, map); + } + if (jsonNode.get("PM") != null) { + JsonNode pm4g = jsonNode.get("PM").get("kpiReport4gVo"); + JsonNode pm5g = jsonNode.get("PM").get("kpiReport5gVo"); + JsonNode kpiReportAgix = jsonNode.get("PM").get("kpiReportAgix"); + JsonNode kpiReportNet = jsonNode.get("PM").get("kpiReportNet"); + JsonNode kpiReportOpticalpowerTop5 = jsonNode.get("PM").get("kpiReportOpticalpower").get("opticalpowerTop5"); + if (pm4g != null) { + Map map = new HashMap<>(); + map.put("场馆总流量4G", "流量GB4g"); + map.put("上行平均干扰4G", "上行平均干扰4g"); + map.put("上行PRB利用率4G", "上行prb利用率4g"); + map.put("下行PRB利用率4G", "下行prb利用率4g"); + map.put("最大用户数4G", "最大用户数4g"); + map.put("无线接通率4G", "无线接通率4g"); + map.put("无线掉线率4G", "无线掉线率4g"); + + modelContent = replacePlaceholder(modelContent, pm4g, map); + } + + if (pm5g != null) { + Map map = new HashMap<>(); + map.put("场馆总流量5G", "流量GB5g"); + map.put("小区RLC层下行丢包率5G", "小区RLC层下行丢包率5g"); + map.put("上行PRB利用率5G", "上行prb利用率5g"); + map.put("下行PRB利用率5G", "下行prb利用率5g"); + map.put("最大用户数5G", "最大用户数5g"); + map.put("平均用户数5G", "平均用户数5g"); + map.put("SN异常释放率5G", "sn异常释放率5g"); + map.put("SgNB添加成功率5G", "sgnb添加成功率5g"); + map.put("切换成功率5G", "切换成功率5g"); + map.put("无线接通率5G", "无线接通率5g"); + map.put("无线掉线率5G", "无线掉线率5g"); + + modelContent = replacePlaceholder(modelContent, pm5g, map); + } + if (kpiReportAgix != null) { + Map map = new HashMap<>(); + map.put("汇聚-核心链路平均时延", "convcoreavgdelay"); + map.put("汇聚-核心链路平均抖动", "convcoreavgjitter"); + map.put("汇聚-核心链路平均丢包", "convcoreavglpackratio"); + map.put("AGIS下行总流量", "dlconvcoreflow"); + map.put("AGIS上行总流量", "ulconvcoreflow"); + map.put("场馆出口下行流速", "dlvenuevelocity"); + map.put("场馆出口上行流速", "ulvenuevelocity"); + map.put("AGIS下行带宽利用率", "dlvenuebandratio"); + map.put("AGIS上行带宽利用率", "ulvenuebandratio"); + map.put("AGIS汇聚_CPU利用率", "conswitchcpuratio"); + map.put("AGIS汇聚_内存利用率", "convswitchramratio"); + map.put("AGIS接入_CPU利用率", "accessswitchcpuratio"); + map.put("AGIS接入_内存利用率", "accessswitchraratio"); + + modelContent = replacePlaceholder(modelContent, kpiReportAgix, map); + } + if (kpiReportNet != null) { + Map map = new HashMap<>(); + map.put("互联网场馆出口_下行流速", "dlvenuevelocity"); + map.put("互联网出口_上行流速", "ulvenuevelocity"); + map.put("互联网下行带宽利用率", "dlvenuebandratio"); + map.put("互联网上行带宽利用率", "ulvenuebandratio"); + + modelContent = replacePlaceholder(modelContent, kpiReportNet, map); + } + if (kpiReportOpticalpowerTop5 != null) { + //实时收光功率前五 + Iterator iterator = kpiReportOpticalpowerTop5.iterator(); + StringBuilder stringBuilder = new StringBuilder(); + while (iterator.hasNext()) { + JsonNode next = iterator.next(); + String mename = next.get("mename").asText(); + String portname = next.get("portname").asText(); + String inOpticalpower = next.get("inOpticalpower").asText(); + stringBuilder.append(mename).append("(").append(portname).append("):").append(inOpticalpower).append("\r\n"); + } + modelContent = modelContent.replace("${toplist}", stringBuilder.toString()); + } + } + } + if (modelContent.contains("场馆现有杭州移动现场保障人员0人,后台保障人员0人")) { + modelContent = modelContent.replace("场馆现有杭州移动现场保障人员0人,后台保障人员0人 。", ""); + } + if (modelContent.contains("现场保障人员0人")) { + modelContent = modelContent.replace("现场保障人员0人,", ""); + } + if (modelContent.contains("后台保障人员0人")) { + modelContent = modelContent.replace(",后台保障人员0人", ""); + } + modelContent = modelContent.replaceAll("\\$\\{([^}]+)}", "0"); + return modelContent; + } + + + @Override + public String assemblyCityBriefing(LocalDateTime sendTime, String city, Integer timeInterval, Long modelId) { + List alarmStaticListVos = ywAlarmMapper.selectYwAlarmStaticList2("yyyy-mm-dd hh24:mi", sendTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), sendTime.plusMinutes(15).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), 2L); + AlarmStaticListVo alarmStaticListVo = new AlarmStaticListVo(); + if (CollUtil.isNotEmpty(alarmStaticListVos)) { + alarmStaticListVo = alarmStaticListVos.get(0); + } + String cityStr = sysDictDataService.selectDictLabel("yw_city", city); + +// try { + +// } catch (Exception e) { +// throw new ServiceException("查询性能数据失败"); +// } + List list = ywSceneMatchMapper.selectList(new LambdaQueryWrapper().eq(YwSceneMatchVo::getTaskStatus, "0").le(YwSceneMatchVo::getBeginTime, new Date()).ge(YwSceneMatchVo::getEndTime, new Date())); + if (CollUtil.isEmpty(list)) { + throw new ServiceException("当前时间没有赛事配置"); + } + List sceneIds = list.stream().map(YwSceneMatchVo::getSceneId).collect(Collectors.toList()); + List scenes = ywSceneService.list(new LambdaQueryWrapper().eq(YwScene::getCityId, city).in(YwScene::getId, sceneIds)); + if (CollUtil.isEmpty(scenes)) { + throw new ServiceException("场馆不存在" + sceneIds); + } + + String b = cityStr + "涉及赛事场馆" + scenes.size() + "个,其中" + "\n"; + StringBuilder f = new StringBuilder(); + String binTime = ""; + String endTime = ""; + for (int i = 0; i < scenes.size(); i++) { + KpiVenueReportVo reportKpi = null; + LocalDateTime bin = LocalDateTime.now(); + reportKpi = pmKpiMonitorCellService.getReportKpi(scenes.get(i).getId().intValue(), null, null, timeInterval); + LocalDateTime end = LocalDateTime.now(); + System.out.println("查询性能数据耗时:" + LocalDateTimeUtil.between(bin, end) + "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + if (reportKpi == null) { + f.append("\n").append(i + 1).append(".").append(scenes.get(i).getVenueName()).append("场馆当前没有性能数据"); + log.info("当前没有性能数据"); + reportKpi = new KpiVenueReportVo(); + reportKpi.set开始时间(sendTime.minusMinutes(timeInterval)); + reportKpi.set结束时间(sendTime); + } + JSONObject jsonObject = ywScenePictureService.listMatchTop3(scenes.get(i).getId()); + binTime = reportKpi.get开始时间().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")); + endTime = reportKpi.get结束时间().format(DateTimeFormatter.ofPattern("HH:mm")); + String e = (i + 1) + "." + scenes.get(i).getVenueName() + "场馆性能情况" + "\n" + + "1)总体情况:红线内外网元总数" + jsonObject.get("netTotalNum") + "个,保障区域网元均无异常告警" + jsonObject.get("totalAlarm") + "。杭州移动现场保障人员" + jsonObject.get("frontUser") + "人,后台保障人员" + jsonObject.get("backUser") + "人,场馆部署应急车" + jsonObject.get("emergencyCarNum") + "辆。\n" + + "2)传输情况:场馆保障共涉及传输设备" + jsonObject.get("transportEquipNum") + "台,接入环" + jsonObject.get("interfaceRingNum") + "个,目前环路状态、设备端口及业务连通性均正常,无告警" + jsonObject.get("csAlarm") + "。 \n" + + "3)4/5G公网情况:网元总数" + jsonObject.get("publicNetNum") + "个,无异常告警" + jsonObject.get("publicAlarm") + ",网络运行正常,网络性能数据正常。 \n"; + String c = "4)4G性能指标:总流量" + reportKpi.get流量GB4g() + "GB;" + + "无线接通率:" + reportKpi.get无线接通率4g() + "%;" + + "无线掉线率:" + reportKpi.get无线掉线率4g() + "%;\n" + + "上行平均干扰:" + reportKpi.get上行平均干扰4g() + ";\n" + + "单小区最高用户数:" + reportKpi.get最大用户数4g() + "个 " + + "(" + reportKpi.get最大用户数小区4g() + ");\n" + + "下行PRB利用率最高:" + reportKpi.get下行prb利用率4g() + "% " + + "(" + reportKpi.get下行prb利用率小区4g() + ");\n" + + "上行PRB利用率最高:" + reportKpi.get上行prb利用率4g() + "% " + + "(" + reportKpi.get上行prb利用率小区4g() + ");\n"; + String d = "5)5G性能指标:总流量" + reportKpi.get流量GB5g() + "GB;" + + "平均用户数:" + reportKpi.get平均用户数5g() + "个;" + + "最大用户数:" + reportKpi.get小区最大用户数5g() + "个;" + + "SN异常释放率:" + reportKpi.getSn异常释放率5g() + "%;" + + "SgNB添加成功率:" + reportKpi.getSgnb添加成功率5g() + "%;" + + "无线接通率:" + reportKpi.get无线接通率5g() + "%;" + + "无线掉线率:" + reportKpi.get无线掉线率5g() + "%;" + + "上行干扰值:" + reportKpi.get上行干扰值5g() + ";" + + "nsa_sgnb添加成功率:" + reportKpi.getSgnb添加成功率5g() + "%;" + + "切换成功率:" + reportKpi.get切换成功率5g() + "%;\n" + + "上行PRB平均利用率最高:" + reportKpi.get上行prb利用率5g() + "%" + + "(" + reportKpi.get上行prb利用率小区5g() + ")\n" + + "下行PRB平均利用率最高:" + reportKpi.get下行prb利用率5g() + "%" + + "(" + reportKpi.get下行prb利用率小区5g() + ")。\n"; + f = new StringBuilder(f + "\n" + e + c + d); + } + String a = "2023 " + cityStr + "亚运保障简报\n" + binTime + "~" + endTime + "\n"; + + return a + b + f; + } + + @Override + public String assemblyCountyBriefing(LocalDateTime sendTime, String county, Integer timeInterval) { + return "XX区县级简报"; + } + + @Override + public List getModel(Long venueId, String modelSuitType) { + List list = ywNoticeModelService.list(new LambdaQueryWrapper() + .eq(venueId != null, YwNoticeModel::getVenueId, venueId) + .and(i -> i.eq(YwNoticeModel::getModelSuitType, "3")).or().eq(YwNoticeModel::getModelSuitType, "4")); +// .eq(StrUtil.isNotBlank(modelSuitType),YwNoticeModel::getModelSuitType,modelSuitType)); + if (StrUtil.isNotBlank(modelSuitType)) { + list = list.stream().filter(l -> modelSuitType.equals(l.getModelSuitType())).collect(Collectors.toList()); + } + List ywNoticeModelVOS = YwNoticeModelConvert.INSTANCE.entityToVoList(list); + for (YwNoticeModelVO vo : ywNoticeModelVOS) { + String modelContent = vo.getModelContent(); + if (hasContent(modelContent)) { + vo.setSendTypeStr("手工发送"); + } else { + vo.setSendTypeStr("自动发送"); + } + } + return ywNoticeModelVOS; + } + + + private List calculationTimePoint(LocalDateTime beginTime, LocalDateTime endTime, + int timeInterval) { +// beginTime.minusMinutes() + return null; + } + + private void translate(YwNoticeBriefingVO vo) { + YwScene entity = ywSceneService.getById(vo.getVenueId()); + if (entity != null) { + vo.setVenueName(entity.getVenueName()); + } + YwNoticeModelVO modelVO = ywNoticeModelService.fetchById(vo.getModelId()); + vo.setNoticeModelIdStr(modelVO); + if (modelVO != null) { + vo.setModelName(modelVO.getModelName()); + } + List objectIds = vo.getObjectIds(); + if (CollUtil.isNotEmpty(objectIds)) { + List objectVOS = ywNoticeObjectService.fetchByIds(objectIds); + if (CollUtil.isNotEmpty(objectVOS)) { + vo.setNoticeObjectIdStr(objectVOS); + vo.setObjectNameStr(objectVOS.stream().map(YwNoticeObjectVO::getObjectName).collect(Collectors.joining(","))); + } + } + List split = vo.getNoticeType(); + ArrayList strings = new ArrayList<>(); + for (String s : split) { + String value = dictDataService.selectDictLabel("sys_notice_type", s); + strings.add(value); + } + vo.setNoticeTypeStr(JSONUtil.toJsonStr(strings)); + Long sendUser = vo.getSendUser(); + SysUser sysUser = sysUserService.selectUserById(sendUser); + if (sysUser != null) { + vo.setSendUserStr(sysUser.getNickName()); + vo.setSendUserPhoneStr(sysUser.getPhonenumber()); + } + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeHandworkServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeHandworkServiceImpl.java new file mode 100644 index 0000000..3ec6b18 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeHandworkServiceImpl.java @@ -0,0 +1,382 @@ +package com.ruoyi.eastcom_yw.service.impl; + + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.SysNotice; +import com.ruoyi.eastcom_yw.domain.YwNoticeHandwork; +import com.ruoyi.eastcom_yw.domain.YwNoticeObject; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeHandworkDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeHandworkQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeBriefingVO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeHandworkVO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeModelVO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeObjectVO; +import com.ruoyi.eastcom_yw.mapper.YwNoticeHandworkMapper; +import com.ruoyi.eastcom_yw.service.*; +import com.ruoyi.eastcom_yw.service.convert.YwNoticeHandworkConvert; +import com.ruoyi.system.service.ISysDictDataService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 通知通告手工通知计划表 服务实现类 + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Service +@Slf4j +public class YwNoticeHandworkServiceImpl extends ServiceImpl implements YwNoticeHandworkService { + + @Resource + private YwNoticeHandworkMapper ywNoticeHandworkMapper; + + @Resource + private YwNoticeModelService ywNoticeModelService; + + @Resource + private YwNoticeObjectService ywNoticeObjectService; + + @Resource + private ISysDictDataService dictDataService; + + @Resource + private YwSceneService ywSceneService; + + @Resource + private SysNoticeService sysNoticeService; + + /** + * 通知通告手工通知计划表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(YwNoticeHandworkQO qo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + // 通知名称 + .like(StrUtil.isNotBlank(qo.getNoticeName()), YwNoticeHandwork::getNoticeName, qo.getNoticeName()) + // 通知模板id + .eq(qo.getNoticeModel() != null, YwNoticeHandwork::getNoticeModel, qo.getNoticeModel()) + // 通知方式--sys_notice_type + .in(CollUtil.isNotEmpty(qo.getNoticeType()), YwNoticeHandwork::getNoticeType, qo.getNoticeType()) + // 通知对象ids + .in(CollUtil.isNotEmpty(qo.getNoticeObject()), YwNoticeHandwork::getNoticeObject, qo.getNoticeObject()) + // 通知内容 +// .eq(StrUtil.isNotBlank(qo.getNoticeContent()), YwNoticeHandwork::getNoticeContent, qo.getNoticeContent()) +// // 通知状态yw_veriy_status 0待提交 1待审核 2已审核 +// .in(CollUtil.isNotEmpty(qo.getNoticeStatus()), YwNoticeHandwork::getNoticeStatus, qo.getNoticeStatus()) + // 日期 + .between(qo.getBeginTime() != null && qo.getEndTime() != null, YwNoticeHandwork::getNoticeDate, qo.getBeginTime(), qo.getEndTime()) + // 开始时间 +// .eq(qo.getBeginTime() != null, YwNoticeHandwork::getBeginTime, qo.getBeginTime()) +// // 结束时间 +// .eq(qo.getEndTime() != null, YwNoticeHandwork::getEndTime, qo.getEndTime()) + // 时间间隔(单位分) +// .eq(qo.getTimeInterval() != null, YwNoticeHandwork::getTimeInterval, qo.getTimeInterval()) + .orderBy(true, false, YwNoticeHandwork::getId) + ; + List list = ywNoticeHandworkMapper.selectList(queryWrapper); + if (CollUtil.isEmpty(list)) { + return new ArrayList<>(); + } + List vos = YwNoticeHandworkConvert.INSTANCE.entityToVoList(list); + //翻译场馆、对象数组、模板 + for (YwNoticeHandworkVO vo : vos) { + String taskId = ywNoticeHandworkMapper.selectTaskIdByProcessId(vo.getFlwProcessid()); + vo.setTaskId(taskId); + translate(vo); + } + if (StrUtil.isNotBlank(qo.getKeyWord())) { + vos = vos.stream().filter(l -> l.getObjectNameStr().contains(qo.getKeyWord()) || l.getNoticeName().contains(qo.getKeyWord())).collect(Collectors.toList()); + } + return vos; + } + + /** + * 通知通告手工通知计划表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public IPage getDataByPage(YwNoticeHandworkQO qo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (StrUtil.isNotBlank(qo.getKeyWord())) { + queryWrapper.and(i -> i.like(YwNoticeHandwork::getNoticeName, qo.getKeyWord()) + .or().like(YwNoticeHandwork::getNoticeObjectNameStr, qo.getKeyWord()) + .or().like(YwNoticeHandwork::getNoticeContent, qo.getKeyWord()) + ); + } + // 通知对象ids + if (CollUtil.isNotEmpty(qo.getNoticeObject())) { + queryWrapper.like(CollUtil.isNotEmpty(qo.getNoticeObject()), YwNoticeHandwork::getNoticeObject, qo.getNoticeObject().get(0)); + } + queryWrapper + // 通知名称 + .like(StrUtil.isNotBlank(qo.getNoticeName()), YwNoticeHandwork::getNoticeName, qo.getNoticeName()) + + // 通知模板id + .eq(qo.getNoticeModel() != null, YwNoticeHandwork::getNoticeModel, qo.getNoticeModel()) + // 通知方式--sys_notice_type + .in(CollUtil.isNotEmpty(qo.getNoticeType()), YwNoticeHandwork::getNoticeType, qo.getNoticeType()) + + // 通知内容 +// .eq(StrUtil.isNotBlank(qo.getNoticeContent()), YwNoticeHandwork::getNoticeContent, qo.getNoticeContent()) +// // 通知状态yw_veriy_status 0待提交 1待审核 2已审核 +// .in(CollUtil.isNotEmpty(qo.getNoticeStatus()), YwNoticeHandwork::getNoticeStatus, qo.getNoticeStatus()) + // 日期 + .between(qo.getBeginTime() != null && qo.getEndTime() != null, YwNoticeHandwork::getNoticeDate, qo.getBeginTime(), qo.getEndTime()) + // 开始时间 +// .eq(qo.getBeginTime() != null, YwNoticeHandwork::getBeginTime, qo.getBeginTime()) +// // 结束时间 +// .eq(qo.getEndTime() != null, YwNoticeHandwork::getEndTime, qo.getEndTime()) + // 时间间隔(单位分) +// .eq(qo.getTimeInterval() != null, YwNoticeHandwork::getTimeInterval, qo.getTimeInterval()) + .orderBy(true, false, YwNoticeHandwork::getId) + ; + + Page page = page(new Page<>(qo.getPageNum(), qo.getPageSize()), queryWrapper); + IPage voPage = page.convert(YwNoticeHandworkConvert.INSTANCE::entityToVo); + + List vos = voPage.getRecords(); + if (CollUtil.isEmpty(vos)) { + return new Page<>(); + } + for (YwNoticeHandworkVO vo : vos) { + String taskId = ywNoticeHandworkMapper.selectTaskIdByProcessId(vo.getFlwProcessid()); + vo.setTaskId(taskId); + translate(vo); + } +// if(StrUtil.isNotBlank(qo.getKeyWord())){ +// vos = vos.stream().filter(l -> l.getObjectNameStr().contains(qo.getKeyWord()) || l.getNoticeName().contains(qo.getKeyWord())).collect(Collectors.toList()); +// } + voPage.setRecords(vos); + return voPage; + } + + @Override + public YwNoticeHandworkVO fetchById(Long id) { + YwNoticeHandwork entity = ywNoticeHandworkMapper.selectById(id); + YwNoticeHandworkVO vo = YwNoticeHandworkConvert.INSTANCE.entityToVo(entity); + translate(vo); + return vo; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long saveOrUpdate(YwNoticeHandworkDTO dto) { + YwNoticeHandwork entity = YwNoticeHandworkConvert.INSTANCE.dtoToEntity(dto); + if (CollUtil.isNotEmpty(entity.getNoticeObject())) { + List objectVOS = ywNoticeObjectService.fetchByIds(entity.getNoticeObject()); + if (CollUtil.isNotEmpty(objectVOS)) { + entity.setNoticeObjectNameStr(objectVOS.stream().map(YwNoticeObjectVO::getObjectName).collect(Collectors.joining(","))); + } + } + entity.setAddFlag("0"); + saveOrUpdate(entity); + return entity.getId(); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(ywNoticeHandworkMapper.deleteBatchIds(ids)); + } + + @Override + public void export(YwNoticeHandworkQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + for (int i = 1; i < data.size() + 1; i++) { + YwNoticeHandworkVO vo = data.get(i - 1); + vo.setId((long) i); + } + ExcelUtil util = new ExcelUtil<>(YwNoticeHandworkVO.class); + util.hideColumn("reason"); + try { + util.exportExcel(response, data, "手工通知计划"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + + // 核查 + // boolean checkFlag; + // checkFlag = checkData(cs, ywSceneList); + // if (checkFlag) { + // checkFlag = checkUnique(cs); + // } + // if (!checkFlag) { + // ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); + // String fileName = (String) util.exportExcel(cs, "网元传输导入结果").get(AjaxResult.MSG_TAG); + // return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + // } + saveBatch(list); + return AjaxResult.success(); + } + + @Override + @Transactional + public void eastcomSelectPassAndAddNoticeSchedule() { + //查询审核通过(name_ = 'processStatus' and text_ = '4')并且尚未添加到sys_notice的手工通知(add_flag = '0') + List ywNoticeHandworkList = ywNoticeHandworkMapper.selectPass(); + //添加到sys_notice + for (YwNoticeHandwork ywNoticeHandwork : ywNoticeHandworkList) { + List objectIds = ywNoticeHandwork.getNoticeObject(); + if (CollUtil.isEmpty(objectIds)) { + continue; + } + List objectVOS = ywNoticeObjectService.fetchByIds(objectIds); + + String noticeType = ywNoticeHandwork.getNoticeType(); + List strings = JSONUtil.toList(noticeType, String.class); + if (CollUtil.isNotEmpty(objectVOS)) { + for (YwNoticeObjectVO vo : objectVOS) { + if (strings.contains("5") && StrUtil.isNotBlank(vo.getGroupId())) { + SysNotice sysNotice = getSysNotice(ywNoticeHandwork, objectIds, vo); + sysNotice.setNoticeType("5"); + sysNotice.setReciveUserPhone(null); + sysNotice.setNoticeObject(sysNotice.getNoticeObject() + ":" + vo.getGroupName()); + sysNotice.setGroupId(vo.getGroupId()); + + sysNoticeService.saveOrUpdate(sysNotice); + } + if (strings.contains("3") && CollUtil.isNotEmpty(vo.getMessageUsers())) { + SysNotice sysNotice = getSysNotice(ywNoticeHandwork, objectIds, vo); + sysNotice.setNoticeType("3"); + sysNotice.setReciveUserPhone(vo.getMessageUsersExcelPhoneStr()); + sysNotice.setNoticeObject(sysNotice.getNoticeObject() + ":" + vo.getMessageName()); + sysNotice.setGroupId(null); + + sysNoticeService.saveOrUpdate(sysNotice); + } + if (strings.contains("7") && CollUtil.isNotEmpty(vo.getIvrUsers())) { + SysNotice sysNotice = getSysNotice(ywNoticeHandwork, objectIds, vo); + sysNotice.setNoticeType("7"); + sysNotice.setReciveUserPhone(vo.getIvrUsersExcelPhoneStr()); + sysNotice.setNoticeObject(sysNotice.getNoticeObject() + ":" + vo.getIvrName()); + + sysNoticeService.saveOrUpdate(sysNotice); + } + } + ywNoticeHandwork.setAddFlag("1"); + ywNoticeHandworkMapper.updateById(ywNoticeHandwork); + } + } + } + + + private SysNotice getSysNotice(YwNoticeHandwork ywNoticeHandwork, List objectIds, YwNoticeObjectVO vo) { + SysNotice sysNotice = new SysNotice(); + sysNotice.setNoticeTitle(ywNoticeHandwork.getNoticeName()); + sysNotice.setNoticeContent(ywNoticeHandwork.getNoticeContent()); + sysNotice.setStatus("0"); + sysNotice.setCreateBy("sys"); + sysNotice.setCreateTime(LocalDateTime.now()); + sysNotice.setUpdateBy("sys"); + sysNotice.setUpdateTime(LocalDateTime.now()); + sysNotice.setFlwProcessid(ywNoticeHandwork.getFlwProcessid()); + sysNotice.setFlwTaskid(null); + sysNotice.setSendTime(null); + sysNotice.setSendStatus(null); + sysNotice.setExpSendTime(ywNoticeHandwork.getNoticeDate()); + sysNotice.setAddFlag("0"); + sysNotice.setModelSuitType("2"); + sysNotice.setHandworkId(ywNoticeHandwork.getId()); + sysNotice.setReciveUser(null); + sysNotice.setNoticeObjectId(objectIds); + sysNotice.setObjectProto(vo.getObjectProto()); + List objectVOS = ywNoticeObjectService.fetchByIds(objectIds); + if (CollUtil.isNotEmpty(objectVOS)) { + sysNotice.setNoticeObjectNameStr(objectVOS.stream().map(YwNoticeObjectVO::getObjectName).collect(Collectors.joining(","))); + } + + String name = ""; + if ("0".equals(vo.getObjectProto())) { + Long venueId = vo.getVenueId(); + YwScene scene = ywSceneService.getById(venueId); + name = scene.getVenueName(); + } + if ("1".equals(vo.getObjectProto())) { + name = dictDataService.selectDictLabel("yw_county", vo.getCounty()); + } + if ("2".equals(vo.getObjectProto())) { + name = dictDataService.selectDictLabel("yw_city", vo.getCity()); + } + Long modelId = ywNoticeHandwork.getNoticeModel(); + if (modelId != null) { + YwNoticeModelVO modelVO = ywNoticeModelService.fetchById(modelId); + if (modelVO != null) { + sysNotice.setNoticeModelId(modelVO.getId()); + sysNotice.setModelScene(modelVO.getModelScene()); + } + } + sysNotice.setNoticeObject(name); + return sysNotice; + } + + private void translate(YwNoticeHandworkVO vo) { + + YwNoticeModelVO modelVO = ywNoticeModelService.fetchById(vo.getNoticeModel()); + if (modelVO != null) { + vo.setNoticeModelIdStr(modelVO); + vo.setNoticeModelName(modelVO.getModelName()); + vo.setModelScene(modelVO.getModelScene()); + vo.setModelSceneStr(modelVO.getModelSceneStr()); + } + List objectIds = vo.getNoticeObject(); + if (CollUtil.isNotEmpty(objectIds)) { + List objectVOS = ywNoticeObjectService.fetchByIds(objectIds); + if (CollUtil.isNotEmpty(objectVOS)) { + vo.setNoticeObjectIdStr(objectVOS); + vo.setNoticeObjectNameStr(objectVOS.stream().map(YwNoticeObjectVO::getObjectName).collect(Collectors.joining(","))); + vo.setObjectNameStr(objectVOS.stream().map(YwNoticeObjectVO::getObjectName).collect(Collectors.joining(","))); + } + } + List split = vo.getNoticeType(); + ArrayList strings = new ArrayList<>(); + for (String s : split) { + String value = dictDataService.selectDictLabel("sys_notice_type", s); + strings.add(value); + } + vo.setNoticeTypeStr(JSONUtil.toJsonStr(strings)); + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeHandworkdetailServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeHandworkdetailServiceImpl.java new file mode 100644 index 0000000..e141644 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeHandworkdetailServiceImpl.java @@ -0,0 +1,153 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwNoticeHandworkdetail; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeHandworkdetailDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeHandworkdetailQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeHandworkdetailVO; +import com.ruoyi.eastcom_yw.mapper.YwNoticeHandworkdetailMapper; +import com.ruoyi.eastcom_yw.service.YwNoticeHandworkdetailService; +import com.ruoyi.eastcom_yw.service.convert.YwNoticeHandworkdetailConvert; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + *

+ * 通知通告手工通知审核表 服务实现类 + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Service +public class YwNoticeHandworkdetailServiceImpl extends ServiceImpl implements YwNoticeHandworkdetailService { + + @Resource + private YwNoticeHandworkdetailMapper ywNoticeHandworkdetailMapper; + + /** + * 通知通告手工通知审核表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(YwNoticeHandworkdetailQO qo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + // 手工通知id + .eq(qo.getHandworkId() != null, YwNoticeHandworkdetail::getHandworkId, qo.getHandworkId()) + // 操作人(提交审核的人 或者 审核的人) + .eq(qo.getOprateUser() != null, YwNoticeHandworkdetail::getOprateUser, qo.getOprateUser()) + // 审核结果(关联字典表yw_veriy_result 0通过 1驳回) + .eq(StrUtil.isNotBlank(qo.getVeriyResult()), YwNoticeHandworkdetail::getVeriyResult, qo.getVeriyResult()) + // 审核状态(关联字典表yw_veriy_status 0 待审核 1 已审核) + .eq(StrUtil.isNotBlank(qo.getVeriyStatus()), YwNoticeHandworkdetail::getVeriyStatus, qo.getVeriyStatus()) + // 驳回原因 + .eq(StrUtil.isNotBlank(qo.getFailReason()), YwNoticeHandworkdetail::getFailReason, qo.getFailReason()) + // 附件 + .eq(StrUtil.isNotBlank(qo.getAppendix()), YwNoticeHandworkdetail::getAppendix, qo.getAppendix()) + ; + List list = ywNoticeHandworkdetailMapper.selectList(queryWrapper); + return YwNoticeHandworkdetailConvert.INSTANCE.entityToVoList(list); + } + + /** + * 通知通告手工通知审核表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public IPage getDataByPage(YwNoticeHandworkdetailQO qo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + // 手工通知id + .eq(qo.getHandworkId() != null, YwNoticeHandworkdetail::getHandworkId, qo.getHandworkId()) + // 操作人(提交审核的人 或者 审核的人) + .eq(qo.getOprateUser() != null, YwNoticeHandworkdetail::getOprateUser, qo.getOprateUser()) + // 审核结果(关联字典表yw_veriy_result 0通过 1驳回) + .eq(StrUtil.isNotBlank(qo.getVeriyResult()), YwNoticeHandworkdetail::getVeriyResult, qo.getVeriyResult()) + // 审核状态(关联字典表yw_veriy_status 0 待审核 1 已审核) + .eq(StrUtil.isNotBlank(qo.getVeriyStatus()), YwNoticeHandworkdetail::getVeriyStatus, qo.getVeriyStatus()) + // 驳回原因 + .eq(StrUtil.isNotBlank(qo.getFailReason()), YwNoticeHandworkdetail::getFailReason, qo.getFailReason()) + // 附件 + .eq(StrUtil.isNotBlank(qo.getAppendix()), YwNoticeHandworkdetail::getAppendix, qo.getAppendix()) + ; + + Page page = page(new Page<>(qo.getPageNum(), qo.getPageSize()), queryWrapper); + IPage voPage = page.convert(YwNoticeHandworkdetailConvert.INSTANCE::entityToVo); + return voPage; + } + + @Override + public YwNoticeHandworkdetailVO fetchById(Long id) { + YwNoticeHandworkdetail entity = ywNoticeHandworkdetailMapper.selectById(id); + return YwNoticeHandworkdetailConvert.INSTANCE.entityToVo(entity); + } + + @Override + public boolean saveOrUpdate(YwNoticeHandworkdetailDTO dto) { + YwNoticeHandworkdetail entity = YwNoticeHandworkdetailConvert.INSTANCE.dtoToEntity(dto); + return saveOrUpdate(entity); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(ywNoticeHandworkdetailMapper.deleteBatchIds(ids)); + } + + @Override + public void export(YwNoticeHandworkdetailQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + ExcelUtil util = new ExcelUtil<>(YwNoticeHandworkdetailVO.class); + try { + util.exportExcel(response, data, "通知通告手工通知审核表信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + + // 核查 + // boolean checkFlag; + // checkFlag = checkData(cs, ywSceneList); + // if (checkFlag) { + // checkFlag = checkUnique(cs); + // } + // if (!checkFlag) { + // ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); + // String fileName = (String) util.exportExcel(cs, "网元传输导入结果").get(AjaxResult.MSG_TAG); + // return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + // } + // saveBatch(list); + return null; + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeListServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeListServiceImpl.java new file mode 100644 index 0000000..617a43d --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeListServiceImpl.java @@ -0,0 +1,238 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwNoticeList; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeListDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeListQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeHandworkVO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeListVO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeModelVO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeObjectVO; +import com.ruoyi.eastcom_yw.mapper.YwNoticeListMapper; +import com.ruoyi.eastcom_yw.service.YwNoticeListService; +import com.ruoyi.eastcom_yw.service.YwNoticeModelService; +import com.ruoyi.eastcom_yw.service.YwNoticeObjectService; +import com.ruoyi.eastcom_yw.service.convert.YwNoticeHandworkConvert; +import com.ruoyi.eastcom_yw.service.convert.YwNoticeListConvert; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 通知通告记录表 服务实现类 + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Service +public class YwNoticeListServiceImpl extends ServiceImpl implements YwNoticeListService { + + @Resource + private YwNoticeListMapper ywNoticeListMapper; + + @Resource + private YwNoticeModelService ywNoticeModelService; + + @Resource + private YwNoticeObjectService ywNoticeObjectService; + + /** + * 通知通告记录表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(YwNoticeListQO qo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper +// // 通知名称(关键字) + .like(StrUtil.isNotBlank(qo.getNoticeName()), YwNoticeList::getNoticeName, qo.getNoticeName()) + // 通知场景--字典yw_notice_scene (0一般告警 1重大告警 ....) + .eq(StrUtil.isNotBlank(qo.getModelScene()), YwNoticeList::getModelScene, qo.getModelScene()) + // 对象属性--yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层) + .eq(StrUtil.isNotBlank(qo.getObjectProto()), YwNoticeList::getObjectProto, qo.getObjectProto()) + // 通知方式--sys_notice_type + .eq(StrUtil.isNotBlank(qo.getNoticeType()), YwNoticeList::getNoticeType, qo.getNoticeType()) + // 通知时间(计划发送时间(同天当前时间之前立即发送)) +// .eq(qo.getNoticeTime() != null, YwNoticeList::getNoticeTime, qo.getNoticeTime()) +// // 通知对象 +// .eq(StrUtil.isNotBlank(qo.getNoticeObject()), YwNoticeList::getNoticeObject, qo.getNoticeObject()) +// // 通知内容 +// .eq(StrUtil.isNotBlank(qo.getNoticeContent()), YwNoticeList::getNoticeContent, qo.getNoticeContent()) +// // 状态 0未读 1已读 +// .in(CollUtil.isNotEmpty(qo.getStatus()), YwNoticeList::getStatus, qo.getStatus()) +// // 通知对象ids数组 +// .eq(StrUtil.isNotBlank(qo.getNoticeObjectId()), YwNoticeList::getNoticeObjectId, qo.getNoticeObjectId()) +// // 通知模板id +// .eq(qo.getNoticeModelId() != null, YwNoticeList::getNoticeModelId, qo.getNoticeModelId()) +// // 实际发送时间 + .orderBy(true,false, YwNoticeList::getSendTime) +// // 发送是否成功,1成功 0失败 +// .in(CollUtil.isNotEmpty(qo.getSendStatus()), YwNoticeList::getSendStatus, qo.getSendStatus()) +// // 计划发送时间(同天当前时间之前立即发送) +// .eq(qo.getExpSendTime() != null, YwNoticeList::getExpSendTime, qo.getExpSendTime()) +// // 加入定时任务标记 默认0未加入 1已加入 +// .in(CollUtil.isNotEmpty(qo.getAddFlag()), YwNoticeList::getAddFlag, qo.getAddFlag()) +// // 通知类型model_suit_type 1 普通 2 手工 3简报 +// .in(CollUtil.isNotEmpty(qo.getModelSuitType()), YwNoticeList::getModelSuitType, qo.getModelSuitType()) +// // 计划id(手工与简报会先配置计划) +// .eq(qo.getPlanId() != null, YwNoticeList::getPlanId, qo.getPlanId()) + ; + List list = ywNoticeListMapper.selectList(queryWrapper); + if(CollUtil.isEmpty(list)){ + return new ArrayList<>(); + } + List vos = YwNoticeListConvert.INSTANCE.entityToVoList(list); + //翻译场馆、对象数组、模板 + for (YwNoticeListVO vo : vos) { + translate(vo); + } + return vos; + } + + /** + * 通知通告记录表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public IPage getDataByPage(YwNoticeListQO qo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper +// // 通知名称(关键字) + .like(StrUtil.isNotBlank(qo.getNoticeName()), YwNoticeList::getNoticeName, qo.getNoticeName()) + // 通知场景--字典yw_notice_scene (0一般告警 1重大告警 ....) + .eq(StrUtil.isNotBlank(qo.getModelScene()), YwNoticeList::getModelScene, qo.getModelScene()) + // 对象属性--yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层) + .eq(StrUtil.isNotBlank(qo.getObjectProto()), YwNoticeList::getObjectProto, qo.getObjectProto()) + // 通知方式--sys_notice_type + .eq(StrUtil.isNotBlank(qo.getNoticeType()), YwNoticeList::getNoticeType, qo.getNoticeType()) + // 通知时间(计划发送时间(同天当前时间之前立即发送)) +// .eq(qo.getNoticeTime() != null, YwNoticeList::getNoticeTime, qo.getNoticeTime()) +// // 通知对象 +// .eq(StrUtil.isNotBlank(qo.getNoticeObject()), YwNoticeList::getNoticeObject, qo.getNoticeObject()) +// // 通知内容 +// .eq(StrUtil.isNotBlank(qo.getNoticeContent()), YwNoticeList::getNoticeContent, qo.getNoticeContent()) +// // 状态 0未读 1已读 +// .in(CollUtil.isNotEmpty(qo.getStatus()), YwNoticeList::getStatus, qo.getStatus()) +// // 通知对象ids数组 +// .eq(StrUtil.isNotBlank(qo.getNoticeObjectId()), YwNoticeList::getNoticeObjectId, qo.getNoticeObjectId()) +// // 通知模板id +// .eq(qo.getNoticeModelId() != null, YwNoticeList::getNoticeModelId, qo.getNoticeModelId()) +// // 实际发送时间 + .orderBy(true,false, YwNoticeList::getSendTime) +// // 发送是否成功,1成功 0失败 +// .in(CollUtil.isNotEmpty(qo.getSendStatus()), YwNoticeList::getSendStatus, qo.getSendStatus()) +// // 计划发送时间(同天当前时间之前立即发送) +// .eq(qo.getExpSendTime() != null, YwNoticeList::getExpSendTime, qo.getExpSendTime()) +// // 加入定时任务标记 默认0未加入 1已加入 +// .in(CollUtil.isNotEmpty(qo.getAddFlag()), YwNoticeList::getAddFlag, qo.getAddFlag()) +// // 通知类型model_suit_type 1 普通 2 手工 3简报 +// .in(CollUtil.isNotEmpty(qo.getModelSuitType()), YwNoticeList::getModelSuitType, qo.getModelSuitType()) +// // 计划id(手工与简报会先配置计划) +// .eq(qo.getPlanId() != null, YwNoticeList::getPlanId, qo.getPlanId()) + ; + + Page page = page(new Page<>(qo.getPageNum(), qo.getPageSize()), queryWrapper); + IPage voPage = page.convert(YwNoticeListConvert.INSTANCE::entityToVo); + + List vos = voPage.getRecords(); + if(CollUtil.isEmpty(vos)){ + return new Page<>(); + } + for (YwNoticeListVO vo : vos) { + translate(vo); + } + voPage.setRecords(vos); + return voPage; + } + + @Override + public YwNoticeListVO fetchById(Long id) { + YwNoticeList entity = ywNoticeListMapper.selectById(id); + YwNoticeListVO vo = YwNoticeListConvert.INSTANCE.entityToVo(entity); + translate(vo); + return vo; + } + + @Override + public boolean saveOrUpdate(YwNoticeListDTO dto) { + YwNoticeList entity = YwNoticeListConvert.INSTANCE.dtoToEntity(dto); + return saveOrUpdate(entity); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(ywNoticeListMapper.deleteBatchIds(ids)); + } + + @Override + public void export(YwNoticeListQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + ExcelUtil util = new ExcelUtil<>(YwNoticeListVO.class); + try { + util.exportExcel(response, data, "通知通告记录表信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + + // 核查 + // boolean checkFlag; + // checkFlag = checkData(cs, ywSceneList); + // if (checkFlag) { + // checkFlag = checkUnique(cs); + // } + // if (!checkFlag) { + // ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); + // String fileName = (String) util.exportExcel(cs, "网元传输导入结果").get(AjaxResult.MSG_TAG); + // return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + // } + // saveBatch(list); + return null; + } + + private void translate(YwNoticeListVO vo) { + + YwNoticeModelVO modelVO = ywNoticeModelService.fetchById(vo.getNoticeModelId()); + vo.setNoticeModelIdStr(modelVO); + + List objectIds = vo.getNoticeObjectId(); + if(CollUtil.isNotEmpty(objectIds)){ + List objectVOS = ywNoticeObjectService.fetchByIds(objectIds); + vo.setNoticeObjectIdStr(objectVOS); + } + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeModelServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeModelServiceImpl.java new file mode 100644 index 0000000..54f4422 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeModelServiceImpl.java @@ -0,0 +1,237 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwNoticeBriefing; +import com.ruoyi.eastcom_yw.domain.YwNoticeModel; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeModelDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeModelQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeModelVO; +import com.ruoyi.eastcom_yw.mapper.YwNoticeBriefingMapper; +import com.ruoyi.eastcom_yw.mapper.YwNoticeModelMapper; +import com.ruoyi.eastcom_yw.service.YwNoticeModelService; +import com.ruoyi.eastcom_yw.service.convert.YwNoticeModelConvert; +import com.ruoyi.system.service.ISysDictDataService; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + *

+ * 通知通告模板表 服务实现类 + *

+ * + * @author ck + * @since 2023-04-07 + */ +@Service +public class YwNoticeModelServiceImpl extends ServiceImpl implements YwNoticeModelService { + + @Resource + private YwNoticeModelMapper ywNoticeModelMapper; + @Resource + private YwNoticeBriefingMapper ywNoticeBriefingMapper; + + @Resource + private ISysDictDataService sysDictDataService; + + /** + * 通知通告模板表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(YwNoticeModelQO qo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + // 模板名称 + .like(StrUtil.isNotBlank(qo.getModelName()), YwNoticeModel::getModelName, qo.getModelName()) + // 模板内容 + .like(StrUtil.isNotBlank(qo.getModelContent()), YwNoticeModel::getModelContent, qo.getModelContent()) + // 场景--字典yw_notice_scene (0一般告警 1重大告警 ....) + .eq(StrUtil.isNotBlank(qo.getModelScene()), YwNoticeModel::getModelScene, qo.getModelScene()) + // 用户名称 + .like(StrUtil.isNotBlank(qo.getCreateBy()), YwNoticeModel::getCreateBy, qo.getCreateBy()) + // 创建时间 + .eq(qo.getCreateTime() != null, YwNoticeModel::getCreateTime, qo.getCreateTime()) + // 模板适用类型 1 普通 2 手工 3简报 + .eq(StrUtil.isNotBlank(qo.getModelSuitType()), YwNoticeModel::getModelSuitType, qo.getModelSuitType()) + // 备注(写一些触发要求) + .like(StrUtil.isNotBlank(qo.getModelDes()), YwNoticeModel::getModelDes, qo.getModelDes()) + // 模板类型--字典model_type 0事件触发型 + .eq(StrUtil.isNotBlank(qo.getModelType()), YwNoticeModel::getModelType, qo.getModelType()) + // 排序号 + .eq(qo.getOrderNum() != null, YwNoticeModel::getOrderNum, qo.getOrderNum()) + .orderBy(true, false, YwNoticeModel::getId) + ; + List list = ywNoticeModelMapper.selectList(queryWrapper); + List ywNoticeModelVOS = YwNoticeModelConvert.INSTANCE.entityToVoList(list); + for (YwNoticeModelVO vo : ywNoticeModelVOS) { + String modelContent = vo.getModelContent(); + if (hasContent(modelContent)) { + vo.setSendTypeStr("手工发送"); + } else { + vo.setSendTypeStr("自动发送"); + } + } + return ywNoticeModelVOS; + } + + private boolean hasContent(String modelContent) { + String s = StrUtil.cleanBlank(modelContent); + String[] split = s.split(" getDataByPage(YwNoticeModelQO qo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + // 模板名称 + .like(StrUtil.isNotBlank(qo.getModelName()), YwNoticeModel::getModelName, qo.getModelName()) + // 模板内容 + .like(StrUtil.isNotBlank(qo.getModelContent()), YwNoticeModel::getModelContent, qo.getModelContent()) + // 场景--字典yw_notice_scene (0一般告警 1重大告警 ....) + .eq(StrUtil.isNotBlank(qo.getModelScene()), YwNoticeModel::getModelScene, qo.getModelScene()) + // 用户名称 + .like(StrUtil.isNotBlank(qo.getCreateBy()), YwNoticeModel::getCreateBy, qo.getCreateBy()) + // 创建时间 + .eq(qo.getCreateTime() != null, YwNoticeModel::getCreateTime, qo.getCreateTime()) + // 模板适用类型 1 普通 2 手工 3简报 + .eq(StrUtil.isNotBlank(qo.getModelSuitType()), YwNoticeModel::getModelSuitType, qo.getModelSuitType()) + // 备注(写一些触发要求) + .like(StrUtil.isNotBlank(qo.getModelDes()), YwNoticeModel::getModelDes, qo.getModelDes()) + // 模板类型--字典model_type 0事件触发型 + .eq(StrUtil.isNotBlank(qo.getModelType()), YwNoticeModel::getModelType, qo.getModelType()) + // 排序号 + .eq(qo.getOrderNum() != null, YwNoticeModel::getOrderNum, qo.getOrderNum()) + .orderBy(true, false, YwNoticeModel::getId) + ; + + Page page = page(new Page<>(qo.getPageNum(), qo.getPageSize()), queryWrapper); + IPage voPage = page.convert(YwNoticeModelConvert.INSTANCE::entityToVo); + + List ywNoticeModelVOS = voPage.getRecords(); + for (YwNoticeModelVO vo : ywNoticeModelVOS) { + String modelContent = vo.getModelContent(); + if (hasContent(modelContent)) { + vo.setSendTypeStr("手工发送"); + } else { + vo.setSendTypeStr("自动发送"); + } + } + voPage.setRecords(ywNoticeModelVOS); + return voPage; + } + + @Override + public YwNoticeModelVO fetchById(Long id) { + YwNoticeModel ywNoticeModel = ywNoticeModelMapper.selectById(id); + YwNoticeModelVO modelVO = YwNoticeModelConvert.INSTANCE.entityToVo(ywNoticeModel); + if (modelVO != null) { + translate(modelVO); + } + return modelVO; + } + + @Override + public boolean saveOrUpdate(YwNoticeModelDTO dto) { + YwNoticeModel entity = YwNoticeModelConvert.INSTANCE.dtoToEntity(dto); + if (entity.getId() != null&&"3".equals(entity.getModelSuitType())) { + String modelContent = entity.getModelContent(); + String newModelContent = modelContent.replaceAll("(\\s*)", "(在此输入其他性能数据)").replaceAll("\\(\\s*\\)", "(在此输入其他性能数据)"); + entity.setModelContent(newModelContent); + if (hasContent(modelContent)) { + ywNoticeBriefingMapper.update(null, new LambdaUpdateWrapper() + .eq(YwNoticeBriefing::getModelId, entity.getId()).set(YwNoticeBriefing::getSendType, "2")); + } else { + ywNoticeBriefingMapper.update(null, new LambdaUpdateWrapper() + .eq(YwNoticeBriefing::getModelId, entity.getId()).set(YwNoticeBriefing::getSendType, "1")); + } + } + return saveOrUpdate(entity); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(ywNoticeModelMapper.deleteBatchIds(ids)); + } + + @Override + public void export(YwNoticeModelQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + for (int i = 1; i < data.size() + 1; i++) { + YwNoticeModelVO vo = data.get(i - 1); + vo.setId((long) i); + } + ExcelUtil util = new ExcelUtil<>(YwNoticeModelVO.class); + util.hideColumn("reason"); + try { + util.exportExcel(response, data, "通知通告模板表信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + + // 核查 +// boolean checkFlag; +// checkFlag = checkData(cs, ywSceneList); +// if (checkFlag) { +// checkFlag = checkUnique(cs); +// } +// if (!checkFlag) { +// ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); +// String fileName = (String) util.exportExcel(cs, "网元传输导入结果").get(AjaxResult.MSG_TAG); +// return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); +// } + saveBatch(list); + return AjaxResult.success(); + + } + + private void translate(YwNoticeModelVO vo) { + String ywNoticeScene = sysDictDataService.selectDictLabel("yw_notice_scene", vo.getModelSuitType()); + vo.setModelSceneStr(ywNoticeScene); + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeObjectServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeObjectServiceImpl.java new file mode 100644 index 0000000..7b387f5 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeObjectServiceImpl.java @@ -0,0 +1,607 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwNoticeObject; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeObjectDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeObjectQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeObjectVO; +import com.ruoyi.eastcom_yw.mapper.YwNoticeObjectMapper; +import com.ruoyi.eastcom_yw.mapper.YwSceneMapper; +import com.ruoyi.eastcom_yw.service.YwNoticeObjectService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.eastcom_yw.service.convert.YwNoticeObjectConvert; +import com.ruoyi.system.service.ISysDictDataService; +import com.ruoyi.system.service.ISysDictTypeService; +import com.ruoyi.system.service.ISysUserService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + *

+ * 通知通告对象表 服务实现类 + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Service +public class YwNoticeObjectServiceImpl extends ServiceImpl implements YwNoticeObjectService { + + @Resource + private YwNoticeObjectMapper ywNoticeObjectMapper; + + @Resource + private YwSceneService ywSceneService; + + @Resource + private YwSceneMapper ywSceneMapper; + + @Resource + private ISysUserService sysUserService; + + @Resource + private ISysDictDataService sysDictDataService; + + @Resource + private ISysDictTypeService sysDictTypeService; + + /** + * 通知通告对象表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(YwNoticeObjectQO qo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + // 地市 + .eq(StrUtil.isNotBlank(qo.getCity()), YwNoticeObject::getCity, qo.getCity()) + // 区县 + .eq(StrUtil.isNotBlank(qo.getCounty()), YwNoticeObject::getCounty, qo.getCounty()) + // 场馆id + .in(CollUtil.isNotEmpty(qo.getVenueId()), YwNoticeObject::getVenueId, qo.getVenueId()) + // 专业 +// .eq(qo.getSpecialty() != null, YwNoticeObject::getSpecialty, qo.getSpecialty()) + // 角色id数组 +// .eq(StrUtil.isNotBlank(qo.getRoleIds()), YwNoticeObject::getRoleIds, qo.getRoleIds()) + // 对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层) + .eq(StrUtil.isNotBlank(qo.getObjectProto()), YwNoticeObject::getObjectProto, qo.getObjectProto()) + // 通知方式sys_notice_type +// .in(CollUtil.isNotEmpty(qo.getNoticeType()), YwNoticeObject::getNoticeType, qo.getNoticeType()) +// // 短信组名 +// .eq(StrUtil.isNotBlank(qo.getMessageName()), YwNoticeObject::getMessageName, qo.getMessageName()) +// // 短信组内成员id数组 +// .eq(StrUtil.isNotBlank(qo.getMessageUsers()), YwNoticeObject::getMessageUsers, qo.getMessageUsers()) +// // 排序号 +// .eq(qo.getOrder() != null, YwNoticeObject::getOrder, qo.getOrder()) +// // 群号 +// .eq(StrUtil.isNotBlank(qo.getGroupId()), YwNoticeObject::getGroupId, qo.getGroupId()) +// // 群名 +// .eq(StrUtil.isNotBlank(qo.getGroupName()), YwNoticeObject::getGroupName, qo.getGroupName()) +// // 备注 +// .eq(StrUtil.isNotBlank(qo.getGroupDes()), YwNoticeObject::getGroupDes, qo.getGroupDes()) + // 对象名称 + .like(StrUtil.isNotBlank(qo.getKeyWord()), YwNoticeObject::getObjectName, qo.getObjectName()) + // ivr组名 +// .eq(StrUtil.isNotBlank(qo.getIvrName()), YwNoticeObject::getIvrName, qo.getIvrName()) +// // ivr组内成员id数组 +// .eq(StrUtil.isNotBlank(qo.getIvrUsers()), YwNoticeObject::getIvrUsers, qo.getIvrUsers()) + //手工通知:查询条件“通知对象”,按选项升序排序(先按数字,再按首字母) + .last("ORDER BY convert_to(object_name,'GB18030')") + ; + List list = ywNoticeObjectMapper.selectList(queryWrapper); + List vos = YwNoticeObjectConvert.INSTANCE.entityToVoList(list); + //翻译场馆和用户名 + for (YwNoticeObjectVO vo : vos) { + translate(vo); + } + return vos; + } + + /** + * 通知通告对象表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public IPage getDataByPage(YwNoticeObjectQO qo) { + + if (CollUtil.isEmpty(qo.getVenueId())&&(StrUtil.isNotBlank(qo.getVenueType())||StrUtil.isNotBlank(qo.getMaintainType()))) { + List ywSceneList = ywSceneMapper.selectList(new LambdaQueryWrapper().eq(StrUtil.isNotBlank(qo.getVenueType()), YwScene::getVenueType, qo.getVenueType()) + .eq(StrUtil.isNotBlank(qo.getMaintainType()), YwScene::getMaintainType, qo.getMaintainType())); + if(CollUtil.isNotEmpty(ywSceneList)){ + List venueIds = ywSceneList.stream().map(YwScene::getId).collect(Collectors.toList()); + qo.setVenueId(venueIds); + } + } + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + // 地市 + .eq(StrUtil.isNotBlank(qo.getCity()), YwNoticeObject::getCity, qo.getCity()) + // 区县 + .eq(StrUtil.isNotBlank(qo.getCounty()), YwNoticeObject::getCounty, qo.getCounty()) + // 场馆id + .in(CollUtil.isNotEmpty(qo.getVenueId()), YwNoticeObject::getVenueId, qo.getVenueId()) + // 专业 +// .eq(qo.getSpecialty() != null, YwNoticeObject::getSpecialty, qo.getSpecialty()) + // 角色id数组 +// .eq(StrUtil.isNotBlank(qo.getRoleIds()), YwNoticeObject::getRoleIds, qo.getRoleIds()) + // 对象属性yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层) + .eq(StrUtil.isNotBlank(qo.getObjectProto()), YwNoticeObject::getObjectProto, qo.getObjectProto()) + // 通知方式sys_notice_type +// .in(CollUtil.isNotEmpty(qo.getNoticeType()), YwNoticeObject::getNoticeType, qo.getNoticeType()) +// // 短信组名 +// .eq(StrUtil.isNotBlank(qo.getMessageName()), YwNoticeObject::getMessageName, qo.getMessageName()) +// // 短信组内成员id数组 +// .eq(StrUtil.isNotBlank(qo.getMessageUsers()), YwNoticeObject::getMessageUsers, qo.getMessageUsers()) +// // 排序号 +// .eq(qo.getOrder() != null, YwNoticeObject::getOrder, qo.getOrder()) +// // 群号 +// .eq(StrUtil.isNotBlank(qo.getGroupId()), YwNoticeObject::getGroupId, qo.getGroupId()) +// // 群名 +// .eq(StrUtil.isNotBlank(qo.getGroupName()), YwNoticeObject::getGroupName, qo.getGroupName()) +// // 备注 +// .eq(StrUtil.isNotBlank(qo.getGroupDes()), YwNoticeObject::getGroupDes, qo.getGroupDes()) + // 对象名称 + .like(StrUtil.isNotBlank(qo.getObjectName()), YwNoticeObject::getObjectName, qo.getObjectName()) + // 关键字 + .like(StrUtil.isNotBlank(qo.getKeyWord()), YwNoticeObject::getObjectName, qo.getKeyWord()) + // ivr组名 +// .eq(StrUtil.isNotBlank(qo.getIvrName()), YwNoticeObject::getIvrName, qo.getIvrName()) +// // ivr组内成员id数组 +// .eq(StrUtil.isNotBlank(qo.getIvrUsers()), YwNoticeObject::getIvrUsers, qo.getIvrUsers()) +// .orderBy(true, false, YwNoticeObject::getId) + //手工通知:查询条件“通知对象”,按选项升序排序(先按数字,再按首字母) + .last("ORDER BY convert_to(object_name,'GB18030')") + ; + + Page page = page(new Page<>(qo.getPageNum(), qo.getPageSize()), queryWrapper); + IPage voPage = page.convert(YwNoticeObjectConvert.INSTANCE::entityToVo); + + List vos = voPage.getRecords(); + //翻译场馆和用户名 + for (YwNoticeObjectVO vo : vos) { + translate(vo); + } + voPage.setRecords(vos); + return voPage; + } + + @Override + public List fetchByIds(List ids) { + List entityList = ywNoticeObjectMapper.selectBatchIds(ids); + List vos = YwNoticeObjectConvert.INSTANCE.entityToVoList(entityList); + if (CollUtil.isNotEmpty(entityList)) { + for (YwNoticeObjectVO vo : vos) { + translate(vo); + } + } + return vos; + } + + @Override + public YwNoticeObjectVO fetchById(Long id) { + YwNoticeObject entity = ywNoticeObjectMapper.selectById(id); + YwNoticeObjectVO vo = YwNoticeObjectConvert.INSTANCE.entityToVo(entity); + translate(vo); + return vo; + } + + @Override + public boolean saveOrUpdate(YwNoticeObjectDTO dto) { + if (StrUtil.isBlank(dto.getGroupId()) && CollUtil.isEmpty(dto.getMessageUsers()) && CollUtil.isEmpty(dto.getIvrUsers())) { + throw new ServiceException("请至少填写一项通知方式!移动办公需填写群号,短信IVR则需选择成员"); + } + YwNoticeObject entity = YwNoticeObjectConvert.INSTANCE.dtoToEntity(dto); + if (dto.getId() == null) { + List ywNoticeObjects = ywNoticeObjectMapper.selectList(new LambdaQueryWrapper().eq(YwNoticeObject::getObjectName, dto.getObjectName())); + if (CollUtil.isNotEmpty(ywNoticeObjects)) { + throw new ServiceException("对象名称已存在"); + } + } + if ("0".equals(entity.getObjectProto())) { + YwScene scene = ywSceneService.getById(dto.getVenueId()); + //根据场馆查地市区域 + entity.setCity(scene.getCityId()); + entity.setCounty(scene.getAreaCountyId()); + } + if ("1".equals(entity.getObjectProto())) { + //根据区域查地市 + entity.setCity(entity.getCounty().substring(0, 4)); + } + return saveOrUpdate(entity); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(ywNoticeObjectMapper.deleteBatchIds(ids)); + } + + @Override + public void export(YwNoticeObjectQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + for (int i = 1; i < data.size() + 1; i++) { + YwNoticeObjectVO vo = data.get(i - 1); + vo.setId((long) i); + } + ExcelUtil util = new ExcelUtil<>(YwNoticeObjectVO.class); + util.hideColumn("reason"); + try { + util.exportExcel(response, data, "通知通告对象表信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + @Transactional + public AjaxResult importData(List list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + for (YwNoticeObjectVO vo : list) { + if (vo == null) { + return AjaxResult.error("导入模板不正确。"); + } + if (StrUtil.isBlank(vo.getGroupId()) && StrUtil.isBlank(vo.getMessageName()) && StrUtil.isBlank(vo.getIvrName())) { + return AjaxResult.error("导入模板不正确。"); + } + } + boolean checkFlag = true; + + for (int i = 0; i < list.size(); i++) { + StringBuilder builder = new StringBuilder(); + YwNoticeObjectVO vo = list.get(i); + if (StrUtil.isBlank(vo.getObjectName())) { + builder.append("【对象名称】不能为空;"); + checkFlag = false; + } + if (StrUtil.isBlank(vo.getObjectProto())) { + builder.append("【对象属性】为空;"); + checkFlag = false; + } + List yw_notice_object = sysDictTypeService.selectDictDataByType("yw_notice_object").stream().map(SysDictData::getDictValue).collect(Collectors.toList()); + if (!yw_notice_object.contains(vo.getObjectProto())) { + builder.append("【对象属性】不存在"); + checkFlag = false; + } + if ("0".equals(vo.getObjectProto())) { + if (StrUtil.isBlank(vo.getVenueName())) { + builder.append("【场馆名】不能为空;"); + checkFlag = false; + } else { + String venueName = vo.getVenueName(); + List scenes = ywSceneService.list(new LambdaQueryWrapper().eq(YwScene::getVenueName, venueName)); + if (CollUtil.isEmpty(scenes)) { + builder.append("【场馆名】不存在;"); + checkFlag = false; + } + } + } + + + if ("1".equals(vo.getObjectProto())) { + if(StrUtil.isBlank(vo.getCounty())) { + builder.append("【区县】为空;"); + checkFlag = false; + }else { + List yw_county = sysDictTypeService.selectDictDataByType("yw_county").stream().map(SysDictData::getDictValue).collect(Collectors.toList()); + if (!yw_county.contains(vo.getCounty())) { + builder.append("【区县】不存在;"); + checkFlag = false; + } + } + } + if ("2".equals(vo.getObjectProto())) { + if(StrUtil.isBlank(vo.getCity())) { + builder.append("【地市】为空;"); + checkFlag = false; + }else { + List yw_city = sysDictTypeService.selectDictDataByType("yw_city").stream().map(SysDictData::getDictValue).collect(Collectors.toList()); + if (!yw_city.contains(vo.getCity())) { + builder.append("【地市】不存在;"); + checkFlag = false; + } + } + } + if (StrUtil.isBlank(vo.getGroupId()) && StrUtil.isEmpty(vo.getMessageUsersExcelPhoneStr()) && StrUtil.isEmpty(vo.getIvrUsersExcelPhoneStr())) { + builder.append("请至少填写一项通知方式!移动办公需填写群号,短信IVR则需选择成员;"); + checkFlag = false; + } + +// 校验手机号是否存在 + String messageUsersExcelPhoneStr = vo.getMessageUsersExcelPhoneStr(); + if (StrUtil.isNotBlank(messageUsersExcelPhoneStr)) { + String[] strings = messageUsersExcelPhoneStr.split(","); + for (String string : strings) { + SysUser sysUser = sysUserService.selectUserByPhone(string); + if (sysUser == null) { + builder.append("短信组内手机号码:").append(string).append(",在系统中不存在;"); + checkFlag = false; + } + } + } + + String ivrUsersExcelPhoneStr = vo.getIvrUsersExcelPhoneStr(); + if (StrUtil.isNotBlank(ivrUsersExcelPhoneStr)) { + String[] strings = ivrUsersExcelPhoneStr.split(","); + for (String string : strings) { + SysUser sysUser = sysUserService.selectUserByPhone(string); + if (sysUser == null) { + builder.append("IVR组内手机号码:").append(string).append(",在系统中不存在;"); + checkFlag = false; + } + } + } + //校验姓名是否存在 + String messageUsersExcelStr = vo.getMessageUsersExcelStr(); + if (StrUtil.isNotBlank(messageUsersExcelStr)) { + String[] strings = messageUsersExcelStr.split(","); + for (String string : strings) { + List sysUsers = sysUserService.selectUserByNickName(string); + if (CollUtil.isEmpty(sysUsers)) { + builder.append("短信组内成员:").append(string).append(",在系统中不存在;"); + checkFlag = false; + } + } + } + + String ivrUsersExcelStr = vo.getIvrUsersExcelStr(); + if (StrUtil.isNotBlank(ivrUsersExcelStr)) { + String[] strings = ivrUsersExcelStr.split(","); + for (String string : strings) { + List sysUsers = sysUserService.selectUserByNickName(string); + if (CollUtil.isEmpty(sysUsers)) { + builder.append("IVR组内成员:").append(string).append(",在系统中不存在;"); + checkFlag = false; + } + } + } + + //校验姓名+手机号是否存在 +// String messageUsersExcelStr = vo.getMessageUsersExcelStr(); +// String messageUsersExcelPhoneStr = vo.getMessageUsersExcelPhoneStr(); + if (StrUtil.isNotBlank(messageUsersExcelPhoneStr) || StrUtil.isNotBlank(messageUsersExcelStr)) { + String[] nicknames = messageUsersExcelStr.split(","); + String[] phones = messageUsersExcelPhoneStr.split(","); + if (nicknames.length != phones.length) { + builder.append("短信组用户姓名与手机号个数不匹配"); + checkFlag = false; + } else { + for (int j = 0; j < nicknames.length; j++) { + String nickname = nicknames[j]; + String phone = phones[j]; + SysUser sysUser = sysUserService.selectUserByNickNameAndPhone(nickname, phone); + if (sysUser==null) { + builder.append("短信组").append(nickname).append("+").append(phone).append(":组合不存在;"); + checkFlag = false; + } + } + } + } + + if (StrUtil.isNotBlank(ivrUsersExcelPhoneStr) || StrUtil.isNotBlank(ivrUsersExcelStr)) { + String[] nicknames = ivrUsersExcelStr.split(","); + String[] phones = ivrUsersExcelPhoneStr.split(","); + if (nicknames.length != phones.length) { + builder.append("IVR组用户姓名与手机号个数不匹配"); + checkFlag = false; + } else { + for (int j = 0; j < nicknames.length; j++) { + String nickname = nicknames[j]; + String phone = phones[j]; + SysUser sysUser = sysUserService.selectUserByNickNameAndPhone(nickname, phone); + if (sysUser==null) { + builder.append("IVR组").append(nickname).append("+").append(phone).append(":组合不存在;"); + checkFlag = false; + } + } + } + } + vo.setReason(builder.toString()); + } + if (checkFlag) { + checkFlag = checkUnique(list); + } + if (!checkFlag) { + ExcelUtil util = new ExcelUtil<>(YwNoticeObjectVO.class); + String fileName = (String) util.exportExcel(list, "通知对象导入结果").get(AjaxResult.MSG_TAG); + return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + } else { + importList(list); + } + + return AjaxResult.success(); + } + + private void importList(List list) { + ArrayList ywNoticeObjects = new ArrayList<>(); + for (YwNoticeObjectVO vo : list) { + YwNoticeObject entity = new YwNoticeObject(); + entity.setCity(vo.getCity()); + entity.setCounty(vo.getCounty()); + entity.setObjectName(vo.getObjectName()); + if ("0".equals(vo.getObjectProto())) { + String venueName = vo.getVenueName(); + List scenes = ywSceneService.list(new LambdaQueryWrapper().eq(YwScene::getVenueName, venueName)); + if (CollUtil.isNotEmpty(scenes)) { + YwScene scene = scenes.get(0); + entity.setVenueId(scene.getId()); + entity.setCounty(scene.getAreaCountyId()); + entity.setCity(scene.getAreaCountyId().substring(0, 4)); + } + + } + if ("1".equals(vo.getObjectProto())) { + entity.setCity(vo.getCounty().substring(0, 4)); + } + entity.setObjectProto(vo.getObjectProto()); + entity.setMessageName(vo.getMessageName()); + String messageUsersExcelPhoneStr = vo.getMessageUsersExcelPhoneStr(); + if (StrUtil.isNotBlank(messageUsersExcelPhoneStr)) { + String[] strings = messageUsersExcelPhoneStr.split(","); + List sysUsers = sysUserService.selectUserListByPhones(strings); + if (CollUtil.isNotEmpty(sysUsers)) { + List userIds = sysUsers.stream().map(SysUser::getUserId).collect(Collectors.toList()); + entity.setMessageUsers(userIds); + } + } + + entity.setGroupId(vo.getGroupId()); + entity.setGroupName(vo.getGroupName()); + entity.setGroupDes(vo.getGroupDes()); + entity.setIvrName(vo.getIvrName()); + String ivrUsersExcelPhoneStr = vo.getIvrUsersExcelPhoneStr(); + if (StrUtil.isNotBlank(ivrUsersExcelPhoneStr)) { + String[] strings = ivrUsersExcelPhoneStr.split(","); + List sysUsers = sysUserService.selectUserListByPhones(strings); + if (CollUtil.isNotEmpty(sysUsers)) { + List userIds = sysUsers.stream().map(SysUser::getUserId).collect(Collectors.toList()); + entity.setIvrUsers(userIds); + } + } + //查询是否存在对象名称相同的数据,如果存在则更新 + YwNoticeObject object = ywNoticeObjectMapper.selectOne(new LambdaQueryWrapper().in(YwNoticeObject::getObjectName, vo.getObjectName())); + if (object != null) { + entity.setId(object.getId()); + ywNoticeObjectMapper.updateById(entity); + } else { + ywNoticeObjects.add(entity); + } + } + saveBatch(ywNoticeObjects); + + } + + private boolean checkUnique(List vos) { + boolean checkFlag = true; + List matchNameList = new ArrayList<>(); + for (YwNoticeObjectVO imp : vos) { + StringBuilder reason = new StringBuilder(); + if (matchNameList.contains(imp.getObjectName())) { + checkFlag = false; + reason.append("表格中多条记录对象名称有重复。"); + } + matchNameList.add(imp.getObjectName()); + imp.setReason(reason.toString()); + } + return checkFlag; + } + + @Override + public Map allObject() { + List data = this.getData(new YwNoticeObjectQO()); + List venueIds = data.stream().map(YwNoticeObjectVO::getVenueId).distinct().collect(Collectors.toList()); + List ywSceneList = ywSceneService.listByIds(venueIds); + if (CollUtil.isEmpty(ywSceneList)) { + return new HashMap(); + } + List ids = ywSceneList.stream().map(YwScene::getId).collect(Collectors.toList()); + venueIds.removeAll(ids); + List list = data.stream().filter(l -> !("0".equals(l.getObjectProto()) && venueIds.contains(l.getVenueId()))).collect(Collectors.toList()); +// 过滤出包含移动办公的 + List collect = list.stream().filter(l -> StrUtil.isNotBlank(l.getGroupId())).collect(Collectors.toList()); + Map>>> map = collect.stream().collect(Collectors.groupingBy(l -> { + String label = sysDictDataService.selectDictLabel("yw_notice_object", l.getObjectProto()); + return l.getObjectProto() + "," + label; + }, Collectors.groupingBy(l -> { + if ("0".equals(l.getObjectProto())) { + YwScene scene = ywSceneService.getById(l.getVenueId()); + if (scene == null) { + throw new ServiceException(l.getObjectName() + ":该对象关联场馆被删除,请重新配置该对象"); + } + return l.getVenueId().toString() + "," + scene.getVenueName(); + } else if ("1".equals(l.getObjectProto())) { + String label = sysDictDataService.selectDictLabel("yw_county", l.getCounty()); + return l.getCounty() + "," + label; + } else if ("2".equals(l.getObjectProto())) { + String label = sysDictDataService.selectDictLabel("yw_city", l.getCity()); + return l.getCity() + "," + label; + } else if ("3".equals(l.getObjectProto())) { + return "ITCC层" + "," + "浙江省"; + } else { + return "未知"; + } + }, Collectors.groupingBy( + l -> { + StringBuilder builder = new StringBuilder(); + builder.append("【"); + ArrayList strings = new ArrayList<>(); + if (StrUtil.isNotBlank(l.getGroupId())) { + strings.add("移"); + } + if (CollUtil.isNotEmpty(l.getMessageUsers())) { + strings.add("短"); + } + if (CollUtil.isNotEmpty(l.getIvrUsers())) { + strings.add("IVR"); + } + String join = StrUtil.join(",", strings); + builder.append(join); + builder.append("】"); +// return l.getId() + "," + l.getObjectName() + builder; + return l.getId() + "," + l.getObjectName(); + })))); + return map; + } + + private void translate(YwNoticeObjectVO vo) { + YwScene entity = ywSceneService.getById(vo.getVenueId()); + if (entity != null) { + vo.setVenueName(entity.getVenueName()); + } + List messageUsers = vo.getMessageUsers(); + if (CollUtil.isNotEmpty(messageUsers)) { + List sysUsers = sysUserService.selectUserByIds(messageUsers); + if (CollUtil.isNotEmpty(sysUsers)) { + vo.setMessageUsersStr(sysUsers.stream().map(SysUser::getNickName).collect(Collectors.toList())); + vo.setMessageUsersExcelStr(StringUtils.join(vo.getMessageUsersStr(), ",")); + vo.setMessageUsersExcelPhoneStr(sysUsers.stream().map(SysUser::getPhonenumber).collect(Collectors.joining(","))); + } + } + + List ivrUsers = vo.getIvrUsers(); + if (CollUtil.isNotEmpty(ivrUsers)) { + List sysUsers = sysUserService.selectUserByIds(ivrUsers); + if (CollUtil.isNotEmpty(sysUsers)) { + vo.setIvrUsersStr(sysUsers.stream().map(SysUser::getNickName).collect(Collectors.toList())); + vo.setIvrUsersExcelStr(StringUtils.join(vo.getIvrUsersStr(), ",")); + vo.setIvrUsersExcelPhoneStr(sysUsers.stream().map(SysUser::getPhonenumber).collect(Collectors.joining(","))); + } + } + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeUserServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeUserServiceImpl.java new file mode 100644 index 0000000..a0d39ac --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwNoticeUserServiceImpl.java @@ -0,0 +1,262 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.date.LocalDateTimeUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.constant.AlarmConstants; +import com.ruoyi.common.constant.TaskConstants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.common.enums.FlowDealStatus; +import com.ruoyi.eastcom_yw.common.enums.WireTaskType; +import com.ruoyi.eastcom_yw.domain.SysNotice; +import com.ruoyi.eastcom_yw.domain.YwNoticeObject; +import com.ruoyi.eastcom_yw.domain.YwNoticeUser; +import com.ruoyi.eastcom_yw.domain.YwWireTaskLog; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeModelQO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeObjectQO; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmInfoVo; +import com.ruoyi.eastcom_yw.domain.vo.YwInspectLogVo; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeModelVO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeObjectVO; +import com.ruoyi.eastcom_yw.mapper.YwAlarmViewMapper; +import com.ruoyi.eastcom_yw.mapper.YwNoticeUserMapper; +import com.ruoyi.eastcom_yw.service.*; +import com.ruoyi.system.service.ISysUserService; +import org.apache.commons.text.StringSubstitutor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + *

+ * 服务实现类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Service +public class YwNoticeUserServiceImpl extends ServiceImpl implements YwNoticeUserService { + + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private YwNoticeUserMapper ywNoticeUserMapper; + + @Autowired + private YwAlarmViewService ywAlarmViewService; + + @Autowired + private YwRoutInspectPlanService ywRoutInspectPlanService; + + @Autowired + private ISysUserService userService; + + @Autowired + private SysNoticeService sysNoticeService; + + @Autowired + private YwNoticeObjectService ywNoticeObjectService; + + @Autowired + private YwNoticeModelService ywNoticeModelService; + + + @Override + public List getYwNoticeUserList(String flwId, String taskId, String groupId,String type) { + return ywNoticeUserMapper.getYwNoticeUserList(flwId,taskId,groupId,type); + } + + @Override + public boolean noticeYW(String flwId, String groupId, String type) { + + Map valuesMap = new HashMap(); + SysNotice notice=new SysNotice(); + //告警发移动办公群,其它暂时发短信 + if(type.equals(TaskConstants.ALARM)) + { + List alarms = ywAlarmViewService.GetAlarmInfoList(flwId,false); + + if(alarms.isEmpty()) + { + logger.error(flwId+"没有查询到相关的告警信息"); + return false; + } + + String venueId = groupId.split("\\|")[0]; + YwNoticeObjectQO qo =new YwNoticeObjectQO(); + List lstVenueId = new ArrayList<>(); + lstVenueId.add(Long.parseLong(venueId)); + qo.setVenueId(lstVenueId); + qo.setObjectProto("0"); + Map> mapGroupIds = ywNoticeObjectService.getData(qo).stream().collect(Collectors.groupingBy(YwNoticeObjectVO::getGroupId)); + if(mapGroupIds.isEmpty()) + { + logger.error(flwId+"告警的场馆没有配置正确的移动办公数据,无法发送"); + return false; + } + + YwAlarmInfoVo alarm = alarms.get(0); + + String zy = DictUtils.getDictLabel("yw_alarm_specialty",alarm.getAlarmType()); + + valuesMap.put("场馆名称", alarm.getCg()); + valuesMap.put("专业名称", zy); + valuesMap.put("告警网元或告警基站",alarm.getSite_name()); + + if (StringUtils.isNotEmpty(alarm.getNet_name())) { + valuesMap.put("告警端口", alarm.getNet_name()); + } + + valuesMap.put("告警名称", alarm.getName()); + valuesMap.put("告警生成时间", alarm.getStart()); + valuesMap.put("告警最近生成时间", alarm.getLastBeginTime()); + valuesMap.put("告警等级", alarm.getAlarmLevel()); + valuesMap.put("定位信息", alarm.getAlarmLoc()); + + + notice.setNoticeTitle("一般告警提醒"); + //从通知模版里面取,后期处理 + String noticeContent = "告警提醒:${场馆名称}${专业名称}一般告警,告警网元:${告警网元或告警基站},告警名称:${告警名称},告警时间:${告警生成时间}"; + if(!(alarm.getAlarmType().equals("wx")||alarm.getAlarmType().equals("dh"))) { + if (StringUtils.isNotEmpty(alarm.getNet_name())) { + noticeContent = noticeContent.replace("${告警网元或告警基站}","${告警网元或告警基站},告警端口:${告警端口}"); + } + } + YwNoticeModelQO ywNoticeModelQO = new YwNoticeModelQO(); + ywNoticeModelQO.setModelScene("0"); + List noticeModelVOList = ywNoticeModelService.getData(ywNoticeModelQO); + + if(!noticeModelVOList.isEmpty()) + { + notice.setNoticeTitle(noticeModelVOList.get(0).getModelName()); + noticeContent = noticeModelVOList.get(0).getModelContent(); + if(!(alarm.getAlarmType().equals("wx")||alarm.getAlarmType().equals("dh"))) { + if (StringUtils.isNotEmpty(alarm.getNet_name())) { + noticeContent = noticeContent.replace("${告警网元或告警基站}","${告警网元或告警基站}\n" + "【告警端口】${告警端口}"); + } + } + } + + StringSubstitutor sub = new StringSubstitutor(valuesMap); + String content= sub.replace(noticeContent); + + +// List lstNoticeObjectId = new ArrayList<>(); +// lstNoticeObjectId.add(noticeObjectId); +// notice.setNoticeObjectId(lstNoticeObjectId); + //TODO:后期可以通过相关字段设置对应的告警级别,目前全都是一般告警 + notice.setModelScene("0"); + notice.setObjectProto("0"); + notice.setNoticeModelId(1L); + //通知类型 + notice.setCreateTime(LocalDateTimeUtil.now()); + notice.setModelSuitType("1"); + notice.setNoticeTitle("一般告警提醒"); + notice.setNoticeContent(content); + notice.setNoticeType("5"); + + notice.setFlwProcessid(flwId); + notice.setExpSendTime(LocalDateTimeUtil.now()); + for(Map.Entry> entry : mapGroupIds.entrySet()) + { + notice.setGroupId(entry.getKey()); + boolean res = sysNoticeService.save(notice); + if(!res) + { + logger.error(entry.getKey() + "移动办公群没有发送成功"); + } + } + + return true; + + } + + else if(type.equals(TaskConstants.INSPECT)) + { + List inspects = ywRoutInspectPlanService.getRoutInspectInfoList(flwId); + + if(inspects.isEmpty()) + { + logger.error(flwId+"没有查询到相关的巡检信息"); + return false; + } + + YwInspectLogVo inspect = inspects.get(0); + valuesMap.put("场馆名称", inspect.getVenueName()); + valuesMap.put("专业名称", inspect.getSpecialtyName()); + + notice.setNoticeTitle("场馆巡检任务下发通知"); + String noticeContent = "${场馆名称}巡检提醒:场馆经理已发布${专业名称}新的巡检任务,请注意待办任务更新"; + + YwNoticeModelQO ywNoticeModelQO = new YwNoticeModelQO(); + ywNoticeModelQO.setModelScene("8"); + List noticeModelVOList = ywNoticeModelService.getData(ywNoticeModelQO); + + if(!noticeModelVOList.isEmpty()) + { + notice.setNoticeTitle(noticeModelVOList.get(0).getModelName()); + noticeContent = noticeModelVOList.get(0).getModelContent(); + } + + StringSubstitutor sub = new StringSubstitutor(valuesMap); + String content= sub.replace(noticeContent); + notice.setNoticeContent(content); + notice.setNoticeType("3"); + } + + notice.setCreateTime(LocalDateTimeUtil.now()); + notice.setStatus("0"); + notice.setCreateBy("sys"); + + if(notice.getNoticeType().equals("3")) { + + String phoneNumber = ""; + + if(!groupId.contains("|")) + { + try { + SysUser user = userService.selectUserById(Long.parseLong(groupId)); + if(ObjectUtils.isNotEmpty(user)) { + phoneNumber = user.getPhonenumber(); + } + } + catch(Exception ex) { + logger.error(flwId+"出错了,groupId不正确"); + } + } + else + { + phoneNumber = ywNoticeUserMapper.getPhoneByGroupId(groupId); + } + + if (StringUtils.isEmpty(phoneNumber)) { + logger.error(flwId + "没有相关提醒人员,无法发送短信"); + return false; + } + + if (StringUtils.isNotEmpty(phoneNumber)) { + notice.setExpSendTime(LocalDateTimeUtil.now()); + notice.setFlwProcessid(flwId); + notice.setReciveUserPhone(phoneNumber); + return sysNoticeService.save(notice); + } + } + + + + return false; + + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectConfigServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectConfigServiceImpl.java new file mode 100644 index 0000000..897e673 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectConfigServiceImpl.java @@ -0,0 +1,28 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectConfig; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectConfigParam; +import com.ruoyi.eastcom_yw.mapper.YwRoutInspectConfigMapper; +import com.ruoyi.eastcom_yw.service.YwRoutInspectConfigService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author huamile + * @date 2023/1/17 16:05 + **/ +@Service +@RequiredArgsConstructor +public class YwRoutInspectConfigServiceImpl extends ServiceImpl implements YwRoutInspectConfigService { + + private final YwRoutInspectConfigMapper ywRoutInspectConfigMapper; + + @Override + public List getInspectConfigList(YwRoutInspectConfigParam param) { + return ywRoutInspectConfigMapper.getList(param); + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectLogServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectLogServiceImpl.java new file mode 100644 index 0000000..d9c1687 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectLogServiceImpl.java @@ -0,0 +1,30 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectLog; +import com.ruoyi.eastcom_yw.mapper.YwRoutInspectLogMapper; +import com.ruoyi.eastcom_yw.service.YwRoutInspectLogService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Date; + +/** + * @author huamile + */ +@Service +@RequiredArgsConstructor +public class YwRoutInspectLogServiceImpl extends ServiceImpl implements YwRoutInspectLogService { + + private final YwRoutInspectLogMapper ywRoutInspectLogMapper; + + @Override + public void updateLog(YwRoutInspectLog log) { + Long userId = SecurityUtils.getUserId(); + log.setFeedBackUser(userId.toString()); + log.setFeedBackTime(new Date()); + ywRoutInspectLogMapper.updateByflwProcessid(log); + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectPlanServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectPlanServiceImpl.java new file mode 100644 index 0000000..adfd198 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectPlanServiceImpl.java @@ -0,0 +1,661 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.github.pagehelper.PageInfo; +import com.google.common.collect.Maps; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.constant.TaskConstants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.dto.StartProcessInstanceDTO; +import com.ruoyi.common.core.domain.dto.json.UserInfo; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.utils.*; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.common.utils.poi.EasyPoiExcelUtil; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.utils.reflect.ReflectUtils; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectConfig; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectLog; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectPlan; +import com.ruoyi.eastcom_yw.domain.YwSceneFile; +import com.ruoyi.eastcom_yw.domain.dto.*; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectConfigParam; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectPlanParam; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectStatParam; +import com.ruoyi.eastcom_yw.domain.vo.YwInspectLogVo; +import com.ruoyi.eastcom_yw.domain.vo.YwInspectPlanStaticVo; +import com.ruoyi.eastcom_yw.domain.vo.YwInspectPlanVo; +import com.ruoyi.eastcom_yw.mapper.*; +import com.ruoyi.eastcom_yw.service.CommonService; +import com.ruoyi.eastcom_yw.service.YwNoticeUserService; +import com.ruoyi.eastcom_yw.service.YwRoutInspectConfigService; +import com.ruoyi.eastcom_yw.service.YwRoutInspectPlanService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * @author huamile + * @date 2023/1/17 16:05 + **/ +@Service +@RequiredArgsConstructor +@Slf4j +public class YwRoutInspectPlanServiceImpl extends ServiceImpl implements YwRoutInspectPlanService { + + private final RedisCache redisCache; + + private final CommonService commonService; + private final YwRoutInspectConfigService ywRoutInspectConfigService; + + private final YwSceneMapper ywSceneMapper; + private final YwRoutInspectLogMapper ywRoutInspectLogMapper; + private final YwRoutInspectPlanMapper ywRoutInspectPlanMapper; + private final YwRoutInspectConfigMapper ywRoutInspectConfigMapper; + + private final YwAlarmViewMapper ywAlarmViewMapper; + + private final YwNoticeUserService ywNoticeUserService; + + private String processDefinitionId = StringUtils.EMPTY; + private final String JOBNOPREFIX = "XJ"; + + private Long getUserId() { + SysUser user = SecurityUtils.getLoginUser().getUser(); + if (user.isAdmin(user) || user.isCenter(user) || user.isLeader(user)) { + return null; + } else { + return user.getUserId(); + } + } + + @Override + public void insetInspectSchedule() { + //获取当前时间 + Calendar instance = Calendar.getInstance(); + instance.set(Calendar.SECOND, 0); + instance.set(Calendar.MILLISECOND, 0); + Date now = instance.getTime(); + + List executablePlanList = + ywRoutInspectPlanMapper.getExecutablePlanList(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now)); + + if (executablePlanList.size() > 0) { + + String templateId = ywAlarmViewMapper.getTemplateId(TaskConstants.INSPECT); + + if (StringUtils.isNotEmpty(templateId)) { + try { + processDefinitionId = commonService.GetProcessDefinitionId(templateId); + } catch (Exception e) { + log.error(e.getMessage()); + return; + } + + UserInfo user = new UserInfo(); + user.setId("2"); + user.setName("系统"); + user.setType("user"); + user.setSex("1"); + user.setSelected(true); + + for (YwInspectLogVo ywInspectLogVo : executablePlanList) { + //筛选,巡检工作流到时间创建工作流定时任务,满足条件执行下面代码 +// boolean flag = false; +// if (now.compareTo(ywInspectLogVo.getBeginTime()) == 0) { +// flag = true; +// } else if (ywInspectLogVo.getCircle() > 1) { +// for (Integer i = 1; i < ywInspectLogVo.getCircle(); i++) { +// Calendar calendar = Calendar.getInstance(); +// calendar.setTime(ywInspectLogVo.getBeginTime()); +// calendar.add(Calendar.MINUTE, ywInspectLogVo.getIntervalTime().intValue()); +// Date time = calendar.getTime(); +// if (now.compareTo(time) == 0) { +// flag = true; +// break; +// } +// } +// } + + log.info("巡检JOB时间" + now + ", " + ywInspectLogVo); + +// if (flag) { + StartProcessInstanceDTO startDTO = new StartProcessInstanceDTO(); + startDTO.setStartUserInfo(user); + startDTO.setProcessDefinitionId(processDefinitionId); + JSONObject json = new JSONObject(); + String groupId = MessageFormat.format("{0}|{1}|xj", ywInspectLogVo.getSceneId().toString().replace(",", ""), ywInspectLogVo.getInspectSpecialty()); + //场馆ID和 + json.put("input_cg_zy_id", groupId); + json.put("input_cg", ywInspectLogVo.getVenueName()); + json.put("input_zy", ywInspectLogVo.getSpecialtyName()); + json.put("input_limit", ywInspectLogVo.getStopTimeOption()); + json.put("input_fkr", ""); + json.put("input_fksj", ""); + json.put("textarea_xjfk", ""); + json.put("input_xjxs", ywInspectLogVo.getCheckNum()); + json.put("input_zcxs", ywInspectLogVo.getCheckNum()); + json.put("input_wtxs", "0"); + json.put("select_wtdl1", ""); + json.put("select_wtxl1", ""); + json.put("textarea_wtms1", ""); + json.put("pictureupload_wtzp1", null); + json.put("textarea_wtms2", ""); + json.put("pictureupload_wtzp2", null); + json.put("textarea_wtms3", ""); + json.put("pictureupload_wtzp3", null); + json.put("textarea_wtms4", ""); + json.put("pictureupload_wtzp4", null); + json.put("textarea_wtms5", ""); + json.put("pictureupload_wtzp5", null); + json.put("textarea_wtms6", ""); + json.put("pictureupload_wtzp6", null); + json.put("textarea_wtms7", ""); + json.put("pictureupload_wtzp7", null); + json.put("textarea_wtms8", ""); + json.put("pictureupload_wtzp8", null); + json.put("textarea_wtms9", ""); + json.put("pictureupload_wtzp9", null); + json.put("textarea_wtms10", ""); + json.put("pictureupload_wtzp10", null); + json.put("pictureupload_pz", null); + + YwSearchDTO ywSearchDTO = new YwSearchDTO(); + ywSearchDTO.setArea_county_id(ywInspectLogVo.getAreaCountyId()); + ywSearchDTO.setTask_type(TaskConstants.INSPECT); + ywSearchDTO.setVenue_id(ywInspectLogVo.getSceneId().toString()); + ywSearchDTO.setVenue_name(ywInspectLogVo.getVenueName()); + ywSearchDTO.setCounty(ywInspectLogVo.getCounty()); + ywSearchDTO.setCity(ywInspectLogVo.getCity()); + //20230303工作流增加任务名称 + ywSearchDTO.setTask_name(ywInspectLogVo.getInspectName()); + json.put("input_search", JSONObject.toJSONString(ywSearchDTO)); + + startDTO.setFormData(json); + try { + String res_flwprocessid = commonService.StartProcess(startDTO); + + if (StringUtils.isNotEmpty(res_flwprocessid)) { + //保存数据到巡检日志表 + YwRoutInspectLog ywRoutInspectLog = new YwRoutInspectLog(); + //巡检计划id + ywRoutInspectLog.setRoutInspectId(ywInspectLogVo.getRoutInspectId()); + //检查项数 + ywRoutInspectLog.setCheckNum(ywInspectLogVo.getCheckNum()); + //返回的工作流流程id + ywRoutInspectLog.setFlwProcessid(res_flwprocessid); + + if (ywRoutInspectLogMapper.insertSelective(ywRoutInspectLog) > 0) { + boolean res = ywNoticeUserService.noticeYW(res_flwprocessid, groupId, TaskConstants.INSPECT); + if (!res) { + log.error("告警工作流已生成,提醒没有发送成功"); + } + + } + } + } catch (Exception e) { + log.error(e.getMessage()); + } +// } + } + } + } + } + + @Override + public List getList(YwRoutInspectConfigParam param) { + param.setUserId(getUserId()); + PageUtils.startPage(param, YwRoutInspectConfigParam.class); + return ywRoutInspectPlanMapper.getList(param); + } + + @Override + public TableDataInfo getPlanList(YwRoutInspectPlanParam param) { + param.setUserId(getUserId()); + TableDataInfo rspData = new TableDataInfo(); + rspData.setTotal(0); + PageUtils.startPage(param, YwRoutInspectPlanParam.class); + List planList = ywRoutInspectPlanMapper.getPlanList(param); + if (planList.size() > 0) { + long total = PageInfo.of(planList).getTotal(); + rspData.setTotal(total); + for (YwInspectPlanVo vo : planList) { + vo.setTaskNo(vo.getFlwProcessid()); + if (vo.getType() != null) { + vo.setTypeName(vo.getType() == 0 ? "临时" : "计划"); + } + if (vo.getFeedBackTime() != null) { + //TODO 需要修改,是否超时根据配置表中stop_time_option字段判断 + + vo.setTimeoutOrNot(vo.getFeedBackTime().after(vo.getPlanFinTime()) ? "是" : "否"); + vo.setTaskStatus("已反馈"); + } else if (vo.getFeedBackTime() == null && StringUtils.isNotEmpty(vo.getFlwProcessid())) { + vo.setTimeoutOrNot(new Date().after(vo.getPlanFinTime()) ? "是" : "否"); + vo.setTaskStatus("执行中"); + } else { + vo.setTimeoutOrNot(new Date().after(vo.getPlanFinTime()) ? "是" : "否"); + vo.setTaskStatus("未启动"); + } +// if ("1".equals(vo.getDealStatus())) { +// vo.setTaskStatus("处理中"); +// } else if ("4".equals(vo.getDealStatus())) { +// vo.setTaskStatus("已反馈"); +// } + + } + + if (param.getIsApp()) { + //查询工作流,比较是否是当前登录用户的待办 + List processIds = commonService.selectCurrenUserTodoProcessId(null); + if (CollUtil.isNotEmpty(processIds)) { + for (String processId : processIds) { + planList.stream().filter(l -> processId.equals(l.getFlwProcessid())).findAny().ifPresent(a -> { + a.setIsTodo(1); + }); + } + } + } + } + rspData.setRows(planList); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setMsg("查询成功"); + return rspData; + } + + @Override + public Map getStatData(YwRoutInspectStatParam param) { + if (!param.isExport()) { + param.setPageNum(null); + param.setPageSize(null); + } +// setDefaultTime(param); + //大屏调用此方法是未登录状态 + if(!param.isTaskFlag()){ + param.setUserId(getUserId()); + } + Integer numOfCompletedPlan = ywRoutInspectPlanMapper.getNumOfCompletedPlan(param); + Integer numOfAllPlan = ywRoutInspectPlanMapper.getNumOfAllPlan(param); + Double rate = 0.00d; + if (numOfAllPlan != 0) { + rate = new BigDecimal((numOfCompletedPlan.doubleValue() / numOfAllPlan) * 100) + .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); + } + + Map map = new HashMap<>(3); + map.put("rate", rate); + map.put("numOfAllPlan", numOfAllPlan); + map.put("numOfCompletedPlan", numOfCompletedPlan); + + return map; + } + + @Override + public Map getStatListData(YwRoutInspectStatParam param) { + PageUtils.startPage(param, YwRoutInspectStatParam.class); +// setDefaultTime(param); + //大屏调用此方法是未登录状态 + if(!param.isTaskFlag()){ + param.setUserId(getUserId()); + } + List list = ywRoutInspectPlanMapper.getStatListData20231012(param); +// addImg(list); + + Map map = Maps.newHashMap(); + map.put("beginDate", param.getBeginDate()); + map.put("endDate", param.getEndDate()); + map.put("total", list.size()); + map.put("list", list); + return map; + } + + + @Override + public Map getResultStatData(YwRoutInspectStatParam param) { + if (!param.isExport()) { + param.setPageNum(null); + param.setPageSize(null); + } +// setDefaultTime(param); + //大屏调用此方法是未登录状态 + if(!param.isTaskFlag()){ + param.setUserId(getUserId()); + } + Integer numOfQuestionPlan = ywRoutInspectPlanMapper.getNumOfQuestionPlan(param) == null ? 0 : ywRoutInspectPlanMapper.getNumOfQuestionPlan(param); + Integer numOfAllPlan = ywRoutInspectPlanMapper.getAllNumOfPlan(param) == null ? 0 : ywRoutInspectPlanMapper.getAllNumOfPlan(param); + Integer numOfNoQuPlan = 0; + + if (numOfQuestionPlan < numOfAllPlan) { + numOfNoQuPlan = numOfAllPlan - numOfQuestionPlan; + } + + Double rate = 0.00d; + if (numOfAllPlan != 0) { + rate = new BigDecimal((numOfNoQuPlan.doubleValue() / numOfAllPlan) * 100) + .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); + } + + Map map = new HashMap<>(3); + map.put("rate", rate); + map.put("numOfAllPlan", numOfAllPlan); + map.put("numOfNoQuPlan", numOfNoQuPlan); + + return map; + } + + @Override + public Map getResultStatListData(YwRoutInspectStatParam param) { + PageUtils.startPage(param, YwRoutInspectStatParam.class); +// setDefaultTime(param); + param.setUserId(getUserId()); + List list = ywRoutInspectPlanMapper.getResultStatListData20231012(param); +// addImg(list); +// + Map map = Maps.newHashMap(); + map.put("beginDate", param.getBeginDate()); + map.put("endDate", param.getEndDate()); + map.put("total", list.size()); + map.put("list", list); + return map; + } + + @Override + public List getRoutInspectInfoList(String processId) { + return ywRoutInspectLogMapper.getRoutInspectInfoList(processId); + } + + private void createSinglePlan(YwInspectTaskDTO dto) throws Exception { + YwInspectPlanDTO ywRoutInspectPlan = dto.getYwRoutInspectPlan(); + + List specialtyList = ywRoutInspectPlan.getSpecialtyList(); + if (CollectionUtil.isNotEmpty(specialtyList)) { + String jobNo = getJobNo(); + ywRoutInspectPlan.setJobNo(jobNo); + ywRoutInspectPlan.setInspectDate(DateUtils.parseDate(ywRoutInspectPlan.getBeginTime().split(" ")[0], "yyyy-MM-dd")); + for (String specialty : specialtyList) { + ywRoutInspectPlan.setInspectSpecialty(specialty); + ywRoutInspectPlanMapper.insertSelective(ywRoutInspectPlan); + } + } + + /*List list = dto.getList(); + List configIds = list.stream().filter(c -> c.getId() != null). + map(YwRoutInspectConfig::getId).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(configIds)) { + ywRoutInspectPlanMapper.delUselessConfig(ywRoutInspectPlan.getSceneId(), + ywRoutInspectPlan.getInspectSpecialty(),configIds); + } + for (int i = 0; i < list.size(); i++) { + YwRoutInspectConfig config = list.get(i); + + List specialtyList = ywRoutInspectPlan.getSpecialtyList(); + if (CollectionUtil.isNotEmpty(specialtyList)) { + for (String specialty : specialtyList) { + ywRoutInspectPlan.setInspectSpecialty(specialty); + addData(ywRoutInspectPlan,config); + ywRoutInspectPlanMapper.insertSelective(ywRoutInspectPlan); + } + } + + if (config.getId() != null) { + ywRoutInspectConfigService.updateById(config); + } else { + ywRoutInspectConfigMapper.insertSelective(config); + } + }*/ + } + + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult create(YwInspectTaskDTO dto) throws Exception { + List> timePeriods = dto.getYwRoutInspectPlan().getTimePeriods(); + if (timePeriods == null) { + return AjaxResult.error("操作失败"); + } + boolean checkFlag; + for (Map map : timePeriods) { + YwInspectTaskDTO taskDTO = new YwInspectTaskDTO(); + BeanUtils.copyBeanProp(taskDTO, dto); + YwInspectPlanDTO ywInspectPlanDTO = taskDTO.getYwRoutInspectPlan(); + ywInspectPlanDTO.setBeginTime(map.get("beginTime")); + ywInspectPlanDTO.setPlanFinTime(map.get("planFinTime")); + List specialtyList = ywInspectPlanDTO.getSpecialtyList(); + if (CollectionUtil.isNotEmpty(specialtyList)) { + for (String special : specialtyList) { + checkFlag = validUnique(ywInspectPlanDTO, special); + if (!checkFlag) { + return AjaxResult.error("巡检计划重复,操作失败"); + } + } + } + } + for (Map map : timePeriods) { + YwInspectTaskDTO taskDTO = new YwInspectTaskDTO(); + BeanUtils.copyBeanProp(taskDTO, dto); + taskDTO.getYwRoutInspectPlan().setBeginTime(map.get("beginTime")); + taskDTO.getYwRoutInspectPlan().setPlanFinTime(map.get("planFinTime")); + createSinglePlan(taskDTO); + } + return AjaxResult.success(); + } + + private boolean validUnique(YwInspectPlanDTO ywInspectPlanDTO, String special) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(YwRoutInspectPlan::getSceneId, ywInspectPlanDTO.getSceneId()); + queryWrapper.eq(YwRoutInspectPlan::getInspectSpecialty, special); + queryWrapper.eq(YwRoutInspectPlan::getBeginTime, DateUtils.parseDate(ywInspectPlanDTO.getBeginTime())); + queryWrapper.eq(YwRoutInspectPlan::getPlanFinTime, DateUtils.parseDate(ywInspectPlanDTO.getPlanFinTime())); + List plans = ywRoutInspectPlanMapper.selectList(queryWrapper); + if (CollectionUtil.isNotEmpty(plans)) { + return false; + } + return true; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updatePlan(YwInspectTaskDTO dto) throws Exception { + YwInspectPlanDTO ywRoutInspectPlan = dto.getYwRoutInspectPlan(); + if (ywRoutInspectPlan.getBeginTime() != null) { + ywRoutInspectPlan.setInspectDate(DateUtils.parseDate(ywRoutInspectPlan.getBeginTime().split(" ")[0], "yyyy-MM-dd")); + } + List list = ywRoutInspectPlanMapper.getListByJobNo(ywRoutInspectPlan.getJobNo()); + List collect = list.stream().map(plan -> plan.getInspectSpecialty()).collect(Collectors.toList()); + ywRoutInspectPlanMapper.delUselessPlan(ywRoutInspectPlan.getJobNo(), ywRoutInspectPlan.getSpecialtyList()); + List updateList = collect; + updateList.retainAll(ywRoutInspectPlan.getSpecialtyList()); + ywRoutInspectPlanMapper.updateByJobNoSelective(ywRoutInspectPlan); + + List addList = ywRoutInspectPlan.getSpecialtyList(); + addList.removeAll(collect); + if (CollectionUtil.isNotEmpty(addList)) { + for (String specialty : addList) { + ywRoutInspectPlan.setInspectSpecialty(specialty); + ywRoutInspectPlanMapper.insertSelective(ywRoutInspectPlan); + } + } + + /*List list = dto.getList(); + if (list.size() > 0) { + YwRoutInspectConfig config = list.get(0); + + YwInspectPlanDTO ywRoutInspectPlan = dto.getYwRoutInspectPlan(); + addData(ywRoutInspectPlan,config); + ywRoutInspectPlanMapper.updateByPrimaryKeySelective(ywRoutInspectPlan); + }*/ + } + + @Override + public void export(YwRoutInspectConfigParam param, HttpServletRequest request, HttpServletResponse response) { + param.setPageNum(1); + param.setPageSize(Integer.MAX_VALUE); + List logList = getList(param); + + List list = new ArrayList<>(); + for (int i = 0; i < logList.size(); i++) { + YwInspectLogVo ywInspectLogVo = logList.get(i); + YwInspectPlanExportDTO dto = new YwInspectPlanExportDTO(); + BeanUtils.copyBeanProp(dto, ywInspectLogVo); + if (StringUtils.isNotEmpty(dto.getNoticeType())) { + dto.setNoticeType(DictUtils.getDictLabel("sys_notice_type", dto.getNoticeType())); + } + list.add(dto); + } + + EasyPoiExcelUtil.exportExcel(null, YwInspectPlanExportDTO.class, list, request, response); + } + + @Override + public void planExport(YwRoutInspectPlanParam param, HttpServletRequest request, HttpServletResponse response) { + param.setPageNum(1); + param.setPageSize(Integer.MAX_VALUE); + List planList = ReflectUtils.toList(getPlanList(param).getRows(), YwInspectPlanVo.class); + + List list = new ArrayList<>(); + for (int i = 0; i < planList.size(); i++) { + YwInspectPlanVo ywInspectPlanVo = planList.get(i); + YwInspectTaskExportDTO dto = new YwInspectTaskExportDTO(); + BeanUtils.copyBeanProp(dto, ywInspectPlanVo); + dto.setRate((ywInspectPlanVo.getQuestionNum() == null ? "--" : ywInspectPlanVo.getQuestionNum()) + + "/" + (ywInspectPlanVo.getCheckNum() == null ? "--" : ywInspectPlanVo.getCheckNum())); + dto.setErrorNum(ywInspectPlanVo.getQuestionNum()); + dto.setNum(ywInspectPlanVo.getCheckNum()); + list.add(dto); + } + + ExcelUtil util = new ExcelUtil<>(YwInspectTaskExportDTO.class); + util.exportExcel(response, list, "巡检记录导出"); + } + + @Override + public List mergeResultStat(YwRoutInspectStatParam param) { + Map statListData = getStatListData(param); + Map resultStatListData = getResultStatListData(param); + List list = (List) statListData.get("list"); + List resList = (List) resultStatListData.get("list"); + if (CollUtil.isNotEmpty(list)) { + for (YwInspectStatDTO dto : list) { + for (YwInspectStatDTO resDto : resList) { + if (dto.getSceneId().equals(resDto.getSceneId())) { + dto.setResulRate(resDto.getRate()); + dto.setResultAllNum(resDto.getAllNum()); + dto.setResulNormalNum(resDto.getCompletedNum()); + } + } + } + } + return list; + } + + @Override + public boolean checkPlanStatus(String dto) { + List list = ywRoutInspectLogMapper.getRoutInspectInfoListByJobNoAndFlowId(dto); + if (!CollectionUtils.isEmpty(list)) { + return true; + } + return false; + } + + @Override + public List getInspectPlanStatic(YwRoutInspectStatParam param) { + List list = ywRoutInspectPlanMapper.getStatListData(param); + List staticVos = new ArrayList<>(); + DecimalFormat df = new DecimalFormat("#.00"); + for (YwInspectStatDTO dto : list) { + YwInspectPlanStaticVo staticVo = new YwInspectPlanStaticVo(); + BeanUtils.copyProperties(dto, staticVo); + staticVo.setRate(df.format(dto.getRate())); + staticVos.add(staticVo); + + } + return staticVos; + } + + private void addData(YwInspectPlanDTO dto, YwRoutInspectConfig config) { + dto.setCheckNum(config.getCheckNum()); + dto.setCheckType(config.getCheckType()); + dto.setCheckDesc(config.getCheckDesc()); + dto.setCircle(config.getCircle()); + dto.setStopTimeOption(config.getStopTimeOption()); + dto.setIntervalTime(config.getIntervalTime()); + dto.setInspectUserId(config.getInspectUserId()); + dto.setRepWarnInterval(config.getRepWarnInterval()); + dto.setNoticeType(config.getNoticeType()); + } + + private String getJobNo() { + String date = new SimpleDateFormat("yyyyMMdd").format(new Date()); + String key = JOBNOPREFIX + date; + + if (redisCache.hasKey(key)) { + String value = redisCache.getCacheObject(key).toString(); + String[] split = value.split("_"); + if (split.length == 3) { + int i = Integer.parseInt(split[2]) + 1; + String num = String.format("%04d", i); + String v = split[0] + "_" + split[1] + "_" + num; + redisCache.setCacheObject(key, v, 1, TimeUnit.DAYS); + return v; + } + } + String value = JOBNOPREFIX + "_" + date + "_" + "0001"; + redisCache.setCacheObject(key, value, 1, TimeUnit.DAYS); + return value; + } + + private void setDefaultTime(YwRoutInspectStatParam param) { + String beginDate = param.getBeginDate(); + if (StrUtil.isBlank(beginDate)) { + String date = DateUtils.getDate(); + beginDate = date + " 00:00:00"; + param.setBeginDate(beginDate); + } + String endDate = param.getEndDate(); + if (StrUtil.isBlank(endDate)) { + Calendar instance = Calendar.getInstance(); + instance.setTime(new Date()); + instance.add(Calendar.HOUR_OF_DAY, -1); + instance.set(Calendar.SECOND, 0); + instance.set(Calendar.MILLISECOND, 0); + Date time = instance.getTime(); + endDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time); + param.setEndDate(endDate); + } + } + + private void addImg(List list) { + if (CollectionUtil.isNotEmpty(list)) { + List ids = list.stream().map(dto -> dto.getSceneId()).collect(Collectors.toList()); + List files = ywSceneMapper.getFilesBySceneIds(ids); + if (CollectionUtil.isNotEmpty(files)) { + for (YwInspectStatDTO dto : list) { + for (YwSceneFile file : files) { + if ("pic".equals(file.getFileType()) && dto.getSceneId().equals(file.getSceneId())) { + dto.setImageurl(file.getFileUrl()); + break; + } + } + } + } + } + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectQuestionConfigServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectQuestionConfigServiceImpl.java new file mode 100644 index 0000000..5dbe47e --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwRoutInspectQuestionConfigServiceImpl.java @@ -0,0 +1,73 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.poi.EasyPoiExcelUtil; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectQuestionConfig; +import com.ruoyi.eastcom_yw.domain.param.YwInspectQuestionConfigParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneVo; +import com.ruoyi.eastcom_yw.mapper.YwRoutInspectQuestionConfigMapper; +import com.ruoyi.eastcom_yw.service.YwRoutInspectQuestionConfigService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author huamile + * @date 2023/2/ 16:50 + **/ +@Service +@RequiredArgsConstructor +public class YwRoutInspectQuestionConfigServiceImpl extends ServiceImpl implements YwRoutInspectQuestionConfigService { + + private final YwRoutInspectQuestionConfigMapper ywRoutInspectQuestionConfigMapper; + + @Override + public List getlist(YwInspectQuestionConfigParam param) { + if (null == param.getPageSize()) { + param.setPageSize(Integer.MAX_VALUE); + } + PageUtils.startPage(param,YwInspectQuestionConfigParam.class); + return ywRoutInspectQuestionConfigMapper.getlist(param); + } + + @Override + public Integer create(YwRoutInspectQuestionConfig ywRoutInspectQuestionConfig) { + return ywRoutInspectQuestionConfigMapper.insertSelective(ywRoutInspectQuestionConfig); + } + + @Override + public Integer updateByPrimaryKeySelective(YwRoutInspectQuestionConfig ywRoutInspectQuestionConfig) { + return ywRoutInspectQuestionConfigMapper.updateByPrimaryKeySelective(ywRoutInspectQuestionConfig); + } + + @Override + public void export(YwInspectQuestionConfigParam param, HttpServletRequest request, HttpServletResponse response) { + param.setPageNum(1); + param.setPageSize(Integer.MAX_VALUE); + List list = getlist(param); + + ExcelUtil util = new ExcelUtil<>(YwRoutInspectQuestionConfig.class); + util.exportExcel(response, list, "巡检问题类型配置"); + +// EasyPoiExcelUtil.exportExcel("巡检问题类型配置",YwRoutInspectQuestionConfig.class,list,request,response); + } + + @Override + public List appList(YwInspectQuestionConfigParam param) { + PageUtils.startPage(param,YwInspectQuestionConfigParam.class); + return ywRoutInspectQuestionConfigMapper.selectList(new LambdaQueryWrapper() + .eq(param.getSceneBigId()!=null,YwRoutInspectQuestionConfig::getSceneBigId,param.getSceneBigId()) + .eq(StrUtil.isNotBlank(param.getSpecialty()),YwRoutInspectQuestionConfig::getSpecialtyId,param.getSpecialty()) + .eq(StrUtil.isNotBlank(param.getQuestionType()),YwRoutInspectQuestionConfig::getQuestionType,param.getQuestionType()) + .eq(StrUtil.isNotBlank(param.getQuestionSonType()),YwRoutInspectQuestionConfig::getQuestionSonType,param.getQuestionSonType()) + ); + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneAlarmServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneAlarmServiceImpl.java new file mode 100644 index 0000000..1956b80 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneAlarmServiceImpl.java @@ -0,0 +1,74 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.poi.EasyPoiExcelUtil; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwSceneAlarm; +import com.ruoyi.eastcom_yw.domain.param.YwSceneAlarmParam; +import com.ruoyi.eastcom_yw.domain.param.YwSceneUserParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneAlarmVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneVo; +import com.ruoyi.eastcom_yw.mapper.YwSceneAlarmMapper; +import com.ruoyi.eastcom_yw.service.YwSceneAlarmService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author huamile + */ +@Service +@RequiredArgsConstructor +public class YwSceneAlarmServiceImpl extends ServiceImpl implements YwSceneAlarmService { + + private final YwSceneAlarmMapper ywSceneAlarmMapper; + + @Override + public List getList(YwSceneAlarmParam param) { + PageUtils.startPage(param, YwSceneUserParam.class); + return ywSceneAlarmMapper.getList(param); + } + + @Override + public List getListBySceneBigId(Long sceneBigId) { + return ywSceneAlarmMapper.getListBySceneBigId(sceneBigId); + } + + @Override + public Integer create(YwSceneAlarm ywSceneAlarm) { + return ywSceneAlarmMapper.insertSelective(ywSceneAlarm); + } + + @Override + public Integer updateByPrimaryKeySelective(YwSceneAlarm ywSceneAlarm) { + return ywSceneAlarmMapper.updateByPrimaryKeySelective(ywSceneAlarm); + } + + @Override + public Integer delBySceneIds(List ids) { + if (CollectionUtil.isNotEmpty(ids)) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.in(YwSceneAlarm::getSceneId,ids); + return ywSceneAlarmMapper.delete(wrapper); + } + return null; + } + + @Override + public void export(YwSceneAlarmParam param, HttpServletRequest request, HttpServletResponse response) { + param.setPageNum(1); + param.setPageSize(Integer.MAX_VALUE); + List list = getList(param); + + ExcelUtil util = new ExcelUtil<>(YwSceneAlarmVo.class); + util.exportExcel(response, list, "场馆告警配置"); + +// EasyPoiExcelUtil.exportExcel("场馆告警配置", YwSceneAlarmVo.class,list,request,response); + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneCalendarServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneCalendarServiceImpl.java new file mode 100644 index 0000000..de14155 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneCalendarServiceImpl.java @@ -0,0 +1,94 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.utils.*; +import com.ruoyi.common.utils.poi.EasyPoiExcelUtil; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwSceneCalendar; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneCalendarDTO; +import com.ruoyi.eastcom_yw.domain.param.YwSceneCalendarParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneAlarmVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneCalendar2Vo; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneCalendarVo; +import com.ruoyi.eastcom_yw.importer.ImporterCalendar; +import com.ruoyi.eastcom_yw.mapper.YwSceneCalendarMapper; +import com.ruoyi.eastcom_yw.mapper.YwSceneMapper; +import com.ruoyi.eastcom_yw.service.YwSceneCalendarService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author huamile + */ +@Service +@RequiredArgsConstructor +public class YwSceneCalendarServiceImpl extends ServiceImpl implements YwSceneCalendarService { + + private final YwSceneCalendarMapper ywSceneCalendarMapper; + private final YwSceneMapper ywSceneMapper; + + @Override + public List getList(YwSceneCalendarParam param) { + PageUtils.startPage(param, YwSceneCalendarParam.class); + return ywSceneCalendarMapper.getList(param); + } + + @Override + public List getListBySceneBigId(Long sceneBigId) { + return ywSceneCalendarMapper.getListBySceneBigId(sceneBigId); + } + + @Override + public Integer create(YwSceneCalendarDTO dto) { + return ywSceneCalendarMapper.insertSelective(dto); + } + + @Override + public Integer updateByPrimaryKeySelective(YwSceneCalendarDTO dto) { + return ywSceneCalendarMapper.updateByPrimaryKeySelective(dto); + } + + @Override + public Integer delBySceneIds(List ids) { + if (CollectionUtil.isNotEmpty(ids)) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.in(YwSceneCalendar::getSceneId, ids); + return ywSceneCalendarMapper.delete(wrapper); + } + return null; + } + + @Override + public void export(YwSceneCalendarParam param, HttpServletRequest request, HttpServletResponse response) { + param.setPageNum(1); + param.setPageSize(Integer.MAX_VALUE); + List list = getList(param); + ExcelUtil util = new ExcelUtil<>(YwSceneCalendarVo.class); + util.exportExcel(response, list, "场馆赛事配置"); + +// EasyPoiExcelUtil.exportExcel("场馆赛事配置", YwSceneCalendarVo.class, list, request, response); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult importSceneCalendar(List vos, Long sceneBigId, String importType) throws Exception { + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.eq(sceneBigId != null, YwScene::getSceneBigId, sceneBigId); + List ywSceneList = ywSceneMapper.selectList(lambdaQueryWrapper); + + ImporterBase importerBase = new ImporterCalendar(ywSceneCalendarMapper); + return importerBase.doAdd(vos, sceneBigId, importType, ywSceneList); + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneMatchServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneMatchServiceImpl.java new file mode 100644 index 0000000..351cce7 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneMatchServiceImpl.java @@ -0,0 +1,49 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.param.YwSceneMatchParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneMatchVo; +import com.ruoyi.eastcom_yw.importer.ImporterMatch; +import com.ruoyi.eastcom_yw.mapper.YwSceneMapper; +import com.ruoyi.eastcom_yw.mapper.YwSceneMatchMapper; +import com.ruoyi.eastcom_yw.service.YwSceneMatchService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * @author los + */ +@Service +@RequiredArgsConstructor +public class YwSceneMatchServiceImpl implements YwSceneMatchService { + + private final YwSceneMatchMapper ywSceneMatchMapper; + private final YwSceneMapper ywSceneMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult importMatch(List vos, Long sceneBigId, String importType) throws Exception { + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.eq(sceneBigId != null, YwScene::getSceneBigId, sceneBigId); + List ywSceneList = ywSceneMapper.selectList(lambdaQueryWrapper); + + ImporterBase importerBase = new ImporterMatch(ywSceneMatchMapper); + return importerBase.doAdd(vos, sceneBigId, importType, ywSceneList); + + } + + @Override + public List list(YwSceneMatchParam param) { + PageUtils.startPage(param, YwSceneMatchParam.class); + return ywSceneMatchMapper.list(param); + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementAgisServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementAgisServiceImpl.java new file mode 100644 index 0000000..c44e542 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementAgisServiceImpl.java @@ -0,0 +1,77 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementAgisParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementAgis; +import com.ruoyi.eastcom_yw.importer.ImporterAgis; +import com.ruoyi.eastcom_yw.mapper.YwSceneNetelementAgisMapper; +import com.ruoyi.eastcom_yw.service.YwSceneNetelementAgisService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author los + */ +@Service +@RequiredArgsConstructor +public class YwSceneNetelementAgisServiceImpl implements YwSceneNetelementAgisService { + + private final YwSceneService ywSceneService; + + private final YwSceneNetelementAgisMapper ywSceneNetelementAgisMapper; + + @Override + public List list(YwSceneNetelementAgisParam para) { + PageUtils.startPage(para, YwSceneNetelementAgisParam.class); + List wxes = ywSceneNetelementAgisMapper.listAll(para); + wxes.forEach(x -> x.setAlarmSpecityName(DictUtils.getDictLabel("yw_alarm_specialty", x.getAlarmSpecityId()))); + return wxes; + } + + /** + * 导入 + * + * @param cs 数据 + * @param sceneBigId 大场景id + * @param opType 导入类型 + * @param sceneId + * @return + * @throws Exception + */ + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult importAgis(List cs, Long sceneBigId, String opType, String sceneId) throws Exception { + + // 获取大场景下场馆信息 + List ywSceneList = ywSceneService.getVenueByBigId(sceneBigId); + + List cellFormatBeans = new ArrayList<>(); + genFormatList(cellFormatBeans); + ImporterBase importer = new ImporterAgis(ywSceneNetelementAgisMapper); + + return importer.doAdd(cs, cellFormatBeans, sceneBigId, opType, ywSceneList, sceneId); + } + + private void genFormatList(List cellFormatBeans) { + cellFormatBeans.add(new CellFormatBean("专业", "alarmSpecityName", "false", "false", "", "", "yw_alarm_specialty", "", "")); + cellFormatBeans.add(new CellFormatBean("场馆", "sceneName", "false", "false", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("网元名称", "netElementName", "false", "false", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("端口", "portA", "true", "false", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("设备类型", "equipmentType", "true", "false", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("对端网元", "netElementB", "true", "false", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("对端端口", "portB", "true", "false", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("对端设备类型", "equipmentTypeB", "true", "false", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("备注", "desc", "true", "false", "", "", "", "", "")); + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementCsServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementCsServiceImpl.java new file mode 100644 index 0000000..e115681 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementCsServiceImpl.java @@ -0,0 +1,78 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.eastcom_yw.common.enums.InRedLine; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementCsParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementCs; +import com.ruoyi.eastcom_yw.importer.ImporterCs; +import com.ruoyi.eastcom_yw.mapper.YwSceneNetelementCsMapper; +import com.ruoyi.eastcom_yw.service.YwSceneNetelementCsService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author los + */ +@Service +@RequiredArgsConstructor +public class YwSceneNetelementCsServiceImpl implements YwSceneNetelementCsService { + + private final YwSceneService ywSceneService; + + private final YwSceneNetelementCsMapper ywSceneNetelementCsMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult importCs(List cs, Long sceneBigId, String opType, String sceneId) throws Exception { + + // 获取大场景下场馆信息 + List ywSceneList = ywSceneService.getVenueByBigId(sceneBigId); + + List cellFormatBeans = new ArrayList<>(); + genFormatList(cellFormatBeans); + ImporterBase importer = new ImporterCs(ywSceneNetelementCsMapper); + + return importer.doAdd(cs, cellFormatBeans, sceneBigId, opType, ywSceneList, sceneId); + } + + private void genFormatList(List cellFormatBeans) { + cellFormatBeans.add(new CellFormatBean("场馆", "sceneName", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("设备类型", "equipmentType", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("组网类型", "networkingType", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("A端网元", "netElementNameA", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("A端端口", "portA", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("A端属性(红线内外)", "attributeA", "", "", "", "", "", "内,外", "")); + cellFormatBeans.add(new CellFormatBean("Z端网元", "netElementZ", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("Z端端口", "portZ", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("Z端属性(红线内外)", "attributeZ", "", "", "", "", "", "内,外", "")); + } + + @Override + public List list(YwSceneNetelementCsParam param) { + PageUtils.startPage(param, YwSceneNetelementCsParam.class); + List cs = ywSceneNetelementCsMapper.listAll(param); + cs.forEach(x -> { + if (InRedLine.IN_RED_LINE.getCode().equals(x.getAttributeA())) { + x.setAttributeA(InRedLine.IN_RED_LINE.getLabel()); + } else if (InRedLine.NOT_IN_RED_LINE.getCode().equals(x.getAttributeA())) { + x.setAttributeA(InRedLine.NOT_IN_RED_LINE.getLabel()); + } + if (InRedLine.IN_RED_LINE.getCode().equals(x.getAttributeZ())) { + x.setAttributeZ(InRedLine.IN_RED_LINE.getLabel()); + } else if (InRedLine.NOT_IN_RED_LINE.getCode().equals(x.getAttributeZ())) { + x.setAttributeZ(InRedLine.NOT_IN_RED_LINE.getLabel()); + } + }); + return cs; + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementDhServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementDhServiceImpl.java new file mode 100644 index 0000000..9c1bbd8 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementDhServiceImpl.java @@ -0,0 +1,70 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.eastcom_yw.common.enums.InRedLine; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementDhParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementDh; +import com.ruoyi.eastcom_yw.importer.ImporterDh; +import com.ruoyi.eastcom_yw.mapper.YwSceneNetelementDhMapper; +import com.ruoyi.eastcom_yw.service.YwSceneNetelementDhService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author los + */ +@Service +@RequiredArgsConstructor +public class YwSceneNetelementDhServiceImpl implements YwSceneNetelementDhService { + + private final YwSceneService ywSceneService; + + private final YwSceneNetelementDhMapper ywSceneNetelementDhMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult importDh(List ywSceneNetelementDhes, Long sceneBigId, String opType, String sceneId) throws Exception { + + // 获取大场景下场馆信息 + List ywSceneList = ywSceneService.getVenueByBigId(sceneBigId); + + List cellFormatBeans = new ArrayList<>(); + genFormatList(cellFormatBeans); + ImporterBase importer = new ImporterDh(ywSceneNetelementDhMapper); + + return importer.doAdd(ywSceneNetelementDhes, cellFormatBeans, sceneBigId, opType, ywSceneList, sceneId); + } + + private void genFormatList(List cellFormatBeans) { + cellFormatBeans.add(new CellFormatBean("场馆", "sceneName", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("地市", "city", "", "", "", "", "yw_city", "", "")); + cellFormatBeans.add(new CellFormatBean("区县", "county", "", "", "", "", "yw_county", "", "")); + cellFormatBeans.add(new CellFormatBean("物理站名", "netElementPhyname", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("机房类型", "roomType", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("红线内外", "inRedline", "false", "", "", "", "", "内,外", "")); + } + + @Override + public List list(YwSceneNetelementDhParam para) { + PageUtils.startPage(para, YwSceneNetelementDhParam.class); + List dhs = ywSceneNetelementDhMapper.listAll(para); + dhs.forEach(x -> { + if (InRedLine.IN_RED_LINE.getCode().equals(x.getInRedline())) { + x.setInRedline(InRedLine.IN_RED_LINE.getLabel()); + } else if (InRedLine.NOT_IN_RED_LINE.getCode().equals(x.getInRedline())) { + x.setInRedline(InRedLine.NOT_IN_RED_LINE.getLabel()); + } + }); + return dhs; + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementServiceImpl.java new file mode 100644 index 0000000..eea4790 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementServiceImpl.java @@ -0,0 +1,86 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.poi.EasyPoiExcelUtil; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwSceneNetelement; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneCalendarVo; +import com.ruoyi.eastcom_yw.mapper.YwSceneNetelementMapper; +import com.ruoyi.eastcom_yw.service.YwSceneNetelementService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author huamile + */ +@Service +@RequiredArgsConstructor +public class YwSceneNetelementServiceImpl extends ServiceImpl implements YwSceneNetelementService { + + private final YwSceneNetelementMapper ywSceneNetelementMapper; + + @Override + public List getList(YwSceneNetelementParam param) { + PageUtils.startPage(param,YwSceneNetelementParam.class); + return ywSceneNetelementMapper.getList(param); + } + + @Override + public List getListBySceneBigId(Long sceneBigId) { + return ywSceneNetelementMapper.getListBySceneBigId(sceneBigId); + } + + @Override + public Integer create(YwSceneNetelement ywSceneNetelement) { + validate(ywSceneNetelement); + return ywSceneNetelementMapper.insertSelective(ywSceneNetelement); + } + + @Override + public Integer updateByPrimaryKeySelective(YwSceneNetelement ywSceneNetelement) { + validate(ywSceneNetelement); + return ywSceneNetelementMapper.updateByPrimaryKeySelective(ywSceneNetelement); + } + + @Override + public Integer delBySceneIds(List ids) { + if (CollectionUtil.isNotEmpty(ids)) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.in(YwSceneNetelement::getSceneId,ids); + return ywSceneNetelementMapper.delete(wrapper); + } + return null; + } + + @Override + public void export(YwSceneNetelementParam param, HttpServletRequest request, HttpServletResponse response) { + param.setPageNum(1); + param.setPageSize(Integer.MAX_VALUE); + List list = getList(param); + ExcelUtil util = new ExcelUtil<>(YwSceneNetelement.class); + util.exportExcel(response, list, "场馆网元配置"); +// EasyPoiExcelUtil.exportExcel("场馆网元配置", YwSceneNetelement.class,list,request,response); + } + + private void validate(YwSceneNetelement ywSceneNetelement) { + //根据网元名称去重 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(StrUtil.isNotBlank(ywSceneNetelement.getNetElementName()),YwSceneNetelement::getNetElementName,ywSceneNetelement.getNetElementName()); + wrapper.ne(ywSceneNetelement.getId() != null,YwSceneNetelement::getId,ywSceneNetelement.getId()); + List list = ywSceneNetelementMapper.selectList(wrapper); + if (CollectionUtil.isNotEmpty(list)) { + throw new ServiceException("网元重复"); + } + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementWxServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementWxServiceImpl.java new file mode 100644 index 0000000..fc99fe9 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNetelementWxServiceImpl.java @@ -0,0 +1,151 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.common.enums.InRedLine; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementWxParam; +import com.ruoyi.eastcom_yw.domain.vo.WholeAreaAssureCellSheet; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementWx; +import com.ruoyi.eastcom_yw.importer.ImporterWx; +import com.ruoyi.eastcom_yw.mapper.YwSceneNetelementWxMapper; +import com.ruoyi.eastcom_yw.service.YwSceneNetelementWxService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author los + */ +@Service +@RequiredArgsConstructor +public class YwSceneNetelementWxServiceImpl implements YwSceneNetelementWxService { + + private final YwSceneService ywSceneService; + + private final YwSceneNetelementWxMapper ywSceneNetelementWxMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult importWx(List ywSceneNetelementWxes, Long sceneBigId, String optType, String sceneId) throws Exception { + + // 获取大场景下场馆信息 + List ywSceneList = ywSceneService.getVenueByBigId(sceneBigId); + + List cellFormatBeans = new ArrayList<>(); + genFormatList(cellFormatBeans); + ImporterBase importer = new ImporterWx(ywSceneNetelementWxMapper); + + return importer.doAdd(ywSceneNetelementWxes, cellFormatBeans, sceneBigId, optType, ywSceneList, sceneId); + + } + + private void genFormatList(List cellFormatBeans) { + cellFormatBeans.add(new CellFormatBean("场馆名称", "sceneName", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("场景名称", "场景名称", "true", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("OMC", "omc", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("地市", "city", "false", "", "", "", "yw_city", "", "")); + cellFormatBeans.add(new CellFormatBean("县市", "county", "false", "", "", "", "yw_county", "", "")); + cellFormatBeans.add(new CellFormatBean("enodebid", "enodebidStr", "", "", "true", "integer", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("本地小区标识", "本地小区标识Str", "", "", "true", "integer", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("小区标识", "小区标识Str", "", "", "true", "integer", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("站号", "站号Str", "", "", "true", "integer", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("基站全称", "基站全称", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("en", "en名称", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("小区名称", "小区名称", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("小区别名", "小区别名", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("ci", "ci", "false", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("红线内外", "inRedline", "false", "", "", "", "", "内,外", "")); + cellFormatBeans.add(new CellFormatBean("小区频段", "小区频段", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("纬度", "纬度Str", "", "", "true", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("经度", "经度Str", "", "", "true", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("纬度gcj", "纬度gcj", "", "", "true", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("经度gcj", "经度gcj", "", "", "true", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("室内室外", "室内室外", "", "", "", "", "", "室内,室外", "")); + cellFormatBeans.add(new CellFormatBean("网络", "网络", "", "", "", "", "", "4G,5G,2G", "")); + cellFormatBeans.add(new CellFormatBean("0427现网状态", "现网状态", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("CGI", "cgi", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("频点", "频点Str", "", "", "true", "integer", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("pci", "pciStr", "", "", "true", "integer", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("tac", "tacStr", "", "", "true", "integer", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("一级场景", "一级场景", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("二级场景", "二级场景", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("设备类型", "设备类型", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("带宽", "带宽Str", "", "", "true", "integer", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("方位角", "方位角Str", "", "", "true", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("扇区id", "扇区id", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("坐席编号", "坐席编号", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("场景类型编码", "sceneTypeCode", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("场景类型", "sceneType", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("场景子类型编码", "subSceneTypeCode", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("场景子类型", "subSceneType", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("场景编码", "sceneCode", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("覆盖子场景编码", "coverSubSceneCode", "", "", "", "", "", "", "")); + cellFormatBeans.add(new CellFormatBean("覆盖子场景", "coverSubScene", "", "", "", "", "", "", "")); + } + + @Override + public List list(YwSceneNetelementWxParam para) { + PageUtils.startPage(para, YwSceneNetelementWxParam.class); + List wxes = ywSceneNetelementWxMapper.listAll(para); + wxes.forEach(x -> { + if (InRedLine.IN_RED_LINE.getCode().equals(x.getInRedline())) { + x.setInRedline(InRedLine.IN_RED_LINE.getLabel()); + } else if (InRedLine.NOT_IN_RED_LINE.getCode().equals(x.getInRedline())) { + x.setInRedline(InRedLine.NOT_IN_RED_LINE.getLabel()); + } + x.setEnodebidStr(StringUtils.nonNullString(x.getEnodebid())); + x.set本地小区标识Str(StringUtils.nonNullString(x.get本地小区标识())); + x.set小区标识Str(StringUtils.nonNullString(x.get小区标识())); + x.set站号Str(StringUtils.nonNullString(x.get站号())); + x.set频点Str(StringUtils.nonNullString(x.get频点())); + x.setPciStr(StringUtils.nonNullString(x.getPci())); + x.setTacStr(StringUtils.nonNullString(x.getTac())); + x.set带宽Str(StringUtils.nonNullString(x.get带宽())); + x.set方位角Str(StringUtils.nonNullString(x.get方位角())); + x.set经度Str(StringUtils.nonNullString(x.get经度())); + x.set纬度Str(StringUtils.nonNullString(x.get纬度())); + x.setCity(StringUtils.isNotEmpty(x.get地市()) ? DictUtils.getDictLabel("yw_city", x.get地市()) : null); + x.setCounty(StringUtils.isNotEmpty(x.get县市()) ? DictUtils.getDictLabel("yw_county", x.get县市()) : null); + }); + return wxes; + } + + @Override + public List list2(YwSceneNetelementWxParam para) { + PageUtils.startPage(para, YwSceneNetelementWxParam.class); + List wxes = ywSceneNetelementWxMapper.listAll2(para); + return wxes; + } + + @Override + public List listCell(YwSceneNetelementWxParam param) { + PageUtils.clearPage(); + List list = ywSceneNetelementWxMapper.listAll(param); + list = list.stream().filter(e -> null != e.get小区名称() && !e.get小区名称().equals("")).collect(Collectors.toList()); + for (YwSceneNetelementWx netelementWx : list) { + if (netelementWx.getAreacountyid() != null && !netelementWx.getAreacountyid().equals("")) + netelementWx.setCity(netelementWx.getAreacountyid().substring(0, 4)); + } + return list; + } + + + @Override + public List listSeat(Long sceneId) { + PageUtils.clearPage(); + List list = ywSceneNetelementWxMapper.listSeatId(sceneId); + list = list.stream().filter(e -> null != e.get坐席编号() && !e.get坐席编号().equals("")).collect(Collectors.toList()); + return list; + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNoticeinfoServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNoticeinfoServiceImpl.java new file mode 100644 index 0000000..9817da3 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneNoticeinfoServiceImpl.java @@ -0,0 +1,272 @@ +package com.ruoyi.eastcom_yw.service.impl; + + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneNoticeinfoSearchDTO; +import com.ruoyi.eastcom_yw.domain.vo.*; +import com.ruoyi.eastcom_yw.importer.ImporterSceneNoticeinfo; +import com.ruoyi.eastcom_yw.mapper.*; +import com.ruoyi.eastcom_yw.service.YwSceneNoticeinfoService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.yaml.snakeyaml.util.ArrayUtils; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * (YwSceneNoticeinfo)表服务实现类 + * + * @author lee + * @since 2023-05-23 10:10:42 + */ +@Service("ywSceneNoticeinfoService") +@RequiredArgsConstructor +public class YwSceneNoticeinfoServiceImpl extends ServiceImpl implements YwSceneNoticeinfoService { + + private final YwSceneNoticeinfoMapper ywSceneNoticeinfoMapper; + + private final YwSceneMapper ywSceneMapper; + + private final YwSceneNetelementMapper ywSceneNetelementMapper; + + private final YwSceneNetelementWxMapper ywSceneNetelementWxMapper; + private final YwSceneNetelementCsMapper ywSceneNetelementCsMapper; + private final YwSceneNetelementDhMapper ywSceneNetelementDhMapper; + private final YwSceneNetelementAgisMapper ywSceneNetelementAgisMapper; + + /** + * 通过条件查询 + * + * @param ywSceneNoticeinfo 条件 + * @return 数据 + */ + @Override + public List getNoticeinfoBySearch(YwSceneNoticeinfoSearchDTO ywSceneNoticeinfo) { + List ywSceneNoticeinfos = ywSceneNoticeinfoMapper.selectBySearch(ywSceneNoticeinfo); + for (YwSceneNoticeinfo sceneNoticeinfo : ywSceneNoticeinfos) { + if (sceneNoticeinfo.getId() == 1) { + sceneNoticeinfo.setSceneName("合计"); + break; + } + } + return ywSceneNoticeinfos; + } + + public static T calculateDynamicFieldSums(Boolean isNet,List entities, Class clazz) { + + T sumEntity; + try { + sumEntity = clazz.getDeclaredConstructor().newInstance(); + Field[] fields = clazz.getDeclaredFields(); + + //只处理网元类的 + if(isNet) { + List netColumn = new ArrayList<>(); + netColumn.add("wxNetNum"); + netColumn.add("dhNetNum"); + netColumn.add("agisNetNum"); + netColumn.add("agisNum"); + netColumn.add("wifiNetNum"); + netColumn.add("voipNetNum"); + netColumn.add("publicTransportEquipNum"); + fields = Arrays.stream(fields).filter(x -> netColumn.contains(x.getName())).toArray(Field[]::new); + } + + for (Field field : fields) { + + if (isNumericField(field.getType())) { + field.setAccessible(true); + int fieldValueSum = 0; + + for (T entity : entities) { + if (field.get(entity) != null) { + int fieldValue = (int) field.get(entity); + fieldValueSum += fieldValue; + } + } + + field.set(sumEntity, fieldValueSum); + } + } + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + return sumEntity; + } + + private static boolean isNumericField(Class fieldType) { + return fieldType == int.class || fieldType == Integer.class; + } + + /** + * 批量导入 + * + * @param ywSceneNoticeinfos 数据 + * @param importType 导入模式 + * @return 导入结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult batchImport(List ywSceneNoticeinfos, String importType) throws Exception { + ImporterBase importer = new ImporterSceneNoticeinfo(ywSceneNoticeinfoMapper, ywSceneMapper); + return importer.doAdd(ywSceneNoticeinfos, null, importType); + } + + @Override + public void reset(Boolean isNet) { + YwSceneNoticeinfoSearchDTO ywSceneNoticeinfo = new YwSceneNoticeinfoSearchDTO(); + ywSceneNoticeinfo.setPageNum(null); + ywSceneNoticeinfo.setPageSize(null); + List allVos = ywSceneNoticeinfoMapper.selectBySearch(ywSceneNoticeinfo); + allVos.remove(0); + YwSceneNoticeinfo sum = calculateDynamicFieldSums(isNet,allVos, YwSceneNoticeinfo.class); + //蓝色雨季: + //专网的根据网元名称去重统计 + // + //蓝色雨季: + //动环的是根据物理站名去重统计 + // + //蓝色雨季: + //传输是根据A端网元去重统计 + // + //蓝色雨季: + //无线也要根据小区ci去重 + //所有原来统计出来各个场馆的告警的4个数据不正确,需要重新取 + Integer [] res =ywSceneNetelementMapper.getNetelementNum(); + //wx + sum.setWxNetNum(res[0]); + //dh + sum.setDhNetNum(res[1]); + //cs + sum.setPublicTransportEquipNum(res[2]); + // agis+wifi+voip + sum.setAgisNetNum(res[3]+res[4]+res[5]); + //agis + sum.setAgisNum(res[3]); + //wifi + sum.setWifiNetNum(res[4]); + //voip + sum.setVoipNetNum(res[5]); + sum.setId(1L); + ywSceneNoticeinfoMapper.updateById(sum); + } + + @Override + @Transactional + public void statisticsNetNum() { + List noticeinfos = ywSceneNoticeinfoMapper.selectBySearch(null); + //无线网元数 + Map wxMap = ywSceneNetelementWxMapper.listAll(null).stream().collect(Collectors.groupingBy(YwSceneNetelementWx::getSceneId, Collectors.summingInt(e -> 1))); + //专网网元数 + Map agisMap = ywSceneNetelementAgisMapper.listAll(null).stream().collect(Collectors.groupingBy(YwSceneNetelementAgis::getSceneId, Collectors.summingInt(e -> 1))); + Map agisNumMap = ywSceneNetelementAgisMapper.listAll(null).stream().filter(l->"agis".equals(l.getAlarmSpecityId())).collect(Collectors.groupingBy(YwSceneNetelementAgis::getSceneId, Collectors.summingInt(e -> 1))); + Map wifiMap = ywSceneNetelementAgisMapper.listAll(null).stream().filter(l->"wifi".equals(l.getAlarmSpecityId())).collect(Collectors.groupingBy(YwSceneNetelementAgis::getSceneId, Collectors.summingInt(e -> 1))); + Map voipMap = ywSceneNetelementAgisMapper.listAll(null).stream().filter(l->"voip".equals(l.getAlarmSpecityId())).collect(Collectors.groupingBy(YwSceneNetelementAgis::getSceneId, Collectors.summingInt(e -> 1))); + //动环网元数 + Map dhMap = ywSceneNetelementDhMapper.listAll(null).stream().collect(Collectors.groupingBy(YwSceneNetelementDh::getSceneId, Collectors.summingInt(e -> 1))); + //公网传输设备 + Map csMap = ywSceneNetelementCsMapper.listAll(null).stream().collect(Collectors.groupingBy(YwSceneNetelementCs::getSceneId, Collectors.summingInt(e -> 1))); + //专网传输设备 +// ywSceneNetelementAgisService.list(); + + ArrayList list = new ArrayList<>(); + for (YwSceneNoticeinfo noticeinfo : noticeinfos) { + YwSceneNoticeinfo sceneNoticeinfo = new YwSceneNoticeinfo(); + sceneNoticeinfo.setId(noticeinfo.getId()); + boolean flag = false; + + + Integer wxReal = wxMap.get(noticeinfo.getSceneId()); + Integer wx = noticeinfo.getWxNetNum(); + if (wxReal == null && (wx == null || wx != 0)) { + sceneNoticeinfo.setWxNetNum(0); + flag = true; + } else if (wxReal != null && !wxReal.equals(wx)) { + sceneNoticeinfo.setWxNetNum(wxReal); + flag = true; + } + + Integer agisReal = agisMap.get(noticeinfo.getSceneId()); +// agis+wifi+voip + Integer agis = noticeinfo.getAgisNetNum(); + if (agisReal == null && (agis == null || agis != 0)) { + sceneNoticeinfo.setAgisNetNum(0); + flag = true; + } else if (agisReal != null && !agisReal.equals(agis)) { + sceneNoticeinfo.setAgisNetNum(agisReal); + flag = true; + } + + Integer agisNumReal = agisNumMap.get(noticeinfo.getSceneId()); + Integer agisNum = noticeinfo.getAgisNum(); + if (agisNumReal == null && (agisNum == null || agisNum != 0)) { + sceneNoticeinfo.setAgisNum(0); + flag = true; + } else if (agisNumReal != null && !agisNumReal.equals(agis)) { + sceneNoticeinfo.setAgisNum(agisNumReal); + flag = true; + } + + Integer wifiReal = wifiMap.get(noticeinfo.getSceneId()); + Integer wifi = noticeinfo.getWifiNetNum(); + if (wifiReal == null && (wifi == null || wifi != 0)) { + sceneNoticeinfo.setWifiNetNum(0); + sceneNoticeinfo.setInternetNetNum(0); + flag = true; + } else if (wifiReal != null && !wifiReal.equals(agis)) { + sceneNoticeinfo.setWifiNetNum(wifiReal); + sceneNoticeinfo.setInternetNetNum(wifiReal); + flag = true; + } + + Integer voipReal = voipMap.get(noticeinfo.getSceneId()); + Integer voip = noticeinfo.getVoipNetNum(); + if (voipReal == null && (voip == null || voip != 0)) { + sceneNoticeinfo.setVoipNetNum(0); + flag = true; + } else if (voipReal != null && !voipReal.equals(agis)) { + sceneNoticeinfo.setVoipNetNum(voipReal); + flag = true; + } + + Integer dhReal = dhMap.get(noticeinfo.getSceneId()); + Integer dh = noticeinfo.getDhNetNum(); + if (dhReal == null && (dh == null || dh != 0)) { + sceneNoticeinfo.setDhNetNum(0); + flag = true; + } else if (dhReal != null && !dhReal.equals(dh)) { + sceneNoticeinfo.setDhNetNum(dhReal); + flag = true; + } + + Integer csReal = csMap.get(noticeinfo.getSceneId()); + Integer cs = noticeinfo.getPublicTransportEquipNum(); + if (csReal == null && (cs == null || cs != 0)) { + sceneNoticeinfo.setPublicTransportEquipNum(0); + flag = true; + } else if (csReal != null && !csReal.equals(cs)) { + sceneNoticeinfo.setPublicTransportEquipNum(csReal); + flag = true; + } + + if (flag) { + list.add(sceneNoticeinfo); + } + } + updateBatchById(list); + //调用一次重置总和 + reset(true); + } + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwScenePictureServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwScenePictureServiceImpl.java new file mode 100644 index 0000000..16cb8b9 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwScenePictureServiceImpl.java @@ -0,0 +1,724 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.domain.YwSceneCalendar; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSignLogDTO; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectStatParam; +import com.ruoyi.eastcom_yw.domain.vo.*; +import com.ruoyi.eastcom_yw.mapper.*; +import com.ruoyi.eastcom_yw.service.YwAlarmViewService; +import com.ruoyi.eastcom_yw.service.YwRoutInspectPlanService; +import com.ruoyi.eastcom_yw.service.YwScenePictureService; +import com.ruoyi.eastcom_yw.service.YwSignLogViewService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.ParseException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author los + */ +@RequiredArgsConstructor +@Service("ywScenePictureServiceImpl") +public class YwScenePictureServiceImpl implements YwScenePictureService { + + private final YwSignLogViewService ywSignLogViewService; + private final YwAlarmViewService ywAlarmViewService; + private final YwRoutInspectPlanService ywRoutInspectPlanService; + + private final YwScenePictureMapper ywScenePictureMapper; + private final YwSceneCalendarMapper ywSceneCalendarMapper; + + private final YwAlarmStatisticsMapper ywAlarmStatisticsMapper; + private final YwSceneNoticeinfoMapper ywSceneNoticeinfoMapper; + + private final YwSignLogViewMapper ywSignLogViewMapper; + + + /** + * 任务管理 + * + * @param id 场馆id + * @return 统计值 + */ + @Override + public JSONObject listTaskManage(Long id) { + JSONObject jsonObject = new JSONObject(); + YwRoutInspectStatParam ywRoutInspectStatParam = new YwRoutInspectStatParam(); + ywRoutInspectStatParam.setVenueIds(new Long[]{id}); + + String date = DateUtils.getDate(); + + ywRoutInspectStatParam.setBeginDate(date); + ywRoutInspectStatParam.setEndDate(date + " 23:59:59"); + ywRoutInspectStatParam.setTaskFlag(true); + + // 巡检正常率 + Map resultStatData = ywRoutInspectPlanService.getResultStatData(ywRoutInspectStatParam); + + // 巡检完成率 + Map statData = ywRoutInspectPlanService.getStatData(ywRoutInspectStatParam); + + // 布线完成率 + /*Integer numOfBxAll = ywScenePictureMapper.getNumOfBXALL(id); + Integer numOfBxComplete = ywScenePictureMapper.getNumOfBXComplete(id); + double rateBxComplete = 0.00d; + if (numOfBxAll != 0) { + rateBxComplete = BigDecimal.valueOf((numOfBxComplete.doubleValue() / numOfBxAll) * 100) + .setScale(2, RoundingMode.HALF_UP).doubleValue(); + }*/ + + // 应巡检数、实巡检数、异常巡检数 + jsonObject.put("xjNumOfAllPlan", statData.get("numOfAllPlan")); + jsonObject.put("xjNumOfCompletedPlan", statData.get("numOfCompletedPlan")); + jsonObject.put("xjNumOfQuesPlan", (Integer) resultStatData.get("numOfAllPlan") - (Integer) resultStatData.get("numOfNoQuPlan")); + + return jsonObject; + } + + /** + * 人员签到 + * + * @param id 场馆id + * @return 统计值 + */ + @Override + public JSONObject listSign(Long id) { + JSONObject jsonObject = new JSONObject(); + + YwSignLogDTO ywSignLogDTO = new YwSignLogDTO(); + ywSignLogDTO.setVenueIds(new Long[]{id}); + ywSignLogDTO.setGenTime(true); + ywSignLogDTO.setStartDate(DateUtils.parseDateToStr("yyyy-MM-dd", DateUtils.getNowDate())); + ywSignLogDTO.setEndDate(DateUtils.parseDateToStr("yyyy-MM-dd", DateUtils.getNowDate())+" 23:59:59"); + ywSignLogDTO.setToday(true); + + List signLogStatic = ywSignLogViewMapper.getSignLogStatic20231012(ywSignLogDTO); + + if (signLogStatic == null || signLogStatic.size() == 0) { + // 应签到数/实签到数/签到率 + jsonObject.put("signAllNum", 0); + jsonObject.put("signFinishNum",0); + jsonObject.put("signFinishRate",0.0); + + } + else { + // 应签到数/实签到数/签到率 + jsonObject.put("signAllNum", signLogStatic.get(0).getAllNum()); + jsonObject.put("signFinishNum", signLogStatic.get(0).getFinishNum()); + jsonObject.put("signFinishRate", BigDecimal.valueOf(signLogStatic.get(0).getFinishRate() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue()); + } + return jsonObject; + } + + /** + * 场馆基本信息 + * + * @param id 场馆id + * @return 统计值 + */ + @Override + public JSONObject listMatchTop3(Long id) { + JSONObject jsonObject = new JSONObject(); + + // 简报用 + YwSceneNoticeinfo ywSceneNoticeinfo = new YwSceneNoticeinfo(); + List ywSceneNoticeinfos = ywSceneNoticeinfoMapper.selectBySceneId(id); + if (CollectionUtil.isNotEmpty(ywSceneNoticeinfos)) { + ywSceneNoticeinfo = ywSceneNoticeinfos.get(0); + } + //无线网元数 + jsonObject.put("wxNetNum", ywSceneNoticeinfo.getWxNetNum()); + //AGIS网元数 + jsonObject.put("agisNetNum", ywSceneNoticeinfo.getAgisNetNum()); + //互联网网元数 + jsonObject.put("internetNetNum", ywSceneNoticeinfo.getInternetNetNum()); + //公网传输设备 + jsonObject.put("publicTransportEquipNum", ywSceneNoticeinfo.getPublicTransportEquipNum()); + //公网接入环 + jsonObject.put("publicInterfaceRingNum", ywSceneNoticeinfo.getPublicInterfaceRingNum()); + //专网传输设备 + jsonObject.put("privateTransportEquipNum", ywSceneNoticeinfo.getPrivateTransportEquipNum()); + //专网接入环 + jsonObject.put("privateInterfaceRingNum", ywSceneNoticeinfo.getPrivateInterfaceRingNum()); + //现场保障人员 + jsonObject.put("frontUser", ywSceneNoticeinfo.getFrontuser()); + //后台保障人员 + jsonObject.put("backUser", ywSceneNoticeinfo.getBackuser()); + //场馆部署应急车 + jsonObject.put("emergencyCarNum", ywSceneNoticeinfo.getEmergencycar()); + //场馆部署应急仓 + jsonObject.put("emergencyWarehouse", ywSceneNoticeinfo.getEmergencyWarehouse()); + Map alarmMap = getAlarmStatisticsAccordingSceneId(id, "Y"); + //AGIS专网 未恢复告警数 + jsonObject.put("agisAlarm", alarmMap.get("agis")); + //无线 未恢复告警数 + jsonObject.put("wxAlarm", alarmMap.get("wx")); + //wifi 未恢复告警数 + jsonObject.put("wifiAlarm", alarmMap.get("wifi")); + //专网传输 未恢复告警数 + jsonObject.put("privateAlarm", alarmMap.get("agis")); + //公网传输 未恢复告警数 + jsonObject.put("publicAlarm", alarmMap.get("cs")); + + Map n = getAlarmStatisticsAccordingSceneId(id, "N"); + //AGIS专网 未恢复告警数 红线外 + jsonObject.put("agisAlarmBydRedLine", n.get("agis")); + //无线 未恢复告警数 红线外 + jsonObject.put("wxAlarmBydRedLine", n.get("wx")); + //专网传输 未恢复告警数 红线外 + jsonObject.put("privateAlarmBydRedLine", n.get("agis")); + //公网传输 未恢复告警数 红线外 + jsonObject.put("publicAlarmBydRedLine", n.get("cs")); + /*//总体情况:告警数 + jsonObject.put("totalAlarm", alarmMap.get("wx") + alarmMap.get("cs") + alarmMap.get("dh") + alarmMap.get("agis")); + //传输情况:告警数 + jsonObject.put("csAlarm", alarmMap.get("cs")); + //45G公网情况:告警数 + jsonObject.put("publicAlarm", alarmMap.get("wx") + alarmMap.get("cs") + alarmMap.get("dh"));*/ + /*//总体情况:红线内外网元总数 + jsonObject.put("netTotalNum", ywSceneNoticeinfo.getNetTotalNum()); + //传输情况:传输设备 + jsonObject.put("transportEquipNum", ywSceneNoticeinfo.getTransportEquipNum()); + //传输情况:接入环 + jsonObject.put("interfaceRingNum", ywSceneNoticeinfo.getInterfaceRingNum()); + //45G公网情况:网元总数 + jsonObject.put("publicNetNum", ywSceneNoticeinfo.getPublicNetNum());*/ + + // 场馆画像用 + /*YwSceneNetelementWxParam param1 = new YwSceneNetelementWxParam(); + param1.setSceneId(id); + List wx = ywSceneNetelementWxMapper.listAll(param1); + if (wx != null) { + jsonObject.put("netNum", wx.size()); + } else { + jsonObject.put("netNum", 0); + } + YwSceneNetelementCsParam param2 = new YwSceneNetelementCsParam(); + param2.setSceneId(id); + List cs = ywSceneNetelementCsMapper.listAll(param2); + if (cs != null) { + jsonObject.put("equipNum", cs.size()); + } else { + jsonObject.put("equipNum", 0); + }*/ + jsonObject.put("netNum", ywSceneNoticeinfo.getNetTotalNum()); + jsonObject.put("equipNum", ywSceneNoticeinfo.getTransportEquipNum()); + + if (id == 2) { + jsonObject.put("manager", "李前兴"); + jsonObject.put("phone", "15088689169"); + } else if (id == 25) { + jsonObject.put("manager", "周珍"); + jsonObject.put("phone", "15868882228"); + } else { + List manager = ywScenePictureMapper.selectManagerInfoBySceneId(id); + if (manager != null && manager.size() > 0) { + jsonObject.put("manager", manager.get(0).getManagerName()); + jsonObject.put("phone", manager.get(0).getPhone()); + } else { + jsonObject.put("manager", null); + jsonObject.put("phone", null); + } + } + + + Date dateDay = null; + Date dateTime = null; + + try { + dateDay = DateUtils.parseDate(DateUtils.parseDateToStr("yyyy-MM-dd", DateUtils.getNowDate()), "yyyy-MM-dd"); + dateTime = DateUtils.parseDate(DateUtils.parseDateToStr("HH:mm:ss", DateUtils.getNowDate()), "HH:mm:ss"); + } catch (ParseException e) { + e.printStackTrace(); + } + List calendarList = null; + if (dateDay != null && dateTime != null) { + calendarList = ywSceneCalendarMapper.selectByMatchDateAndSceneIdAndEndTimeGreaterThanEqualOrderByBeginTime(dateDay, id, dateTime); + for (YwSceneCalendar ywSceneCalendar : calendarList) { + if (StringUtils.isNotEmpty(ywSceneCalendar.getMatchType())) { + // 赛事图标 + ywSceneCalendar.setUrl("/profile/upload/matchicon/" + ywSceneCalendar.getMatchType() + ".png"); + //场馆画像版赛事图标 + ywSceneCalendar.setScenePictureUrl("/profile/upload/scenePictureMatchicon/" + ywSceneCalendar.getMatchType() + ".png"); + ywSceneCalendar.setMatchType(DictUtils.getDictLabel("yw_match_type", ywSceneCalendar.getMatchType())); + } + } + } + jsonObject.put("matchTop", calendarList); + return jsonObject; + } + + public void generateAlarmStatisticsEvery5Minutes() { + Calendar instance = Calendar.getInstance(); + instance.add(Calendar.MINUTE, 1); + instance.set(Calendar.SECOND, 0); + instance.set(Calendar.MILLISECOND, 0); + Date now = instance.getTime(); + YwAlarmDTO ywAlarmDTO = new YwAlarmDTO(); + // 去除分页 + ywAlarmDTO.setPageNum(1); + ywAlarmDTO.setPageSize(Integer.MAX_VALUE); + // 查实时的 + ywAlarmDTO.setAlarmStatus("0"); + // 排除挂起的 + ywAlarmDTO.setDealStatus("1"); + // 排除红线外的 + ywAlarmDTO.setInRedLine("Y"); + // 不需要排序 + ywAlarmDTO.setOrderByTime("no"); + + String[] alarmTypes = new String[]{"wx", "cs", "dh", "agis"}; + Map> alarmMap = new HashMap<>(4); + for (String alarmType : alarmTypes) { + // 查相应专业的 + ywAlarmDTO.setAlarmType(alarmType); + // 过滤掉故障数清零的 + List ywAlarmByDto = ywAlarmViewService.getYwAlarmByDto(ywAlarmDTO).stream(). + filter(x -> !x.getClearNumDisplay().split("/")[0].equals(x.getClearNumDisplay().split("/")[1])). + collect(Collectors.toList()); + alarmMap.put(alarmType, ywAlarmByDto); + } + + List ywAlarmStatistics = new ArrayList<>(); + for (String next : alarmMap.keySet()) { + Set sceneSet = new HashSet<>(); + List ywAlarmViewVos = alarmMap.get(next); + for (YwAlarmViewVo ywAlarmViewVo : ywAlarmViewVos) { + if (ywAlarmViewVo.getVenueId() != null) { + sceneSet.add(ywAlarmViewVo.getVenueId()); + } + } + for (Integer integer : sceneSet) { + YwAlarmStatistics ywAlarmStatistics1 = new YwAlarmStatistics(); + int count = 0; + for (YwAlarmViewVo ywAlarmViewVo : ywAlarmViewVos) { + if (Objects.equals(integer, ywAlarmViewVo.getVenueId())) { + count++; + } + } + ywAlarmStatistics1.setSceneId(Long.valueOf(integer)); + ywAlarmStatistics1.setNum((long) count); + ywAlarmStatistics1.setProfession(next); + ywAlarmStatistics1.setCreateTime(now); + ywAlarmStatistics.add(ywAlarmStatistics1); + } + } + + if(ywAlarmStatistics.size()>0) { + ywAlarmStatisticsMapper.deleteByCreateTimeBefore(); + ywAlarmStatisticsMapper.insertBatch(ywAlarmStatistics); + } + } + + /** + * 中小屏场馆画像-巡检统计数据 + * + * @param id 场馆id + * @return + */ + @Override + public JSONObject listTaskManage2(Long id,Boolean taskFlag) { + JSONObject jsonObject = new JSONObject(); + YwRoutInspectStatParam ywRoutInspectStatParam = new YwRoutInspectStatParam(); + ywRoutInspectStatParam.setVenueIds(new Long[]{id}); + + LocalDateTime now = LocalDateTime.now(); + +// String date = DateUtils.getDate(); + + String date = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); + + ywRoutInspectStatParam.setBeginDate(date); + + String time = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + + ywRoutInspectStatParam.setEndDate(time); + + ywRoutInspectStatParam.setTaskFlag(taskFlag); + + // 巡检正常率 + Map resultStatData = ywRoutInspectPlanService.getResultStatData(ywRoutInspectStatParam); + + // 巡检完成率 + Map statData = ywRoutInspectPlanService.getStatData(ywRoutInspectStatParam); + + // 应巡检数、实巡检数、异常巡检数 + jsonObject.put("xjNumOfAllPlan", statData.get("numOfAllPlan")); + jsonObject.put("xjNumOfCompletedPlan", statData.get("numOfCompletedPlan")); + jsonObject.put("xjNumOfQuesPlan", (Integer) resultStatData.get("numOfAllPlan") - (Integer) resultStatData.get("numOfNoQuPlan")); + + return jsonObject; + } + + /** + * 场馆告警 + * + * @param id 场馆id + * @return 统计值 + */ + @Override + public JSONObject listAlarm(Long id) { + + Map alarmMap = getAlarmStatisticsAccordingSceneId(id, "Y"); + + /*List xaxis = new ArrayList<>(); + List value = new ArrayList<>(); + List value2 = new ArrayList<>(); + List value3 = new ArrayList<>(); + List value4 = new ArrayList<>(); + + Calendar instance = Calendar.getInstance(); + instance.set(Calendar.SECOND, 0); + instance.set(Calendar.MILLISECOND, 0); + Date now = instance.getTime(); + instance.add(Calendar.MINUTE, -15); + Date nowMinus15Min = instance.getTime(); + instance.add(Calendar.MINUTE, -15); + Date nowMinus30Min = instance.getTime(); + instance.add(Calendar.MINUTE, -15); + Date nowMinus45Min = instance.getTime();*/ + + JSONObject jsonObject = new JSONObject(); +/* + xaxis.add(DateUtils.parseDateToStr("HH:mm", nowMinus45Min)); + xaxis.add(DateUtils.parseDateToStr("HH:mm", nowMinus30Min)); + xaxis.add(DateUtils.parseDateToStr("HH:mm", nowMinus15Min)); + xaxis.add(DateUtils.parseDateToStr("HH:mm", now)); + + YwAlarmStatistics ywWxAlarmStatistics15 = ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus15Min, "wx").size() == 0 ? null : ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus15Min, "wx").get(0); + YwAlarmStatistics ywWxAlarmStatistics30 = ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus30Min, "wx").size() == 0 ? null : ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus30Min, "wx").get(0); + YwAlarmStatistics ywWxAlarmStatistics45 = ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus45Min, "wx").size() == 0 ? null : ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus45Min, "wx").get(0); + YwAlarmStatistics ywCsAlarmStatistics15 = ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus15Min, "cs").size() == 0 ? null : ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus15Min, "cs").get(0); + YwAlarmStatistics ywCsAlarmStatistics30 = ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus30Min, "cs").size() == 0 ? null : ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus30Min, "cs").get(0); + YwAlarmStatistics ywCsAlarmStatistics45 = ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus45Min, "cs").size() == 0 ? null : ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus45Min, "cs").get(0); + YwAlarmStatistics ywDhAlarmStatistics15 = ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus15Min, "dh").size() == 0 ? null : ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus15Min, "dh").get(0); + YwAlarmStatistics ywDhAlarmStatistics30 = ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus30Min, "dh").size() == 0 ? null : ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus30Min, "dh").get(0); + YwAlarmStatistics ywDhAlarmStatistics45 = ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus45Min, "dh").size() == 0 ? null : ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus45Min, "dh").get(0); + YwAlarmStatistics ywAgisAlarmStatistics15 = ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus15Min, "agis").size() == 0 ? null : ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus15Min, "agis").get(0); + YwAlarmStatistics ywAgisAlarmStatistics30 = ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus30Min, "agis").size() == 0 ? null : ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus30Min, "agis").get(0); + YwAlarmStatistics ywAgisAlarmStatistics45 = ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus45Min, "agis").size() == 0 ? null : ywAlarmStatisticsMapper.selectBySceneIdAndCreateTimeAndProfession(id, nowMinus45Min, "agis").get(0); + + value.add(null == ywWxAlarmStatistics45 ? 0 : ywWxAlarmStatistics45.getNum().intValue()); + value.add(null == ywWxAlarmStatistics30 ? 0 : ywWxAlarmStatistics30.getNum().intValue()); + value.add(null == ywWxAlarmStatistics15 ? 0 : ywWxAlarmStatistics15.getNum().intValue()); + value.add(alarmMap.get("wx")); + + value2.add(null == ywCsAlarmStatistics45 ? 0 : ywCsAlarmStatistics45.getNum().intValue()); + value2.add(null == ywCsAlarmStatistics30 ? 0 : ywCsAlarmStatistics30.getNum().intValue()); + value2.add(null == ywCsAlarmStatistics15 ? 0 : ywCsAlarmStatistics15.getNum().intValue()); + value2.add(alarmMap.get("cs")); + + value3.add(null == ywDhAlarmStatistics45 ? 0 : ywDhAlarmStatistics45.getNum().intValue()); + value3.add(null == ywDhAlarmStatistics30 ? 0 : ywDhAlarmStatistics30.getNum().intValue()); + value3.add(null == ywDhAlarmStatistics15 ? 0 : ywDhAlarmStatistics15.getNum().intValue()); + value3.add(alarmMap.get("dh")); + + value4.add(null == ywAgisAlarmStatistics45 ? 0 : ywAgisAlarmStatistics45.getNum().intValue()); + value4.add(null == ywAgisAlarmStatistics30 ? 0 : ywAgisAlarmStatistics30.getNum().intValue()); + value4.add(null == ywAgisAlarmStatistics15 ? 0 : ywAgisAlarmStatistics15.getNum().intValue()); + value4.add(alarmMap.get("agis"));*/ + +// jsonObject.put("xaxis", xaxis); + jsonObject.put("wx", alarmMap.get("wx")); + jsonObject.put("cs", alarmMap.get("cs")); + jsonObject.put("dh", alarmMap.get("dh")); + jsonObject.put("agis", alarmMap.get("agis")); + jsonObject.put("wifi", alarmMap.get("wifi")); + jsonObject.put("voip", alarmMap.get("voip")); + jsonObject.put("public", alarmMap.get("wx") + alarmMap.get("cs") + alarmMap.get("dh")); + jsonObject.put("private", alarmMap.get("agis") + alarmMap.get("wifi") + alarmMap.get("voip")); + + return jsonObject; + + } + + /** + * 场馆性能(15分粒度) + * + * @param id 场馆id + * @param typeId 4g5g + * @return 统计数据 + */ + @Override + public JSONObject listKPI(Long id, String typeId) { + + JSONObject jsonObject = new JSONObject(); + List list = ywScenePictureMapper.getLineChartKpi(id, typeId); + List xaxis = new ArrayList<>(); + List value = new ArrayList<>(); + List value2 = new ArrayList<>(); + List value3 = new ArrayList<>(); + List value4 = new ArrayList<>(); + List value5 = new ArrayList<>(); + List value6 = new ArrayList<>(); + Float maxUserNum = 0f; + Float avgInterfere = 0f; + Float flux = 0f; + Float wirelessCompletionRate = 0f; + + if (list != null && list.size() == 0) { + Calendar instance = Calendar.getInstance(); + instance.set(Calendar.SECOND, 0); + instance.set(Calendar.MILLISECOND, 0); + Date now = instance.getTime(); + instance.add(Calendar.MINUTE, -15); + Date nowMinus15Min = instance.getTime(); + instance.add(Calendar.MINUTE, -15); + Date nowMinus30Min = instance.getTime(); + instance.add(Calendar.MINUTE, -15); + Date nowMinus45Min = instance.getTime(); + instance.add(Calendar.MINUTE, -15); + Date nowMinus60Min = instance.getTime(); + xaxis.add(DateUtils.parseDateToStr("HH:mm", nowMinus60Min)); + xaxis.add(DateUtils.parseDateToStr("HH:mm", nowMinus45Min)); + xaxis.add(DateUtils.parseDateToStr("HH:mm", nowMinus30Min)); + xaxis.add(DateUtils.parseDateToStr("HH:mm", nowMinus15Min)); + xaxis.add(DateUtils.parseDateToStr("HH:mm", now)); + for (int i = 0; i < 5; i++) { + value.add(0f); + value2.add(0f); + value3.add(0f); + value4.add(0f); + value5.add(0f); + value6.add(0f); + } + } else if (list != null) { + for (int i = 0; i < list.size(); i++) { + YwSceneKPIStatisticsVo vo = list.get(i); + xaxis.add(vo.getDatetime()); + value.add(vo.getValue()); + value2.add(vo.getValue2()); + value3.add(vo.getMaxUserNum()); + value4.add(vo.getAvgInterfere()); + value5.add(vo.getFlux()); + value6.add(vo.getWirelessCompletionRate()); + if (i == list.size() - 1) { + maxUserNum = vo.getMaxUserNum(); + avgInterfere = vo.getAvgInterfere(); + flux = vo.getFlux(); + wirelessCompletionRate = vo.getWirelessCompletionRate(); + } + } + } + + jsonObject.put("xaxis", xaxis); + jsonObject.put("value", StringUtils.isNull(value) ? 0f : value); + jsonObject.put("value2", StringUtils.isNull(value2) ? 0f : value2); + jsonObject.put("value3", StringUtils.isNull(value3) ? 0f : value3); + jsonObject.put("value4", StringUtils.isNull(value4) ? 0f : value4); + jsonObject.put("value5", StringUtils.isNull(value5) ? 0f : value5); + jsonObject.put("value6", StringUtils.isNull(value6) ? 0f : value6); + jsonObject.put("maxUserNum", StringUtils.isNull(maxUserNum) ? 0f : maxUserNum); + jsonObject.put("avgInterfere", StringUtils.isNull(avgInterfere) ? 0f : avgInterfere); + jsonObject.put("flux", StringUtils.isNull(flux) ? 0f : flux); + jsonObject.put("wirelessCompletionRate", StringUtils.isNull(wirelessCompletionRate) ? 0f : wirelessCompletionRate); + + return jsonObject; + + } + + @Override + public Map listKPIALL(Long id) { + + Map map = new HashMap<>(); + + JSONObject kpi4g = listKPI(id, "1"); + + map.put("4g", kpi4g); + + + JSONObject kpi5g = listKPI(id, "2"); + + map.put("5g", kpi5g); + + return map; + } + + @Override + public AjaxResult listNetKpi(Long id, Integer type) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + if (type == 1) { + YwSceneNetAgixStaVo netAgixStatis = ywScenePictureMapper.getNetAgixStatis(id, null, null); + if (null != netAgixStatis) { + return AjaxResult.success(netAgixStatis); + } + } else if (type == 2) { + YwSceneNetStaVo netStatis = ywScenePictureMapper.getNetStatis(id, null, null); + if (null != netStatis) { + String statdate = netStatis.getStatdate(); + LocalDateTime endTime = LocalDateTime.parse(statdate, formatter); + LocalDateTime beginTime = endTime.minusHours(3); + netStatis.setList(ywScenePictureMapper.getNetVelocityStatis(id, beginTime, endTime)); + return AjaxResult.success(netStatis); + } + } else if (type == 3) { + YwSceneNetFixtelStaVo netFixtelStatis = ywScenePictureMapper.getNetFixtelStatis(id,null,null); + if (null != netFixtelStatis) { + String statdate = netFixtelStatis.getStatdate(); + LocalDateTime endTime = LocalDateTime.parse(statdate, formatter); + LocalDateTime beginTime = endTime.minusHours(3); + List netFixtelRegSuccStatis = ywScenePictureMapper.getNetFixtelRegSuccStatis(id, beginTime, endTime); + netFixtelStatis.setList(netFixtelRegSuccStatis); + return AjaxResult.success(netFixtelStatis); + } + } + AjaxResult ajaxResult = AjaxResult.success(); + ajaxResult.put("data", null); + return ajaxResult; + } + + @Override + public AjaxResult listTransKpi(Long id, Integer type) { + if (type == 1) { + List gbtop5List = ywScenePictureMapper.getGbtop5List(id); + return AjaxResult.success(gbtop5List); + } else if (type == 2) { + List list = ywScenePictureMapper.getOpticalpowerTop5List(id,5,null,null); + return AjaxResult.success(list); + } + AjaxResult ajaxResult = AjaxResult.success(); + ajaxResult.put("data", null); + return ajaxResult; + } + + /** + * 简报H5版本查询告警详细 + * + * @param id 场馆id + * @return 告警详细 + */ + @Override + public JSONObject getAlarmTopDetail(Long id) { + JSONObject js = new JSONObject(); + YwAlarmDTO ywAlarmDTO = new YwAlarmDTO(); + // 去除分页 + ywAlarmDTO.setPageNum(1); + ywAlarmDTO.setPageSize(Integer.MAX_VALUE); + // 查实时的 + ywAlarmDTO.setAlarmStatus("0"); + // 排除挂起的 + ywAlarmDTO.setDealStatus("1"); + // 排除红线外的 + ywAlarmDTO.setInRedLine("Y"); + // 不要排序 + ywAlarmDTO.setOrderByTime("no"); + List ids = new ArrayList<>(); + ids.add(id); + // 查该场馆的 + ywAlarmDTO.setVenues(ids); + String[] alarmTypes = new String[]{"wx", "cs", "dh", "agis", "wifi", "voip"}; + for (String alarmType : alarmTypes) { + // 查相应专业的 + ywAlarmDTO.setAlarmType(alarmType); + // 过滤掉故障数清零的 + List ywAlarmByDto = ywAlarmViewService.getYwAlarmByDto(ywAlarmDTO).stream(). + filter(x -> !x.getClearNumDisplay().split("/")[0].equals(x.getClearNumDisplay().split("/")[1])). + collect(Collectors.toList()); + LinkedHashMap linkedHashMap = getAlarmDetailAccordingSceneId(ywAlarmByDto); + List otherAlarms = new ArrayList<>(); + Integer cOthers = 0; + int c = 0; + List ywAlarmClassificationDetails = new ArrayList<>(); + for (String k : linkedHashMap.keySet()) { + c++; + if (c > 4) { + otherAlarms.addAll(ywAlarmByDto.stream().filter(x -> k.equals(x.getName())).collect(Collectors.toList())); + cOthers = cOthers + (int) ywAlarmByDto.stream().filter(x -> k.equals(x.getName())).count(); + } else { + YwAlarmClassificationDetail ywAlarmClassificationDetail = new YwAlarmClassificationDetail(); + ywAlarmClassificationDetail.setAlarmName(k); + ywAlarmClassificationDetail.setAlarmList(ywAlarmByDto.stream().filter(x -> k.equals(x.getName())).collect(Collectors.toList())); + ywAlarmClassificationDetail.setAlarmNum((int) ywAlarmByDto.stream().filter(x -> k.equals(x.getName())).count()); + ywAlarmClassificationDetails.add(ywAlarmClassificationDetail); + } + } + if (c > 4) { + YwAlarmClassificationDetail ywAlarmClassificationDetail = new YwAlarmClassificationDetail(); + ywAlarmClassificationDetail.setAlarmName("其他告警"); + ywAlarmClassificationDetail.setAlarmList(otherAlarms); + ywAlarmClassificationDetail.setAlarmNum(cOthers); + ywAlarmClassificationDetails.add(ywAlarmClassificationDetail); + } + js.put(alarmType + "AlarmDetail", JSONArray.parseArray(JSON.toJSONString(ywAlarmClassificationDetails))); + } + return js; + } + + private LinkedHashMap getAlarmDetailAccordingSceneId(List ywAlarmByDto) { + Set alarmNameSet = new HashSet<>(); + Map alarmNameCountMap = new HashMap<>(); + + for (YwAlarmViewVo ywAlarmViewVo : ywAlarmByDto) { + alarmNameSet.add(ywAlarmViewVo.getName()); + } + for (String s : alarmNameSet) { + int count = 0; + for (YwAlarmViewVo ywAlarmViewVo : ywAlarmByDto) { + if (s.equals(ywAlarmViewVo.getName())) { + count++; + } + } + alarmNameCountMap.put(s, count); + } + List> entryList = new ArrayList<>(alarmNameCountMap.entrySet()); + entryList.sort((o1, o2) -> { + //正序排列,倒序反过来 + return o2.getValue() - o1.getValue(); + }); + LinkedHashMap linkedHashMap = new LinkedHashMap<>(); + for (Map.Entry e : entryList) { + linkedHashMap.put(e.getKey(), e.getValue()); + } + + return linkedHashMap; + } + + private Map getAlarmStatisticsAccordingSceneId(Long id, String inRedLine) { + YwAlarmDTO ywAlarmDTO = new YwAlarmDTO(); + // 去除分页 + ywAlarmDTO.setPageNum(1); + ywAlarmDTO.setPageSize(Integer.MAX_VALUE); + // 查实时的 + ywAlarmDTO.setAlarmStatus("0"); + // 排除挂起的 + ywAlarmDTO.setDealStatus("1"); + // 排除红线外的 + ywAlarmDTO.setInRedLine(inRedLine); + // 不要排序 + ywAlarmDTO.setOrderByTime("no"); + List ids = new ArrayList<>(); + ids.add(id); + // 查该场馆的 + ywAlarmDTO.setVenues(ids); + + String[] alarmTypes = new String[]{"wx", "cs", "dh", "agis", "wifi", "voip"}; + Map alarmMap = new HashMap<>(6); + for (String alarmType : alarmTypes) { + // 查相应专业的 + ywAlarmDTO.setAlarmType(alarmType); + // 过滤掉故障数清零的 + List ywAlarmByDto = ywAlarmViewService.getYwAlarmByDto(ywAlarmDTO).stream(). + filter(x -> !x.getClearNumDisplay().split("/")[0].equals(x.getClearNumDisplay().split("/")[1])). + collect(Collectors.toList()); + alarmMap.put(alarmType, ywAlarmByDto.size()); + } + return alarmMap; + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneServiceImpl.java new file mode 100644 index 0000000..b9f1369 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneServiceImpl.java @@ -0,0 +1,706 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.afterturn.easypoi.entity.vo.NormalExcelConstants; +import cn.afterturn.easypoi.excel.ExcelImportUtil; +import cn.afterturn.easypoi.excel.annotation.Excel; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.ImportParams; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.common.collect.Maps; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.ExcelSelector; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.ZipUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.common.utils.file.FileUtils; +import com.ruoyi.common.utils.poi.EasyPoiExcelUtil; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.*; +import com.ruoyi.eastcom_yw.domain.dto.YwDataDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneDTO; +import com.ruoyi.eastcom_yw.domain.param.YwSceneParam; +import com.ruoyi.eastcom_yw.domain.vo.*; +import com.ruoyi.eastcom_yw.importer.ImporterScene; +import com.ruoyi.eastcom_yw.mapper.*; +import com.ruoyi.eastcom_yw.service.*; +import com.ruoyi.system.service.ISysDictDataService; +import lombok.RequiredArgsConstructor; +import org.apache.commons.compress.utils.Lists; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.PostConstruct; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + *

+ * 服务实现类 + *

+ * + * @author jkj + * @since 2023-01-12 + */ +@Service +@RequiredArgsConstructor +public class YwSceneServiceImpl extends ServiceImpl implements YwSceneService { + + private final YwSceneMapper ywSceneMapper; + + private final YwSceneUserMapper ywSceneUserMapper; + + private final ISysDictDataService dictDataService; + private final YwSceneUserService ywSceneUserService; + private final YwSceneAlarmService ywSceneAlarmService; + private final YwSceneCalendarService ywSceneCalendarService; + private final YwSceneNetelementService ywSceneNetelementService; + + private final YwSceneNetelementDhMapper ywSceneNetelementDh; + + private final YwSceneNetelementWxMapper ywSceneNetelementWx; + + private final YwSceneNetelementAgisMapper ywSceneNetelementAgis; + + private final YwSceneNetelementCsMapper ywSceneNetelementCs; + + private final RedisCache redisCache; + + private String key = CacheConstants.YW_VENUES; + + @Value("${file.sceneJsonPath}") + private String sceneJsonPath; + + @PostConstruct + public void init() { + loadingVenueCache(); + } + + @Override + public void loadingVenueCache() { + List list = ywSceneMapper.getAllVenues(); + redisCache.setCacheObject(key, list); + } + + @Override + public List selectVenues() { + + + if (redisCache.hasKey(key)) { + try { + List res = redisCache.getCacheObject(key); + if (ObjectUtils.isEmpty(res)) { + throw new Exception(); + } + return res; + } catch (Exception ex) { + + List list = ywSceneMapper.getAllVenues(); + + redisCache.setCacheObject(key, list); + + return list; + + } + } + + List list = ywSceneMapper.getAllVenues(); + + redisCache.setCacheObject(key, list); + + return list; + } + + @Override + public Object validateUserVenues(Object o, Class clazz, String targetName) { + + try { + SysUser user = SecurityUtils.getLoginUser().getUser(); + //场馆集合 + if (!(user.isAdmin(user) || user.isCenter(user))) { + Field handleField = clazz.getDeclaredField(targetName); + handleField.setAccessible(true); + if("venueIds".equals(targetName)) { + boolean needSet = false; + if (ObjectUtils.isEmpty(handleField.get(o))) { + needSet = true; + } + if (needSet) { + List ywScenes = this.getVenueByUser(user); + Long[] lVenueIds = ywScenes.stream().map(YwScene::getId).toArray(Long[]::new); + handleField.set(o, lVenueIds); + } + } + } + + } + catch (Exception ex) + { + log.error("处理类异常:原因:"+ex.getMessage()); + } + finally { + return o; + } + + } + + /** + * 根据大场景id获取场馆 + * + * @param sceneBigId 大场景id + * @return 场馆 + */ + @Override + public List getVenueByBigId(Long sceneBigId) { + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.eq(sceneBigId != null, YwScene::getSceneBigId, sceneBigId); + List ywSceneList = ywSceneMapper.selectList(lambdaQueryWrapper); + return ywSceneList; + } + + @Override + public List getVenueByUser(SysUser user) { + List list = new ArrayList(); + boolean isAdmin = user.isAdmin(user); + + if (isAdmin) { + list = ywSceneMapper.getVenueByUserId(null); + } + if (!isAdmin) { + + //是否领导角色 + boolean isLeader = user.isLeader(user); + + if (isLeader) { + + list = ywSceneMapper.getVenueByUserId(user.getUserId()); + + if (list.size() == 0) { + + if (StringUtils.isNotEmpty(user.getCounty())) { + list = ywSceneMapper.getVenueByArea(user.getCounty()); + + } else if (StringUtils.isNotEmpty(user.getCity())) { + list = ywSceneMapper.getVenueByArea(user.getCity()); + + } else { + + //如果用户查出来没有配置场馆,就设置一个不能够查询的场馆用户用户查询 + list = ywSceneMapper.getVenueByUserId(null); + } + } + } + + + if (!isLeader) { + //中心库显示全部 + boolean isCenterRole = user.isCenter(user); + if (isCenterRole) { + list = ywSceneMapper.getVenueByUserId(null); + } + if (!isCenterRole) { + list = ywSceneMapper.getVenueByUserId(user.getUserId()); + } + //如果用户查出来没有配置场馆,就设置一个不能够查询的场馆用户用户查询 + if (list.size() == 0) { + YwScene scene = new YwScene(); + scene.setId(-1L); + scene.setVenueName("该用户没有场馆"); + list.add(scene); + } + } + + } + + //查询场馆图片 +// for (YwScene scene : list) { +// Long id = scene.getId(); +// List ywSceneFiles = ywSceneMapper.getFileByCondition(id, null); +// if (CollUtil.isNotEmpty(ywSceneFiles)) { +// scene.setYwSceneFile(ywSceneFiles.get(0)); +// } +// } + + return list; + + } + + @Override + public List getVenueByUserCanNoData(SysUser user,Boolean display) { + List list = new ArrayList(); + if (user.isAdmin(user)) { + if(display) + { + list = ywSceneMapper.getVenueByUserId(null); + } + //list = ywSceneMapper.getVenueByUserId(null); + return list; + } else { + //是否领导角色 + boolean isLeader = user.isLeader(user); + if (isLeader) { + + list = ywSceneMapper.getVenueByUserId(user.getUserId()); + + if (list.size() == 0) { + + if (StringUtils.isNotEmpty(user.getCounty())) { + list = ywSceneMapper.getVenueByArea(user.getCounty()); + + } else if (StringUtils.isNotEmpty(user.getCity())) { + list = ywSceneMapper.getVenueByArea(user.getCity()); + } else { + if(display) + { + list = ywSceneMapper.getVenueByUserId(null); + } + return list; + } + } + } + if (!isLeader) { + //中心库显示全部 + boolean isCenterRole = user.isCenter(user); + if (isCenterRole) { + if(display) + { + list = ywSceneMapper.getVenueByUserId(null); + } + return list; + } + if (!isCenterRole) { + list = ywSceneMapper.getVenueByUserId(user.getUserId()); + } + //如果用户查出来没有配置场馆,就设置一个不能够查询的场馆用户用户查询 + if (list.size() == 0) { + YwScene scene = new YwScene(); + scene.setId(-1L); + scene.setVenueName("该用户没有场馆"); + list.add(scene); + } + } + } + + return list; + } + + + @Override + public List getVenueByUser(SysUser user, Long sceneBigId) { + List list = new ArrayList(); + + //如果大场景是空的,则获取status为2的默认大场景 + if (ObjectUtils.isEmpty(sceneBigId)) { + sceneBigId = ywSceneMapper.getCurrentSceneBigId(); + } + + if (user.isAdmin(user)) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(YwScene::getSceneBigId, sceneBigId); + wrapper.orderByAsc(YwScene::getId); + list = ywSceneMapper.selectList(wrapper); + } else { + //是否领导角色 + boolean isLeader = user.isLeader(user); + if (isLeader) { + list = ywSceneMapper.getVenueByUserId(user.getUserId()); + + if (list.size() == 0) { + if (StringUtils.isNotEmpty(user.getCounty())) { + list = ywSceneMapper.getVenueByArea(user.getCounty()); + + } else if (StringUtils.isNotEmpty(user.getCity())) { + list = ywSceneMapper.getVenueByArea(user.getCity()); + } else { + list = ywSceneMapper.getVenueByUserId(null); + } + } + } + if (!isLeader) { + //中心库显示全部 + boolean isCenterRole = user.isCenter(user); + if (isCenterRole) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(YwScene::getSceneBigId, sceneBigId); + wrapper.orderByAsc(YwScene::getId); + list = ywSceneMapper.selectList(wrapper); + } + if (!isCenterRole) { + list = ywSceneMapper.getVenueByUserIdAndBigId(user.getUserId(), sceneBigId); + } + } + //如果用户查出来没有配置场馆,就设置一个不能够查询的场馆用户用户查询 + if (list.size() == 0) { + YwScene scene = new YwScene(); + scene.setId(-1L); + scene.setVenueName("该用户没有场馆"); + } + } + return list; + } + + @Override + public List getSysUserByVenueAndOther(YwDataDTO ywDataDTO) { + List list = ywSceneMapper.getSysUserByVenueAndOther(ywDataDTO); + return list; + } + + @Override + public List msgList(YwSceneParam param) { + PageUtils.startPage(param, YwSceneParam.class); + return ywSceneMapper.getList(param); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(YwSceneDTO dto) { + validate(dto); + if (dto.getSceneBigId() == null) { + dto.setSceneBigId(ywSceneMapper.getCurrentSceneBigId()); + } + ywSceneMapper.insertSelective(dto); + List files = dto.getFiles(); + if (CollectionUtil.isNotEmpty(files)) { + for (YwSceneFile file : files) { + file.setSceneId(dto.getId()); + ywSceneMapper.insertFileSelective(file); + } + + this.loadingVenueCache(); + + } + } + + @Override + @Transactional + public void updateByPrimaryKeySelective(YwSceneDTO dto) { + validate(dto); + List files = dto.getFiles(); + if (files.size() > 0) { + List ids = files.stream().filter(file -> file.getSceneId() != null).map(file -> file.getSceneId()).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(ids)) { + delUselessSourceFile(dto.getId(), ids); + ywSceneMapper.delUselessFile(dto.getId(), ids); + } else { + delUselessSourceFile(dto.getId(), null); + ywSceneMapper.delUselessFile(dto.getId(), null); + } + for (YwSceneFile file : files) { + if (file.getSceneId() == null) { + file.setSceneId(dto.getId()); + ywSceneMapper.insertFileSelective(file); + } + } + } else { + delUselessSourceFile(dto.getId(), null); + ywSceneMapper.delUselessFile(dto.getId(), null); + } + ywSceneMapper.updateByPrimaryKeySelective(dto); + //20230814同步当前场馆的网元 + ywSceneNetelementDh.syncBySceneId(dto.getId()); + ywSceneNetelementCs.syncBySceneId(dto.getId()); + ywSceneNetelementAgis.syncBySceneId(dto.getId()); + ywSceneNetelementWx.syncBySceneId(dto.getId()); + this.loadingVenueCache(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delByIds(List ids) { + ywSceneMapper.deleteBatchIds(ids); + ywSceneUserService.delBySceneIds(ids); + ywSceneAlarmService.delBySceneIds(ids); + ywSceneCalendarService.delBySceneIds(ids); + //这个删除网元的代码有问题,没有用到这个表 + ywSceneNetelementService.delBySceneIds(ids); + if (CollectionUtil.isNotEmpty(ids)) { + for (Long id : ids) { + delUselessSourceFile(id, null); + ywSceneMapper.delUselessFile(id, null); + } + } + this.loadingVenueCache(); + } + + @Override + public void export(YwSceneParam param, HttpServletRequest request, HttpServletResponse response) { + param.setPageNum(1); + param.setPageSize(Integer.MAX_VALUE); + List list = msgList(param); + ExcelUtil util = new ExcelUtil<>(YwSceneVo.class); + util.exportExcel(response, list, "场馆信息"); +// EasyPoiExcelUtil.exportExcel(null, YwSceneVo.class, list, request, response); + } + + @Override + public void bigSceneExport(Long sceneBigId, HttpServletRequest request, HttpServletResponse response) { + List> list = Lists.newArrayList(); + //场景 + List sceneBigList = ywSceneMapper.getSceneBigById(sceneBigId); + + list.add(getMap("场景", sceneBigList, YwSceneBigConfig.class)); + //场馆 + List sceneList = ywSceneMapper.getSceneBySceneBigId(sceneBigId); + list.add(getMap("场馆", sceneList, YwSceneVo.class)); + //场馆告警 + List sceneAlarmList = ywSceneAlarmService.getListBySceneBigId(sceneBigId); + list.add(getMap("场馆告警", sceneAlarmList, YwSceneAlarmVo.class)); + //场馆人员 + List sceneUserList = ywSceneUserService.getListBySceneBigId(sceneBigId); + list.add(getMap("场馆人员", sceneUserList, YwSceneUserVo.class)); + //场馆网元 + List sceneNetelementList = ywSceneNetelementService.getListBySceneBigId(sceneBigId); + list.add(getMap("场馆网元", sceneNetelementList, YwSceneNetelement.class)); + //场馆赛事 + List sceneCalendarList = ywSceneCalendarService.getListBySceneBigId(sceneBigId); + list.add(getMap("场馆赛事", sceneCalendarList, YwSceneCalendarVo.class)); + EasyPoiExcelUtil.exportMultiSheetExcel(list, null, request, response); + } + + @Override + public void exportTemplate(HttpServletRequest request, HttpServletResponse response) { + List> list = Lists.newArrayList(); + //场景 + List sceneBigList = Lists.newArrayList(); + list.add(getMap("场景", sceneBigList, YwSceneBigConfig.class)); + //场馆 + List sceneList = Lists.newArrayList(); + list.add(getMap("场馆", sceneList, YwSceneVo.class)); + //场馆告警 + List sceneAlarmList = Lists.newArrayList(); + list.add(getMap("场馆告警", sceneAlarmList, YwSceneAlarmVo.class)); + //场馆人员 + List sceneUserList = Lists.newArrayList(); + list.add(getMap("场馆人员", sceneUserList, YwSceneUser.class)); + //场馆网元 + List sceneNetelementList = Lists.newArrayList(); + list.add(getMap("场馆网元", sceneNetelementList, YwSceneNetelement.class)); + //场馆赛事 + List sceneCalendarList = Lists.newArrayList(); + list.add(getMap("场馆赛事", sceneCalendarList, YwSceneCalendarVo.class)); + + //获取下拉框数据 + List selectorList = getExcelSelectorData(); + EasyPoiExcelUtil.exportMultiSheetExcel(list, selectorList, request, response); + } + + @Override + public void importSceneBigConfig(MultipartFile file) throws Exception { + ImportParams params = new ImportParams(); + params.setTitleRows(2); + //场景 + params.setStartSheetIndex(0); + List sceneBigList = ExcelImportUtil.importExcel(file.getInputStream(), YwSceneBigConfig.class, params); + //场馆 + params.setStartSheetIndex(1); + List sceneList = ExcelImportUtil.importExcel(file.getInputStream(), YwSceneVo.class, params); + this.loadingVenueCache(); + //场馆告警 + params.setStartSheetIndex(2); + List sceneAlarmList = ExcelImportUtil.importExcel(file.getInputStream(), YwSceneAlarmVo.class, params); + //场馆人员 + params.setStartSheetIndex(3); + List sceneUserList = ExcelImportUtil.importExcel(file.getInputStream(), YwSceneUser.class, params); + //场馆网元 + params.setStartSheetIndex(4); + List sceneNetelementList = ExcelImportUtil.importExcel(file.getInputStream(), YwSceneUser.class, params); + //场馆赛事 + params.setStartSheetIndex(5); + List sceneCalendarList = ExcelImportUtil.importExcel(file.getInputStream(), YwSceneCalendarVo.class, params); + } + + private List getExcelSelectorData() { + List list = Lists.newArrayList(); + + //地市 + List city = dictDataService.selectDictLabelByValues("yw_city", null); + encapsulationData(1, "city", YwSceneVo.class, city, list); + //区县 + List county = dictDataService.selectDictLabelByValues("yw_county", null); + encapsulationData(1, "county", YwSceneVo.class, county, list); + //场馆属性 + List sceneType = dictDataService.selectDictLabelByValues("yw_scene_type", null); + encapsulationData(1, "venueTypeName", YwSceneVo.class, sceneType, list); + //场馆级别 + List sceneLevel = dictDataService.selectDictLabelByValues("yw_scene_level", null); + encapsulationData(1, "venueLevelName", YwSceneVo.class, sceneLevel, list); + //场馆维护类型 + List sceneMaintainType = dictDataService.selectDictLabelByValues("yw_scene_maintain_type", null); + encapsulationData(1, "maintainTypeName", YwSceneVo.class, sceneMaintainType, list); + //专业 + List specialty = dictDataService.selectDictLabelByValues("yw_specialty", null); + encapsulationData(2, "specialtyName", YwSceneAlarmVo.class, specialty, list); + encapsulationData(4, "specialty", YwSceneNetelement.class, specialty, list); + //网元状态 + List netelementStatus = dictDataService.selectDictLabelByValues("ye_netelement_status", null); + encapsulationData(4, "statusName", YwSceneNetelement.class, netelementStatus, list); + //赛事类型 + List matchType = dictDataService.selectDictLabelByValues("yw_match_type", null); + encapsulationData(5, "matchTypeName", YwSceneCalendarVo.class, matchType, list); + //开关状态 + List status = dictDataService.selectDictLabelByValues("sys_normal_disable", null); + encapsulationData(0, "statusName", YwSceneBigConfig.class, status, list); + + return list; + } + + private void encapsulationData(int sheetIndex, String attributeName, Class cla, + List dictList, List list) { + ExcelSelector excelSelector = new ExcelSelector(); + try { + int firstCol = Integer.parseInt(cla.getDeclaredField(attributeName).getAnnotation(Excel.class).orderNum()); + excelSelector.setSheetIndex(sheetIndex); + excelSelector.setFirstCol(firstCol); + excelSelector.setLastCol(firstCol); + List collect = dictList.stream().map(dict -> dict.getDictLabel()).collect(Collectors.toList()); + excelSelector.setDatas(collect.toArray(new String[collect.size()])); + list.add(excelSelector); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + System.out.println(e.getMessage()); + } + } + + private Map getMap(String title, List dataList, Class cls) { + Map map = Maps.newHashMap(); + map.put("title", new ExportParams(title, title)); + map.put(NormalExcelConstants.DATA_LIST, dataList); + map.put(NormalExcelConstants.CLASS, cls); + return map; + } + + private void validate(YwSceneDTO dto) { + //根据场馆名称去重 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(StrUtil.isNotBlank(dto.getVenueName()), YwScene::getVenueName, dto.getVenueName()); + wrapper.eq(null != dto.getSceneBigId(), YwScene::getSceneBigId, dto.getSceneBigId()); + wrapper.ne(dto.getId() != null, YwScene::getId, dto.getId()); + List list = ywSceneMapper.selectList(wrapper); + if (CollectionUtil.isNotEmpty(list)) { + throw new ServiceException("场馆重复"); + } + } + + private void delUselessSourceFile(Long id, List ids) { + List files = ywSceneMapper.getFileByCondition(id, ids); + if (CollectionUtil.isNotEmpty(files)) { + for (YwSceneFile file : files) { + String fileUrl = file.getFileUrl(); + int dirLastIndex = Constants.RESOURCE_PREFIX.length() + 1; + fileUrl = StringUtils.substring(fileUrl, dirLastIndex); + fileUrl = RuoYiConfig.getProfile() + fileUrl; + FileUtils.deleteFile(fileUrl); + } + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult importYWScene(List list, Long sceneBigId, String importType) throws Exception { + ImporterBase importer = new ImporterScene(ywSceneMapper, ywSceneUserMapper); + AjaxResult ajaxResult = importer.doAdd(list, sceneBigId, importType); + if (HttpStatus.SUCCESS == (int) ajaxResult.get(AjaxResult.CODE_TAG)) { + this.loadingVenueCache(); + } + return ajaxResult; + } + + @Override + public void exportReal(YwSceneParam param, HttpServletRequest request, HttpServletResponse response) { + param.setPageNum(1); + param.setPageSize(Integer.MAX_VALUE); + List list = msgList(param); + List list1 = new ArrayList<>(); + for (YwSceneVo vo : list) { + YwSceneExportVo yw = new YwSceneExportVo(); + BeanUtils.copyBeanProp(yw, vo); + list1.add(yw); + } + ExcelUtil util = new ExcelUtil<>(YwSceneExportVo.class); + util.exportExcel(response, list1, "场馆导出"); +// EasyPoiExcelUtil.exportExcel(null,YwSceneVo.class,list,request,response); + } + + @Override + public void importStationByScene(MultipartFile multipartFile, Long sceneBigId, Long sceneId) { + String fileName = sceneId + ".json"; + String zipFileName = sceneId + ".zip"; + File file = new File(sceneJsonPath + fileName); +// File file = new File("D:/home/" + fileName); + String[] files = {file.getAbsolutePath()}; + File zipFile = new File(sceneJsonPath + zipFileName); +// File zipFile = new File("D:/home/" + zipFileName); + if (!file.exists()) { + try { + multipartFile.transferTo(file); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + try { + file.delete(); + multipartFile.transferTo(file); + } catch (IOException e) { + e.printStackTrace(); + } + } + + if (!zipFile.exists()) { + try { + zipFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + try { + zipFile.delete(); + zipFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + ZipUtils.zip(files, zipFile); + + } + + @Override + public void getJsonBySceneId(Long sceneId,HttpServletResponse response) throws Exception{ + String fileName = sceneId + ".zip"; + File file = FileUtil.file(sceneJsonPath + fileName); +// File file = FileUtil.file("D:/home/" + fileName); + ServletOutputStream outputStream = response.getOutputStream(); + outputStream.write(FileUtil.readBytes(file));//hutool 工具类 FileUtil + //强制将缓存区的数据进行输出 + outputStream.flush(); + //关流 + outputStream.close(); + + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneTestDataServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneTestDataServiceImpl.java new file mode 100644 index 0000000..86fff3d --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneTestDataServiceImpl.java @@ -0,0 +1,186 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.http.HttpUtils; +import com.ruoyi.eastcom_yw.domain.YwSceneTestData; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneTestDataInterface; +import com.ruoyi.eastcom_yw.mapper.YwSceneTestDataInterfaceMapper; +import com.ruoyi.eastcom_yw.mapper.YwSceneTestDataMapper; +import com.ruoyi.eastcom_yw.service.YwSceneTestDataService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +@Service +@Slf4j +@RequiredArgsConstructor +public class YwSceneTestDataServiceImpl implements YwSceneTestDataService { + + private final YwSceneTestDataMapper ywSceneTestDataMapper; + + private final YwSceneTestDataInterfaceMapper ywSceneTestDataInterfaceMapper; + + public List getList() { + List jsonObjects = new ArrayList<>(); + + List list = ywSceneTestDataMapper.selectList(new QueryWrapper<>()); + + for (YwSceneTestData ywSceneTestData : list) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("name", ywSceneTestData.getScenename()); + jsonObject.put("type", ywSceneTestData.getNettype()); + jsonObject.put("GPS", ywSceneTestData.getLat() + "," + ywSceneTestData.getLng()); + jsonObject.put("ConnectDelay", String.valueOf(ywSceneTestData.getConnectdelay())); + jsonObject.put("DLSpeed", String.valueOf(ywSceneTestData.getDlspeed())); + jsonObject.put("PageComplete", String.valueOf(ywSceneTestData.getPagecomplete())); + jsonObject.put("ULSpeed", String.valueOf(ywSceneTestData.getUlspeed())); + jsonObject.put("UpdateTime", null == ywSceneTestData.getUpdateTime() ? "" : DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", ywSceneTestData.getUpdateTime())); + jsonObjects.add(jsonObject); + } + + return jsonObjects; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void insertTestData() { + + List ywSceneTestDatas = new ArrayList<>(); + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(YwSceneTestDataInterface::getEnable, "1"); + List ywSceneTestDataInterfaces = ywSceneTestDataInterfaceMapper.selectList(wrapper); + + for (YwSceneTestDataInterface ywSceneTestDataInterface : ywSceneTestDataInterfaces) { + apply(ywSceneTestDataInterface, ywSceneTestDatas); + } + + List sceneIdList = new ArrayList<>(); + for (YwSceneTestData ywSceneTestData : ywSceneTestDatas) { + sceneIdList.add(ywSceneTestData.getSceneId()); + } + if (ywSceneTestDatas.size() > 0) { + ywSceneTestDataMapper.deleteBySceneIdIn(sceneIdList); + ywSceneTestDataMapper.insertBatch(ywSceneTestDatas); + } + + } + + private void apply(YwSceneTestDataInterface ywSceneTestDataInterface, List ywSceneTestDatas) { + String s = HttpUtils.sendGet(ywSceneTestDataInterface.getUrl(), "", "UTF-8"); + log.info(s); + if (StringUtils.isNotEmpty(s)) { + parseJsonArr(s, ywSceneTestDatas, ywSceneTestDataInterface); + } else { + log.error("请求接口失败。"); + } + } + + private void parseJsonArr(String s, List ywSceneTestDatas, YwSceneTestDataInterface ywSceneTestDataInterface) { + String net = ""; + if (ywSceneTestDataInterface.getUrl().contains("4g")) { + net = "4G"; + } else if (ywSceneTestDataInterface.getUrl().contains("5g")) { + net = "5G"; + } + List objects; + try { + objects = JSON.parseArray(s, HashMap.class); + } catch (Exception e) { + log.error("json转Map失败"); + return; + } + for (HashMap object : objects) { + try { + YwSceneTestData ywSceneTestData = new YwSceneTestData(); + String bZName = (String) object.get("BZName"); + String connectDelay = (String) object.get("ConnectDelay"); + String dLSpeed = (String) object.get("DLSpeed"); + String deviceID = (String) object.get("DeviceID"); + Float lat = ((BigDecimal) object.get("Lat")).floatValue(); + Float lng = ((BigDecimal) object.get("Lng")).floatValue(); + String pageComplete = (String) object.get("PageComplete"); + String sceneName = (String) object.get("SceneName"); + String uLSpeed = (String) object.get("ULSpeed"); + String updateTime = (String) object.get("UpdateTime"); + + ywSceneTestData.setBzname(bZName); + ywSceneTestData.setConnectdelay(StringUtils.isNotEmpty(connectDelay.replace("ms", "").trim()) ? Float.parseFloat(connectDelay.replace("ms", "").trim()) : null); + ywSceneTestData.setDlspeed(StringUtils.isNotEmpty(dLSpeed.replace("Mbps", "").trim()) ? Float.parseFloat(dLSpeed.replace("Mbps", "").trim()) : null); + ywSceneTestData.setDeviceoid(deviceID); + ywSceneTestData.setLat(lat); + ywSceneTestData.setLng(lng); + ywSceneTestData.setPagecomplete(StringUtils.isNotEmpty(pageComplete.replace("%", "").trim()) ? Float.parseFloat(pageComplete.replace("%", "").trim()) : null); + ywSceneTestData.setScenename(sceneName); + ywSceneTestData.setUlspeed(StringUtils.isNotEmpty(uLSpeed.replace("Mbps", "").trim()) ? Float.parseFloat(uLSpeed.replace("Mbps", "").trim()) : null); + ywSceneTestData.setUpdateTime(StringUtils.isNotEmpty(updateTime.replace("T", "").trim()) ? DateUtils.parseDate(updateTime.replace("T", " "), "yyyy-MM-dd HH:mm:ss") : null); + ywSceneTestData.setSceneId(ywSceneTestDataInterface.getSceneId()); + ywSceneTestData.setNettype(net); + ywSceneTestDatas.add(ywSceneTestData); + } catch (Exception e) { + log.error("xml转实体失败。"); + } + } + } + + /*private void parseXml(String s, List ywSceneTestDatas, String url) { + String net = ""; + if (url.contains("4g")) { + net = "4G"; + } else if (url.contains("5g")) { + net = "5G"; + } + + try { + Document document = DocumentHelper.parseText(s); + Element rootElement = document.getRootElement(); + + Iterator tzDeviceInfo2 = rootElement.elementIterator("TZDeviceInfo2"); + while (tzDeviceInfo2.hasNext()) { + Element next1 = (Element) tzDeviceInfo2.next(); + YwSceneTestData ywSceneTestData = new YwSceneTestData(); + String bZName = next1.elementTextTrim("BZName"); + String connectDelay = next1.elementTextTrim("ConnectDelay"); + String dLSpeed = next1.elementTextTrim("DLSpeed"); + String deviceID = next1.elementTextTrim("DeviceID"); + String lat = next1.elementTextTrim("Lat"); + String lng = next1.elementTextTrim("Lng"); + String pageComplete = next1.elementTextTrim("PageComplete"); + String sceneName = next1.elementTextTrim("SceneName"); + String uLSpeed = next1.elementTextTrim("ULSpeed"); + String updateTime = next1.elementTextTrim("UpdateTime"); + try { + ywSceneTestData.setBzname(bZName); + ywSceneTestData.setConnectdelay(StringUtils.isNotEmpty(connectDelay.replace("ms", "").trim()) ? Float.parseFloat(connectDelay.replace("ms", "").trim()) : null); + ywSceneTestData.setDlspeed(StringUtils.isNotEmpty(dLSpeed.replace("Mbps", "").trim()) ? Float.parseFloat(dLSpeed.replace("Mbps", "").trim()) : null); + ywSceneTestData.setDeviceoid(deviceID); + ywSceneTestData.setLat(StringUtils.isNotEmpty(lat) ? Float.parseFloat(lat) : null); + ywSceneTestData.setLng(StringUtils.isNotEmpty(lng) ? Float.parseFloat(lng) : null); + ywSceneTestData.setPagecomplete(pageComplete); + ywSceneTestData.setScenename(sceneName); + ywSceneTestData.setUlspeed(StringUtils.isNotEmpty(uLSpeed.replace("Mbps", "").trim()) ? Float.parseFloat(uLSpeed.replace("Mbps", "").trim()) : null); + ywSceneTestData.setUpdateTime(StringUtils.isNotEmpty(updateTime.replace("T", "").trim()) ? DateUtils.parseDate(updateTime.replace("T", " "), "yyyy-MM-dd HH:mm:ss") : null); + ywSceneTestData.setSceneId(2); + ywSceneTestData.setNettype(net); + ywSceneTestDatas.add(ywSceneTestData); + } catch (Exception e) { + log.error("xml转实体失败。"); + } + } + } catch (Exception e) { + log.error("解析xml失败。"); + } + }*/ + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneUserServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneUserServiceImpl.java new file mode 100644 index 0000000..69910df --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSceneUserServiceImpl.java @@ -0,0 +1,208 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.SysUserImp; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwSceneUser; +import com.ruoyi.eastcom_yw.domain.param.SysUserParam; +import com.ruoyi.eastcom_yw.domain.param.YwSceneUserParam; +import com.ruoyi.eastcom_yw.domain.vo.SysUserVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneUserVo; +import com.ruoyi.eastcom_yw.importer.ImporterSceneUser; +import com.ruoyi.eastcom_yw.mapper.YwSceneMapper; +import com.ruoyi.eastcom_yw.mapper.YwSceneUserMapper; +import com.ruoyi.eastcom_yw.service.YwSceneUserService; +import com.ruoyi.system.mapper.SysRoleMapper; +import com.ruoyi.system.mapper.SysUserMapper; +import com.ruoyi.system.mapper.SysUserRoleMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author huamile + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class YwSceneUserServiceImpl extends ServiceImpl implements YwSceneUserService { + + private final YwSceneUserMapper ywSceneUserMapper; + + private final SysUserMapper sysUserMapper; + + private final SysRoleMapper sysRoleMapper; + + private final SysUserRoleMapper sysUserRoleMapper; + + private final YwSceneMapper ywSceneMapper; + + @Override + public List getList(YwSceneUserParam param) { + PageUtils.startPage(param, YwSceneUserParam.class); + return ywSceneUserMapper.getList(param); + } + + @Override + public List getVenuesByUserId(Long userId) { + return ywSceneUserMapper.getVenuesByUserId(userId); + } + + @Override + public List getVenuesByUserIds(List userIds) { + return ywSceneUserMapper.getVenuesByUserIds(userIds); + } + + @Override + public List getListBySceneBigId(Long sceneBigId) { + return ywSceneUserMapper.getListBySceneBigId(sceneBigId); + } + + @Override + public void create(YwSceneUser ywSceneUser) { + if(ObjectUtils.isEmpty(ywSceneUser.getSceneId())) + { + throw new ServiceException("场馆ID不允许为空"); + } + //validate(ywSceneUser); + List userIds = ywSceneUser.getUserIds(); + if (CollectionUtil.isNotEmpty(userIds)) { + for (Long userId : userIds) { + ywSceneUser.setUserId(userId); + ywSceneUserMapper.insertSelective(ywSceneUser); + } + } + } + + //用于用户的修改,增加了删除用户关联的场馆的方法 + @Override + public void delete(Long userId) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(YwSceneUser::getUserId, userId); + ywSceneUserMapper.delete(wrapper); + } + + @Override + public void updateByPrimaryKeySelective(YwSceneUser ywSceneUser) { + //validate(ywSceneUser); + ywSceneUserMapper.updateByPrimaryKeySelective(ywSceneUser); + } + + @Override + public Integer delBySceneIds(List ids) { + if (CollectionUtil.isNotEmpty(ids)) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.in(YwSceneUser::getSceneId, ids); + return ywSceneUserMapper.delete(wrapper); + } + return null; + } + + @Override + public void export(YwSceneUserParam param, HttpServletRequest request, HttpServletResponse response) { + param.setPageNum(1); + param.setPageSize(Integer.MAX_VALUE); + List list = getList(param); + list.forEach(x -> x.setNeedSign("0".equals(x.getNeedSign()) ? "否" : "是")); + + ExcelUtil util = new ExcelUtil<>(YwSceneUserVo.class); + util.exportExcel(response, list, "场馆人员配置"); +// EasyPoiExcelUtil.exportExcel("场馆人员配置", YwSceneUserVo.class, list, request, response); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult importSysUser(List imps, Long sceneBigId, String importType) throws Exception { + + List roles = sysRoleMapper.selectRoleAll(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(YwScene::getSceneBigId, sceneBigId); + List ywScenes = ywSceneMapper.selectList(queryWrapper); + List ywSceneUsers = ywSceneUserMapper.selectList(null); + + ImporterBase importer = new ImporterSceneUser(sysUserMapper, sysUserRoleMapper, ywSceneUserMapper); + return importer.doAdd(imps, sceneBigId, importType, roles, ywScenes, ywSceneUsers); + + } + + @Override + public List listSysUser(SysUserParam para) { + + PageUtils.startPage(para, SysUserParam.class); + + List sysUserVos = ywSceneUserMapper.listSysUser(para.getSceneBigId()); + + return sysUserVos; + } + + @Override + public void exportForImport(SysUserParam para, HttpServletRequest request, HttpServletResponse response) { + para.setPageNum(1); + para.setPageSize(Integer.MAX_VALUE); + + List sysUserVos = listSysUser(para); + + for (SysUserVo vo : sysUserVos) { + vo.setStatus(StringUtils.isNotEmpty(vo.getStatus()) ? DictUtils.getDictLabel("sys_user_status", vo.getStatus()) : null); + vo.setUserType(StringUtils.isNotEmpty(vo.getUserType()) ? DictUtils.getDictLabel("yw_specialty", vo.getUserType()) : null); + vo.setCity(StringUtils.isNotEmpty(vo.getCity()) ? DictUtils.getDictLabel("yw_city", vo.getCity()) : null); + vo.setCounty(StringUtils.isNotEmpty(vo.getCounty()) ? DictUtils.getDictLabel("yw_county", vo.getCounty()) : null); + if (StringUtils.isEmpty(vo.getDistinctArea())) { + + } else if (!vo.getDistinctArea().contains("|")) { + vo.setDistinctArea(StringUtils.isNotEmpty(vo.getDistinctArea()) ? DictUtils.getDictLabel("yw_belong_area", vo.getDistinctArea()) : null); + } else { + StringBuilder sb = new StringBuilder(); + String[] dis = vo.getDistinctArea().split("\\|"); + for (String s : dis) { + sb.append(StringUtils.isNotEmpty(s) ? (DictUtils.getDictLabel("yw_belong_area", s) + "|") : "|"); + } + sb.deleteCharAt(sb.length() - 1); + vo.setDistinctArea(sb.toString()); + } + if (StringUtils.isEmpty(vo.getNeedSign())) { + + } else if (!vo.getNeedSign().contains("|")) { + if ("1".equals(vo.getNeedSign())) { + vo.setNeedSign("是"); + } else if ("0".equals(vo.getNeedSign())) { + vo.setNeedSign("否"); + } + } else { + StringBuilder sb = new StringBuilder(); + String[] dis = vo.getNeedSign().split("\\|"); + for (String s : dis) { + if ("1".equals(s)) { + sb.append("是|"); + } else if ("0".equals(s)) { + sb.append("否|"); + } else { + sb.append("|"); + } + } + sb.deleteCharAt(sb.length() - 1); + vo.setNeedSign(sb.toString()); + } + } + + ExcelUtil util = new ExcelUtil<>(SysUserVo.class); + util.exportExcel(response, sysUserVos, "人员导出"); + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSignLogServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSignLogServiceImpl.java new file mode 100644 index 0000000..dad560d --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSignLogServiceImpl.java @@ -0,0 +1,284 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.CoordinateConversionUtils; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwSignLog; +import com.ruoyi.eastcom_yw.domain.YwSignPlanView; +import com.ruoyi.eastcom_yw.domain.dto.YwSignDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSignInDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwSignVo; +import com.ruoyi.eastcom_yw.mapper.YwSignLogMapper; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.eastcom_yw.service.YwSignLogService; +import com.ruoyi.eastcom_yw.service.YwSignPlanService; +import org.gavaghan.geodesy.Ellipsoid; +import org.gavaghan.geodesy.GlobalCoordinates; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.List; + +import static com.ruoyi.common.utils.GeoUtils.getDistanceMeter; + +@Service +public class YwSignLogServiceImpl extends ServiceImpl implements YwSignLogService { + + @Autowired + YwSignLogMapper ywSignLogMapper; + @Autowired + YwSignPlanService ywSignPlanService; + @Autowired + YwSceneService ywSceneService; + + @Override + public void SignIn(YwSignInDTO ywSignInDTO) { + + String signDate = ywSignInDTO.getSignTime().split(" ")[0]; + + //20230316手动打卡前端没限制,签到时间必须签到时间的前4小时到后5分钟的时间范围 + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + if (ObjectUtils.isEmpty(ywSignInDTO.getSignPlanId())) { + lambdaQueryWrapper.eq(YwSignPlanView::getSceneId, ywSignInDTO.getVenueId()); + lambdaQueryWrapper.eq(YwSignPlanView::getSignDate, DateUtils.parseDate(signDate)); + lambdaQueryWrapper.eq(YwSignPlanView::getIsOpen, "1"); + } + + if (ObjectUtils.isNotEmpty(ywSignInDTO.getSignPlanId())) { + lambdaQueryWrapper.eq(YwSignPlanView::getId, ywSignInDTO.getSignPlanId()); + } + + //先找场馆的签到计划 + List lstYwSignPlan = ywSignPlanService.list(lambdaQueryWrapper); + + if (lstYwSignPlan.isEmpty()) { + if (ywSignInDTO.getSignType() == 0) { + throw new ServiceException("打卡的签到计划不存在"); + } + } + + if (lstYwSignPlan.size() > 1) { + throw new ServiceException("打卡的签到计划存在重复"); + } + + LocalDateTime signTime = LocalDateTimeUtil.of(DateUtils.parseDate(ywSignInDTO.getSignTime())); + + if (ywSignInDTO.getSignType() == 0) { + //配置时间前4小时可打卡 + LocalDateTime beginTime = LocalDateTimeUtil.of(lstYwSignPlan.get(0).getBeginTime()); + + if (signTime.isAfter(beginTime.plusMinutes(5)) || signTime.isBefore(beginTime.minusHours(lstYwSignPlan.get(0).getRepSignInterval()))) { + throw new ServiceException("超过限定时间,不允许打卡"); + } + } + + if (ywSignInDTO.getSignType() == 1) { + LocalDateTime end = LocalDateTimeUtil.of(lstYwSignPlan.get(0).getEndTime()); + if (signTime.isBefore(end)) { + throw new ServiceException("签退时间必须大于晚签到时间"); + } + } + + ywSignInDTO.setUserId(SecurityUtils.getUserId()); + //ywSignInDTO.setUserId(1L); + ywSignLogMapper.SingIn(ywSignInDTO); + + } + + @Override + public YwSignVo couldSign(YwSignDTO ywSignDTO) { + + if (StrUtil.isBlank(ywSignDTO.getLatitude()) || StrUtil.isBlank(ywSignDTO.getLongitude())) { + throw new ServiceException("未取得经纬度"); + } + + //查询当前登录人员场馆配置 + Long userId = SecurityUtils.getUserId(); + SysUser sysUser = new SysUser(); + sysUser.setUserId(userId); + sysUser.setRoles(SecurityUtils.getLoginUser().getUser().getRoles()); + List ywSceneList = ywSceneService.getVenueByUser(sysUser); + if (CollUtil.isEmpty(ywSceneList)) { + throw new ServiceException("当前用户未配置场馆"); + } + + // Date date = new Date(); +// SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); +// String today = dateFormat.format(date); + YwSignPlanView one = null; + //获取签到计划 + if (ObjectUtils.isEmpty(ywSignDTO.getSignPlanId())) { + + if (ywSignDTO.getVenueId() == null) { + throw new ServiceException("未传场馆id"); + } + + one = ywSignPlanService.getOne(new LambdaQueryWrapper() + .eq(YwSignPlanView::getSceneId, ywSignDTO.getVenueId()) + .eq(YwSignPlanView::getSignDate, DateUtils.getNowDate()) + .eq(YwSignPlanView::getIsOpen, "1")); + + } + if (ObjectUtils.isNotEmpty(ywSignDTO.getSignPlanId())) { + one = ywSignPlanService.getOne(new LambdaQueryWrapper() + .eq(YwSignPlanView::getId, ywSignDTO.getSignPlanId())); + } + + if (one == null) { + throw new ServiceException("签到计划不存在"); + } + + YwScene ywScene = ywSceneService.getById(one.getSceneId()); + if (ywScene == null) { + throw new ServiceException("场馆不存在"); + } + + if (ObjectUtils.isEmpty(ywScene.getSignScope())) { + ywScene.setSignScope(400); + } + + + int flag = 0; + StringBuilder stringBuilder = new StringBuilder(); + //判断当前时间是否可打卡 如果signType为空,则只校验距离 + if (ywSignDTO.getSignType() != null) { + LocalDateTime now = LocalDateTime.now(); + if (ywSignDTO.getSignType() == 0) { + //配置时间前4小时可打卡 + LocalDateTime beginTime = LocalDateTimeUtil.of(one.getBeginTime()); + if (now.isAfter(beginTime)) { + flag = 1; + stringBuilder.append("超过签到打卡时间将无法打卡,请于您的场馆经理联系,申请手工打卡;"); + } else if (now.isBefore(beginTime.minusHours(one.getRepSignInterval()))) { + flag = 1; + stringBuilder.append("未到打卡时间,最早为:").append(beginTime.minusHours(one.getRepSignInterval()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))); + } + } else { + LocalDateTime endTime = LocalDateTimeUtil.of(one.getEndTime()); + if (now.isBefore(endTime)) { + flag = 1; + stringBuilder.append("下班时间未到,无法打卡;"); + } else if (!now.toLocalDate().isEqual(endTime.toLocalDate())) { + flag = 1; + stringBuilder.append("无法跨天打卡"); + } + } + } + double lng = Double.parseDouble(ywSignDTO.getLongitude()); + double lat = Double.parseDouble(ywSignDTO.getLatitude()); +// WGS84转GCj02 + String s = CoordinateConversionUtils.wgs84togcj02(lng, lat); + double lng02 = Double.parseDouble(s.split(",")[0]); + double lat02 = Double.parseDouble(s.split(",")[1]); + //比较经纬度 + if (ywScene.getLatitudeGcj02() == null || ywScene.getLongitudeGcj02() == null) { + throw new ServiceException("场馆未配置经纬度"); + } + GlobalCoordinates source = new GlobalCoordinates(ywScene.getLatitudeGcj02(), ywScene.getLongitudeGcj02()); + GlobalCoordinates target = new GlobalCoordinates(lat02, lng02); + //GPS 使用 WGS84 + double geoCurve = getDistanceMeter(source, target, Ellipsoid.WGS84); + if (geoCurve > ywScene.getSignScope()) { + if (flag == 1) { + flag = 3; + } else { + flag = 2; + } + stringBuilder.append("您未进入打卡范围;"); + } + if (stringBuilder.length() > 0) { + return YwSignVo.builder().couldSign(false).failType(flag).failMsg(stringBuilder.toString()).build(); + } + return YwSignVo.builder().couldSign(true).build(); + } + + + public static void main(String[] args) { + double a=120.155; + double b=30.27607641627596; + double v = new BigDecimal(a).setScale(6, RoundingMode.HALF_UP).doubleValue(); + System.out.println(v); + } + + @Override + public Boolean sign(YwSignDTO ywSignDTO) { + YwSignVo ywSignVo = couldSign(ywSignDTO); + if (!ywSignVo.getCouldSign()) { + throw new ServiceException(ywSignVo.getFailMsg()); + } + YwSignLog signLog = ywSignLogMapper.selectOne(new LambdaQueryWrapper() + .eq(YwSignLog::getUserId, SecurityUtils.getUserId()) + .eq(YwSignLog::getSignType, ywSignDTO.getSignType()) + .eq(YwSignLog::getSignPlanId, ywSignDTO.getSignPlanId())); + if (signLog == null) { + throw new ServiceException("签到记录未生成"); + } + if (signLog.getSignTime() != null) { + throw new ServiceException("您已完成打卡,请勿重新打卡"); + } + YwSignLog ywSignLog = new YwSignLog(); + ywSignLog.setSignPlanId(ywSignDTO.getSignPlanId()); + ywSignLog.setUserId(SecurityUtils.getUserId()); + ywSignLog.setSignTime(new Date()); + Double j = new BigDecimal(ywSignDTO.getLongitude()).setScale(6, RoundingMode.HALF_UP).doubleValue(); + ywSignLog.setSignJ(j); + Double w = new BigDecimal(ywSignDTO.getLatitude()).setScale(6, RoundingMode.HALF_UP).doubleValue(); + ywSignLog.setSignW(w); +// ywSignLog.setIsDaiSign(false); + ywSignLog.setSignType(ywSignDTO.getSignType().toString()); + SysUser sysUser = new SysUser(); + sysUser.setUserId(SecurityUtils.getUserId()); + sysUser.setRoles(SecurityUtils.getLoginUser().getUser().getRoles()); +// List ywSceneList = ywSceneService.getVenueByUser(sysUser); +// Long sceneId = ywSceneList.get(0).getId(); + ywSignLogMapper.sign(ywSignLog, ywSignDTO.getVenueId()); + return true; + } + + @Override + public Boolean signTest(YwSignDTO ywSignDTO) { + YwSignVo ywSignVo = couldSign(ywSignDTO); + if (!ywSignVo.getCouldSign()) { + throw new ServiceException(ywSignVo.getFailMsg()); + } + YwSignLog signLog = ywSignLogMapper.selectOne(new LambdaQueryWrapper() + .eq(YwSignLog::getUserId, SecurityUtils.getUserId()) + .eq(YwSignLog::getSignType, ywSignDTO.getSignType()) + .eq(YwSignLog::getSignPlanId, ywSignDTO.getSignPlanId())); + if (signLog == null) { + throw new ServiceException("签到记录未生成"); + } + YwSignLog ywSignLog = new YwSignLog(); + ywSignLog.setSignPlanId(ywSignDTO.getSignPlanId()); + ywSignLog.setUserId(SecurityUtils.getUserId()); + ywSignLog.setSignTime(new Date()); + Double j = new BigDecimal(ywSignDTO.getLongitude()).setScale(6, RoundingMode.HALF_UP).doubleValue(); + ywSignLog.setSignJ(j); + Double w = new BigDecimal(ywSignDTO.getLatitude()).setScale(6, RoundingMode.HALF_UP).doubleValue(); + ywSignLog.setSignW(w); +// ywSignLog.setIsDaiSign(false); + ywSignLog.setSignType(ywSignDTO.getSignType().toString()); + SysUser sysUser = new SysUser(); + sysUser.setUserId(SecurityUtils.getUserId()); + sysUser.setRoles(SecurityUtils.getLoginUser().getUser().getRoles()); +// List ywSceneList = ywSceneService.getVenueByUser(sysUser); +// Long sceneId = ywSceneList.get(0).getId(); + ywSignLogMapper.sign(ywSignLog, ywSignDTO.getVenueId()); + return true; + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSignLogViewServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSignLogViewServiceImpl.java new file mode 100644 index 0000000..194876a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSignLogViewServiceImpl.java @@ -0,0 +1,257 @@ +package com.ruoyi.eastcom_yw.service.impl; + + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwSceneUser; +import com.ruoyi.eastcom_yw.domain.YwSignLogView; +import com.ruoyi.eastcom_yw.domain.dto.YwSignLogDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwSignLogStaticVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSignLogVo; +import com.ruoyi.eastcom_yw.mapper.YwSceneMapper; +import com.ruoyi.eastcom_yw.mapper.YwSceneUserMapper; +import com.ruoyi.eastcom_yw.mapper.YwSignLogViewMapper; +import com.ruoyi.eastcom_yw.service.YwSignLogViewService; +import com.ruoyi.system.mapper.SysRoleMapper; +import com.ruoyi.system.mapper.SysUserRoleMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@Service +public class YwSignLogViewServiceImpl extends ServiceImpl implements YwSignLogViewService { + + + @Autowired + YwSignLogViewMapper ywSignLogViewMapper; + + @Autowired + private YwSceneMapper ywSceneMapper; + + @Autowired + private YwSceneUserMapper ywSceneUserMapper; + + @Autowired + private SysRoleMapper sysRoleMapper; + + + @Override + public TableDataInfo getSignLog(YwSignLogDTO ywSignLogDTO) { + + LambdaQueryWrapper lambdaQueryWrapper=new LambdaQueryWrapper<>(); + + lambdaQueryWrapper.like(StringUtils.isNotEmpty(ywSignLogDTO.getCity()),YwSignLogView::getAreaCountyId,ywSignLogDTO.getCity()); + + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywSignLogDTO.getCounty()),YwSignLogView::getAreaCountyId,ywSignLogDTO.getCounty()); + + lambdaQueryWrapper.like(StringUtils.isNotEmpty(ywSignLogDTO.getNickName()),YwSignLogView::getNickName,ywSignLogDTO.getNickName()); + + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywSignLogDTO.getSignStatus()),YwSignLogView::getSignStatus,ywSignLogDTO.getSignStatus()); + + if(ObjectUtils.isNotEmpty(ywSignLogDTO.getVenueIds())) + { + lambdaQueryWrapper.in(ywSignLogDTO.getVenueIds().length>0,YwSignLogView::getSceneId,ywSignLogDTO.getVenueIds()); + } + + boolean needDate = true; + + if(ObjectUtils.isNotEmpty(ywSignLogDTO.getGenTime())) { + if (StringUtils.isNotEmpty(ywSignLogDTO.getStartDate()) && StringUtils.isNotEmpty(ywSignLogDTO.getEndDate())) { + if (ywSignLogDTO.getStartDate().substring(0, 10).equals(ywSignLogDTO.getEndDate().substring(0, 10))) { + LocalDateTime now = LocalDateTime.now(); + String time = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); + if (ywSignLogDTO.getStartDate().substring(0, 10).equals(time)) { + if (ywSignLogDTO.getGenTime()) { + lambdaQueryWrapper.lt(YwSignLogView::getGenTime, now); + } + if (!ywSignLogDTO.getGenTime()) { + lambdaQueryWrapper.lt(YwSignLogView::getBeginTime, now); + + lambdaQueryWrapper.between( + YwSignLogView::getBeginTime, DateUtils.parseDate(ywSignLogDTO.getStartDate()), now); + needDate = false; + + } + + } + } + } + } + + if(needDate) { + if (StringUtils.isNotEmpty(ywSignLogDTO.getStartDate()) && StringUtils.isNotEmpty(ywSignLogDTO.getEndDate())) { + try { + lambdaQueryWrapper.between( + YwSignLogView::getBeginTime, DateUtils.parseDate(ywSignLogDTO.getStartDate()), DateUtils.parseDate(ywSignLogDTO.getEndDate(), "yyyy-MM-dd HH:mm:ss")); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + } + + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywSignLogDTO.getUserType()),YwSignLogView::getUserType,ywSignLogDTO.getUserType()); + + +// lambdaQueryWrapper.orderByAsc(YwSignLogView::getSceneId); + lambdaQueryWrapper.orderByDesc(YwSignLogView::getSignDate); + lambdaQueryWrapper.orderByDesc(YwSignLogView::getBeginTime); + lambdaQueryWrapper.orderByAsc(YwSignLogView::getUserId); + List list=null; + + TableDataInfo rspData = new TableDataInfo(); + + if(ObjectUtils.isNotEmpty(ywSignLogDTO.getPageSize())) + { + //传入-1为全部数据 + if(ywSignLogDTO.getPageSize()==-1) + { + list = ywSignLogViewMapper.selectList(lambdaQueryWrapper); + rspData.setTotal(list.size()); + } + else + { + if(ObjectUtils.isEmpty(ywSignLogDTO.getPageNum())) + { + ywSignLogDTO.setPageNum(1); + } + + Page page=ywSignLogViewMapper.selectPage(new Page<>(ywSignLogDTO.getPageNum(), ywSignLogDTO.getPageSize()),lambdaQueryWrapper); + list = page.getRecords(); + rspData.setTotal(page.getTotal()); + } + + if(list.size()>0) { + + List list_signlogvo = new ArrayList<>(); + + list.forEach( + ywSignLogView -> { + YwSignLogVo ywSignLogVo = new YwSignLogVo(); + + //设置角色 + Long userId = ywSignLogView.getUserId(); + List sysRoles = sysRoleMapper.selectRolePermissionByUserId(userId); + ywSignLogVo.setRoleNames(sysRoles.stream().map(SysRole::getRoleName).toArray(String[]::new)); + + //设置区域 +// List venuesByUserId = ywSceneUserMapper.getVenuesByUserId(userId); +// ywSignLogVo.setSceneUser(venuesByUserId); + + BeanUtils.copyBeanProp(ywSignLogVo, ywSignLogView); + + //导出时对时间的处理 + if (ObjectUtils.isNotEmpty(ywSignLogView.getBeginTime())) { + ywSignLogVo.setStrBeginTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", ywSignLogView.getBeginTime())); + } + + if (ObjectUtils.isNotEmpty(ywSignLogView.getEndTime())) { + ywSignLogVo.setStrEndTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", ywSignLogView.getEndTime())); + } + + if (ObjectUtils.isNotEmpty(ywSignLogView.getSignInTime())) { + ywSignLogVo.setStrSignInTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", ywSignLogView.getSignInTime())); + } + + if (ObjectUtils.isNotEmpty(ywSignLogView.getSignOutTime())) { + ywSignLogVo.setStrSignOutTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", ywSignLogView.getSignOutTime())); + } + + list_signlogvo.add(ywSignLogVo); + } + ); + + rspData.setRows(list_signlogvo); + + } + } + + + return rspData; + + } + + + + @Override + public List getSignLogStatic(YwSignLogDTO ywSignLogDTO) { + + if(ObjectUtils.isNotEmpty(ywSignLogDTO.getGenTime())) + { + //当天的签到统计数据,当前时间大于签到计划生成时间,设置变量TODAY,用于SQL过滤 + if(StringUtils.isNotEmpty(ywSignLogDTO.getStartDate())&&StringUtils.isNotEmpty(ywSignLogDTO.getEndDate())) + { + if(ywSignLogDTO.getStartDate().substring(0,10).equals(ywSignLogDTO.getEndDate().substring(0,10))) + { + LocalDateTime now = LocalDateTime.now(); + String time = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); + if(ywSignLogDTO.getStartDate().substring(0,10).equals(time)) + { + ywSignLogDTO.setToday(true); + } + } + } + } + else + { + if(StringUtils.isNotEmpty(ywSignLogDTO.getEndDate())) + { + LocalDateTime now = LocalDateTime.now(); + LocalDateTime endTime = LocalDateTimeUtil.parse(ywSignLogDTO.getEndDate(),DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + if(now.isBefore(endTime)) + { + return ywSignLogViewMapper.getSignLogStatic(ywSignLogDTO); + } + } + } + return ywSignLogViewMapper.getSignLogStatic20231012(ywSignLogDTO); + } + + @Override + public List getSignLogAndPlan(Long venueId) { + Long userId = SecurityUtils.getUserId(); +// Date date = new Date(); +// SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); +// String today = dateFormat.format(date); + List ywScenes = ywSceneMapper.getVenueByUserId(userId); + if(CollUtil.isEmpty(ywScenes)){ + throw new ServiceException("用户未绑定场馆"); + } + return ywSignLogViewMapper.selectList(new LambdaQueryWrapper() + .eq(YwSignLogView::getSignDate, DateUtils.getNowDate()) + .eq(YwSignLogView::getUserId, userId) + .eq(YwSignLogView::getSceneId, venueId)); + + } + + @Override + public List getSignLogByPlanId(Long signPlanId) { + Long userId = SecurityUtils.getUserId(); + List ywScenes = ywSceneMapper.getVenueByUserId(userId); + if(CollUtil.isEmpty(ywScenes)){ + throw new ServiceException("用户未绑定场馆"); + } + return ywSignLogViewMapper.selectList(new LambdaQueryWrapper() + .eq(YwSignLogView::getUserId, userId) + .eq(YwSignLogView::getSignPlanId, signPlanId)); + + } +} \ No newline at end of file diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSignPlanServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSignPlanServiceImpl.java new file mode 100644 index 0000000..c880ec4 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSignPlanServiceImpl.java @@ -0,0 +1,769 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.github.pagehelper.util.StringUtil; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwSceneUser; +import com.ruoyi.eastcom_yw.domain.YwSignPlanView; +import com.ruoyi.eastcom_yw.domain.dto.YwSignPlanDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwSignPlanVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSignUserVo; +import com.ruoyi.eastcom_yw.mapper.*; +import com.ruoyi.eastcom_yw.service.YwSignPlanService; +import com.ruoyi.system.mapper.SysUserMapper; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + + +@Service +public class YwSignPlanServiceImpl extends ServiceImpl implements YwSignPlanService { + + @Autowired + private YwSignPlanMapper ywSignPlanMapper; + + @Autowired + private YwSignLogMapper ywSignLogMapper; + + @Autowired + private YwSceneMapper ywSceneMapper; + + @Autowired + private YwSceneViewMapper ywSceneViewMapper; + + @Autowired + private SysUserMapper sysUserMapper; + + @Autowired + private YwSceneUserMapper ywSceneUserMapper; + + @Override + public TableDataInfo getSignPlan(YwSignPlanDTO ywSignPlanDTO) { + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + if (ObjectUtils.isNotEmpty(ywSignPlanDTO.getVenueIds())) { + lambdaQueryWrapper.in(ywSignPlanDTO.getVenueIds().length > 0, YwSignPlanView::getSceneId, ywSignPlanDTO.getVenueIds()); + } + + //20230621获取用户自己的签到计划 + if (StringUtils.isNotEmpty(ywSignPlanDTO.getSignUsers())) { + lambdaQueryWrapper.apply("id in (select sign_plan_id from v_yw_sign_log where user_id = {0}::numeric)", ywSignPlanDTO.getSignUsers()); + } + + //20230629场馆类别的筛选 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywSignPlanDTO.getVenueType()), YwSignPlanView::getVenueType, ywSignPlanDTO.getVenueType()); + + //20230629维护类型的筛选 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywSignPlanDTO.getMaintainType()), YwSignPlanView::getMaintainType, ywSignPlanDTO.getMaintainType()); + + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywSignPlanDTO.getSignDate()), YwSignPlanView::getSignDate, + DateUtils.parseDate(ywSignPlanDTO.getSignDate())); + + lambdaQueryWrapper.between(ObjectUtils.isNotEmpty(ywSignPlanDTO.getStartDate()) && ObjectUtils.isNotEmpty(ywSignPlanDTO.getEndDate()), + YwSignPlanView::getSignDate, DateUtils.parseDate(ywSignPlanDTO.getStartDate()), DateUtils.parseDate(ywSignPlanDTO.getEndDate())); + + lambdaQueryWrapper.orderByDesc(YwSignPlanView::getSignDate, YwSignPlanView::getBeginTime); + + List list = null; + + TableDataInfo rspData = new TableDataInfo(); + + if (ObjectUtils.isNotEmpty(ywSignPlanDTO.getPageSize())) { + if (ywSignPlanDTO.getPageSize() == -1) { + list = ywSignPlanMapper.selectList(lambdaQueryWrapper); + rspData.setTotal(list.size()); + } else { + Page page = ywSignPlanMapper.selectPage(new Page<>(ywSignPlanDTO.getPageNum(), ywSignPlanDTO.getPageSize()), lambdaQueryWrapper); + list = page.getRecords(); + rspData.setTotal(page.getTotal()); + } + + if (list.size() > 0) { + List listSignPlanVo = new ArrayList<>(); + + list.forEach( + ywSignPlanView -> { + + YwSignPlanVo ywSignPlanVo = handleYwSignPlan(ywSignPlanView); + //应签到用户的人数 +// if(ObjectUtils.isNotEmpty(ywSignPlanVo.getSignUsers())&&ywSignPlanVo.getSignUsers().size()>0) { +// ywSignPlanVo.setSignUsersNum(ywSignPlanVo.getSignUsers().size()); +// } +// else +// { +// ywSignPlanVo.setSignUsersNum(0); +// } + if (ywSignPlanDTO.getIsExport()) { + if (ObjectUtils.isNotEmpty(ywSignPlanView.getSignDate())) { + ywSignPlanVo.setStrSignDate("'" + DateUtils.parseDateToStr("yyyy-MM-dd", ywSignPlanView.getSignDate()) + "'"); + } + + if (ObjectUtils.isNotEmpty(ywSignPlanView.getBeginTime())) { + ywSignPlanVo.setStrBeginTime("'" + DateUtils.parseDateToStr("HH:mm:ss", ywSignPlanView.getBeginTime()) + "'"); + } + + if (ObjectUtils.isNotEmpty(ywSignPlanView.getEndTime())) { + ywSignPlanVo.setStrEndTime("'" + DateUtils.parseDateToStr("HH:mm:ss", ywSignPlanView.getEndTime()) + "'"); + } + } + + if (!ywSignPlanDTO.getIsExport()) { + if (ObjectUtils.isNotEmpty(ywSignPlanView.getSignDate())) { + ywSignPlanVo.setStrSignDate(DateUtils.parseDateToStr("yyyy-MM-dd", ywSignPlanView.getSignDate())); + } + + if (ObjectUtils.isNotEmpty(ywSignPlanView.getBeginTime())) { + ywSignPlanVo.setStrBeginTime(DateUtils.parseDateToStr("HH:mm:ss", ywSignPlanView.getBeginTime())); + } + + if (ObjectUtils.isNotEmpty(ywSignPlanView.getEndTime())) { + ywSignPlanVo.setStrEndTime(DateUtils.parseDateToStr("HH:mm:ss", ywSignPlanView.getEndTime())); + } + } + + listSignPlanVo.add(ywSignPlanVo); + } + ); + + rspData.setRows(listSignPlanVo); + } + + } + + return rspData; + } + + + public YwSignPlanVo handleYwSignPlan(YwSignPlanView ywSignPlanView) { + YwSignPlanVo ywSignPlanVo = new YwSignPlanVo(); + + BeanUtils.copyBeanProp(ywSignPlanVo, ywSignPlanView); + + if (StringUtils.isNotEmpty(ywSignPlanView.getSignUsers())) { + String[] arrUserId = ywSignPlanView.getSignUsers().split(","); + + List lstUserId = new ArrayList<>(); + + for (String strUserId : arrUserId) { + if (NumberUtils.isCreatable(strUserId)) { + + Long userId = Long.parseLong(strUserId); + //验证用户是否在当前场馆下 + YwSceneUser sceneUser = new YwSceneUser(); + sceneUser.setUserId(userId); + sceneUser.setSceneId(ywSignPlanView.getSceneId()); + List lstSceneUser = ywSceneUserMapper.getListByUserIdAndSceneId(sceneUser); + if (!lstSceneUser.isEmpty()) { + lstUserId.add(userId); + } + } + } + + if (lstUserId.size() > 0) { + + List lstUser = sysUserMapper.selectUserByIds(lstUserId); + + if (!lstUser.isEmpty()) { + List lstSignUser = new ArrayList<>(); + for (SysUser user : lstUser) { + //不要显示冻结的 + if ("2".equals(user.getStatus())) { + continue; + } + YwSignUserVo signUser = new YwSignUserVo(); + signUser.setUserId(user.getUserId()); + signUser.setUserName(user.getNickName()); + lstSignUser.add(signUser); + } + ywSignPlanVo.setSignUsers(lstSignUser); + } + + } + + } + + return ywSignPlanVo; + } + + @Override + public List getSignPlan(Long venueId, String signDate) { + + Long user_id = SecurityUtils.getUserId(); + + return ywSignPlanMapper.getSignPlanList(user_id, venueId, signDate); + + } + + private boolean checkData(List signPlanList, Long sceneBigId) throws ParseException { + boolean checkFlag = true; + for (YwSignPlanDTO plan : signPlanList) { + StringBuilder reason = new StringBuilder(); + + if (ObjectUtils.isNotEmpty(plan.getRepSignInterval())) { + if (!(plan.getRepSignInterval().equals(1) || plan.getRepSignInterval().equals(2) || plan.getRepSignInterval().equals(4))) { + checkFlag = false; + reason.append("【签到时间量】只允许1,2,4,不填默认为4"); + } + } + + if (StringUtil.isEmpty(plan.getVenueName())) { + checkFlag = false; + reason.append("【场馆】场馆不能为空。"); + } + List venues = new ArrayList<>(); + //需要当前操作用户的ID +// Long user_id = SecurityUtils.getUserId(); + + SysUser user = SecurityUtils.getLoginUser().getUser(); + + //用户能否操作处理的场馆 + //sysadmin和admin的可以操作所有场馆,不是管理员需要验证场馆 + if (!user.isAdmin(user)) { +// if (!SecurityUtils.isAdmin(user_id)) { + venues = ywSceneMapper.getVenueByQuery(user.getUserId(), plan.getVenueName(), sceneBigId); + if (venues.isEmpty()) { + checkFlag = false; + reason.append("【场馆】当前用户没有操作【" + plan.getVenueName() + "】场馆的权限。"); + } + } + + //todo:这里应该不管是不是管理员都要验证场馆是否存在 + //todo:如果这个场馆不存在,是不是肯定不会有这个场馆的权限 +// if(!user.isAdmin(user)) { +//// if (SecurityUtils.isAdmin(user_id)) { +// QueryWrapper queryWrapper = new QueryWrapper<>(); +// queryWrapper.eq("venue_name", plan.getVenueName()); +// queryWrapper.eq("scene_big_id", sceneBigId); +// venues = ywSceneMapper.selectList(queryWrapper); +// if (venues.isEmpty()) { +// checkFlag = false; +// reason.append("【场馆】系统中没有该场馆。"); +// } +// } + + String strSignDate = plan.getSignDate().replace("'", ""); + Date signDate = null; + if (StringUtil.isEmpty(strSignDate)) { + checkFlag = false; + reason.append("【签到日期】签到日期不能为空。"); + } else if (!StringUtils.isDate(strSignDate, "yyyy-MM-dd")) { + checkFlag = false; + reason.append("【签到日期】签到日期格式不正确。"); + } else { + signDate = DateUtils.parseDate(strSignDate, "yyyy-MM-dd"); + if (signDate.before(DateUtils.dateTime("yyyy-MM-dd", DateUtils.getDate()))) { + checkFlag = false; + reason.append("【签到日期】签到日期不能早于当前日期。"); + } + } + + String strTime = plan.getBeginTime().replace("'", ""); + Date signBeginTime = null; + if (StringUtil.isEmpty(strTime)) { + checkFlag = false; + reason.append("【早签到时间】早签到时间不能为空。"); + } else if (!StringUtils.isDate(strTime, "HH:mm:ss")) { + checkFlag = false; + reason.append("【早签到时间】早签到时间格式不正确。"); + } else if (!StringUtil.isEmpty(strSignDate) && StringUtils.isDate(strSignDate, "yyyy-MM-dd")) { + String beginTime = strSignDate + " " + strTime; + signBeginTime = DateUtils.parseDate(beginTime, "yyyy-MM-dd HH:mm:ss"); + if (signBeginTime.before(DateUtils.getNowDate())) { + checkFlag = false; + reason.append("【早签到时间】签到时间不能早于当前时间。"); + } + } + + strTime = plan.getEndTime().replace("'", ""); + Date signEndTime; + if (StringUtil.isEmpty(strTime)) { + checkFlag = false; + reason.append("【晚签到时间】晚签到时间不能为空。"); + } else if (!StringUtils.isDate(strTime, "HH:mm:ss")) { + checkFlag = false; + reason.append("【晚签到时间】晚签到时间格式不正确。"); + } else if (!StringUtil.isEmpty(strSignDate) && StringUtils.isDate(strSignDate, "yyyy-MM-dd")) { + String endTime = strSignDate + " " + strTime; + signEndTime = DateUtils.parseDate(endTime, "yyyy-MM-dd HH:mm:ss"); + if (signBeginTime != null && signEndTime.before(signBeginTime)) { + checkFlag = false; + reason.append("【晚签到时间】晚签到时间必须大于早签到时间。"); + } + } + + //20230406 未对“提前通知量”进行校验 + if (!StringUtil.isEmpty(plan.getRepWarnInterval())) { + String[] arrIntervals = plan.getRepWarnInterval().split(","); + + for (String strInterval : arrIntervals) { + if (!StringUtils.isNumeric(strInterval)) { + checkFlag = false; + reason.append("【通知时间量】通知时间量必须是数字,多个用英文逗号隔开"); + } + + Integer interval = Integer.parseInt(strInterval); + + if (interval <= 0) { + checkFlag = false; + reason.append("【通知时间量】通知时间量必须大于0"); + } +//先不判断是否是5的倍数 +// if( interval % 5 != 0 ) +// { +// checkFlag = false; +// reason.append("【提醒时间量】提醒时间量必须是5的倍数"); +// } + + + } + + } + + if (StringUtil.isEmpty(plan.getNoticeType())) { + checkFlag = false; + reason.append("【通知方式】通知方式不能为空。"); + } else { + //TODO:通知方式可能是通知或者公告,不知道要不要判断 + + /*String noticeVal = DictUtils.getDictValue("sys_notice_type", plan.getNoticeType()); + if (StringUtils.isEmpty(noticeVal)) { + checkFlag = false; + reason.append("【通知方式】通知方式不正确。"); + }*/ + if (!"短信".equals(plan.getNoticeType()) && !"微信".equals(plan.getNoticeType()) && !"移动办公".equals(plan.getNoticeType()) && + !"邮件".equals(plan.getNoticeType()) && !"IVR".equals(plan.getNoticeType())) { + checkFlag = false; + reason.append("【通知方式】通知方式不正确。"); + } + } + +// if (CollectionUtil.isNotEmpty(venues) && signDate != null) { +// Long venueId = venues.get(0).getId(); +// LambdaQueryWrapper lambdaQueryWrapper2 = new LambdaQueryWrapper<>(); +// lambdaQueryWrapper2.eq(YwSignPlan::getSceneId, venueId); +// lambdaQueryWrapper2.eq(YwSignPlan::getSignDate, signDate); +// // 验证是否存在这个场馆的签到日期 +// List venuePlan = ywSignPlanMapper.selectList(lambdaQueryWrapper2); +// if (!venuePlan.isEmpty()) { +// checkFlag = false; +// reason.append("【" + DateUtils.dateTime(signDate) + "】,场馆【" + plan.getVenueName() + "】的签到计划已经存在"); +// } +// } + + plan.setReason(reason.toString()); + } + return checkFlag; + } + + @Override + public boolean insertSignPlan(YwSignPlanDTO ywSignPlanDTO) { + + ValidateSignPlan(ywSignPlanDTO); + + try { + if (ywSignPlanMapper.insertSignPlan(ywSignPlanDTO) > 0) { + return true; + } + } catch (Exception ex) { + System.out.println(ex.getMessage()); + } + + return false; + + } + + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult importSignPlan(List signPlanList, Boolean isUpdateSupport, Long sceneBigId) throws ParseException { + if (StringUtils.isNull(signPlanList) || signPlanList.size() == 0) { + throw new ServiceException("导入数据不能为空!"); + } + + // 核查数据 + boolean checkFlag; + checkFlag = checkData(signPlanList, sceneBigId); + if (!checkFlag) { + ExcelUtil util = new ExcelUtil<>(YwSignPlanDTO.class); + String fileName = (String) util.exportExcel(signPlanList, "签到导入结果").get(AjaxResult.MSG_TAG); + return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + } + + /*int successNum = 0; + int failureNum = 0; + int planNum=1; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder();*/ + + for (YwSignPlanDTO plan : signPlanList) { +// try +// { +// if ( StringUtil.isEmpty(plan.getVenueName()) ) { +// throw new ServiceException("场馆不能为空"); +// } + +// LambdaQueryWrapper lambdaQueryWrapper1=new LambdaQueryWrapper<>(); +// lambdaQueryWrapper1.eq(YwSceneView::getVenueName,plan.getVenueName()); +// //验证这个场馆是否是数据库可以用的场馆 +// List venues = ywSceneViewMapper.selectList(lambdaQueryWrapper1); + List venues; + +// Long user_id =1L; +// Long user_id = SecurityUtils.getUserId(); + +// if(!SecurityUtils.isAdmin(user_id)) { +// venues = ywSceneMapper.getVenueByQuery(user_id, plan.getVenueName(),sceneBigId); +// if (venues.isEmpty()) { +// throw new ServiceException("当前用户没有操作【"+plan.getVenueName()+"】场馆的权限"); +// } +// } + +// if(SecurityUtils.isAdmin(user_id)) +// { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("venue_name", plan.getVenueName()); + queryWrapper.eq("scene_big_id", sceneBigId); + venues = ywSceneMapper.selectList(queryWrapper); +// if (venues.isEmpty()) { +// throw new ServiceException("系统中没有该场馆"); +// } +// } + + Long venueId = venues.get(0).getId(); + + plan.setVenueIds(new Long[]{venueId}); + + + String strSignDate = plan.getSignDate().replace("'", ""); + +// if ( StringUtil.isEmpty(strSignDate) ) { +// throw new ServiceException("签到日期不能为空"); +// } +// + Date signDate = DateUtils.parseDate(strSignDate); +// +// if(ObjectUtils.isEmpty(signDate)) +// { +// throw new ServiceException("签到日期格式不正确"); +// } + + strSignDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, signDate); + + plan.setSignDates(new String[]{strSignDate}); + +// String strTime = plan.getBeginTime().replace("'",""); + +// if ( StringUtil.isEmpty(strTime) ) { +// throw new ServiceException("早签到时间不能为空"); +// } + +// String beginTime = strSignDate +" "+strTime; + +// Date signBeginTime = DateUtils.parseDate(beginTime); + +// if(ObjectUtils.isEmpty(signBeginTime)) +// { +// throw new ServiceException("早签到时间格式不正确"); +// } + +// strTime = plan.getEndTime().replace("'",""); + +// if ( StringUtil.isEmpty(strTime) ) { +// throw new ServiceException("晚签到时间不能为空"); +// } + +// String endTime = strSignDate +" "+strTime; +// +// Date signEndTime = DateUtils.parseDate(endTime); + +// if(ObjectUtils.isEmpty(signEndTime)) +// { +// throw new ServiceException("晚签到时间格式不正确"); +// } +// +// if(signEndTime.before(signBeginTime)) +// { +// throw new ServiceException("晚签到时间必须大于早签到时间"); +// } +// +// if (StringUtil.isEmpty(plan.getNoticeType()) ) { +// throw new ServiceException("提醒方式不能为空"); +// } + + //TODO:通知方式可能是通知或者公告,不知道要不要判断 + + String noticeVal = DictUtils.getDictValue("sys_notice_type", plan.getNoticeType()); +// if(StringUtils.isEmpty(noticeVal)) +// { +// throw new ServiceException("提醒方式不正确"); +// } + + plan.setNoticeType(noticeVal); + +// LambdaQueryWrapper lambdaQueryWrapper2=new LambdaQueryWrapper<>(); +// lambdaQueryWrapper2.eq(YwSignPlan::getSceneId,venueId); +// lambdaQueryWrapper2.eq(YwSignPlan::getSignDate,DateUtils.dateTime(signDate)); +// +// // 验证是否存在这个场馆的签到日期 +// List venuePlan = ywSignPlanMapper.selectList(lambdaQueryWrapper2); +// +// if(!venuePlan.isEmpty()) +// { +// throw new ServiceException("【"+DateUtils.dateTime(signDate)+"】,场馆【"+plan.getVenueName()+"】的相同场馆存在时间重叠"); +// } + + //获取场馆的人员为签到用户 +// QueryWrapper queryUserWrapper=new QueryWrapper<>(); +// queryUserWrapper.eq("scene_id",venueId); +// +// List lstSceneUser = ywSceneUserMapper.selectList(queryUserWrapper); +// +// List lstUserId = lstSceneUser.stream().map(x->x.getUserId()).collect(Collectors.toList()); +// +// plan.setSignUsers(StringUtils.join(lstUserId,",")); + + plan.setCreateBy(SecurityUtils.getUsername()); + + int res = ywSignPlanMapper.insertSignPlan(plan); + + if (res == 0) { + // 需要获取到字典标签,不然导入结果显示有问题 + plan.setNoticeType(DictUtils.getDictLabel("sys_notice_type", plan.getNoticeType())); + plan.setReason(plan.getSignDates()[0] + " " + plan.getBeginTime() + " " + plan.getEndTime() + "相同场馆存在时间重叠"); + ExcelUtil util = new ExcelUtil<>(YwSignPlanDTO.class); + String fileName = (String) util.exportExcel(signPlanList, "签到导入结果").get(AjaxResult.MSG_TAG); + return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + } + + if (res > 0) { + plan.setReason("导入成功"); + } + + /*if(!this.insertSignPlan(plan)) + { + throw new ServiceException("签到计划生成失败了,数据存在异常"); + }*/ +// } +// catch (Exception e) +// { +// /*failureNum++; +// String msg = "
" + failureNum + "、第 " + planNum + "列 导入失败:"; +// failureMsg.append(msg + e.getMessage());*/ +//// log.error(msg, e); +// } +// finally { +//// planNum++; +// } + } + /*if (failureNum > 0) + { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new ServiceException(failureMsg.toString()); + } + else + { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + }*/ + return AjaxResult.success(); + } + + @Override + @Transactional + public boolean updateSignPlan(YwSignPlanDTO ywSignPlanDTO) { + + ValidateSignPlan(ywSignPlanDTO); + + //删除这个签到计划已经生成的签到记录,重新出一份新的这个签到计划的签到记录出来 + //定时器去处理,这边就不需要再修改删除 + //ywSignLogMapper.deleteSignLogByPlan(ywSignPlanDTO.getId()); + + if (ywSignPlanMapper.updateSignPlan(ywSignPlanDTO) > 0) { + return true; + } + + return false; + } + + private void ValidateSignPlan(YwSignPlanDTO ywSignPlanDTO) { + + if (ywSignPlanDTO.getVenueIds().length == 0) { + throw new ServiceException("请选择一个场馆"); + } + + SysUser user = SecurityUtils.getLoginUser().getUser(); + + //用户能否操作处理的场馆 + //sysadmin和admin的可以操作所有场馆,不是管理员需要验证场馆 + if (!user.isAdmin(user)) { + +// 可以处理场馆数 + Integer handleVenueNum = 0; + + List venues = ywSceneMapper.getVenueByUserId(user.getUserId()); + + for (Long venueId : ywSignPlanDTO.getVenueIds()) { + + boolean canHandle = false; + + for (YwScene venue : venues) { + if (venue.getId().equals(venueId)) { + canHandle = true; + break; + } + } + + if (canHandle) { + handleVenueNum++; + } + + } + + //全部场馆都可以处理才算有权限 + if (!handleVenueNum.equals(ywSignPlanDTO.getVenueIds().length)) { + throw new ServiceException("当前用户没有操作其中一个场馆的权限"); + } + } + + + String strSignDate = ywSignPlanDTO.getSignDate().replace("'", ""); + + if (StringUtil.isEmpty(strSignDate)) { + throw new ServiceException("签到日期不能为空"); + } + + Date signDate = DateUtils.parseDate(strSignDate); + + if (ObjectUtils.isEmpty(signDate)) { + throw new ServiceException("签到日期格式不正确"); + } + + strSignDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, signDate); + + String strTime = ywSignPlanDTO.getBeginTime().replace("'", ""); + + if (StringUtil.isEmpty(strTime)) { + throw new ServiceException("早签到时间不能为空"); + } + + String beginTime = strSignDate + " " + strTime; + + Date signBeginTime = DateUtils.parseDate(beginTime); + + if (ObjectUtils.isEmpty(signBeginTime)) { + throw new ServiceException("早签到时间格式不正确"); + } + + if (signBeginTime.before(DateUtils.getNowDate())) { + throw new ServiceException("早签到时间不能早于当前时间"); + } + + strTime = ywSignPlanDTO.getEndTime().replace("'", ""); + + String endTime = strSignDate + " " + strTime; + + Date signEndTime = DateUtils.parseDate(endTime); + + if (ObjectUtils.isEmpty(signBeginTime)) { + throw new ServiceException("晚签到时间格式不正确"); + } + + if (signEndTime.before(signBeginTime)) { + throw new ServiceException("晚签到时间必须大于早签到时间"); + } + + if (ObjectUtils.isNotEmpty(ywSignPlanDTO.getId())) { + + //验证时间是否重叠 + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + lambdaQueryWrapper.ne(YwSignPlanView::getId, ywSignPlanDTO.getId()); + + lambdaQueryWrapper.in(YwSignPlanView::getSceneId, ywSignPlanDTO.getVenueIds()); + + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywSignPlanDTO.getSignDate()), YwSignPlanView::getSignDate, + DateUtils.parseDate(ywSignPlanDTO.getSignDate())); + + lambdaQueryWrapper.and( + wrapper -> wrapper + .apply("{0} between begin_time and end_time", signBeginTime).or() + .apply("{0} between begin_time and end_time", signEndTime).or() + .between(YwSignPlanView::getBeginTime, signBeginTime, signEndTime).or() + .between(YwSignPlanView::getEndTime, signBeginTime, signEndTime) + ); + + List list = ywSignPlanMapper.selectList(lambdaQueryWrapper); + + if (!list.isEmpty()) { + throw new ServiceException(ywSignPlanDTO.getSignDates()[0] + " " + ywSignPlanDTO.getBeginTime() + " " + ywSignPlanDTO.getEndTime() + "相同场馆存在时间重叠"); + } + } + + if (!StringUtil.isEmpty(ywSignPlanDTO.getRepWarnInterval())) { + String[] arrIntervals = ywSignPlanDTO.getRepWarnInterval().split(","); + + for (String strInterval : arrIntervals) { + + if (!StringUtils.isNumeric(strInterval)) { + throw new ServiceException("提醒时间量必须是数字,多个用英文逗号隔开"); + } + + Integer interval = Integer.parseInt(strInterval); + + if (interval <= 0) { + throw new ServiceException("提醒时间量必须大于0"); + } + + } + } +// 验证签到用户的ID是否是数字 +// if(StringUtils.isNotEmpty(ywSignPlanDTO.getSignUsers())) +// { +// String [] arrUsers = ywSignPlanDTO.getSignUsers().split(","); +// +// for (String strUser : arrUsers) +// { +// if(!StringUtils.isNum(strUser)) +// { +// throw new ServiceException("签到用户异常"); +// } +// } +// +// } + + } + + + @Override + @Transactional + public boolean deleteSignPlan(Long id) { + //删除已经生成的签到记录 + ywSignLogMapper.deleteSignLogByPlan(id); + //删除签到计划 + if (ywSignPlanMapper.deleteSignPlan(id) > 0) { + return true; + } + return false; + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSparePartsServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSparePartsServiceImpl.java new file mode 100644 index 0000000..4bf6542 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwSparePartsServiceImpl.java @@ -0,0 +1,162 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.importer.ImporterBase; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwSpareParts; +import com.ruoyi.eastcom_yw.domain.dto.YwSparePartsDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwSparePartsQO; +import com.ruoyi.eastcom_yw.domain.vo.YwSparePartsVO; +import com.ruoyi.eastcom_yw.importer.ImportSpareParts; +import com.ruoyi.eastcom_yw.mapper.YwSparePartsMapper; +import com.ruoyi.eastcom_yw.service.YwSparePartsService; +import com.ruoyi.eastcom_yw.service.convert.YwSparePartsConvert; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** + *

+ * 亚运备件表 服务实现类 + *

+ * + * @author yqf + * @since 2023-08-31 + */ +@Service +public class YwSparePartsServiceImpl extends ServiceImpl implements YwSparePartsService { + + @Resource + private YwSparePartsMapper ywSparePartsMapper; + + /** + * 亚运备件表列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List getData(YwSparePartsQO qo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + // 场馆名称 + .like(StrUtil.isNotBlank(qo.getVenueName()), YwSpareParts::getVenueName, qo.getVenueName()) + // 场馆类型 + .eq(StrUtil.isNotBlank(qo.getVenueType()), YwSpareParts::getVenueType, qo.getVenueType()) + // 设备类型 + .eq(StrUtil.isNotBlank(qo.getDeviceType()), YwSpareParts::getDeviceType, qo.getDeviceType()) + // 专业 + .eq(StrUtil.isNotBlank(qo.getMajor()), YwSpareParts::getMajor, qo.getMajor()) + // 联系人 + .like(StrUtil.isNotBlank(qo.getContacts()), YwSpareParts::getContacts, qo.getContacts()) + // 联系电话 + .like(StrUtil.isNotBlank(qo.getTelephone()), YwSpareParts::getTelephone, qo.getTelephone()) + ; + if(StrUtil.isNotBlank(qo.getQueryType())){ + queryWrapper.and(c -> c.like(YwSpareParts::getDeviceType, qo.getQueryType()) + .or().like(YwSpareParts::getBoardModel, qo.getQueryType()) + .or().like(YwSpareParts::getPartModel, qo.getQueryType()) + .or().like(YwSpareParts::getMajor, qo.getQueryType()) + ); + } + List list = ywSparePartsMapper.selectList(queryWrapper); + return YwSparePartsConvert.INSTANCE.entityToVoList(list); + } + + /** + * 亚运备件表分页列表 + * + * @param qo 根据需要进行传值 + * @return + */ + @Override + public IPage getDataByPage(YwSparePartsQO qo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + // 场馆名称 + .like(StrUtil.isNotBlank(qo.getVenueName()), YwSpareParts::getVenueName, qo.getVenueName()) + // 场馆类型 + .eq(StrUtil.isNotBlank(qo.getVenueType()), YwSpareParts::getVenueType, qo.getVenueType()) + // 设备类型 + .eq(StrUtil.isNotBlank(qo.getDeviceType()), YwSpareParts::getDeviceType, qo.getDeviceType()) + // 专业 + .eq(StrUtil.isNotBlank(qo.getMajor()), YwSpareParts::getMajor, qo.getMajor()) + // 联系人 + .like(StrUtil.isNotBlank(qo.getContacts()), YwSpareParts::getContacts, qo.getContacts()) + // 联系电话 + .like(StrUtil.isNotBlank(qo.getTelephone()), YwSpareParts::getTelephone, qo.getTelephone()) + ; + if(StrUtil.isNotBlank(qo.getQueryType())){ + queryWrapper.and(c -> c.like(YwSpareParts::getDeviceType, qo.getQueryType()) + .or().like(YwSpareParts::getBoardModel, qo.getQueryType()) + .or().like(YwSpareParts::getPartModel, qo.getQueryType()) + .or().like(YwSpareParts::getMajor, qo.getQueryType()) + ); + } + + Page page = page(new Page<>(qo.getPageNum(), qo.getPageSize()), queryWrapper); + IPage voPage = page.convert(YwSparePartsConvert.INSTANCE::entityToVo); + return voPage; + } + + @Override + public YwSparePartsVO fetchById(Long id) { + YwSpareParts entity = ywSparePartsMapper.selectById(id); + return YwSparePartsConvert.INSTANCE.entityToVo(entity); + } + + @Override + public boolean saveOrUpdate(YwSparePartsDTO dto) { + YwSpareParts entity = YwSparePartsConvert.INSTANCE.dtoToEntity(dto); + return saveOrUpdate(entity); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(ywSparePartsMapper.deleteBatchIds(ids)); + } + + @Override + public void export(YwSparePartsQO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List data = this.getData(qo); + ExcelUtil util = new ExcelUtil<>(YwSparePartsVO.class); + try { + util.exportExcel(response, data, "亚运备件表信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult importData(List list) throws Exception { + ImporterBase importer = new ImportSpareParts(ywSparePartsMapper); + AjaxResult ajaxResult = importer.doAdd(list, null, null); + return ajaxResult; + } +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwWireTaskLogServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwWireTaskLogServiceImpl.java new file mode 100644 index 0000000..682a75c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/YwWireTaskLogServiceImpl.java @@ -0,0 +1,533 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ArrayUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.domain.dto.TaskDTO; +import com.ruoyi.common.core.domain.dto.json.UserInfo; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.eastcom_yw.domain.YwAlarmView; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwSignLogView; +import com.ruoyi.eastcom_yw.domain.YwWireTaskLog; +import com.ruoyi.eastcom_yw.domain.dto.YwWireTaskLogDTO; +import com.ruoyi.eastcom_yw.domain.enums.WireTaskStatus; +import com.ruoyi.eastcom_yw.domain.vo.FlowContentVo; +import com.ruoyi.eastcom_yw.domain.vo.YwConstrucTeamVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSignLogVo; +import com.ruoyi.eastcom_yw.domain.vo.YwWireTaskLogVo; +import com.ruoyi.eastcom_yw.mapper.YwConstrucTeamMapper; +import com.ruoyi.eastcom_yw.mapper.YwWireTaskLogMapper; +import com.ruoyi.eastcom_yw.service.CommonService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.eastcom_yw.service.YwWireTaskLogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + *

+ * 服务实现类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Service +public class YwWireTaskLogServiceImpl extends ServiceImpl implements YwWireTaskLogService { + + + @Autowired + private YwWireTaskLogMapper ywWireTaskLogMapper; + + @Autowired + private YwSceneService yw_sceneService; + + @Autowired + private CommonService commonService; + + @Autowired + private YwConstrucTeamMapper construcTeamMapper; + + @Autowired + private RedisCache redisCache; + + private final String JOBNOPREFIX = "BX"; + + + @Override + public Boolean insertWireTaskLog(YwWireTaskLogDTO ywWireTaskLogDTO) { + + if(ywWireTaskLogMapper.insertWireTask(ywWireTaskLogDTO)>0) + { + return true; + } + + return false; + + } + + private String getJobNo() { + String date = new SimpleDateFormat("yyyyMMdd").format(new Date()); + String key = JOBNOPREFIX + date; + + if (redisCache.hasKey(key)) { + String value = redisCache.getCacheObject(key).toString(); + String[] split = value.split("-"); + if (split.length == 3) { + int i = Integer.parseInt(split[2]) + 1; + String num = String.format("%04d", i); + String v = split[0] + "-" + split[1] + "-" + num; + redisCache.setCacheObject(key,v,1, TimeUnit.DAYS); + return v; + } + } + String value = JOBNOPREFIX + "-" + date + "-" + "0001"; + redisCache.setCacheObject(key,value,1, TimeUnit.DAYS); + return value; + } + + @Override + public String insertWireTaskLogReWireTaskId(YwWireTaskLogDTO ywWireTaskLogDTO) { + + if(StringUtils.isEmpty(ywWireTaskLogDTO.getWireTaskName())) + { + throw new ServiceException("任务名称不能为空"); + } + + //只有布线和布线拆除才需要通过场馆ID找施工队 + if(ywWireTaskLogDTO.getTaskType()==1||ywWireTaskLogDTO.getTaskType()==2) + { + if(ywWireTaskLogDTO.getTaskType()==1) + { + //新增布线任务的时候自动生成布线任务Id + //taskType=1,不管是否有WireTaskId,都是系统新增一条 +// if(StringUtils.isEmpty(ywWireTaskLogDTO.getWireTaskId())) +// { + //通过数据库表生成,因为异常原因可能导致重复的任务ID,需要修改成其它方案 +// String wireTaskId=ywWireTaskLogMapper.getWireTaskId(); + String wireTaskId=getJobNo(); + ywWireTaskLogDTO.setWireTaskId(wireTaskId); +// } + } + + if(ObjectUtils.isEmpty(ywWireTaskLogDTO.getVenueId())) + { + throw new ServiceException("没有场馆数据,无法新增任务"); + } + + //布线和拆线根据布线任务的场馆ID自动生成相应施工单位 + if(ObjectUtils.isNotEmpty(ywWireTaskLogDTO.getVenueId())) + { + List lstYct = construcTeamMapper.getConstrucTeamByVenueId(ywWireTaskLogDTO.getVenueId()); + + if(lstYct.size()==0) + { + throw new ServiceException("没有找到该场馆的施工队,请先配置施工队"); + } + + if(lstYct.size()>0) + { + ywWireTaskLogDTO.setConstrucUnit(lstYct.get(0).getVenderName()); + } + } + } + + if(StringUtils.isEmpty(ywWireTaskLogDTO.getWireTaskId())) + { + throw new ServiceException("没有任务ID,无法新增任务"); + } + + if(ywWireTaskLogDTO.getTaskType()==3||ywWireTaskLogDTO.getTaskType()==4) + { + String [] strWireTaskIds = ywWireTaskLogDTO.getWireTaskId().split("-"); + + if(strWireTaskIds.length!=4) + { + throw new ServiceException("任务ID号存在异常,无法新增任务"); + } + +// 取前三个 + String faterWireTaskId = StringUtils.join(ArrayUtil.remove(strWireTaskIds,3),"-"); + + //查找相应的任务类型的施工单位 + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + lambdaQueryWrapper.eq(YwWireTaskLog::getWireTaskId,faterWireTaskId); + + if(ywWireTaskLogDTO.getTaskType()==3) + { + lambdaQueryWrapper.eq(YwWireTaskLog::getTaskType,1); + } + if(ywWireTaskLogDTO.getTaskType()==4) + { + lambdaQueryWrapper.eq(YwWireTaskLog::getTaskType,2); + } + + YwWireTaskLog taskLog = ywWireTaskLogMapper.selectOne(lambdaQueryWrapper); + + if(taskLog==null) + { + throw new ServiceException("未找到相关任务,数据有错误,无法结算"); + } + + if(taskLog!=null) + { + ywWireTaskLogDTO.setVenueId(taskLog.getVenueId()); + ywWireTaskLogDTO.setConstrucUnit(taskLog.getConstrucUnit()); + } + + } + + if(ywWireTaskLogMapper.insertWireTask(ywWireTaskLogDTO)>0) + { + return ywWireTaskLogDTO.getWireTaskId(); + } + + return ""; + } + + @Override + public Boolean updateWireTaskLog(YwWireTaskLogDTO ywWireTaskLogDTO) { + + if(StringUtils.isEmpty(ywWireTaskLogDTO.getWireTaskId())) + { + throw new ServiceException("请求的任务ID不能为空"); + } + + if(StringUtils.isEmpty(ywWireTaskLogDTO.getFlwProcessid())) + { + throw new ServiceException("请求的流程ID不能为空"); + } + + if(ObjectUtils.isEmpty(ywWireTaskLogDTO.getTaskType())) + { + throw new ServiceException("请求的任务类型不能为空"); + } + + if(ywWireTaskLogMapper.updateWireTask(ywWireTaskLogDTO)>0) + { + return true; + } + + return false; + + } + + @Override + public Boolean deleteWireTaskLog(YwWireTaskLogDTO ywWireTaskLogDTO) { + + if(StringUtils.isEmpty(ywWireTaskLogDTO.getWireTaskId())) + { + throw new ServiceException("请求的任务ID不能为空"); + } + + if(ObjectUtils.isEmpty(ywWireTaskLogDTO.getTaskType())) + { + throw new ServiceException("请求的任务类型不能为空"); + } + + if(ywWireTaskLogMapper.deleteWireTask(ywWireTaskLogDTO)>0) + { + return true; + } + + return false; + + } + + + @Override + public TableDataInfo getWireTaskLog(YwWireTaskLogDTO ywWireTaskLogDTO) { + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + //20230314增加任务号 +// lambdaQueryWrapper.like(StringUtils.isNotEmpty(ywWireTaskLogDTO.getWireTaskId()),YwWireTaskLog::getWireTaskId,ywWireTaskLogDTO.getWireTaskId()); + //20230314增加任务号和任务名称的一起筛选 + if(StringUtils.isNotEmpty(ywWireTaskLogDTO.getWireTaskId())) { + lambdaQueryWrapper.and(i -> i.like(YwWireTaskLog::getWireTaskId, ywWireTaskLogDTO.getWireTaskId()) + .or().like(YwWireTaskLog::getWireTaskName, ywWireTaskLogDTO.getWireTaskId())); + } + //20230314增加创建人 + lambdaQueryWrapper.like(StringUtils.isNotEmpty(ywWireTaskLogDTO.getCreater()),YwWireTaskLog::getCreateName,ywWireTaskLogDTO.getCreater()); + + lambdaQueryWrapper.like(StringUtils.isNotEmpty(ywWireTaskLogDTO.getCurrentUser()),YwWireTaskLog::getDealUser,ywWireTaskLogDTO.getCurrentUser()); + + lambdaQueryWrapper.like(StringUtils.isNotEmpty(ywWireTaskLogDTO.getSgdw()),YwWireTaskLog::getConstrucUnit,ywWireTaskLogDTO.getSgdw()); + + //20230303区县改为AreaCountyId查询 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywWireTaskLogDTO.getCounty()),YwWireTaskLog::getAreaCountyId,ywWireTaskLogDTO.getCounty()); + + //20230809,APP端增加地市的查询 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywWireTaskLogDTO.getCity()),YwWireTaskLog::getCity,ywWireTaskLogDTO.getCity()); + + //20230313 jkj 增加场馆ID筛选 + if(ObjectUtils.isNotEmpty(ywWireTaskLogDTO.getVenueIds())) { + lambdaQueryWrapper.in(ywWireTaskLogDTO.getVenueIds().length > 0, YwWireTaskLog::getVenueId, ywWireTaskLogDTO.getVenueIds()); + } + //20230303任务名称模糊查询 + lambdaQueryWrapper.like(StringUtils.isNotEmpty(ywWireTaskLogDTO.getWireTaskName()), YwWireTaskLog::getWireTaskName, ywWireTaskLogDTO.getWireTaskName()); + + if(ObjectUtils.isNotEmpty(ywWireTaskLogDTO.getTaskTypes())) + { + lambdaQueryWrapper.in(ywWireTaskLogDTO.getTaskTypes().length>0,YwWireTaskLog::getTaskType,ywWireTaskLogDTO.getTaskTypes()); + } + + //20230310 增加新的筛选 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywWireTaskLogDTO.getStatus()),YwWireTaskLog::getDealStatus,ywWireTaskLogDTO.getStatus()); + //20230310 增加按当前环节筛选 + lambdaQueryWrapper.like(StringUtils.isNotEmpty(ywWireTaskLogDTO.getCurStep()),YwWireTaskLog::getCurStep,ywWireTaskLogDTO.getCurStep()); + + //告警的时间 + lambdaQueryWrapper.between(StrUtil.isNotBlank(ywWireTaskLogDTO.getStartTime()) && StrUtil.isNotBlank(ywWireTaskLogDTO.getEndTime()), YwWireTaskLog::getCreateTime,DateUtils.parseDate(ywWireTaskLogDTO.getStartTime()) , DateUtils.parseDate(ywWireTaskLogDTO.getEndTime())); + + //20230703增加场馆类型和维护类型的筛选 + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywWireTaskLogDTO.getVenueType()),YwWireTaskLog::getVenueType,ywWireTaskLogDTO.getVenueType()); + + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywWireTaskLogDTO.getMaintainType()),YwWireTaskLog::getMaintainType,ywWireTaskLogDTO.getMaintainType()); + + TableDataInfo rspData = new TableDataInfo(); + List list = null; + if (ObjectUtils.isNotEmpty(ywWireTaskLogDTO.getPageSize())) { + + + if (ywWireTaskLogDTO.getPageSize() == -1) { + list = ywWireTaskLogMapper.selectList(lambdaQueryWrapper); + rspData.setTotal(list.size()); + } else { + + if(ObjectUtils.isEmpty(ywWireTaskLogDTO.getPageNum())) + { + ywWireTaskLogDTO.setPageNum(1); + } + + Page page = ywWireTaskLogMapper.selectPage(new Page<>(ywWireTaskLogDTO.getPageNum(), ywWireTaskLogDTO.getPageSize()), lambdaQueryWrapper); + list = page.getRecords(); + rspData.setTotal(page.getTotal()); + } + + // 没有加这个导致前端返回的rows为null + // rspData.setRows(list); + + if (list.size() > 0) { + + List list_wireTaskLogVo = new ArrayList<>(); + + + //导出加字段 + if(ywWireTaskLogDTO.getIsExport()) + { + List lstFC = ywWireTaskLogMapper.getWireTaskFlowContent(); + + for (YwWireTaskLog ywWireTaskLog : list) { + YwWireTaskLogVo ywWireTaskLogVo = new YwWireTaskLogVo(); + BeanUtils.copyBeanProp(ywWireTaskLogVo, ywWireTaskLog); + list_wireTaskLogVo.add(ywWireTaskLogVo); + + if (ObjectUtils.isNotEmpty(ywWireTaskLog.getCreateTime())) { + ywWireTaskLogVo.setStrCreateTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", ywWireTaskLog.getCreateTime())); + } + + if (ObjectUtils.isNotEmpty(ywWireTaskLog.getEndTime())) { + ywWireTaskLogVo.setStrEndTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", ywWireTaskLog.getEndTime())); + } + + List lstFC2 = lstFC.stream().filter(x->x.getFlwId().equals(ywWireTaskLog.getFlwProcessid())).collect(Collectors.toList()); + + //任务子类 + List lstTaskSubType = lstFC2.stream().filter(x->x.getName().equals("select_tasksubtype")).map(FlowContentVo::getText).collect(Collectors.toList()); + + if(!lstTaskSubType.isEmpty()) + { + ywWireTaskLogVo.setTaskSubType(lstTaskSubType.get(0)); + } + + //比赛名称 + List lstScxx = lstFC2.stream().filter(x->x.getName().equals("select_scxx")).map(FlowContentVo::getMatchName).collect(Collectors.toList()); + + if(!lstScxx.isEmpty()) + { + ywWireTaskLogVo.setScxx(lstScxx.get(0)); + } + + //任务描述 + List lstRwms = lstFC2.stream().filter(x->x.getName().equals("textarea_rwms")).map(FlowContentVo::getText).collect(Collectors.toList()); + + if(!lstRwms.isEmpty()) + { + ywWireTaskLogVo.setRwms(lstRwms.get(0)); + } + + if(StringUtils.isEmpty(ywWireTaskLog.getCurStep())) + { + continue; + } + + int taskCode = WireTaskStatus.getCodeByLabel(ywWireTaskLog.getCurStep()); + + if(ywWireTaskLog.getCurStep().contains(",")) + { + taskCode = WireTaskStatus.sgjs.getCode(); + } + +// if(("任务审核").equals(ywWireTaskLog.getCurStep())) +// { +// continue; +// } + + if(taskCode == WireTaskStatus.rwsh.getCode()) + { + continue; + } + + //任务审核结果 + List lstShjg = lstFC2.stream().filter(x->x.getName().equals("radio_shjg2")).map(FlowContentVo::getText).collect(Collectors.toList()); + + if(!lstShjg.isEmpty()) + { + if(lstShjg.get(0).equals("ok")) + { + if(taskCode>WireTaskStatus.rwsh.getCode()) { + ywWireTaskLogVo.setShjg(1); + } + } + else + { + ywWireTaskLogVo.setShjg(0); + } + } + + + //任务审核说明 + List lstShsm = lstFC2.stream().filter(x -> x.getName().equals("textarea_sm3")).map(FlowContentVo::getText).collect(Collectors.toList()); + + if (!lstShsm.isEmpty()) { + ywWireTaskLogVo.setShsm(lstShsm.get(0)); + } + + //图纸说明 + List lstTzsm = lstFC2.stream().filter(x -> x.getName().equals("textarea_tzsm")).map(FlowContentVo::getText).collect(Collectors.toList()); + + if (!lstTzsm.isEmpty()) { + ywWireTaskLogVo.setTzsm(lstTzsm.get(0)); + } + + if(taskCode == WireTaskStatus.tzqr.getCode()) + { + continue; + } + + //图纸确认结果 + List lstTzjg = lstFC2.stream().filter(x -> x.getName().equals("radio_shjg")).map(FlowContentVo::getText).collect(Collectors.toList()); + + if (!lstTzjg.isEmpty()) { + if (lstTzjg.get(0).equals("ok")) { + if(taskCode>WireTaskStatus.tzqr.getCode()) { + ywWireTaskLogVo.setTzjg(1); + } + } else { + ywWireTaskLogVo.setTzjg(0); + } + + + //图纸确认说明 + List lstTzqrsm = lstFC2.stream().filter(x -> x.getName().equals("textarea_sm1")).map(FlowContentVo::getText).collect(Collectors.toList()); + + if (!lstTzqrsm.isEmpty()) { + + ywWireTaskLogVo.setTzqrsm(lstTzqrsm.get(0)); + } + } + + if(taskCode == WireTaskStatus.xcys.getCode()) + { + continue; + } + + //现场验收结果 + List lstYsjg = lstFC2.stream().filter(x -> x.getName().equals("radio_qrjg")).map(FlowContentVo::getText).collect(Collectors.toList()); + + if (!lstYsjg.isEmpty()) { + if (lstYsjg.get(0).equals("ok")) { + if(taskCode == WireTaskStatus.lcjs.getCode()) { + ywWireTaskLogVo.setYsjg(1); + } + } else { + ywWireTaskLogVo.setYsjg(0); + } + } + + //现场验收说明 + List lstYssm = lstFC2.stream().filter(x -> x.getName().equals("textarea_sm2")).map(FlowContentVo::getText).collect(Collectors.toList()); + + if (!lstYssm.isEmpty()) { + ywWireTaskLogVo.setYssm(lstYssm.get(0)); + } + + + } + + } + else { + for (YwWireTaskLog ywWireTaskLog : list) { + YwWireTaskLogVo ywWireTaskLogVo = new YwWireTaskLogVo(); + BeanUtils.copyBeanProp(ywWireTaskLogVo, ywWireTaskLog); + list_wireTaskLogVo.add(ywWireTaskLogVo); + + if (ObjectUtils.isNotEmpty(ywWireTaskLog.getCreateTime())) { + ywWireTaskLogVo.setStrCreateTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", ywWireTaskLog.getCreateTime())); + } + + if (ObjectUtils.isNotEmpty(ywWireTaskLog.getEndTime())) { + ywWireTaskLogVo.setStrEndTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", ywWireTaskLog.getEndTime())); + } + } + } + + if(ywWireTaskLogDTO.getIsApp()) { + //查询工作流,比较是否是当前登录用户的待办 + List processIds = commonService.selectCurrenUserTodoProcessId(null); + if (CollUtil.isNotEmpty(processIds)) { + for (String processId : processIds) { + list_wireTaskLogVo.stream().filter(l -> processId.equals(l.getFlwProcessid())).findAny().ifPresent(a -> { + a.setIsTodo(1); + }); + } + } + } + + + rspData.setRows(list_wireTaskLogVo); + + } + + + } + + return rspData; + } + + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/yw_alarm_deal_logServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/yw_alarm_deal_logServiceImpl.java new file mode 100644 index 0000000..3083218 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/yw_alarm_deal_logServiceImpl.java @@ -0,0 +1,63 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.eastcom_yw.domain.yw_alarm_deal_log; +import com.ruoyi.eastcom_yw.mapper.yw_alarm_deal_logMapper; +import com.ruoyi.eastcom_yw.mapper.yw_alarm_deal_resMapper; +import com.ruoyi.eastcom_yw.service.yw_alarm_deal_logService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + + +/** + *

+ * 服务实现类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Service +public class yw_alarm_deal_logServiceImpl extends ServiceImpl implements yw_alarm_deal_logService { + + + @Autowired + private yw_alarm_deal_resMapper alarm_deal_resMapper; + + @Autowired + private yw_alarm_deal_logMapper alarm_deal_logMapper; + + @Deprecated + private void update_yw_alarm_deal_schedule() { + + //弃用,原来需要做定时器同步工作流的操作用户和状态,现在直接通过关联 + //数据库关联都用v_yw_alarm_deal_log的视图,yw_alarm_deal_log表不再更新deal_user,deal_status,end_time + int res =alarm_deal_resMapper.selectList(null).size(); + + alarm_deal_resMapper.selectList(null).forEach( + + alarm_deal->{ + + yw_alarm_deal_log yw_alarm_deal_log=new yw_alarm_deal_log(); + + yw_alarm_deal_log.setId(alarm_deal.getId()); + + yw_alarm_deal_log.setDealUser(alarm_deal.getAssignee()); + + yw_alarm_deal_log.setDealStatus(alarm_deal.getProcessstatus()); + + yw_alarm_deal_log.setEndTime(alarm_deal.getEndTime()); + + alarm_deal_logMapper.updateById(yw_alarm_deal_log); + + } + ); + } + + @Override + public void updateEndTime() + { + alarm_deal_logMapper.updateEndTime(); + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/yw_alarm_deal_resServiceImpl.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/yw_alarm_deal_resServiceImpl.java new file mode 100644 index 0000000..60dce5b --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/impl/yw_alarm_deal_resServiceImpl.java @@ -0,0 +1,20 @@ +package com.ruoyi.eastcom_yw.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.eastcom_yw.domain.yw_alarm_deal_res; +import com.ruoyi.eastcom_yw.mapper.yw_alarm_deal_resMapper; +import com.ruoyi.eastcom_yw.service.yw_alarm_deal_resService; +import org.springframework.stereotype.Service; + +/** + *

+ * 服务实现类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +@Service +public class yw_alarm_deal_resServiceImpl extends ServiceImpl implements yw_alarm_deal_resService { + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/yw_alarm_deal_logService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/yw_alarm_deal_logService.java new file mode 100644 index 0000000..a34a6f6 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/yw_alarm_deal_logService.java @@ -0,0 +1,17 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.yw_alarm_deal_log; + +/** + *

+ * 服务类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +public interface yw_alarm_deal_logService extends IService { + + public void updateEndTime(); +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/yw_alarm_deal_resService.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/yw_alarm_deal_resService.java new file mode 100644 index 0000000..d9415d3 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/service/yw_alarm_deal_resService.java @@ -0,0 +1,16 @@ +package com.ruoyi.eastcom_yw.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.eastcom_yw.domain.yw_alarm_deal_res; + +/** + *

+ * 服务类 + *

+ * + * @author jkj + * @since 2023-01-06 + */ +public interface yw_alarm_deal_resService extends IService { + +} diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2AgisLink5miMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2AgisLink5miMapper.xml new file mode 100644 index 0000000..dcb2647 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2AgisLink5miMapper.xml @@ -0,0 +1,23 @@ + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2MmlListMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2MmlListMapper.xml new file mode 100644 index 0000000..39995df --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2MmlListMapper.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2PnNetVenue5miMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2PnNetVenue5miMapper.xml new file mode 100644 index 0000000..6181604 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2PnNetVenue5miMapper.xml @@ -0,0 +1,35 @@ + + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2SpotCellMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2SpotCellMapper.xml new file mode 100644 index 0000000..8186585 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2SpotCellMapper.xml @@ -0,0 +1,16 @@ + + + + + delete from dp_2_spot_cell + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2SpotConfigMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2SpotConfigMapper.xml new file mode 100644 index 0000000..aeb88d1 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2SpotConfigMapper.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2ViewPowerAlarmMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2ViewPowerAlarmMapper.xml new file mode 100644 index 0000000..eb6bebf --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2ViewPowerAlarmMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2ViewWirelessAlarmMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2ViewWirelessAlarmMapper.xml new file mode 100644 index 0000000..7a771ab --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/Dp2ViewWirelessAlarmMapper.xml @@ -0,0 +1,23 @@ + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/DpSceneConfigMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/DpSceneConfigMapper.xml new file mode 100644 index 0000000..d547a4d --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/DpSceneConfigMapper.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/LargeScreenMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/LargeScreenMapper.xml new file mode 100644 index 0000000..45a569e --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/LargeScreenMapper.xml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi4gCellMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi4gCellMapper.xml new file mode 100644 index 0000000..dfbed08 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi4gCellMapper.xml @@ -0,0 +1,421 @@ + + + + + + + + + + + + + + update dp_scene_control set mintype = #{mintype},nettype=#{nettype},kpiname = #{kpiname} where id = 1 + + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi4gMinMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi4gMinMapper.xml new file mode 100644 index 0000000..f30bb46 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi4gMinMapper.xml @@ -0,0 +1,184 @@ + + + + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi4gVenueMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi4gVenueMapper.xml new file mode 100644 index 0000000..9dbb117 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi4gVenueMapper.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi5gCellMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi5gCellMapper.xml new file mode 100644 index 0000000..d06216f --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi5gCellMapper.xml @@ -0,0 +1,397 @@ + + + + + + + + + + + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi5gMinMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi5gMinMapper.xml new file mode 100644 index 0000000..a36e485 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi5gMinMapper.xml @@ -0,0 +1,178 @@ + + + + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi5gVenueMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi5gVenueMapper.xml new file mode 100644 index 0000000..02b5c04 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/PmKpi5gVenueMapper.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/SysNoticeMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/SysNoticeMapper.xml new file mode 100644 index 0000000..cb9cafd --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/SysNoticeMapper.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + update sys_notice set status='1' + where notice_id in + + #{noticeId} + + + + + + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmHangupLogMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmHangupLogMapper.xml new file mode 100644 index 0000000..b8fe33a --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmHangupLogMapper.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmMapper.xml new file mode 100644 index 0000000..8bb8083 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmMapper.xml @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + update hm_trans_alarm set 恢复时间 = now()::timestamp(0) without time zone , 修改时间 = now()::timestamp(0) without time zone + where id = #{alarmId} and 恢复时间 is null + + + update hm_dyn_ring_alarm set 恢复时间 = now()::timestamp(0) without time zone , 修改时间 = now()::timestamp(0) without time zone + where id = #{alarmId} and 恢复时间 is null + + + update hm_wireless_alarm set 恢复时间 = now()::timestamp(0) without time zone , 修改时间 = now()::timestamp(0) without time zone + where id = #{alarmId} and 恢复时间 is null + + + update hm_alarm_derive set 恢复时间 = now()::timestamp(0) without time zone , 修改时间 = now()::timestamp(0) without time zone + where id = #{alarmId} and 恢复时间 is null + + + + update hm_agis_alarm set 恢复时间 = now()::timestamp(0) without time zone , 修改时间 = now()::timestamp(0) without time zone + where id = #{alarmId} and 恢复时间 is null + + + + + + + + + + update hm_trans_alarm set 恢复时间 = now() ::timestamp(0) without time zone , 修改时间 = now()::timestamp(0) without time zone + where groupid = #{groupId} and 恢复时间 is null + + + update hm_dyn_ring_alarm set 恢复时间 = now()::timestamp(0) without time zone , 修改时间 = now()::timestamp(0) without time zone + where 关联组号 = #{groupId} and 恢复时间 is null + + + update hm_wireless_alarm set 恢复时间 = now()::timestamp(0) without time zone , 修改时间 = now()::timestamp(0) without time zone + where 关联组号 = #{groupId} and 恢复时间 is null + + + update hm_alarm_derive set 恢复时间 = now()::timestamp(0) without time zone , 修改时间 = now()::timestamp(0) without time zone + where groupid = #{groupId} and 恢复时间 is null + + + + update hm_agis_alarm set 恢复时间 = now()::timestamp(0) without time zone , 修改时间 = now()::timestamp(0) without time zone + where groupid = #{groupId} and 恢复时间 is null + + + + + + + + + + update dx_ag_transmition set closed=1 + where groupid = #{groupId} + + + + update dx_ag_power set closed=1 + where 关联组号 = #{groupId} + + + + update dx_ag_wireless set closed=1 + where 关联组号= #{groupId} + + + + + + + + + update dx_ag_agis set closed=1 + where groupid = #{groupId} + + + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmStatisticsMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmStatisticsMapper.xml new file mode 100644 index 0000000..5ad65fc --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmStatisticsMapper.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + insert into public.yw_alarm_statistics(profession, create_time, scene_id, num) + values + + (#{entity.profession}, #{entity.createTime}, #{entity.sceneId}, #{entity.num}) + + + + delete from yw_alarm_statistics + + AND create_time now() + '-2 hour' + + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmViewMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmViewMapper.xml new file mode 100644 index 0000000..3363e7a --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwAlarmViewMapper.xml @@ -0,0 +1,510 @@ + + + + + + + + + and area_county_id like CONCAT('%',cast(#{city} as varchar),'%') + + + + + + + + + + + + + + + + and t_status.alarm_status = #{alarmStatus} and (t_deal.assignee_ != '2' or t_deal.assignee_ is null) + + + + + + + + + and case when t_status is not null then t_status.alarm_status else case when t1.end_time is null then '0' else '1' end end = #{alarmStatus} + and (t_deal.assignee_ != '2' or t_deal.assignee_ is null) + + + + + + + and t1.site_type=#{siteType} + + + + and t2.alarm_level in + + #{alarmLevel} + + + + + and t1.is_red=#{inRedLine} + + + + and sc.area_county_id = #{county} + + + + + and t_status.text_ = #{dealStatus} + + + + + + and (t_status.text_ in ('1','4','5') or t_status.text_ is null) + + + + + + + + and t1.scene_id in + + #{venueId} + + + + + and t1.scene_id in (select scene_id from yw_scene_user where user_id= #{userId}) + + + + + + and t2.start between #{startTime}::TIMESTAMP and #{endTime}::TIMESTAMP + + + + AND concat(t2.name,',',t2.net_name,',',t2.site_name,',',t2.site_id,',',su.nick_name) LIKE CONCAT('%',#{searchBox} :: text,'%') + + + + and sc.venue_type = #{venueType} + + + and sc.maintain_type = #{maintainType} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwConstrucTeamMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwConstrucTeamMapper.xml new file mode 100644 index 0000000..aeaf6f3 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwConstrucTeamMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwDrsConfigMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwDrsConfigMapper.xml new file mode 100644 index 0000000..062d37e --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwDrsConfigMapper.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwDrsTempTaskMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwDrsTempTaskMapper.xml new file mode 100644 index 0000000..f92ef12 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwDrsTempTaskMapper.xml @@ -0,0 +1,31 @@ + + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwKpiConfigMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwKpiConfigMapper.xml new file mode 100644 index 0000000..7448cb4 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwKpiConfigMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeBriefingMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeBriefingMapper.xml new file mode 100644 index 0000000..2872926 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeBriefingMapper.xml @@ -0,0 +1,41 @@ + + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeHandworkMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeHandworkMapper.xml new file mode 100644 index 0000000..3a8d8e3 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeHandworkMapper.xml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeModelMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeModelMapper.xml new file mode 100644 index 0000000..cc316ec --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeModelMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeObjectMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeObjectMapper.xml new file mode 100644 index 0000000..4667d62 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeObjectMapper.xml @@ -0,0 +1,14 @@ + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeUserMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeUserMapper.xml new file mode 100644 index 0000000..87e9bb8 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwNoticeUserMapper.xml @@ -0,0 +1,63 @@ + + + + + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectConfigMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectConfigMapper.xml new file mode 100644 index 0000000..24eb1c6 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectConfigMapper.xml @@ -0,0 +1,102 @@ + + + + + + + + + SELECT currval(pg_get_serial_sequence('yw_rout_inspect_config','id')) + + insert into yw_rout_inspect_config + + + scene_id, + + + specialty, + + + check_num, + + + check_type, + + + check_desc, + + + circle, + + + stop_time_option, + + + interval_time, + + + scene_big_id, + + + inspect_user_id, + + + rep_warn_interval, + + + notice_type, + + + + + #{sceneId}, + + + #{specialty}, + + + #{checkNum}, + + + #{checkType}, + + + #{checkDesc}, + + + #{circle}, + + + #{stopTimeOption}, + + + #{intervalTime}, + + + #{sceneBigId}, + + + #{inspectUserId}, + + + #{repWarnInterval}, + + + #{noticeType}, + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectLogMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectLogMapper.xml new file mode 100644 index 0000000..14e8446 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectLogMapper.xml @@ -0,0 +1,90 @@ + + + + + + + SELECT currval(pg_get_serial_sequence('yw_rout_inspect_log','id')) + + insert into yw_rout_inspect_log + + + rout_inspect_id, + + + flw_processid, + + + check_num, + + + question_num, + + + question_desc, + + + feed_back_user, + + + feed_back_time, + + + + + #{routInspectId}, + + + #{flwProcessid}, + + + #{checkNum}, + + + #{questionNum}, + + + #{{questionDesc}}, + + + #{feedBackUser}, + + + #{feedBackTime}, + + + + + update yw_rout_inspect_log + + + check_num = #{checkNum}, + + + question_num = #{questionNum}, + + + question_desc = #{questionDesc}, + + + feed_back_user = #{feedBackUser}::numeric, + + + feed_back_time = #{feedBackTime}, + + + where flw_processid = #{flwProcessid} and feed_back_time is null + + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectPlanMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectPlanMapper.xml new file mode 100644 index 0000000..0b6a37a --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectPlanMapper.xml @@ -0,0 +1,574 @@ + + + + + + + AND POSITION((#{city}) IN (area_county_id)) > 0 + + + AND area_county_id = #{county} + + + AND scene_id IN #{venueId} + + + AND inspect_specialty = #{specialty} + + + AND begin_time between #{beginDate}::TIMESTAMP and #{endDate}::TIMESTAMP + + + and venue_type = #{venueType} + + + and maintain_type = #{maintainType} + + + and scene_id in (SELECT id FROM yw_scene t where t.venue_type='比赛场馆' and match_type is not null and area_county_id like '0571%') + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM yw_rout_inspect_config WHERE scene_id = #{sceneId} AND specialty = #{specialty} + AND id NOT IN #{configId} + + + + delete from yw_rout_inspect_plan where job_no = #{jobNo} + and inspect_specialty not in #{specialty} + + + + + SELECT currval(pg_get_serial_sequence('yw_rout_inspect_plan','id')) + + insert into yw_rout_inspect_plan + + + scene_id, + + + inspect_date, + + + inspect_specialty, + + + begin_time, + + + plan_fin_time, + + + scene_big_id, + + + type, + + + inspect_name, + + + check_num, + + + check_type, + + + check_desc, + + + circle, + + + stop_time_option, + + + interval_time, + + + inspect_user_id, + + + rep_warn_interval, + + + notice_type, + + + job_no, + + + city, + + + county, + + + description, + + + + + #{sceneId}, + + + #{inspectDate, jdbcType=DATE}, + + + #{inspectSpecialty}, + + + #{beginTime}::timestamp, + + + #{planFinTime}::timestamp, + + + #{sceneBigId}, + + + #{type}, + + + #{inspectName}, + + + #{checkNum}, + + + #{checkType}, + + + #{checkDesc}, + + + #{circle}, + + + #{stopTimeOption}, + + + #{intervalTime}, + + + #{inspectUserId}, + + + #{repWarnInterval}, + + + #{noticeType}, + + + #{jobNo}, + + + #{city}, + + + #{county}, + + + #{description}, + + + + + + update yw_rout_inspect_plan + + + scene_id = #{sceneId}, + + + inspect_date = #{inspectDate, jdbcType=DATE}, + + + inspect_specialty = #{inspectSpecialty}, + + + begin_time = #{beginTime}::TIMESTAMP, + + + plan_fin_time = #{planFinTime}::TIMESTAMP, + + + scene_big_id = #{sceneBigId}, + + + type = #{type}, + + + inspect_name = #{inspectName}, + + + check_num = #{checkNum}, + + + check_type = #{checkType}, + + + check_desc = #{checkDesc}, + + + circle = #{circle}, + + + stop_time_option = #{stopTimeOption}, + + + interval_time = #{intervalTime}, + + + inspect_user_id = #{inspectUserId}, + + + rep_warn_interval = #{repWarnInterval}, + + + notice_type = #{noticeType}, + + + description = #{description}, + + + where job_no = #{jobNo} + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectQuestionConfigMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectQuestionConfigMapper.xml new file mode 100644 index 0000000..6514652 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwRoutInspectQuestionConfigMapper.xml @@ -0,0 +1,77 @@ + + + + + + + + + SELECT currval(pg_get_serial_sequence('yw_rout_inspect_question_config','id')) + + insert into yw_rout_inspect_question_config + + + question_type, + + + question_son_type, + + + scene_big_id, + + + specialty_id, + + + + + #{questionType}, + + + #{questionSonType}, + + + #{sceneBigId}, + + + #{specialtyId}, + + + + + + update yw_rout_inspect_question_config + + + question_type = #{questionType}, + + + question_son_type = #{questionSonType}, + + + scene_big_id = #{sceneBigId}, + + + specialty_id = #{specialtyId}, + + + where id = #{id} + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneAlarmMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneAlarmMapper.xml new file mode 100644 index 0000000..1d7b581 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneAlarmMapper.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + SELECT currval(pg_get_serial_sequence('yw_scene_alarm','id')) + + insert into yw_scene_alarm + + + scene_id, + + + alarm_code, + + + alarm_name, + + + blackorwhite, + + + alarm_specity_id, + + + status, + + + + + #{sceneId}, + + + #{alarmCode}, + + + #{alarmName}, + + + #{blackorwhite}, + + + #{alarmSpecityId}, + + + #{status}, + + + + + + update yw_scene_alarm + + + scene_id = #{sceneId}, + + + alarm_code = #{alarmCode}, + + + alarm_name = #{alarmName}, + + + blackorwhite = #{blackorwhite}, + + + alarm_specity_id = #{alarmSpecityId}, + + + status = #{status}, + + + where id = #{id} + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneBigConfigMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneBigConfigMapper.xml new file mode 100644 index 0000000..b3b83de --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneBigConfigMapper.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneCalendarMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneCalendarMapper.xml new file mode 100644 index 0000000..b813662 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneCalendarMapper.xml @@ -0,0 +1,194 @@ + + + + + + delete + from yw_scene_calendar + where scene_id in (select id from yw_scene a where a.scene_big_id = #{sceneBigId}) + + + + + + + + + + SELECT currval(pg_get_serial_sequence('yw_scene_calendar','id')) + + insert into yw_scene_calendar + + + scene_id, + + + match_type, + + + match_name, + + + match_remark, + + + begin_time, + + + end_time, + + + match_date, + + + status, + + + + + #{sceneId}, + + + #{matchType}, + + + #{matchName}, + + + #{matchRemark}, + + + #{beginTime}, + + + #{endTime}, + + + #{matchDate}, + + + #{status}, + + + + + insert into yw_scene_calendar (scene_id, match_type, match_name, match_remark, begin_time, end_time, match_date, + status, create_time, create_by) values + + + (#{item.sceneId}, #{item.matchType}, #{item.matchName}, #{item.matchRemark}, #{item.beginTime}::TIME, + #{item.endTime}::TIME, #{item.matchDate}::DATE, #{item.status}, #{item.createTime}::TIMESTAMP, + #{item.createBy}) + + + + + update yw_scene_calendar + + + scene_id = #{sceneId}, + + + match_type = #{matchType}, + + + match_name = #{matchName}, + + + match_remark = #{matchRemark}, + + + begin_time = #{beginTime}, + + + end_time = #{endTime}, + + + match_date = #{matchDate}, + + + status = #{status}, + + + where id = #{id} + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneMapper.xml new file mode 100644 index 0000000..a18d016 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneMapper.xml @@ -0,0 +1,748 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + insert into yw_scene + + + venue_name, + + + venue_desc, + + + venue_address, + + + area_county_id, + + + latitude, + + + longitude, + + + venue_type, + + + venue_level, + + + acc_person, + + + scene_big_id, + + + sign_scope, + + + status, + + + create_by, + + + create_time, + + + update_by, + + + update_time, + + + venue_shortname, + + + city_id, + + + english_name, + + + english_shortname, + + + maintain_type, + + + longitude_gcj02, + + + latitude_gcj02, + + + match_type, + + + venue_category, + + + + + #{venueName}, + + + #{venueDesc}, + + + #{venueAddress}, + + + #{areaCountyId}, + + + #{latitude}, + + + #{longitude}, + + + #{venueType}, + + + #{venueLevel}, + + + #{accPerson}, + + + #{sceneBigId}, + + + #{signScope}, + + + #{status}, + + + #{createBy}, + + + #{createTime}::TIMESTAMP, + + + #{updateBy}, + + + #{updateTime}::TIMESTAMP, + + + #{venueShortname}, + + + #{cityId}, + + + #{englishName}, + + + #{englishShortname}, + + + #{maintainType}, + + + #{longitudeGcj02}, + + + #{latitudeGcj02}, + + + #{matchType}, + + + #{venueCategory}, + + + + + + update yw_scene + + + venue_name = #{venueName}, + + + venue_desc = #{venueDesc}, + + + venue_address = #{venueAddress}, + + + area_county_id = #{areaCountyId}, + + + latitude = #{latitude}, + + + longitude = #{longitude}, + + + venue_type = #{venueType}, + + + venue_level = #{venueLevel}, + + + acc_person = #{accPerson}, + + + scene_big_id = #{sceneBigId}, + + + sign_scope = #{signScope}, + + + status = #{status}, + + + create_by = #{createBy}, + + + create_time = #{createTime}::TIMESTAMP, + + + update_by = #{updateBy}, + + + update_time = #{updateTime}::TIMESTAMP, + + + venue_shortname = #{venueShortname}, + + + city_id = #{cityId}, + + + english_name = #{englishName}, + + + english_shortname = #{englishShortname}, + + + maintain_type = #{maintainType}, + + + longitude_gcj02 = #{longitudeGcj02}, + + + latitude_gcj02 = #{latitudeGcj02}, + + + match_type = #{matchType}, + + + venue_category = #{venueCategory}, + + + where id = #{id} + + + + + + + + + + + insert into yw_scene_file + + + scene_id, + + + remark, + + + create_by, + + + create_time, + + + update_by, + + + update_time, + + + file_name, + + + file_size, + + + file_url, + + + file_type, + + + file_resolution, + + + + + #{sceneId}, + + + #{remark}, + + + #{createBy}, + + + #{createTime}, + + + #{updateBy}, + + + #{updateTime}, + + + #{fileName}, + + + #{fileSize}, + + + #{fileUrl}, + + + #{fileType}, + + + #{fileResolution}, + + + + + + insert into yw_scene (venue_name, venue_shortname, english_shortname, maintain_type, venue_type, venue_level, + longitude, latitude, longitude_gcj02, latitude_gcj02, city_id, area_county_id, match_type, venue_address, + venue_desc, scene_big_id, create_time, create_by) values + + (#{item.venueName}, #{item.venueShortname}, #{item.englishShortname}, #{item.maintainType}, + #{item.venueType}, #{item.venueLevel}, + #{item.longitude}, #{item.latitude}, #{item.longitudeGcj02}, #{item.latitudeGcj02}, #{item.cityId}, + #{item.areaCountyId}, #{item.matchType}, #{item.venueAddress}, #{item.venueDesc}, #{item.sceneBigId}, now(), + #{item.createBy}) + + + + + update yw_scene_file + + + scene_id = #{sceneId}, + + + remark = #{remark}, + + + create_by = #{createBy}, + + + create_time = #{createTime}, + + + update_by = #{updateBy}, + + + update_time = #{updateTime}, + + + file_name = #{fileName}, + + + file_size = #{fileSize}, + + + file_url = #{fileUrl}, + + + file_type = #{fileType}, + + + file_resolution = #{fileResolution}, + + + where id = #{id} + + + + update yw_scene + + + venue_desc = #{venueDesc}, + + + venue_address = #{venueAddress}, + + + area_county_id = #{areaCountyId}, + + + latitude = #{latitude}, + + + longitude = #{longitude}, + + + venue_type = #{venueType}, + + + venue_level = #{venueLevel}, + + + acc_person = #{accPerson}, + + + scene_big_id = #{sceneBigId}, + + + sign_scope = #{signScope}, + + + status = #{status}, + + + create_by = #{createBy}, + + + create_time = #{createTime}, + + + update_by = #{updateBy}, + + + update_time = #{updateTime}, + + + venue_shortname = #{venueShortname}, + + + city_id = #{cityId}, + + + english_name = #{englishName}, + + + english_shortname = #{englishShortname}, + + + maintain_type = #{maintainType}, + + + longitude_gcj02 = #{longitudeGcj02}, + + + latitude_gcj02 = #{latitudeGcj02}, + + + match_type = #{matchType}, + + + venue_category = #{venueCategory}, + + + where venue_name = #{venueName} + + + + delete from yw_scene_file + where scene_id = #{sceneId} + + and id not in + #{id} + + + + + delete + from yw_scene + where scene_big_id = #{sceneBigId} + + + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneMatchMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneMatchMapper.xml new file mode 100644 index 0000000..c5bf01c --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneMatchMapper.xml @@ -0,0 +1,30 @@ + + + + + + insert into yw_scene_match (scene_id, task_name, task_status, begin_time, end_time, create_time, create_by, + task_type) values + + (#{it.sceneId}, #{it.taskName}, #{it.taskStatus}, #{it.beginTime}::TIMESTAMP, #{it.endTime}::TIMESTAMP, + #{it.createTime}::TIMESTAMP, #{it.createBy}, #{it.taskType}) + + + + delete + from yw_scene_match + where scene_id in (select id from yw_scene where scene_big_id = #{sceneBigId}) + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementAgisMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementAgisMapper.xml new file mode 100644 index 0000000..187a846 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementAgisMapper.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + insert into yw_scene_netelement_agis (scene_id, alarm_specity_id, net_element_name, "port_A", "net_element_B", + "port_B", "desc", update_time, update_by,equipment_type,"equipment_type_B") values + + (#{item.sceneId}, #{item.alarmSpecityId}, #{item.netElementName}, #{item.portA}, #{item.netElementB}, + #{item.portB}, #{item.desc}, #{item.updateTime}, #{item.updateBy}, #{item.equipmentType}, #{item.equipmentTypeB}) + + + + + delete + from yw_scene_netelement_agis + where scene_id in (select id from yw_scene a where a.scene_big_id = #{sceneBigId}) + + + + + delete from yw_scene_netelement_agis + + + and scene_id = #{sceneId,jdbcType=NUMERIC} + + + + + update yw_scene_netelement_agis set update_time = now() + where scene_id = #{sceneId} + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementCsMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementCsMapper.xml new file mode 100644 index 0000000..a0f43c0 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementCsMapper.xml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + SELECT currval(pg_get_serial_sequence('yw_scene_netelement_cs','id')) + + insert into yw_scene_netelement_cs + + + scene_id, + + + equipment_type, + + + "net_element_name_A", + + + "port_A", + + + "attribute_A", + + + networking_type, + + + "net_element_Z", + + + "port_Z", + + + "attribute_Z", + + + + + #{sceneId}, + + + #{equipmentType}, + + + #{netElementNameA}, + + + #{portA}, + + + #{attributeA}, + + + #{networkingType}, + + + #{netElementZ}, + + + #{portZ}, + + + #{attributeZ}, + + + + + insert into yw_scene_netelement_cs (scene_id, equipment_type, "net_element_name_A", "port_A", "attribute_A", + networking_type, "net_element_Z", "port_Z", "attribute_Z", update_time, update_by) values + + (#{item.sceneId}, #{item.equipmentType}, #{item.netElementNameA}, #{item.portA}, #{item.attributeA}, + #{item.networkingType}, #{item.netElementZ}, #{item.portZ}, #{item.attributeZ}, #{item.updateTime}, #{item.updateBy}) + + + + update yw_scene_netelement_cs + + equipment_type = #{equipmentType}, + "net_element_name_A" = #{netElementNameA}, + "port_A" = #{portA}, + "attribute_A" = #{attributeA}, + networking_type = #{networkingType}, + "net_element_Z" = #{netElementZ}, + "port_Z" = #{portZ}, + "attribute_Z" = #{attributeZ}, + + where scene_id = #{sceneId} + + + + delete + from yw_scene_netelement_cs + where scene_id in (select id from yw_scene a where a.scene_big_id = #{sceneBigId}) + + + + + + delete from yw_scene_netelement_cs + + + and scene_id = #{sceneId,jdbcType=NUMERIC} + + + + + update yw_scene_netelement_cs set update_time = now() + where scene_id = #{sceneId} + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementDhMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementDhMapper.xml new file mode 100644 index 0000000..d73e971 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementDhMapper.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + SELECT currval(pg_get_serial_sequence('yw_scene_netelement_dh','id')) + + insert into yw_scene_netelement_dh + + + scene_id, + + + in_redline, + + + city, + + + county, + + + net_element_phyname, + + + room_type, + + + + + #{sceneId}, + + + #{inRedline}, + + + #{city}, + + + #{county}, + + + #{netElementPhyname}, + + + #{roomType}, + + + + + insert into yw_scene_netelement_dh (scene_id, in_redline, city, county, net_element_phyname, room_type, update_time, update_by) values + + (#{item.sceneId}, #{item.inRedline}, #{item.city}, #{item.county}, #{item.netElementPhyname}, + #{item.roomType}, #{item.updateTime}, #{item.updateBy}) + + + + update yw_scene_netelement_dh + + + in_redline = #{inRedline}, + + + city = #{city}, + + + county = #{county}, + + + net_element_phyname = #{netElementPhyname}, + + + room_type = #{roomType}, + + + where scene_id = #{sceneId} + + + + delete + from yw_scene_netelement_dh + where scene_id in (select id from yw_scene a where a.scene_big_id = #{sceneBigId}) + + + + + + delete from yw_scene_netelement_dh + + + and scene_id = #{sceneId,jdbcType=NUMERIC} + + + + + update yw_scene_netelement_dh set update_time = now() + where scene_id = #{sceneId} + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementMapper.xml new file mode 100644 index 0000000..6316813 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementMapper.xml @@ -0,0 +1,222 @@ + + + + + + + + + + + SELECT currval(pg_get_serial_sequence('yw_scene_netelement','id')) + + insert into yw_scene_netelement + + + scene_id, + + + net_element_name, + + + alarm_specity_id, + + + net_element_code, + + + net_element_lat, + + + net_element_lon, + + + type, + + + status, + + + net_element_phyname, + + + in_redline, + + + blackorwhite, + + + room, + + + port, + + + net_element_cname, + + + ci, + + + + + #{sceneId}, + + + #{netElementName}, + + + #{alarmSpecityId}, + + + #{netElementCode}, + + + #{netElementLat}, + + + #{netElementLon}, + + + #{type}, + + + #{status}, + + + #{netElementPhyname}, + + + #{inRedline}, + + + #{blackorwhite}, + + + #{room}, + + + #{port}, + + + #{netElementCname}, + + + #{ci}, + + + + + + update yw_scene_netelement + + + scene_id = #{sceneId}, + + + net_element_name = #{netElementName}, + + + alarm_specity_id = #{alarmSpecityId}, + + + net_element_code = #{netElementCode}, + + + net_element_lat = #{netElementLat}, + + + net_element_lon = #{netElementLon}, + + + type = #{type}, + + + status = #{status}, + + + net_element_phyname = #{netElementPhyname}, + + + in_redline = #{inRedline}, + + + blackorwhite = #{blackorwhite}, + + + room = #{room}, + + + port = #{port}, + + + net_element_cname = #{netElementCname}, + + + ci = #{ci}, + + + where id = #{id} + + + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementWxMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementWxMapper.xml new file mode 100644 index 0000000..f203f91 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNetelementWxMapper.xml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + SELECT currval(pg_get_serial_sequence('yw_scene_netelement_wx','id')) + + insert into yw_scene_netelement_wx + + + scene_id, + + + in_redline, + + + ci, + + + + + #{sceneId}, + + + #{inRedline}, + + + #{ci}, + + + + + + update yw_scene_netelement_wx + + + in_redline = #{inRedline}, + + + ci = #{ci}, + + + where scene_id = #{sceneId} + + + + delete + from yw_scene_netelement_wx + where scene_id in (select id from yw_scene a where a.scene_big_id = #{sceneBigId}) + + + + + + + + + + + delete from yw_scene_netelement_wx + + + and scene_id = #{sceneId,jdbcType=NUMERIC} + + + + + + insert into yw_scene_netelement_wx(scene_id, + omc, + 县市,enodebid,本地小区标识, + 小区标识,站号,基站全称,场景名称, + en名称,小区名称,小区别名,ci, + in_redline,小区频段,纬度, + 经度,纬度gcj,经度gcj, + 室内室外,网络,现网状态, + cgi,频点,pci, + tac,一级场景,二级场景, + 设备类型,带宽,方位角, + 扇区id,坐席编号,update_by, + update_time,地市,scene_type_code,scene_type,sub_scene_type_code,sub_scene_type,scene_code,cover_sub_scene_code,cover_sub_scene) + values + + (#{item.sceneId,jdbcType=NUMERIC}::bigint, + #{item.omc,jdbcType=VARCHAR}, + #{item.县市,jdbcType=VARCHAR},#{item.enodebid,jdbcType=INTEGER}::bigint,#{item.本地小区标识,jdbcType=INTEGER}::bigint, + #{item.小区标识,jdbcType=INTEGER}::bigint,#{item.站号,jdbcType=INTEGER}::bigint,#{item.基站全称,jdbcType=VARCHAR},#{item.场景名称,jdbcType=VARCHAR}, + #{item.en名称,jdbcType=VARCHAR},#{item.小区名称,jdbcType=VARCHAR},#{item.小区别名,jdbcType=VARCHAR},#{item.ci,jdbcType=VARCHAR}, + #{item.inRedline,jdbcType=VARCHAR},#{item.小区频段,jdbcType=VARCHAR},round(#{item.纬度,jdbcType=DOUBLE}::numeric, + 6), + round(#{item.经度,jdbcType=DOUBLE}::numeric, 6),round(wgs84togcj02(#{item.经度,jdbcType=VARCHAR}::numeric, + #{item.纬度,jdbcType=VARCHAR}::numeric, + 'lat')::numeric, 6),round(wgs84togcj02(#{item.经度,jdbcType=VARCHAR}::numeric, + #{item.纬度,jdbcType=VARCHAR}::numeric, + 'lng')::numeric, 6), + #{item.室内室外,jdbcType=VARCHAR},#{item.网络,jdbcType=VARCHAR},#{item.现网状态,jdbcType=VARCHAR}, + #{item.cgi,jdbcType=VARCHAR},#{item.频点,jdbcType=INTEGER}::bigint,#{item.pci,jdbcType=INTEGER}::bigint, + #{item.tac,jdbcType=INTEGER}::bigint,#{item.一级场景,jdbcType=VARCHAR},#{item.二级场景,jdbcType=VARCHAR}, + #{item.设备类型,jdbcType=VARCHAR},#{item.带宽,jdbcType=INTEGER}::bigint,#{item.方位角,jdbcType=FLOAT}::float, + #{item.扇区id,jdbcType=VARCHAR},#{item.坐席编号,jdbcType=VARCHAR},#{item.updateBy,jdbcType=VARCHAR}, + NOW(),#{item.地市,jdbcType=VARCHAR},#{item.sceneTypeCode,jdbcType=VARCHAR},#{item.sceneType,jdbcType=VARCHAR},#{item.subSceneTypeCode,jdbcType=VARCHAR}, + #{item.subSceneType,jdbcType=VARCHAR},#{item.sceneCode,jdbcType=VARCHAR},#{item.coverSubSceneCode,jdbcType=VARCHAR},#{item.coverSubScene,jdbcType=VARCHAR}) + + + + + update yw_scene_netelement_wx + set update_time = now() + where scene_id = #{sceneId} + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNoticeinfoMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNoticeinfoMapper.xml new file mode 100644 index 0000000..a87c1b5 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneNoticeinfoMapper.xml @@ -0,0 +1,175 @@ + + + + + + + insert into public.yw_scene_noticeinfo(scene_id, frontuser, backuser, emergencycar, county, public_net_num, + transport_equip_num, interface_ring_num, net_total_num,public_transport_equip_num,public_interface_ring_num, + private_transport_equip_num,private_interface_ring_num,emergency_communication_car,emergency_electric_car, + emergency_repair_car,wifi_spare,dredge_spare,trans_spare, + emergency_warehouse,wx_net_num,agis_net_num,internet_net_num,supportcar,dict_equip_num) + values + + (#{entity.sceneId}, #{entity.frontuser}, #{entity.backuser}, #{entity.emergencycar}, #{entity.county}, + #{entity.publicNetNum}, #{entity.transportEquipNum}, #{entity.interfaceRingNum}, #{entity.netTotalNum}, + #{entity.publicTransportEquipNum}, #{entity.publicInterfaceRingNum}, + #{entity.privateTransportEquipNum}, #{entity.privateInterfaceRingNum}, + #{entity.emergencyCommunicationCar},#{entity.emergencyElectricCar}, + #{entity.emergencyRepairCar},#{entity.wifiSpare},#{entity.dredgeSpare},#{entity.transSpare}, + #{entity.emergencyWarehouse}, + #{entity.wxNetNum},#{entity.agisNetNum},#{entity.internetNetNum},#{entity.supportcar},#{entity.dictEquipNum}) + + + + + delete + from yw_scene_noticeinfo + + + + + + + + insert into yw_scene_noticeinfo + + scene_id, + frontuser, + backuser, + emergencycar, + county, + public_net_num, + transport_equip_num, + interface_ring_num, + net_total_num, + emergency_warehouse, + wx_net_num, + dh_net_num, + agis_net_num, + internet_net_num, + public_transport_equip_num, + public_interface_ring_num, + private_transport_equip_num, + private_interface_ring_num, + supportcar, + dict_equip_num, + emergency_communication_car, + emergency_electric_car, + emergency_repair_car, + wifi_spare, + dredge_spare, + trans_spare, + public_power_equip, + private_power_equip + + values + + #{sceneId,jdbcType=NUMERIC}, + #{frontuser,jdbcType=NUMERIC}, + #{backuser,jdbcType=NUMERIC}, + #{emergencycar,jdbcType=NUMERIC}, + #{county,jdbcType=VARCHAR}, + #{publicNetNum,jdbcType=NUMERIC}, + #{transportEquipNum,jdbcType=NUMERIC}, + #{interfaceRingNum,jdbcType=NUMERIC}, + #{netTotalNum,jdbcType=NUMERIC}, + #{emergencyWarehouse,jdbcType=NUMERIC}, + #{wxNetNum,jdbcType=NUMERIC}, + #{dhNetNum,jdbcType=NUMERIC}, + #{agisNetNum,jdbcType=NUMERIC}, + #{internetNetNum,jdbcType=NUMERIC}, + #{publicTransportEquipNum,jdbcType=NUMERIC}, + #{publicInterfaceRingNum,jdbcType=NUMERIC}, + #{privateTransportEquipNum,jdbcType=NUMERIC}, + #{privateInterfaceRingNum,jdbcType=NUMERIC}, + #{supportcar,jdbcType=NUMERIC}, + #{dictEquipNum,jdbcType=NUMERIC}, + #{emergencyCommunicationCar,jdbcType=NUMERIC}, + #{emergencyElectricCar,jdbcType=NUMERIC}, + #{emergencyRepairCar,jdbcType=NUMERIC}, + #{wifiSpare,jdbcType=NUMERIC}, + #{dredgeSpare,jdbcType=NUMERIC}, + #{transSpare,jdbcType=NUMERIC}, + #{publicPowerEquip,jdbcType=NUMERIC}, + #{privatePowerEquip,jdbcType=NUMERIC} + + + + + update yw_scene_noticeinfo + set frontuser = #{frontuser,jdbcType=NUMERIC}, + backuser = #{backuser,jdbcType=NUMERIC}, + emergencycar = #{emergencycar,jdbcType=NUMERIC}, + county = #{county,jdbcType=VARCHAR}, + public_net_num = #{publicNetNum,jdbcType=NUMERIC}, + transport_equip_num = #{transportEquipNum,jdbcType=NUMERIC}, + interface_ring_num = #{interfaceRingNum,jdbcType=NUMERIC}, + net_total_num = #{netTotalNum,jdbcType=NUMERIC}, + emergency_warehouse = #{emergencyWarehouse,jdbcType=NUMERIC}, + wx_net_num = #{wxNetNum,jdbcType=NUMERIC}, + dh_net_num = #{dhNetNum,jdbcType=NUMERIC}, + agis_net_num = #{agisNetNum,jdbcType=NUMERIC}, + internet_net_num = #{internetNetNum,jdbcType=NUMERIC}, + public_transport_equip_num = #{publicTransportEquipNum,jdbcType=NUMERIC}, + + public_interface_ring_num = #{publicInterfaceRingNum,jdbcType=NUMERIC}, + + private_transport_equip_num = #{privateTransportEquipNum,jdbcType=NUMERIC}, + + private_interface_ring_num = #{privateInterfaceRingNum,jdbcType=NUMERIC}, + + supportcar = #{supportcar,jdbcType=NUMERIC}, + + dict_equip_num = #{dictEquipNum,jdbcType=NUMERIC}, + + emergency_communication_car = #{emergencyCommunicationCar,jdbcType=NUMERIC}, + emergency_electric_car = #{emergencyElectricCar,jdbcType=NUMERIC}, + emergency_repair_car = #{emergencyRepairCar,jdbcType=NUMERIC}, + wifi_spare = #{wifiSpare,jdbcType=NUMERIC}, + dredge_spare = #{dredgeSpare,jdbcType=NUMERIC}, + trans_spare = #{transSpare,jdbcType=NUMERIC}, + public_power_equip = #{publicPowerEquip,jdbcType=NUMERIC}, + private_power_equip = #{privatePowerEquip,jdbcType=NUMERIC} + + where scene_id = #{sceneId,jdbcType=NUMERIC} + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwScenePictureMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwScenePictureMapper.xml new file mode 100644 index 0000000..97da30b --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwScenePictureMapper.xml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneTestDataInterfaceMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneTestDataInterfaceMapper.xml new file mode 100644 index 0000000..f408440 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneTestDataInterfaceMapper.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneTestDataMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneTestDataMapper.xml new file mode 100644 index 0000000..540ee7a --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneTestDataMapper.xml @@ -0,0 +1,32 @@ + + + + + + + insert into public.yw_scene_test_data(bzname, scenename, deviceoid, connectdelay, dlspeed, lat, lng, + pagecomplete, ulspeed, update_time, nettype, scene_id) + values + + (#{entity.bzname}, #{entity.scenename}, #{entity.deviceoid}, #{entity.connectdelay}, #{entity.dlspeed}, + #{entity.lat}, #{entity.lng}, #{entity.pagecomplete}, #{entity.ulspeed}, #{entity.updateTime}, + #{entity.nettype}, #{entity.sceneId}) + + + + + delete + from yw_scene_test_data + where 1 = 1 + + + + delete from yw_scene_test_data where scene_id in ( + + #{entity} + + ) + + + + diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneUserMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneUserMapper.xml new file mode 100644 index 0000000..55164cb --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSceneUserMapper.xml @@ -0,0 +1,225 @@ + + + + + + delete + from yw_scene_user + where scene_id in (select id from yw_scene where scene_big_id = #{sceneBigId}) + + + + delete + from yw_scene_user + where user_id = #{userId,jdbcType=NUMERIC} + and scene_id in (select id from yw_scene where scene_big_id = #{sceneBigId,jdbcType=NUMERIC}) + + + + + + + + + SELECT currval(pg_get_serial_sequence('yw_scene_user','id')) + + insert into yw_scene_user + + + scene_id, + + + user_id, + + update_time, + update_by, + create_time, + create_by, + + + + #{sceneId}, + + + #{userId}, + + #{updateTime}, + #{updateBy}, + #{createTime}, + #{createBy}, + + on conflict (scene_id, user_id) do nothing + + + insert into yw_scene_user (scene_id, user_id, create_time, create_by) values + + (#{item.sceneId}, #{item.userId}, #{item.createTime}::TIMESTAMP, + #{item.createBy}) + + + + + update yw_scene_user + + + scene_id = #{sceneId}, + + + user_id = #{userId}, + + + belong_area = #{belongArea}, + + + need_sign = #{needSign}, + + + where id = #{id} + + + + update yw_scene_user + + update_time = #{updateTime}, + update_by = #{updateBy}, + + where user_id = #{userId} and scene_id = #{sceneId} + + + + + + + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSignLogMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSignLogMapper.xml new file mode 100644 index 0000000..f62d41a --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSignLogMapper.xml @@ -0,0 +1,89 @@ + + + + + + update yw_sign_log set is_dai_sign=#{userId}, sign_time=to_timestamp(#{signTime}, 'yyyy-mm-dd HH24:mi:ss') + where sign_time is null and sign_type=#{signType} + and user_id in + ( + + + + #{user} + + + + select user_id from yw_scene_user t1 + where t1.scene_id=#{venueId} and exists (select 1 from sys_user t2 where t1.user_id=t2.user_id + + and user_type in + + #{userType} + + + ) + + + ) + + + and sign_plan_id = #{signPlanId} + + + and sign_plan_id in (select id from yw_sign_plan where sign_date=#{signTime} and scene_id=#{venueId}) + + + + + + update yw_sign_log set sign_time=to_timestamp(#{ywSignLog.signTime}, 'yyyy-mm-dd HH24:mi:ss'), + sign_j = cast(#{ywSignLog.signJ} as float8), + sign_w = cast(#{ywSignLog.signW} as float8) + where sign_time is null and sign_type =cast( #{ywSignLog.signType} as int2 ) + and user_id =#{ywSignLog.userId} + + + and sign_plan_id = #{ywSignLog.signPlanId} + + + and sign_plan_id in (select id from yw_sign_plan where sign_date=#{ywSignLog.signTime} and scene_id=#{sceneId}) + + + + + + insert into yw_sign_log(sign_plan_id,user_id,belong_area,sign_type) + select sign_plan_id,user_id,belong_area,0 from v_yw_sign_log_handle t1 + where sign_date=CURRENT_DATE + and begin_time is not null and user_id is not null and now() >= gen_time + union + select sign_plan_id,user_id,belong_area,1 from v_yw_sign_log_handle t1 + where sign_date=CURRENT_DATE + and end_time is not null and user_id is not null and now() >= gen_time + + + + delete from yw_sign_log where sign_plan_id=#{id} + + + + delete from yw_sign_log t3 where + not exists (select 1 + from yw_sign_plan t1 left join yw_scene_user t2 on t1.scene_id = t2.scene_id + where t3.sign_plan_id=t1.id and t3.user_id=t2.user_id) and sign_plan_id=#{id} + + + + delete from yw_sign_log t3 where + not exists (select 1 + from yw_sign_plan t1 left join yw_scene_user t2 on t1.scene_id = t2.scene_id + where t3.sign_plan_id=t1.id and t3.user_id=t2.user_id) + and sign_plan_id in (select id from yw_sign_plan ysp where ysp.sign_date = CURRENT_DATE) + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSignLogViewMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSignLogViewMapper.xml new file mode 100644 index 0000000..2c1fcb8 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSignLogViewMapper.xml @@ -0,0 +1,286 @@ + + + + + + + + + and area_county_id like CONCAT('%',cast(#{city} as varchar),'%') + + + and area_county_id = #{county} + + + and scene_id in + + #{venueId} + + + + and user_type = #{userType} + + + and sign_status = #{signStatus} + + + + and venue_type = #{venueType} + + + + and maintain_type = #{maintainType} + + + + and begin_time between #{startDate}::TIMESTAMP and #{endDate}::TIMESTAMP + + + + and scene_id in (SELECT id FROM yw_scene t where t.venue_type='比赛场馆' and match_type is not null and area_county_id like '0571%') + + + + + + + + and now()>gen_time + + + and now()>begin_time + + + + + + + + + + and now()>begin_time + concat('-', rep_sign_interval::text, ' hour')::interval + + + and now()>begin_time + + + + + + + + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSignPlanMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSignPlanMapper.xml new file mode 100644 index 0000000..6984676 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSignPlanMapper.xml @@ -0,0 +1,115 @@ + + + + + + + + + + and t1.id in + + #{venueId} + + + + + and scene_id in + + #{venueId} + + + + + and sign_date in + + to_date(#{arrSignDate}, 'yyyy-mm-dd') + + + + + insert into yw_sign_plan(scene_id,sign_date, + begin_time, + end_time, + rep_warn_interval, + notice_type, + create_by, + sign_num, + + rep_sign_interval, + create_time, + update_time, + is_open, + sign_users + ) + + select id,to_date(#{arrSignDate}, 'yyyy-mm-dd'), + to_timestamp(#{arrSignDate}||' '||#{beginTime}, 'yyyy-mm-dd HH24:mi:ss'), + to_timestamp(#{arrSignDate}||' '||#{endTime}, 'yyyy-mm-dd HH24:mi:ss'), + #{repWarnInterval}, + #{noticeType}, + #{createBy}, + #{signNum}, + + #{repSignInterval}, + now(), + now(), + '1', + + + #{signUsers} + + + ysu.sign_users + + + from yw_scene t1 + LEFT JOIN ( SELECT yw_scene_user.scene_id, + string_agg(yw_scene_user.user_id::character varying::text, ','::text) AS sign_users + FROM yw_scene_user + GROUP BY yw_scene_user.scene_id) ysu ON ysu.scene_id = t1.id + where not exists (select 1 from yw_sign_plan t2 where t1.id=t2.scene_id and t2.sign_date=to_date(#{arrSignDate}, 'yyyy-mm-dd') + and (to_timestamp(#{arrSignDate}||' '||#{beginTime}, 'yyyy-mm-dd HH24:mi:ss') between begin_time and end_time or begin_time between to_timestamp(#{arrSignDate}||' '||#{beginTime}, 'yyyy-mm-dd HH24:mi:ss') and to_timestamp(#{arrSignDate}||' '||#{endTime}, 'yyyy-mm-dd HH24:mi:ss') + or to_timestamp(#{arrSignDate}||' '||#{endTime}, 'yyyy-mm-dd HH24:mi:ss') between begin_time and end_time)) + + + + + + update yw_sign_plan + + sign_date = #{signDate}::DATE, + begin_time=to_timestamp(to_char(sign_date,'yyyy-mm-dd')||' '||#{beginTime}::text, 'yyyy-mm-dd HH24:mi:ss'), + end_time=to_timestamp(to_char(sign_date,'yyyy-mm-dd')||' '||#{endTime}::text, 'yyyy-mm-dd HH24:mi:ss'), + rep_warn_interval=#{repWarnInterval}, + notice_type=#{noticeType}, + is_open=#{isOpen}, + sign_num=#{signNum} + sign_users=#{signUsers}, + rep_sign_interval=#{repSignInterval}, + update_by = #{updateBy}, + update_time = now() + + where id = #{id} + + + + delete from yw_sign_plan where id=#{id} + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSparePartsMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSparePartsMapper.xml new file mode 100644 index 0000000..6309aa2 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwSparePartsMapper.xml @@ -0,0 +1,21 @@ + + + + + insert into yw_spare_parts (venue_name, venue_type, device_type, board_model, current_num, board_num, + part_model, need_num, configure_num, gap_num, major, comment, contacts, telephone, + create_by, create_time) values + + (#{item.venueName}, #{item.venueType}, #{item.deviceType}, #{item.boardModel}, + #{item.currentNum}, #{item.boardNum}, + #{item.partModel}, #{item.needNum}, #{item.configureNum}, #{item.gapNum}, #{item.major}, + #{item.comment}, #{item.contacts}, #{item.telephone}, #{item.createBy}, #{item.createTime}) + + + + truncate table yw_spare_parts + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwWireTaskLogMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwWireTaskLogMapper.xml new file mode 100644 index 0000000..7af6472 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/YwWireTaskLogMapper.xml @@ -0,0 +1,76 @@ + + + + + + + + insert into yw_wire_task_log( + + flw_processid, + + + wire_task_name, + + + construc_unit, + + create_by,create_time,wire_task_id,task_type,venue_id) + values( + + #{flwProcessid}, + + + #{wireTaskName}, + + + #{construcUnit}, + + #{createBy}, + + + to_timestamp(#{createTime}, 'yyyy-mm-dd HH24:mi:ss'), + + + now(), + + + #{wireTaskId},#{taskType},#{venueId}) + + + + update yw_wire_task_log set flw_processid=#{flwProcessid} + where wire_task_id=#{wireTaskId} and task_type=#{taskType} + + + + update yw_wire_task_log set report=#{report} + where wire_task_id=#{wireTaskId} and task_type=#{taskType} + + + + delete from yw_wire_task_log + where wire_task_id=#{wireTaskId} + + and task_type=#{taskType} + + + + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/resources/mapper/eastcom_yw/yw_alarm_deal_logMapper.xml b/eastcom_yw/src/main/resources/mapper/eastcom_yw/yw_alarm_deal_logMapper.xml new file mode 100644 index 0000000..82e4f78 --- /dev/null +++ b/eastcom_yw/src/main/resources/mapper/eastcom_yw/yw_alarm_deal_logMapper.xml @@ -0,0 +1,18 @@ + + + + + + + update yw_alarm_deal_log set hangup_timespan=COALESCE(hangup_timespan,0) + #{minute} where flw_processid = #{processId} + + + + + update yw_alarm_deal_log set end_time = getalarmclear(group_id,alarm_type) + where end_time is null + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..617e54d --- /dev/null +++ b/pom.xml @@ -0,0 +1,339 @@ + + + 4.0.0 + + com.ruoyi + ruoyi + 3.8.4 + + ruoyi + http://www.ruoyi.vip + 若依管理系统 + + + 3.8.4 + UTF-8 + UTF-8 + 1.8 + true + 3.1.1 + 1.2.15 + 1.21 + 3.0.0 + 2.3.3 + + 1.4.5 + 2.0.20 + 6.3.2 + 2.11.0 + 1.4 + 3.2.2 + 1.6 + 4.1.2 + 2.3 + 0.9.1 + 1.18.20 + 3.5.1 + 3.3.1 + 5.8.0 + 1.1.3 + 1.3.1.Final + 3.1.2 + 3.21.3 + + + + + + + + + org.springframework.boot + spring-boot-dependencies + 2.5.14 + pom + import + + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + + + eu.bitwalker + UserAgentUtils + ${bitwalker.version} + + + + + + + + + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.vesion} + + + + com.baomidou + mybatis-plus-generator + ${mybatis-plus.vesion} + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pagehelper.boot.version} + + + + + com.github.oshi + oshi-core + ${oshi.version} + + + + + io.springfox + springfox-boot-starter + ${swagger.version} + + + io.swagger + swagger-models + + + + + + + + + org.projectlombok + lombok + ${lombok.version} + + + + + commons-io + commons-io + ${commons.io.version} + + + + + commons-fileupload + commons-fileupload + ${commons.fileupload.version} + + + + + org.apache.poi + poi-ooxml + ${poi.version} + + + + + + + org.apache.velocity + velocity-engine-core + ${velocity.version} + + + + + commons-collections + commons-collections + ${commons.collections.version} + + + + + + + com.alibaba.fastjson2 + fastjson2 + ${fastjson.version} + + + + + io.jsonwebtoken + jjwt + ${jwt.version} + + + + + pro.fessional + kaptcha + ${kaptcha.version} + + + + + com.ruoyi + ruoyi-quartz + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-generator + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-framework + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-system + ${ruoyi.version} + + + + + + com.ruoyi + ruoyi-common + ${ruoyi.version} + + + + + com.ruoyi + eastcom_yw + ${ruoyi.version} + + + + com.ruoyi + ruoyi-sunlm + ${ruoyi.version} + + + + com.ruoyi + cmcc_gm + ${ruoyi.version} + + + + cn.hutool + hutool-all + ${hutool-all.version} + + + + + org.gavaghan + geodesy + ${geodesy.version} + + + + org.apache.commons + commons-text + ${commons-text.version} + + + + + org.springframework.boot + spring-boot-starter-actuator + ${actuator.version} + + + + org.redisson + redisson + ${redisson.version} + + + + + + + ruoyi-admin + ruoyi-app + ruoyi-framework + ruoyi-system + ruoyi-quartz + ruoyi-generator + eastcom_yw + ruoyi-sunlm + ruoyi-common + cmcc_gm + + pom + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + false + + + + + \ No newline at end of file diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml new file mode 100644 index 0000000..5d57404 --- /dev/null +++ b/ruoyi-admin/pom.xml @@ -0,0 +1,140 @@ + + + + ruoyi + com.ruoyi + 3.8.4 + + 4.0.0 + jar + ruoyi-admin + + + web服务入口 + + + + + + + org.springframework.boot + spring-boot-devtools + true + + + + + io.springfox + springfox-boot-starter + + + + + io.swagger + swagger-models + 1.6.2 + + + + + + + + + + org.postgresql + postgresql + + + + com.ruoyi + ruoyi-framework + + + + + com.ruoyi + ruoyi-quartz + + + + com.ruoyi + eastcom_yw + + + + + com.ruoyi + ruoyi-generator + + + + junit + junit + 4.13.2 + test + + + org.springframework + spring-test + 5.3.23 + test + + + org.springframework.boot + spring-boot-test + 2.7.5 + test + + + com.ruoyi + ruoyi-sunlm + + + + com.ruoyi + cmcc_gm + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.1.1.RELEASE + + true + + + + + repackage + + + + + + org.apache.maven.plugins + maven-war-plugin + 3.1.0 + + false + ${project.artifactId} + + + + + + ${project.artifactId} + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java new file mode 100644 index 0000000..b7dc11b --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java @@ -0,0 +1,42 @@ +package com.ruoyi; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.transaction.annotation.EnableTransactionManagement; +import org.springframework.web.client.RestTemplate; + +/** + * 启动程序 + * + * @author ruoyi + */ +@EnableTransactionManagement +@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) +public class RuoYiApplication +{ + + @Bean + public RestTemplate restTemplate(RestTemplateBuilder builder) { + return builder.build(); + } + + public static void main(String[] args) + { + // System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(RuoYiApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiServletInitializer.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiServletInitializer.java new file mode 100644 index 0000000..6de67dc --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiServletInitializer.java @@ -0,0 +1,18 @@ +package com.ruoyi; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * web容器中进行部署 + * + * @author ruoyi + */ +public class RuoYiServletInitializer extends SpringBootServletInitializer +{ + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) + { + return application.sources(RuoYiApplication.class); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsClassesController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsClassesController.java new file mode 100644 index 0000000..0199461 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsClassesController.java @@ -0,0 +1,197 @@ +package com.ruoyi.web.controller.cmcc_gm; + + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.cmcc_gm.domain.YwMaterialsClasses; +import com.ruoyi.cmcc_gm.domain.dto.YmMaterialsClassesParam; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsStockImportDTO; +import com.ruoyi.cmcc_gm.service.YwMaterialsClassesService; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.utils.reflect.ReflectUtils; +import com.ruoyi.eastcom_yw.domain.dto.YwSignLogDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSignPlanDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwSignLogVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.Serializable; +import java.util.List; + +/** + * (YwMaterialsClasses)表控制层 + * + * @author lee + * @since 2023-04-19 10:15:59 + */ +@Api(tags = "物资类别") +@RestController +@RequestMapping("/eastcom_yw/ywMaterialsClasses") +public class YwMaterialsClassesController extends BaseController { + + /** + * 服务对象 + */ + @Resource + private YwMaterialsClassesService ywMaterialsClassesService; + + /** + * 分页查询所有数据 + * + * @param ywMaterialsClasses 查询实体 + * @return 所有数据 + */ + @ApiOperation(value = "分页查询", notes = "分页查询") + @PostMapping("/list") + public TableDataInfo selectAll(@RequestBody YmMaterialsClassesParam ywMaterialsClasses) { + PageUtils.startPage(ywMaterialsClasses, YmMaterialsClassesParam.class); + return getDataTable(ywMaterialsClassesService.getMaterialsBySearch(ywMaterialsClasses)); + } + + /** + * 通过主键查询单条数据 + * + * @param id 主键 + * @return 单条数据 + */ + @ApiOperation(value = "根据id查询", notes = "根据id查询") + @GetMapping("{id}") + public AjaxResult selectOne(@PathVariable Serializable id) { + return AjaxResult.success(this.ywMaterialsClassesService.getById(id)); + } + + /** + * 新增数据 + * + * @param ywMaterialsClasses 实体对象 + * @return 新增结果 + */ + @Log(title = "新增物资的大小类", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增", notes = "新增") + @PostMapping + public AjaxResult insert(@RequestBody YwMaterialsClasses ywMaterialsClasses) { + // 校验 + if (StringUtils.isEmpty(ywMaterialsClasses.getBigClass()) || + StringUtils.isEmpty(ywMaterialsClasses.getSmallClass())) { + throw new ServiceException("参数校验不通过"); + } + YmMaterialsClassesParam ymMaterialsClassesParam = new YmMaterialsClassesParam(); + List materialsBySearch = ywMaterialsClassesService.getMaterialsBySearch(ymMaterialsClassesParam); + for (YwMaterialsClasses bySearch : materialsBySearch) { + if (ywMaterialsClasses.getBigClass().equals(bySearch.getBigClass()) && + ywMaterialsClasses.getSmallClass().equals(bySearch.getSmallClass())) { + throw new ServiceException("大类+小类组合已存在"); + } + } + boolean res = this.ywMaterialsClassesService.save(ywMaterialsClasses); + if (res) { + ywMaterialsClassesService.loadingMaterialsClassesCache(); + } + return AjaxResult.success(res); + } + + /** + * 修改数据 + * + * @param ywMaterialsClasses 实体对象 + * @return 修改结果 + */ + @Log(title = "修改物资的大小类", businessType = BusinessType.UPDATE) + @ApiOperation(value = "修改", notes = "修改") + @PutMapping + public AjaxResult update(@RequestBody YwMaterialsClasses ywMaterialsClasses) { + + // 校验 + if (StringUtils.isEmpty(ywMaterialsClasses.getBigClass()) || + StringUtils.isEmpty(ywMaterialsClasses.getSmallClass())) { + throw new ServiceException("参数校验不通过"); + } + YwMaterialsClasses byId = ywMaterialsClassesService.getById(ywMaterialsClasses.getId()); + if (ObjectUtils.isEmpty(byId)) { + throw new ServiceException("id不存在"); + } + YmMaterialsClassesParam ymMaterialsClassesParam = new YmMaterialsClassesParam(); + List materialsBySearch = ywMaterialsClassesService.getMaterialsBySearch(ymMaterialsClassesParam); + for (YwMaterialsClasses bySearch : materialsBySearch) { + if (ywMaterialsClasses.getBigClass().equals(bySearch.getBigClass()) && + ywMaterialsClasses.getSmallClass().equals(bySearch.getSmallClass()) && + !byId.getBigClass().equals(bySearch.getBigClass()) && + !byId.getSmallClass().equals(bySearch.getSmallClass())) { + throw new ServiceException("大类+小类组合已存在"); + } + } + + boolean b = ywMaterialsClassesService.checkClassesInUse(byId); + if (b) { + throw new ServiceException("不允许修改已在使用中的大类+小类组合"); + } + + boolean res = this.ywMaterialsClassesService.updateById(ywMaterialsClasses); + if (res) { + ywMaterialsClassesService.loadingMaterialsClassesCache(); + } + return AjaxResult.success(res); + + } + + /** + * 删除数据 + * + * @param idList 主键结合 + * @return 删除结果 + */ + @Log(title = "删除物资的大小类", businessType = BusinessType.DELETE) + @ApiOperation(value = "删除", notes = "删除") + @DeleteMapping + public AjaxResult delete(@RequestParam("idList") List idList) { + for (Long aLong : idList) { + YwMaterialsClasses byId = ywMaterialsClassesService.getById(aLong); + if (ObjectUtils.isEmpty(byId)) { + throw new ServiceException("id不存在"); + } else { + boolean b = ywMaterialsClassesService.checkClassesInUse(byId); + if (b) { + throw new ServiceException("不允许删除已在使用中的大类+小类组合"); + } + } + } + boolean res = this.ywMaterialsClassesService.removeByIds(idList); + if (res) { + ywMaterialsClassesService.loadingMaterialsClassesCache(); + } + return AjaxResult.success(this.ywMaterialsClassesService.removeByIds(idList)); + } + + + @Log(title = "物资大小类导出", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, YmMaterialsClassesParam ywMaterialsClasses) throws IllegalAccessException { + List list= ywMaterialsClassesService.getMaterialsBySearch(ywMaterialsClasses); + ExcelUtil util = new ExcelUtil(YwMaterialsClasses.class); + util.hideColumn("reason"); + util.exportExcel(response, list, "物资大小类数据"); + } + + @Log(title = "物资大小类导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, Boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(YwMaterialsClasses.class); + List lstClasses = util.importExcel(file.getInputStream()); + return ywMaterialsClassesService.importMaterialsClasses(lstClasses,updateSupport); + + } + +} + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsController.java new file mode 100644 index 0000000..20f790b --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsController.java @@ -0,0 +1,967 @@ +package com.ruoyi.web.controller.cmcc_gm; + + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.cmcc_gm.common.enums.OrderStatus; +import com.ruoyi.cmcc_gm.common.enums.OrderType; +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import com.ruoyi.cmcc_gm.domain.YwMaterialsOrderLog; +import com.ruoyi.cmcc_gm.domain.dto.*; +import com.ruoyi.cmcc_gm.domain.qo.YwMaterialsSnListQO; +import com.ruoyi.cmcc_gm.domain.vo.MaterialsXlsToJsonArrayVo; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsExportVo; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsInformRedisVo; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsVo; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsBatchMapper; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsOrderLogMapper; +import com.ruoyi.cmcc_gm.service.*; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.dto.HandleDataDTO; +import com.ruoyi.common.core.domain.dto.StartProcessInstanceDTO; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.service.CommonService; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + *

+ * 物资工单日志表 前端控制器 + *

+ * + * @author jkj + * @since 2023-04-07 + */ +@RestController +@RequestMapping("/cmcc_gm/ywMaterials") +public class YwMaterialsController extends BaseController { + + @Autowired + private YwMaterialsStockService ywMaterialsStockService; + + @Autowired + private YwMaterialsInformService ywMaterialsInformService; + + @Autowired + private YwMaterialsOrderLogService ywMaterialsOrderLogService; + + @Autowired + private YwMaterialsClassesService ywMaterialsClassesService; + + @Autowired + private YwMaterialsBatchService ywMaterialsBatchService; + + @Autowired + private YwMaterialsBatchMapper ywMaterialsBatchMapper; + + @Autowired + private YwMaterialsOrderLogMapper ywMaterialsOrderLogMapper; + + @Autowired + private YwMaterialsSnListService ywMaterialsSnListService; + + @Autowired + private CommonService commonService; + + + @ApiOperation("根据条件查询仓库的物资库存数据") + @PostMapping("/stock/list") + public TableDataInfo list(@RequestBody YwMaterialsSearchDTO ywMaterialsSearchDTO) throws Exception { + String pageNum = ServletUtils.getParameter("pageNum"); + String pageSize = ServletUtils.getParameter("pageSize"); + if (!StringUtils.isEmpty(pageNum) && !StringUtils.isEmpty(pageSize)) { + startPage(); + } + return getDataTable(ywMaterialsStockService.getMaterialsStock(ywMaterialsSearchDTO)); + } + + @ApiOperation("根据条件查询仓库的物资出入库明细记录数据") + @PostMapping("/stock/detail") + public TableDataInfo materialNumlist(@RequestBody YwMaterialsSearchDTO ywMaterialsSearchDTO) throws Exception { + if (ObjectUtils.isEmpty(ywMaterialsSearchDTO.getStoreId())) { + throw new ServiceException("请选择仓库名称"); + } + + if (ObjectUtils.isEmpty(ywMaterialsSearchDTO.getMaterialCode())) { + throw new ServiceException("请选择物资编码"); + } + + String pageNum = ServletUtils.getParameter("pageNum"); + String pageSize = ServletUtils.getParameter("pageSize"); + if (!StringUtils.isEmpty(pageNum) && !StringUtils.isEmpty(pageSize)) { + startPage(); + } + + return getDataTable(ywMaterialsOrderLogMapper.selectOrderMaterialsNumLog(ywMaterialsSearchDTO.getStoreId(),ywMaterialsSearchDTO.getMaterialCode())); + } + + /** + * 导出 + * + * @param ywMaterialsSearchDTO 查询参数 + * @param httpServletResponse response + * @throws Exception 异常 + */ + @ApiOperation("根据条件导出仓库的物资库存数据") + @PostMapping("/stock/export") + public void export(@RequestBody YwMaterialsSearchDTO ywMaterialsSearchDTO, HttpServletResponse httpServletResponse) throws Exception { +// if (ObjectUtils.isEmpty(ywMaterialsSearchDTO.getStoreId())) { +// throw new ServiceException("请选择仓库名称"); +// } + ywMaterialsSearchDTO.setPageNum(1); + ywMaterialsSearchDTO.setPageSize(Integer.MAX_VALUE); + List materialsStock = ywMaterialsStockService.getMaterialsStock(ywMaterialsSearchDTO); + List list = new ArrayList<>(); + for (YwMaterialsVo ywMaterialsVo : materialsStock) { + YwMaterialsExportVo vo = new YwMaterialsExportVo(); + BeanUtils.copyBeanProp(vo, ywMaterialsVo); + vo.setStoreSum(vo.getAvailSum() + vo.getOutWaySum() + vo.getInWaySum()); + list.add(vo); + } + ExcelUtil util = new ExcelUtil<>(YwMaterialsExportVo.class); + util.exportExcel(httpServletResponse, list, "数据"); + } + + @Log(title = "更新物资库存信息数据", businessType = BusinessType.UPDATE) + @ApiOperation("更新物资库存信息数据") + @PostMapping("/stock/update") + @Transactional + public AjaxResult updateStock(@RequestBody YwMaterialsDTO ywMaterialsDTO) throws Exception { + + + Boolean res = true; + + if (ObjectUtils.isEmpty(ywMaterialsDTO.getOpType())) { + throw new ServiceException("操作类型不能为空"); + } + + if (ObjectUtils.isEmpty(ywMaterialsDTO.getOrderType())) { + throw new ServiceException("物资工单类型不能为空"); + } + +// 验证当前用户的角色是否具有操作权限 + List roles = SecurityUtils.getLoginUser().getUser().getRoles(); + + List filterRoles = null; + + boolean needCheck = false; + + if (ywMaterialsDTO.getOpType().equals("提交申请")) { + + if (ywMaterialsDTO.getOrderType().equals(OrderType.ZXK.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("centerstoragechecker")).collect(Collectors.toList()); + } + + if (ywMaterialsDTO.getOrderType().equals(OrderType.SL.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.TK.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("venuestoragechecker") || e.getRoleKey().equals("venuemanager")).collect(Collectors.toList()); + } + + if (ywMaterialsDTO.getOrderType().equals(OrderType.CK.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.RK.getCode())) { + + filterRoles = new ArrayList<>(); + } + + if (ywMaterialsDTO.getOrderType().equals(OrderType.DB.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("centerstoragemaster")).collect(Collectors.toList()); + } + + //管理员可以提交申请 + if(filterRoles!=null) { + if (filterRoles.isEmpty()) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("admin")).collect(Collectors.toList()); + } + } + + //20230815 出入库不需要验证角色 + if (ywMaterialsDTO.getOrderType().equals(OrderType.CK.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.RK.getCode())) { +// filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("builder")).collect(Collectors.toList()); + + } + else + { + needCheck = true; + } + + } + + if (ywMaterialsDTO.getOpType().equals("审核任务")) { + + if (ywMaterialsDTO.getOrderType().equals(OrderType.ZXK.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.SL.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.TK.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("centerstoragemaster")).collect(Collectors.toList()); + } + + + if (ywMaterialsDTO.getOrderType().equals(OrderType.CK.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.RK.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.DB.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("venuestoragemaster")).collect(Collectors.toList()); + } + needCheck = true; + } + + if (ywMaterialsDTO.getOpType().equals("出库确认") || ywMaterialsDTO.getOpType().equals("入库确认")) { + + if (!ywMaterialsDTO.getOrderType().equals(OrderType.ZXK.getCode())) { +// 默认都是场馆物资仓库管理员出入库确认 + //物资退库,是中心库物资维护员角色提交入库 + if (ywMaterialsDTO.getOpType().equals("入库确认")) { + if (ywMaterialsDTO.getOrderType().equals(OrderType.TK.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("centerstoragechecker")).collect(Collectors.toList()); + } else { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("venuestoragekeeper")).collect(Collectors.toList()); + } + } else { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("venuestoragekeeper")).collect(Collectors.toList()); + } + } + needCheck = true; + } + + if (needCheck) { + if(filterRoles!=null) { + if (filterRoles.isEmpty()) { + throw new ServiceException("当前用户没有操作的权限"); + } + } + } + + //创建时如果不是中心库,折旧入库 的需要冻结库存 + if (ywMaterialsDTO.getOpType().equals("创建")) { + + + YwMaterialsOrderLog ywMaterialsOrderLog = ywMaterialsStockService.Validate(ywMaterialsDTO); + + //待申请的才可以创建 + if (!OrderStatus.DSQ.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前物资订单状态不允许该操作"); + } + + if (!(ywMaterialsDTO.getOrderType() == OrderType.ZXK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.RK.getCode())) { + +// //正向,冻结操作放在了批量表的插入 +// if(StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) +// { +// res = ywMaterialsStockService.freezeOutWayMaterialsStock(ywMaterialsDTO, ywMaterialsOrderLog); +// } + + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + if (ywMaterialsDTO.getIsBack().equals("是")) { + res = ywMaterialsStockService.freezeOutWayMaterialsStockBack(ywMaterialsDTO, ywMaterialsOrderLog); + } + } + } + + } + + if (ywMaterialsDTO.getOpType().equals("撤销")) { + + YwMaterialsOrderLog ywMaterialsOrderLog = ywMaterialsStockService.Validate(ywMaterialsDTO); + + if (!OrderStatus.DSQ.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前物资订单状态不允许该操作"); + } + + res = ywMaterialsStockService.freezeOutWayMaterialsStockBack(ywMaterialsDTO, ywMaterialsOrderLog); + + if (res) { + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + orderDto.setOrderId(ywMaterialsOrderLog.getOrderId()); + orderDto.setOrderType(ywMaterialsOrderLog.getOrderType()); + orderDto.setTaskStatus(OrderStatus.CX.getCode()); + res = ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); + + } + + if (res) { + return AjaxResult.success("撤销物资订单成功"); + } + + return AjaxResult.error("撤销物资订单失败"); + + } + + if (ywMaterialsDTO.getOpType().equals("驳回") || ywMaterialsDTO.getOpType().equals("提交申请")) { + + YwMaterialsOrderLog ywMaterialsOrderLog = ywMaterialsStockService.Validate(ywMaterialsDTO); + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + + orderDto.setOrderId(ywMaterialsOrderLog.getOrderId()); + orderDto.setOrderType(ywMaterialsOrderLog.getOrderType()); + + //正向 + if (StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) { + + if (ywMaterialsDTO.getOpType().equals("驳回")) { + + if (!OrderStatus.DSH.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前物资订单不是待审核状态,无法驳回"); + } + + //驳回后释放库存 + boolean resBack = ywMaterialsStockService.freezeOutWayMaterialsStockBack(ywMaterialsDTO, ywMaterialsOrderLog); + + if (!resBack) { + throw new ServiceException("释放库存异常,驳回失败了,不用走工作流"); + } + + orderDto.setTaskStatus(OrderStatus.DSQ.getCode()); + } + + if (ywMaterialsDTO.getOpType().equals("提交申请")) { + + if (!OrderStatus.DSQ.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前物资订单不是待申请状态,无法提交申请"); + } + + orderDto.setTaskStatus(OrderStatus.DSH.getCode()); + } + + } + + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + + if (ywMaterialsDTO.getIsBack().equals("是")) { + + if (ywMaterialsDTO.getOpType().equals("驳回")) { + + if (!OrderStatus.DSQ.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前物资订单不是待申请状态,无法回滚到待审核"); + } + + //工作流驳回失败了,重新冻结上去 + boolean resBack = ywMaterialsStockService.freezeOutWayMaterialsStock(ywMaterialsDTO, ywMaterialsOrderLog); + + if (!resBack) { + throw new ServiceException("回滚驳回库存异常,需要人工处理"); + } + + if (ywMaterialsDTO.getIsBack().equals("是")) { + orderDto.setTaskStatus(OrderStatus.DSH.getCode()); + } + } + + if (ywMaterialsDTO.getOpType().equals("提交申请")) { + + if (!OrderStatus.DSH.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前物资订单不是待审核状态,无法回滚到待申请"); + } + + if (ywMaterialsDTO.getIsBack().equals("是")) { + orderDto.setTaskStatus(OrderStatus.DSQ.getCode()); + } + + } + + } + + + + } + + res = ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); + +// if(!res) +// { +// //回滚释放库存的操作 +// throw new ServiceException("修改为待审核异常,驳回失败了"); +// } + + } + + //中心库审核任务通过就入库确认 + if (ywMaterialsDTO.getOpType().equals("审核任务")) { + if (ywMaterialsDTO.getOrderType() == OrderType.ZXK.getCode()) { + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + if (ywMaterialsDTO.getIsBack().equals("是")) { + res = ywMaterialsStockService.updateMaterialsStockBack(ywMaterialsDTO); + } + } + + //正向 + if (StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) { + res = ywMaterialsStockService.updateMaterialsStock(ywMaterialsDTO); + } + } else { + + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + if (ywMaterialsDTO.getIsBack().equals("是")) { + if(ywMaterialsDTO.getOrderType() == OrderType.SL.getCode() || ywMaterialsDTO.getOrderType() == OrderType.RK.getCode()) { + res = ywMaterialsStockService.updateFreezeOutWayMaterialsStockBack(ywMaterialsDTO); + } + + if(ywMaterialsDTO.getOrderType() == OrderType.TK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.CK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.DB.getCode()) { + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + orderDto.setOrderId(ywMaterialsDTO.getOrderId()); + orderDto.setOrderType(ywMaterialsDTO.getOrderType()); + orderDto.setTaskStatus(OrderStatus.DSH.getCode()); + res = ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); + } + + } + } + + //正向 + if (StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) { +// 申领和入库在审核环节释放库存 + if(ywMaterialsDTO.getOrderType() == OrderType.SL.getCode() || ywMaterialsDTO.getOrderType() == OrderType.RK.getCode()) { + res = ywMaterialsStockService.updateFreezeOutWayMaterialsStock(ywMaterialsDTO); + } + + if(ywMaterialsDTO.getOrderType() == OrderType.TK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.CK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.DB.getCode()) { + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + + orderDto.setOrderId(ywMaterialsDTO.getOrderId()); + orderDto.setOrderType(ywMaterialsDTO.getOrderType()); + orderDto.setTaskStatus(OrderStatus.YSH.getCode()); + res = ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); + } + + + + + } + + } + } + + if (ywMaterialsDTO.getOpType().equals("出库确认")) { + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + if (ywMaterialsDTO.getIsBack().equals("是")) { + if(ywMaterialsDTO.getOrderType() == OrderType.TK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.CK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.DB.getCode()) { + res = ywMaterialsStockService.updateFreezeOutWayMaterialsStockBack(ywMaterialsDTO); + } + else + { + return AjaxResult.error("当前步骤和任务状态不同步"); + } + } + } + + //正向 + if (StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) { + // 退库,出库和调拨在出库确认环节释放库存 + if(ywMaterialsDTO.getOrderType() == OrderType.TK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.CK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.DB.getCode()) { + res = ywMaterialsStockService.updateFreezeOutWayMaterialsStock(ywMaterialsDTO); + } + else + { + return AjaxResult.error("当前步骤和任务状态不同步"); + } + } + + } + + if (ywMaterialsDTO.getOpType().equals("入库确认")) { + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + if (ywMaterialsDTO.getIsBack().equals("是")) { + res = ywMaterialsStockService.updateMaterialsStockBack(ywMaterialsDTO); + } + } + + //正向 + if (StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) { + res = ywMaterialsStockService.updateMaterialsStock(ywMaterialsDTO); + } + } + + if (res) { + return AjaxResult.success("更新物资库存成功"); + } + + return AjaxResult.error("更新物资库存失败"); + + } + + + @Log(title = "更新物资库存信息数据", businessType = BusinessType.UPDATE) + @ApiOperation("更新物资库存信息数据,未完成") + @PostMapping("/stock/updateNew") + @Transactional + public AjaxResult updateStockNew(@RequestBody YwMaterialsDTO ywMaterialsDTO, YwMaterialsOrderLogDTO ywMaterialsOrderLogDTO) throws Exception { + + + Boolean res = true; + + if (ObjectUtils.isEmpty(ywMaterialsDTO.getOpType())) { + throw new ServiceException("操作类型不能为空"); + } + + if (ObjectUtils.isEmpty(ywMaterialsDTO.getOrderType())) { + throw new ServiceException("物资工单类型不能为空"); + } + + //1.验证请求用户的权限 +// 验证当前用户的角色是否具有操作权限 + List roles = SecurityUtils.getLoginUser().getUser().getRoles(); + + List filterRoles = null; + + boolean needCheck = false; + + if (ywMaterialsDTO.getOpType().equals("创建") || ywMaterialsDTO.getOpType().equals("提交申请")) { + + if (ywMaterialsDTO.getOrderType().equals(OrderType.ZXK.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("centerstoragechecker")).collect(Collectors.toList()); + } + + if (ywMaterialsDTO.getOrderType().equals(OrderType.SL.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.TK.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("venuestoragechecker") || e.getRoleKey().equals("venuemanager")).collect(Collectors.toList()); + } + + if (ywMaterialsDTO.getOrderType().equals(OrderType.CK.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.RK.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("builder")).collect(Collectors.toList()); + } + + if (ywMaterialsDTO.getOrderType().equals(OrderType.DB.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("centerstoragemaster")).collect(Collectors.toList()); + } + needCheck = true; + + } + + if (ywMaterialsDTO.getOpType().equals("审核任务")) { + + if (ywMaterialsDTO.getOrderType().equals(OrderType.ZXK.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.SL.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.TK.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("centerstoragemaster")).collect(Collectors.toList()); + } + + + if (ywMaterialsDTO.getOrderType().equals(OrderType.CK.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.RK.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.DB.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("venuestoragemaster")).collect(Collectors.toList()); + } + needCheck = true; + } + + if (ywMaterialsDTO.getOpType().equals("出库确认") || ywMaterialsDTO.getOpType().equals("入库确认")) { + + if (!ywMaterialsDTO.getOrderType().equals(OrderType.ZXK.getCode())) { +// 默认都是场馆物资仓库管理员出入库确认 + //物资退库,是中心库物资维护员角色提交入库 + if (ywMaterialsDTO.getOpType().equals("入库确认")) { + if (ywMaterialsDTO.getOrderType().equals(OrderType.TK.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("centerstoragechecker")).collect(Collectors.toList()); + } else { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("venuestoragekeeper")).collect(Collectors.toList()); + } + } else { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("venuestoragekeeper")).collect(Collectors.toList()); + } + } + needCheck = true; + } + + + if (needCheck) { + if(filterRoles!=null) { + if (filterRoles.isEmpty()) { + throw new ServiceException("当前用户没有操作的权限"); + } + } + } + + //2.物资订单表的操作 + //创建时如果不是中心库,折旧入库 的需要冻结库存 + if (ywMaterialsDTO.getOpType().equals("创建")) { + + try { + + //新增物资订单,返回orderID + //根据这个ID,回填工作流的ID + String orderId = ywMaterialsOrderLogService.insertMaterialsOrderLog(ywMaterialsOrderLogDTO); + + ywMaterialsOrderLogDTO.setOrderId(orderId); + + StartProcessInstanceDTO dto = new StartProcessInstanceDTO(); + //返回工作流ID + String flwId = commonService.StartProcess(dto); + + ywMaterialsOrderLogDTO.setFlwProcessid(flwId); + + //回填工作流ID + ywMaterialsOrderLogService.updateMaterialsOrderLog(ywMaterialsOrderLogDTO); + + } catch (Exception ex) { + throw new ServiceException(ex.getMessage()); + } + + } + + if (ywMaterialsDTO.getOpType().equals("撤销")) { + + YwMaterialsOrderLog ywMaterialsOrderLog = ywMaterialsStockService.Validate(ywMaterialsDTO); + + if (!OrderStatus.DSQ.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前物资订单状态不允许该操作"); + } + + res = ywMaterialsStockService.freezeOutWayMaterialsStockBack(ywMaterialsDTO, ywMaterialsOrderLog); + + if (res) { + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + orderDto.setOrderId(ywMaterialsOrderLog.getOrderId()); + orderDto.setOrderType(ywMaterialsOrderLog.getOrderType()); + orderDto.setTaskStatus(OrderStatus.CX.getCode()); + res = ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); + + } + + if (res) { + return AjaxResult.success("撤销物资订单成功"); + } + + return AjaxResult.error("撤销物资订单失败"); + + } + + if (ywMaterialsDTO.getOpType().equals("驳回") || ywMaterialsDTO.getOpType().equals("提交申请")) { + + YwMaterialsOrderLog ywMaterialsOrderLog = ywMaterialsStockService.Validate(ywMaterialsDTO); + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + + orderDto.setOrderId(ywMaterialsOrderLog.getOrderId()); + orderDto.setOrderType(ywMaterialsOrderLog.getOrderType()); + + if (ywMaterialsDTO.getOpType().equals("驳回")) { + + if (!OrderStatus.DSH.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前物资订单不是待审核状态,无法驳回"); + } + + //驳回后释放库存 + boolean resBack = ywMaterialsStockService.freezeOutWayMaterialsStockBack(ywMaterialsDTO, ywMaterialsOrderLog); + + if (!resBack) { + throw new ServiceException("释放库存异常,驳回失败了,不用走工作流"); + } + + orderDto.setTaskStatus(OrderStatus.DSQ.getCode()); + } + + if (ywMaterialsDTO.getOpType().equals("提交申请")) { + + if (!OrderStatus.DSQ.getCode().equals(ywMaterialsOrderLog.getTaskStatus())) { + throw new ServiceException("当前物资订单不是待申请状态,无法提交申请"); + } + + orderDto.setTaskStatus(OrderStatus.DSH.getCode()); + } + + res = ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); + + + } + + //中心库审核任务通过就入库确认 + if (ywMaterialsDTO.getOpType().equals("审核任务")) { + if (ywMaterialsDTO.getOrderType() == OrderType.ZXK.getCode()) { + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + if (ywMaterialsDTO.getIsBack().equals("是")) { + res = ywMaterialsStockService.updateMaterialsStockBack(ywMaterialsDTO); + } + } + + //正向 + if (StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) { + res = ywMaterialsStockService.updateMaterialsStock(ywMaterialsDTO); + } + } else { + + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + if (ywMaterialsDTO.getIsBack().equals("是")) { + if(ywMaterialsDTO.getOrderType() == OrderType.SL.getCode() || ywMaterialsDTO.getOrderType() == OrderType.RK.getCode()) { + res = ywMaterialsStockService.updateFreezeOutWayMaterialsStockBack(ywMaterialsDTO); + } + } + } + + //正向 + if (StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) { +// 申领和入库在审核环节释放库存 + if(ywMaterialsDTO.getOrderType() == OrderType.SL.getCode() || ywMaterialsDTO.getOrderType() == OrderType.RK.getCode()) { + res = ywMaterialsStockService.updateFreezeOutWayMaterialsStock(ywMaterialsDTO); + } + + } + + } + } + + if (ywMaterialsDTO.getOpType().equals("出库确认")) { + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + if (ywMaterialsDTO.getIsBack().equals("是")) { + if(ywMaterialsDTO.getOrderType() == OrderType.TK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.CK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.DB.getCode()) { + res = ywMaterialsStockService.updateFreezeOutWayMaterialsStock(ywMaterialsDTO); + } + } + } + + //正向 + if (StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) { + res = ywMaterialsStockService.updateInWayMaterialsStock(ywMaterialsDTO); + // 退库,出库和调拨在出库确认环节释放库存 + if(ywMaterialsDTO.getOrderType() == OrderType.TK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.CK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.DB.getCode()) { + res = ywMaterialsStockService.updateFreezeOutWayMaterialsStock(ywMaterialsDTO); + } + } + + } + + if (ywMaterialsDTO.getOpType().equals("入库确认")) { + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + if (ywMaterialsDTO.getIsBack().equals("是")) { + res = ywMaterialsStockService.updateMaterialsStockBack(ywMaterialsDTO); + } + } + + //正向 + if (StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) { + res = ywMaterialsStockService.updateMaterialsStock(ywMaterialsDTO); + } + } + + if (ywMaterialsDTO.getOpType().equals("驳回")) { + + try { + + HandleDataDTO dto = new HandleDataDTO(); + } catch (Exception ex) { + throw new ServiceException(ex.getMessage()); + } + + } else { + try { + + HandleDataDTO dto = new HandleDataDTO(); + res = commonService.agreeTask(dto); + if (!res) { + throw new Exception("workspace/process/start请求返回错误"); + } + } catch (Exception ex) { + throw new ServiceException(ex.getMessage()); + } + + } + + + if (res) { + return AjaxResult.success("更新物资库存成功"); + } + + return AjaxResult.error("更新物资库存失败"); + + } + + + @ApiOperation("根据条件查询仓库的物资信息数据") + @PostMapping("/info/list") + public TableDataInfo info(@RequestBody YwMaterialsSearchDTO ywMaterialsSearchDTO) throws Exception { + String pageNum = ServletUtils.getParameter("pageNum"); + String pageSize = ServletUtils.getParameter("pageSize"); + if (!StringUtils.isEmpty(pageNum) && !StringUtils.isEmpty(pageSize)) { + startPage(); + } + return getDataTable(ywMaterialsInformService.selectMaterials(ywMaterialsSearchDTO)); + } + + @ApiOperation("获取所有物资信息数据") + @GetMapping("/info/list") + public AjaxResult InfoAll() throws Exception { + List list = ywMaterialsInformService.getMaterials(); + if (ObjectUtils.isNotEmpty(list)) { + return AjaxResult.success("获取物资信息数据成功", list); + } + return AjaxResult.error("获取物资信息数据失败"); + } + + + @Log(title = "新增物资信息数据", businessType = BusinessType.INSERT) + @ApiOperation("新增物资信息数据") + @PostMapping("/info/insert") + public AjaxResult insertInfo(@RequestBody YwMaterialsInformDTO ywMaterialsInformDTO) { + + Boolean res = ywMaterialsInformService.insertMaterials(ywMaterialsInformDTO); + if (res) { + return AjaxResult.success("新增物资信息数据成功"); + } + return AjaxResult.error("新增物资信息数据失败"); + + } + + @Log(title = "修改物资信息数据", businessType = BusinessType.UPDATE) + @ApiOperation("修改物资信息数据") + @PostMapping("/info/update") + public AjaxResult updateInfo(@RequestBody YwMaterialsInformDTO ywMaterialsInformDTO) { + Boolean res = ywMaterialsInformService.updateMaterials(ywMaterialsInformDTO); + if (res) { + return AjaxResult.success("修改物资信息数据成功"); + } + return AjaxResult.error("修改物资信息数据失败"); + + } + + + @ApiOperation("查询所有大小类") + @GetMapping("/classes/list") + public AjaxResult list() throws Exception { + + Map map = ywMaterialsClassesService.GetMaterialsClasses(); + if (ObjectUtils.isNotEmpty(map)) { + return AjaxResult.success("获取大小类数据成功", map); + } + + return AjaxResult.error("获取大小类数据失败"); + } + + @Log(title = "新增申领数据", businessType = BusinessType.INSERT) + @ApiOperation("新增申领数据") + @PostMapping("/batch/insert") + public AjaxResult insertBatch(@RequestBody YwMaterialsBatchDTO ywMaterialsBatchDTO) { + + boolean res = ywMaterialsBatchService.insertBatch(ywMaterialsBatchDTO); + + if (res) { + return AjaxResult.success("新增申领数据成功"); + } + return AjaxResult.error("新增申领数据失败"); + + } + + @Log(title = "修改申领数据", businessType = BusinessType.UPDATE) + @ApiOperation("修改申领数据") + @PostMapping("/batch/update") + public AjaxResult updateBatch(@RequestBody YwMaterialsBatch ywMaterialsBatch) { + + boolean res = ywMaterialsBatchService.updateBatch(ywMaterialsBatch); + + if (res) { + return AjaxResult.success("修改申领数据成功"); + } + + return AjaxResult.error("修改申领数据失败"); + + } + + @Log(title = "删除申领数据", businessType = BusinessType.DELETE) + @ApiOperation("删除申领数据") + @PostMapping("/batch/delete") + public AjaxResult deleteBatch(@RequestBody YwMaterialsBatchDTO ywMaterialsBatchDTO) { + + boolean res = ywMaterialsBatchService.deleteBatch(ywMaterialsBatchDTO); + + if (res) { + return AjaxResult.success("删除申领数据成功"); + } + + return AjaxResult.error("删除申领数据失败"); + } + + @ApiOperation("查询物资申领数据") + @PostMapping("/batch/list") + public TableDataInfo getBatch(@RequestBody YwMaterialsBatchDTO ywMaterialsBatchDTO) { + String pageNum = ServletUtils.getParameter("pageNum"); + String pageSize = ServletUtils.getParameter("pageSize"); + if (!StringUtils.isEmpty(pageNum) && !StringUtils.isEmpty(pageSize)) { + startPage(); + } + return getDataTable(ywMaterialsBatchMapper.selectBatch(ywMaterialsBatchDTO.getOrderId())); + } + + @Log(title = "新增物资串码数据", businessType = BusinessType.INSERT) + @ApiOperation("新增物资串码数据") + @PostMapping("/snList/insert") + public AjaxResult insertBatch(@RequestBody YwMaterialsSnListDTO ywMaterialsSnListDTO) { + + + List roles = SecurityUtils.getLoginUser().getUser().getRoles(); + + List filterRoles = roles.stream().filter(e -> "venuestoragekeeper".equals(e.getRoleKey()) || "centerstoragechecker".equals(e.getRoleKey())).collect(Collectors.toList()); + + if(filterRoles!=null) { + if (filterRoles.isEmpty()) { + return AjaxResult.error("当前用户没有操作的权限"); + } + } + + boolean res = ywMaterialsSnListService.insertSnList(ywMaterialsSnListDTO); + + if (res) { + return AjaxResult.success("新增串码数据成功"); + } + return AjaxResult.error("新增串码数据失败"); + + + } + + @ApiOperation("查询物资串码数据") + @PostMapping("/snList/list") + public TableDataInfo getSnList(@RequestBody YwMaterialsSnListQO ywMaterialsSnListQO) { + String pageNum = ServletUtils.getParameter("pageNum"); + String pageSize = ServletUtils.getParameter("pageSize"); + if (!StringUtils.isEmpty(pageNum) && !StringUtils.isEmpty(pageSize)) { + startPage(); + } + return getDataTable(ywMaterialsSnListService.selectSnList(ywMaterialsSnListQO)); + } + + @ApiOperation("excel转JSON数组") + @PostMapping("/transformMaterialsXlsToJsonArray") + public AjaxResult transformMaterialsXlsToJsonArray(@RequestPart("file") MultipartFile file, @RequestParam("materialStoreId") Long material_store_id) throws Exception { + ExcelUtil util = new ExcelUtil<>(MaterialsXlsToJsonArrayVo.class); + List xls = util.importExcel(file.getInputStream()); + return ywMaterialsStockService.importXlsReturnList(xls, material_store_id); + } + + @ApiOperation("JSON数组转excel") + @PostMapping("/transformJsonArrayToMaterialsXls") + public void transformJsonArrayToMaterialsXls(@RequestBody TransformJsonArrayToMaterialsXlsDTO arrayVos, HttpServletResponse response) { + if (ObjectUtils.isEmpty(arrayVos)) { + throw new ServiceException("参数校验不通过"); + } + ExcelUtil util = new ExcelUtil<>(MaterialsXlsToJsonArrayVo.class); + if (5 == arrayVos.getTaskType() || 3 == arrayVos.getTaskType()) { + util.hideColumn("id", "reason", "outSum", "inSum", "operation", "availSum"); + } else { + util.hideColumn("id", "reason", "outSum", "inSum", "operation"); + } + List data = arrayVos.getData(); + util.exportExcel(response, data, "数据"); + } + + + + + +} + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsInformController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsInformController.java new file mode 100644 index 0000000..15976f6 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsInformController.java @@ -0,0 +1,234 @@ +package com.ruoyi.web.controller.cmcc_gm; + + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.cmcc_gm.domain.YwMaterialsInform; +import com.ruoyi.cmcc_gm.domain.YwMaterialsStock; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSearchDTO; +import com.ruoyi.cmcc_gm.service.YwMaterialsInformService; +import com.ruoyi.cmcc_gm.service.YwMaterialsStockService; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.Serializable; +import java.util.List; + +/** + * 物资信息表(YwMaterialsInform)表控制层 + * + * @author lee + * @since 2023-04-14 16:35:17 + */ +@Api("物料信息") +@RestController +@RequestMapping("/eastcom_yw/ywMaterialsInform") +public class YwMaterialsInformController extends BaseController { + + /** + * 服务对象 + */ + @Resource + private YwMaterialsInformService ywMaterialsInformService; + + @Resource + private YwMaterialsStockService ywMaterialsStockService; + + + /** + * 分页查询所有数据 + * + * @param ywMaterialsInform 查询实体 + * @return 所有数据 + */ + @ApiOperation("分页查询") + @PostMapping("/list") + public TableDataInfo selectAll(@RequestBody YwMaterialsSearchDTO ywMaterialsInform) { + PageUtils.startPage(ywMaterialsInform, YwMaterialsSearchDTO.class); + return getDataTable(ywMaterialsInformService.getMaterialsBySearch(ywMaterialsInform)); + } + + /** + * 导出 + * + * @param ywMaterialsInform + */ + @ApiOperation("导出") + @PostMapping("/export") + public void exportRd(@RequestBody YwMaterialsSearchDTO ywMaterialsInform, HttpServletResponse response) { + ywMaterialsInform.setPageNum(1); + ywMaterialsInform.setPageSize(Integer.MAX_VALUE); + List list = ywMaterialsInformService.getMaterialsBySearch(ywMaterialsInform); + ExcelUtil util = new ExcelUtil<>(YwMaterialsInform.class); + util.hideColumn("sum", "reason", "rowId", "special", "detail"); + util.exportExcel(response, list, "物资配置信息"); + } + + /** + * 通过主键查询单条数据 + * + * @param id 主键 + * @return 单条数据 + */ + @ApiOperation("根据id查询") + @GetMapping("{id}") + public AjaxResult selectOne(@PathVariable Serializable id) { + return AjaxResult.success(this.ywMaterialsInformService.getById(id)); + } + + /** + * 新增数据 + * + * @param ywMaterialsInform 实体对象 + * @return 新增结果 + */ + @Log(title = "新增物资信息", businessType = BusinessType.INSERT) + @ApiOperation("插入") + @PostMapping + public AjaxResult insert(@RequestBody YwMaterialsInform ywMaterialsInform) { + //检查物资编号是否已经存在 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(YwMaterialsInform::getMaterialCode, ywMaterialsInform.getMaterialCode()); + + YwMaterialsInform inform = ywMaterialsInformService.getOne(query); + + if (ObjectUtils.isNotEmpty(inform)) { + throw new ServiceException("物资编号已存在"); + } + + //检查物资名称+规格型号是否存在 + query = new LambdaQueryWrapper<>(); + query.eq(YwMaterialsInform::getMaterialName, ywMaterialsInform.getMaterialName()) + .eq(YwMaterialsInform::getMaterialStand, ywMaterialsInform.getMaterialStand()); + YwMaterialsInform one = ywMaterialsInformService.getOne(query); + if (ObjectUtils.isNotEmpty(one)) { + throw new ServiceException("物资名称+规格型号已存在"); + } + + boolean res = this.ywMaterialsInformService.save(ywMaterialsInform); + if (res) { + ywMaterialsInformService.loadingMaterialsInfoCache(); + } + return AjaxResult.success(res); + } + + /** + * 修改数据 + * + * @param ywMaterialsInform 实体对象 + * @return 修改结果 + */ + @Log(title = "修改物资信息", businessType = BusinessType.UPDATE) + @ApiOperation("更新") + @PutMapping + public AjaxResult update(@RequestBody YwMaterialsInform ywMaterialsInform) { + + if (ObjectUtils.isEmpty(ywMaterialsInform.getMaterialCode()) || + ObjectUtils.isEmpty(ywMaterialsInform.getMaterialName()) || + ObjectUtils.isEmpty(ywMaterialsInform.getMaterialStand()) || + ObjectUtils.isEmpty(ywMaterialsInform.getMaterialBigClass()) || + ObjectUtils.isEmpty(ywMaterialsInform.getMaterialSmallClass()) || + ObjectUtils.isEmpty(ywMaterialsInform.getSnCode()) || + ObjectUtils.isEmpty(ywMaterialsInform.getMaterialUnit())) { + throw new ServiceException("参数校验不通过"); + } + + YwMaterialsSearchDTO searchDTO = new YwMaterialsSearchDTO(); + searchDTO.setMaterialName(ywMaterialsInform.getMaterialName()); + searchDTO.setMaterialStand(ywMaterialsInform.getMaterialStand()); + List materialsBySearch = ywMaterialsInformService.getMaterialsBySearch(searchDTO); + if (CollectionUtils.isNotEmpty(materialsBySearch)) { + for (YwMaterialsInform bySearch : materialsBySearch) { + if (!bySearch.getMaterialCode().equals(ywMaterialsInform.getMaterialCode())) { + throw new ServiceException("“物资名称+规格型号”已存在"); + } + } + } + + boolean res = this.ywMaterialsInformService.updateById(ywMaterialsInform); + if (res) { + ywMaterialsInformService.loadingMaterialsInfoCache(); + } + return AjaxResult.success(); + + } + + /** + * 删除数据 + * + * @param idList 主键结合 + * @return 删除结果 + */ + @Log(title = "删除物资信息", businessType = BusinessType.DELETE) + @ApiOperation("删除") + @DeleteMapping + public AjaxResult delete(@RequestParam("idList") List idList) { + if (ObjectUtils.isEmpty(idList) || idList.size() == 0) { + throw new ServiceException("参数校验不通过"); + } + YwMaterialsInform byId = ywMaterialsInformService.getById(idList.get(0)); + if (ObjectUtils.isEmpty(byId)) { + throw new ServiceException("id不存在"); + } + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(YwMaterialsStock::getMaterialCode, byId.getMaterialCode()); + YwMaterialsStock one = ywMaterialsStockService.getOne(queryWrapper, false); + if (ObjectUtils.isNotEmpty(one)) { + throw new ServiceException("无法删除已存在于物资库中的物资"); + } + + boolean res = this.ywMaterialsInformService.removeById(idList.get(0)); + if (res) { + ywMaterialsInformService.loadingMaterialsInfoCache(); + } + return AjaxResult.success(); + } + + /** + * 导入 + * + * @param file excel + * @return + * @throws Exception + */ + @Log(title = "导入物资信息", businessType = BusinessType.IMPORT) + @ApiOperation("导入") + @PostMapping("/import") + + public AjaxResult doImport(@RequestPart(name = "file") MultipartFile file,String importType) throws Exception { + + boolean delNoUse = false; + //20230808增加覆盖导入,原来是只有追加 + //覆盖导入先把物资信息中库存表不存在的物资删除掉 + if(StringUtils.isNotEmpty(importType)) + { + if("0".equals(importType)) + { + //删除多余的物资数据 +// ywMaterialsInformService.deleteNotExistsMaterials(); + delNoUse = true; + } + } + ExcelUtil util = new ExcelUtil<>(YwMaterialsInform.class); + util.hideColumn("sum"); + List informs = util.importExcel(file.getInputStream()); + return ywMaterialsInformService.doImport(informs,delNoUse); + } + +} + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsOrderLogController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsOrderLogController.java new file mode 100644 index 0000000..839b995 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsOrderLogController.java @@ -0,0 +1,238 @@ +package com.ruoyi.web.controller.cmcc_gm; + + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.cmcc_gm.common.enums.OrderType; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsOrderLogDTO; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSearchDTO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsOrderLogVo; +import com.ruoyi.cmcc_gm.service.YwMaterialsOrderLogService; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.mapper.YwSceneMapper; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletResponse; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + *

+ * 物资工单日志表 前端控制器 + *

+ * + * @author jkj + * @since 2023-04-07 + */ +@RestController +@RequestMapping("/cmcc_gm/ywMaterialsOrderLog") +public class YwMaterialsOrderLogController extends BaseController { + + @Autowired + private YwMaterialsOrderLogService ywMaterialsOrderLogService; + + @Autowired + private YwSceneMapper ywSceneMapper; + + + @Log(title = "新增物资日志记录", businessType = BusinessType.INSERT) + @ApiOperation("新增物资日志记录") + @PostMapping("/insert") + public AjaxResult insert(@RequestBody YwMaterialsOrderLogDTO ywMaterialsOrderLogDTO) { + try { + String res = ywMaterialsOrderLogService.insertMaterialsOrderLog(ywMaterialsOrderLogDTO); + + if (StringUtils.isNotEmpty(res)) { + return AjaxResult.success("新增物资工单日志成功", res); + } + + return AjaxResult.error("新增物资工单日志失败"); + + } catch (Exception ex) { + return AjaxResult.error(ex.getMessage()); + } + + } + + @Log(title = "修改物资日志记录", businessType = BusinessType.UPDATE) + @ApiOperation("修改物资日志记录") + @PostMapping("/update") + public AjaxResult update(@RequestBody YwMaterialsOrderLogDTO ywMaterialsOrderLogDTO) { + try { + boolean res = ywMaterialsOrderLogService.updateMaterialsOrderLog(ywMaterialsOrderLogDTO); + if (res) { + return AjaxResult.success("修改物资日志记录成功"); + } + + return AjaxResult.error("修改物资日志记录失败"); + + } catch (Exception ex) { + return AjaxResult.error(ex.getMessage()); + } + + } + + @Log(title = "删除物资日志记录", businessType = BusinessType.DELETE) + @ApiOperation("删除物资日志记录") + @PostMapping("/delete") + public AjaxResult remove(@RequestBody YwMaterialsOrderLogDTO ywMaterialsOrderLogDTO) { + try { + boolean res = ywMaterialsOrderLogService.deleteMaterialsOrderLog(ywMaterialsOrderLogDTO); + if (res) { + return AjaxResult.success("删除物资日志记录成功"); + } + + return AjaxResult.error("删除物资日志记录失败"); + + } catch (Exception ex) { + return AjaxResult.error(ex.getMessage()); + } + } + + + @ApiOperation("获取物资日志记录") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwMaterialsSearchDTO ywMaterialsSearchDTO) throws Exception { +// TableDataInfo resData = ywMaterialsOrderLogService.getMaterialsOrderLog(ywMaterialsSearchDTO); +// return getDataTable(resData.getRows(), resData.getTotal()); + + if (ObjectUtils.isEmpty(ywMaterialsSearchDTO.getOrderType())) { + throw new ServiceException("工单类型不能为空"); + } + +// if(ObjectUtils.isEmpty(ywMaterialsSearchDTO.getInStoreId()) || ObjectUtils.isEmpty(ywMaterialsSearchDTO.getOutStoreId())) +// { +// throw new ServiceException("入库ID和出库ID不允许为空"); +// } + + if (!(ywMaterialsSearchDTO.getOrderType() == OrderType.ZXK.getCode() || ywMaterialsSearchDTO.getOrderType() == OrderType.DB.getCode())) { + if (ObjectUtils.isNotEmpty(ywMaterialsSearchDTO.getInStoreId()) && ObjectUtils.isNotEmpty(ywMaterialsSearchDTO.getOutStoreId())) { + if (ywMaterialsSearchDTO.getInStoreId() == -2 || ywMaterialsSearchDTO.getOutStoreId() == -2) { + SysUser user = getLoginUser().getUser(); + if (!(user.isAdmin(user) || user.isCenter(user))) { + List list = ywSceneMapper.getVenueByUserId(user.getUserId()); + if (list.size() > 0) { + List lstIds = list.stream().map(x -> x.getId()).collect(Collectors.toList()); + Long[] arr_ids = lstIds.toArray(new Long[lstIds.size()]); + if (ywMaterialsSearchDTO.getInStoreId() == -2) { + ywMaterialsSearchDTO.setInStoreIds(arr_ids); + ywMaterialsSearchDTO.setInStoreId(null); + } + if (ywMaterialsSearchDTO.getOutStoreId() == -2) { + ywMaterialsSearchDTO.setOutStoreIds(arr_ids); + ywMaterialsSearchDTO.setOutStoreId(null); + } + } + } else { + if (ywMaterialsSearchDTO.getInStoreId() == -2) { + ywMaterialsSearchDTO.setInStoreId(null); + } + if (ywMaterialsSearchDTO.getOutStoreId() == -2) { + ywMaterialsSearchDTO.setOutStoreId(null); + } + } + } + } + } + + startPage(); + return getDataTable(ywMaterialsOrderLogService.selectMaterialsOrderLog(ywMaterialsSearchDTO)); + + } + + @ApiOperation("导出物资日志记录") + @PostMapping("/export") + public void export(@RequestBody YwMaterialsSearchDTO ywMaterialsSearchDTO, HttpServletResponse response) throws Exception { + Map orderTypeMap = new HashMap<>(); + Map taskStatusMap = new HashMap<>(); + taskStatusMap.put("0", "待申请"); + taskStatusMap.put("1", "待审核"); + taskStatusMap.put("2", "已审核"); + taskStatusMap.put("3", "已出库"); + taskStatusMap.put("4", "已入库"); + orderTypeMap.put(1, "中心库物资更新"); + orderTypeMap.put(2, "物资申领"); + orderTypeMap.put(3, "物资退库"); + orderTypeMap.put(4, "工程出库"); + orderTypeMap.put(5, "折旧入库"); + orderTypeMap.put(6, "物资调拨"); + ywMaterialsSearchDTO.setPageNum(1); + ywMaterialsSearchDTO.setPageSize(Integer.MAX_VALUE); + if (ObjectUtils.isEmpty(ywMaterialsSearchDTO.getOrderType())) { + throw new ServiceException("工单类型不能为空"); + } + if (!(ywMaterialsSearchDTO.getOrderType() == OrderType.ZXK.getCode() || ywMaterialsSearchDTO.getOrderType() == OrderType.DB.getCode())) { + if (ObjectUtils.isNotEmpty(ywMaterialsSearchDTO.getInStoreId()) && ObjectUtils.isNotEmpty(ywMaterialsSearchDTO.getOutStoreId())) { + if (ywMaterialsSearchDTO.getInStoreId() == -2 || ywMaterialsSearchDTO.getOutStoreId() == -2) { + SysUser user = getLoginUser().getUser(); + if (!(user.isAdmin(user) || user.isCenter(user))) { + List list = ywSceneMapper.getVenueByUserId(user.getUserId()); + if (list.size() > 0) { + List lstIds = list.stream().map(x -> x.getId()).collect(Collectors.toList()); + Long[] arr_ids = lstIds.toArray(new Long[lstIds.size()]); + if (ywMaterialsSearchDTO.getInStoreId() == -2) { + ywMaterialsSearchDTO.setInStoreIds(arr_ids); + ywMaterialsSearchDTO.setInStoreId(null); + } + if (ywMaterialsSearchDTO.getOutStoreId() == -2) { + ywMaterialsSearchDTO.setOutStoreIds(arr_ids); + ywMaterialsSearchDTO.setOutStoreId(null); + } + } + } else { + if (ywMaterialsSearchDTO.getInStoreId() == -2) { + ywMaterialsSearchDTO.setInStoreId(null); + } + if (ywMaterialsSearchDTO.getOutStoreId() == -2) { + ywMaterialsSearchDTO.setOutStoreId(null); + } + } + } + } + } + List ywMaterialsOrderLogVos = ywMaterialsOrderLogService.selectMaterialsOrderLog(ywMaterialsSearchDTO); + for (YwMaterialsOrderLogVo ywMaterialsOrderLogVo : ywMaterialsOrderLogVos) { + ywMaterialsOrderLogVo.setOutStoreName(ywMaterialsOrderLogVo.getInStoreName()); + ywMaterialsOrderLogVo.setOutVenue2Name(ywMaterialsOrderLogVo.getOutVenueName()); + ywMaterialsOrderLogVo.setInVenue2Name(ywMaterialsOrderLogVo.getInVenueName()); + if (StringUtils.isNotNull(ywMaterialsOrderLogVo.getOrderType())) { + ywMaterialsOrderLogVo.setOrderTypeName(orderTypeMap.get(ywMaterialsOrderLogVo.getOrderType())); + } + if (StringUtils.isNotEmpty(ywMaterialsOrderLogVo.getTaskStatus())) { + ywMaterialsOrderLogVo.setTaskStatus(taskStatusMap.get(ywMaterialsOrderLogVo.getTaskStatus())); + } + } + ExcelUtil util = new ExcelUtil<>(YwMaterialsOrderLogVo.class); + if (ywMaterialsSearchDTO.getOrderType() == 1) { + util.hideColumn("inVenueName", "outVenueName", "wireTaskId", "outStoreName", "inStoreName", "inVenue2Name", "outVenue2Name"); + } else if (ywMaterialsSearchDTO.getOrderType() == 2) { + util.hideColumn("wireTaskId", "outStoreName", "outVenueName", "inVenue2Name", "outVenue2Name"); + } else if (ywMaterialsSearchDTO.getOrderType() == 3) { + util.hideColumn("wireTaskId", "inStoreName", "inVenueName", "inVenue2Name", "outVenue2Name"); + } else if (ywMaterialsSearchDTO.getOrderType() == 4) { + util.hideColumn("inStoreName", "inVenueName", "inVenue2Name", "outVenue2Name"); + } else if (ywMaterialsSearchDTO.getOrderType() == 5) { + util.hideColumn("outStoreName", "outVenueName", "inVenue2Name", "outVenue2Name"); + } else if (ywMaterialsSearchDTO.getOrderType() == 6) { + util.hideColumn("wireTaskId", "inVenueName", "outVenueName", "inStoreName", "outStoreName", "checkName"); + } + util.exportExcel(response, ywMaterialsOrderLogVos, "数据"); + } + +} + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsStockController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsStockController.java new file mode 100644 index 0000000..fa54038 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cmcc_gm/YwMaterialsStockController.java @@ -0,0 +1,124 @@ +package com.ruoyi.web.controller.cmcc_gm; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.cmcc_gm.domain.YwMaterialsStock; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsStockImportDTO; +import com.ruoyi.cmcc_gm.service.YwMaterialsStockService; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.util.List; + +/** + * 物资库存表(YwMaterialsStock)表控制层 + * + * @author lee + * @since 2023-04-24 09:48:06 + */ +@Api(tags = "场馆物资") +@RestController +@RequestMapping("/eastcom_yw/ywMaterialsStock") +public class YwMaterialsStockController extends BaseController { + + /** + * 服务对象 + */ + @Resource + private YwMaterialsStockService ywMaterialsStockService; + + /** + * 分页查询所有数据 + * + * @param page 分页对象 + * @param ywMaterialsStock 查询实体 + * @return 所有数据 + */ + @ApiOperation("分页查询") + @GetMapping + public AjaxResult selectAll(Page page, YwMaterialsStock ywMaterialsStock) { + return AjaxResult.success(this.ywMaterialsStockService.page(page, new QueryWrapper<>(ywMaterialsStock))); + } + + /** + * 通过主键查询单条数据 + * + * @param id 主键 + * @return 单条数据 + */ + @ApiOperation("根据id查") + @GetMapping("{id}") + public AjaxResult selectOne(@PathVariable Serializable id) { + return AjaxResult.success(this.ywMaterialsStockService.getById(id)); + } + + /** + * 新增数据 + * + * @param ywMaterialsStock 实体对象 + * @return 新增结果 + */ + @Log(title = "新增物资库存", businessType = BusinessType.INSERT) + @ApiOperation("新增") + @PostMapping + public AjaxResult insert(@RequestBody YwMaterialsStock ywMaterialsStock) { + return AjaxResult.success(this.ywMaterialsStockService.save(ywMaterialsStock)); + } + + /** + * 修改数据 + * + * @param ywMaterialsStock 实体对象 + * @return 修改结果 + */ + @Log(title = "修改物资库存", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult update(@RequestBody YwMaterialsStock ywMaterialsStock) { + return AjaxResult.success(this.ywMaterialsStockService.updateById(ywMaterialsStock)); + } + + /** + * 删除数据 + * + * @param idList 主键结合 + * @return 删除结果 + */ + @Log(title = "删除物资库存", businessType = BusinessType.DELETE) + @ApiOperation("删除") + @DeleteMapping + public AjaxResult delete(@RequestParam("idList") List idList) { + return AjaxResult.success(this.ywMaterialsStockService.removeByIds(idList)); + } + + /** + * 场馆物资导入 + * + * @param file + * @param sceneBigId + * @param materialStoreId + * @return + */ + @Log(title = "导入物资库存", businessType = BusinessType.IMPORT) + @ApiOperation("导入") + @RequestMapping(method = RequestMethod.POST, value = "/import") + public AjaxResult importXls(@RequestPart("file") MultipartFile file, + @RequestParam(value = "sceneBigId", defaultValue = "1") Long sceneBigId, + @RequestParam("materialStoreId") Long materialStoreId, + @RequestParam("importType") String importType) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwMaterialsStockImportDTO.class); + List beans = util.importExcel(file.getInputStream()); + return ywMaterialsStockService.importXls(beans, sceneBigId, importType, materialStoreId); + } + +} + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java new file mode 100644 index 0000000..d2d6e8c --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java @@ -0,0 +1,94 @@ +package com.ruoyi.web.controller.common; + +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import javax.annotation.Resource; +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.FastByteArrayOutputStream; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import com.google.code.kaptcha.Producer; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.utils.sign.Base64; +import com.ruoyi.common.utils.uuid.IdUtils; +import com.ruoyi.system.service.ISysConfigService; + +/** + * 验证码操作处理 + * + * @author ruoyi + */ +@RestController +public class CaptchaController +{ + @Resource(name = "captchaProducer") + private Producer captchaProducer; + + @Resource(name = "captchaProducerMath") + private Producer captchaProducerMath; + + @Autowired + private RedisCache redisCache; + + @Autowired + private ISysConfigService configService; + /** + * 生成验证码 + */ + @GetMapping("/captchaImage") + public AjaxResult getCode(HttpServletResponse response) throws IOException + { + AjaxResult ajax = AjaxResult.success(); + boolean captchaEnabled = configService.selectCaptchaEnabled(); + ajax.put("captchaEnabled", captchaEnabled); + if (!captchaEnabled) + { + return ajax; + } + + // 保存验证码信息 + String uuid = IdUtils.simpleUUID(); + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; + + String capStr = null, code = null; + BufferedImage image = null; + + // 生成验证码 + String captchaType = RuoYiConfig.getCaptchaType(); + if ("math".equals(captchaType)) + { + String capText = captchaProducerMath.createText(); + capStr = capText.substring(0, capText.lastIndexOf("@")); + code = capText.substring(capText.lastIndexOf("@") + 1); + image = captchaProducerMath.createImage(capStr); + } + else if ("char".equals(captchaType)) + { + capStr = code = captchaProducer.createText(); + image = captchaProducer.createImage(capStr); + } + + redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + // 转换流信息写出 + FastByteArrayOutputStream os = new FastByteArrayOutputStream(); + try + { + ImageIO.write(image, "jpg", os); + } + catch (IOException e) + { + return AjaxResult.error(e.getMessage()); + } + + ajax.put("uuid", uuid); + ajax.put("img", Base64.encode(os.toByteArray())); + return ajax; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java new file mode 100644 index 0000000..3b40d3b --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java @@ -0,0 +1,262 @@ +package com.ruoyi.web.controller.common; + +import java.util.ArrayList; +import java.util.List; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.fastjson2.JSONObject; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.common.config.MinioConfig; +import com.ruoyi.common.utils.file.MimeTypeUtils; +import com.ruoyi.framework.web.domain.dto.MobileOfficesDTO; +import com.ruoyi.framework.web.service.sms.MessageService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.FileUploadUtils; +import com.ruoyi.common.utils.file.FileUtils; +import com.ruoyi.framework.config.ServerConfig; + +/** + * 通用请求处理 + * + * @author ruoyi + */ +@Api("通用请求处理") +@RestController +@RequestMapping("/common") +public class CommonController +{ + private static final Logger log = LoggerFactory.getLogger(CommonController.class); + + @Autowired + private ServerConfig serverConfig; + + @Autowired + private MessageService messageService; + + private static final String FILE_DELIMETER = ","; + + /** + * 通用下载请求 + * + * @param fileName 文件名称 + * @param delete 是否删除 + */ + @ApiOperation("通用下载请求") + @GetMapping("/download") + public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) + { + try + { + if (!FileUtils.checkAllowDownload(fileName)) + { + throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName)); + } + String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1); + String filePath = RuoYiConfig.getDownloadPath() + fileName; + + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, realFileName); + FileUtils.writeBytes(filePath, response.getOutputStream()); + if (delete) + { + FileUtils.deleteFile(filePath); + } + } + catch (Exception e) + { + log.error("下载文件失败", e); + } + } + + /** + * 通用上传请求(单个) + */ + @ApiOperation("通用上传请求(单个)") + @PostMapping("/upload") + public AjaxResult uploadFile(MultipartFile file) throws Exception + { + try + { + // 上传文件路径 + String filePath = RuoYiConfig.getUploadPath(); + // 上传并返回新文件名称 + String fileName = FileUploadUtils.upload(filePath, file); + String url = serverConfig.getUrl() + fileName; + AjaxResult ajax = AjaxResult.success(); + ajax.put("url", url); + ajax.put("fileName", fileName); + ajax.put("newFileName", FileUtils.getName(fileName)); + ajax.put("originalFilename", file.getOriginalFilename()); + ajax.put("fileSize",file.getSize()); + return ajax; + } + catch (Exception e) + { + return AjaxResult.error(e.getMessage()); + } + } + + @ApiOperation("minio上传请求(单个)") + @PostMapping("/uploadMinio") + public AjaxResult uploadFileMinio(MultipartFile file) { + try { + // 上传并返回新文件名称 + String fileName = FileUploadUtils.uploadMinio(file); + AjaxResult ajax = AjaxResult.success(); + ajax.put("url", fileName.replace(MinioConfig.getUrl(),serverConfig.getUrl()+"/profile/")); + ajax.put("fileName", fileName.replace(MinioConfig.getUrl(),"/profile/")); + ajax.put("newFileName", FileUtils.getName(fileName)); + ajax.put("originalFilename", file.getOriginalFilename()); + return ajax; + } + catch (Exception e) { + return AjaxResult.error(e.getMessage()); + } + } + + /** + * 图片上传 + */ + @ApiOperation("通用上传图片请求(单个)") + @PostMapping("/upload/image") + public AjaxResult uploadImageFile(@RequestParam("imagefile") MultipartFile file) throws Exception + { + if (!file.isEmpty()) + { + try + { + + String imageurl = FileUploadUtils.upload(RuoYiConfig.getUploadPath(), file, MimeTypeUtils.IMAGE_EXTENSION); + AjaxResult ajax = AjaxResult.success(); + ajax.put("imgUrl", imageurl); + return ajax; + + } + catch (Exception e) + { + return AjaxResult.error(e.getMessage()); + } + } + return AjaxResult.error("没有上传图片文件"); + } + + @ApiOperation("minio上传请求(单个)") + @PostMapping("/upload/imageMinio") + public AjaxResult uploadImageFileMinio(MultipartFile file) { + if (!file.isEmpty()) + { + try + { + + String imageurl = FileUploadUtils.uploadMinio(file, MimeTypeUtils.IMAGE_EXTENSION); + AjaxResult ajax = AjaxResult.success(); + ajax.put("imgUrl", imageurl); + return ajax; + + } + catch (Exception e) + { + return AjaxResult.error(e.getMessage()); + } + } + return AjaxResult.error("没有上传图片文件"); + } + + /** + * 通用上传请求(多个) + */ + @ApiOperation("通用上传请求(多个)") + @PostMapping("/uploads") + public AjaxResult uploadFiles(List files) throws Exception + { + try + { + // 上传文件路径 + String filePath = RuoYiConfig.getUploadPath(); + List urls = new ArrayList(); + List fileNames = new ArrayList(); + List newFileNames = new ArrayList(); + List originalFilenames = new ArrayList(); + for (MultipartFile file : files) + { + // 上传并返回新文件名称 + String fileName = FileUploadUtils.upload(filePath, file); + String url = serverConfig.getUrl() + fileName; + urls.add(url); + fileNames.add(fileName); + newFileNames.add(FileUtils.getName(fileName)); + originalFilenames.add(file.getOriginalFilename()); + } + AjaxResult ajax = AjaxResult.success(); + ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER)); + ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER)); + ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER)); + ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER)); + return ajax; + } + catch (Exception e) + { + return AjaxResult.error(e.getMessage()); + } + } + + /** + * 本地资源通用下载 + */ + @ApiOperation("本地资源通用下载") + @GetMapping("/download/resource") + public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) + throws Exception + { + try + { + if (!FileUtils.checkAllowDownload(resource)) + { + throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource)); + } + // 本地资源路径 + String localPath = RuoYiConfig.getProfile(); + // 数据库资源地址 + String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX); + // 下载名称 + String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, downloadName); + FileUtils.writeBytes(downloadPath, response.getOutputStream()); + } + catch (Exception e) + { + log.error("下载文件失败", e); + } + } + + @ApiOperation("测试发送移动办公群") + @PostMapping("/testSendMobileOffice") + public JSONObject testSendMobileOffice(@RequestBody MobileOfficesDTO dto){ + return messageService.sendMobileOffice(dto); + } + + @ApiOperation("测试发送短信") + @GetMapping("/testSendSMS") + public JSONObject testSendSMS(@RequestParam String content,@RequestParam String mobile){ + return messageService.sendSMS(content, mobile); + } + + @ApiOperation("测试发送IVR") + @GetMapping("/testSendIVR") + public JSONObject testSendIVR(@RequestParam String content,@RequestParam String mobile){ + return messageService.sendIvr(content, mobile); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2MmlListController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2MmlListController.java new file mode 100644 index 0000000..01887b3 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2MmlListController.java @@ -0,0 +1,116 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.eastcom_yw.domain.Dp2MmlList; +import com.ruoyi.eastcom_yw.domain.qo.Dp2MmlListQO; +import com.ruoyi.eastcom_yw.service.Dp2MmlListService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + *

+ * 前端控制器 + *

+ * + * @author ck + * @since 2023-09-12 + */ +@Api(tags = "") +@RestController +@RequestMapping("/eastcom_yw/dp2MmlList") +@Slf4j +@RequiredArgsConstructor +public class Dp2MmlListController extends BaseController { + + private final Dp2MmlListService dp2MmlListService; + + /** + * 列表 + */ + @ApiOperation(value = "列表", notes = "列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody Dp2MmlListQO qo) { + List list = dp2MmlListService.getData(qo); + return getDataTable(list); + } + + + /** + * 分页列表 + */ + @ApiOperation(value = "分页列表", notes = "分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody Dp2MmlListQO qo) { + PageInfo page = dp2MmlListService.getDataByPage(qo); + return getDataTable(page.getList(), page.getTotal()); + } + +// /** +// * 获取详情 +// */ +// @ApiOperation(value = "详情", notes = "详情") +// @GetMapping(value = "/fetchById/{id}") +// public AjaxResult fetchById(@PathVariable Long id) { +// return AjaxResult.success(dp2MmlListService.fetchById(id)); +// } +// +// /** +// * 新增或修改 +// */ +// @Log(title = "新增或修改", businessType = BusinessType.INSERT) +// @ApiOperation(value = "新增或修改", notes = "新增或修改") +// @PostMapping(value = "/saveOrUpdate") +// public AjaxResult saveOrUpdate(@RequestBody @Validated Dp2MmlList dto) { +// dp2MmlListService.saveOrUpdate(dto); +// return AjaxResult.success(); +// } +// +// /** +// * 根据id删除 +// */ +// @Log(title = "根据id删除", businessType = BusinessType.DELETE) +// @ApiOperation(value = "根据id删除", notes = "根据id删除") +// @GetMapping(value = "/deleteById/{id}") +// public AjaxResult deleteById(@PathVariable Long id) { +// dp2MmlListService.deleteById(id); +// return AjaxResult.success(); +// } +// +// /** +// * 根据id批量删除 +// */ +// @Log(title = "根据id批量删除", businessType = BusinessType.DELETE) +// @ApiOperation(value = "根据id批量删除", notes = "根据id批量删除") +// @PostMapping(value = "/deleteByIdBatch") +// public AjaxResult deleteByIdBatch(@RequestBody List ids) { +// dp2MmlListService.deleteByIdBatch(ids); +// return AjaxResult.success(); +// } + +// @Log(title = "导入", businessType = BusinessType.IMPORT) +// @PostMapping("/import") +// public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { +// ExcelUtil util = new ExcelUtil<>(Dp2MmlList.class); +// List list = util.importExcel(file.getInputStream()); +// dp2MmlListService.importData(list, updateSupport); +// return AjaxResult.success(); +// } + + + /** + * 导出 + */ + @ApiOperation(value = "导出") + @PostMapping(value = "/export") + public void export(@RequestBody Dp2MmlListQO qo) { + dp2MmlListService.export(qo); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2SpotCellController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2SpotCellController.java new file mode 100644 index 0000000..7405e01 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2SpotCellController.java @@ -0,0 +1,117 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.Dp2SpotCell; +import com.ruoyi.eastcom_yw.domain.qo.Dp2SpotCellQO; +import com.ruoyi.eastcom_yw.service.Dp2SpotCellService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + * @author ck + * @since 2023-08-10 + */ +@Api(tags = "") +@RestController +@RequestMapping("/eastcom_yw/dp2SpotCell") +@Slf4j +@RequiredArgsConstructor +public class Dp2SpotCellController extends BaseController { + + private final Dp2SpotCellService dp2SpotCellService; + + /** + * 列表 + */ + @ApiOperation(value = "列表", notes = "列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody Dp2SpotCellQO qo) { + List list = dp2SpotCellService.getData(qo); + return getDataTable(list); + } + + + /** + * 分页列表 + */ + @ApiOperation(value = "分页列表", notes = "分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody Dp2SpotCellQO qo) { + PageInfo page = dp2SpotCellService.getDataByPage(qo); + return getDataTable(page.getList(), page.getTotal()); + } + + /** + * 获取详情 + */ + @ApiOperation(value = "详情", notes = "详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(dp2SpotCellService.fetchById(id)); + } + + /** + * 新增或修改 + */ + @Log(title = "新增或修改", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改", notes = "新增或修改") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated Dp2SpotCell entity) { + dp2SpotCellService.saveOrUpdated(entity); + return AjaxResult.success(); + } + + /** + * 根据id删除 + */ + @Log(title = "根据id删除", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除", notes = "根据id删除") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + dp2SpotCellService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除 + */ + @Log(title = "根据id批量删除", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除", notes = "根据id批量删除") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + dp2SpotCellService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(Dp2SpotCell.class); + List list = util.importExcel(file.getInputStream()); + return dp2SpotCellService.importData(list, updateSupport); + } + + + /** + * 导出 + */ + @ApiOperation(value = "导出") + @PostMapping(value = "/export") + public void export(@RequestBody Dp2SpotCellQO qo) { + dp2SpotCellService.export(qo); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2SpotConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2SpotConfigController.java new file mode 100644 index 0000000..fa69152 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2SpotConfigController.java @@ -0,0 +1,120 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.Dp2SpotConfig; +import com.ruoyi.eastcom_yw.domain.dto.Dp2SpotConfigDTO; +import com.ruoyi.eastcom_yw.domain.qo.Dp2SpotConfigQO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2SpotConfigVO; +import com.ruoyi.eastcom_yw.service.Dp2SpotConfigService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + * @author ck + * @since 2023-08-09 + */ +@Api(tags = "景区配置") +@RestController +@RequestMapping("/eastcom_yw/dp2SpotConfig") +@Slf4j +@RequiredArgsConstructor +public class Dp2SpotConfigController extends BaseController { + + private final Dp2SpotConfigService dp2SpotConfigService; + + /** + * 列表 + */ + @ApiOperation(value = "列表", notes = "列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody Dp2SpotConfigQO qo) { + List list = dp2SpotConfigService.getData(qo); + return getDataTable(list); + } + + + /** + * 分页列表 + */ + @ApiOperation(value = "分页列表", notes = "分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody Dp2SpotConfigQO qo) { + PageInfo page = dp2SpotConfigService.getDataByPage(qo); + return getDataTable(page.getList(), page.getTotal()); + } + + /** + * 获取详情 + */ + @ApiOperation(value = "详情", notes = "详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(dp2SpotConfigService.fetchById(id)); + } + + /** + * 新增或修改 + */ + @Log(title = "新增或修改", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改", notes = "新增或修改") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated Dp2SpotConfigDTO dto) { + dp2SpotConfigService.saveOrUpdate(dto); + return AjaxResult.success(); + } + + /** + * 根据id删除 + */ + @Log(title = "根据id删除", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除", notes = "根据id删除") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + dp2SpotConfigService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除 + */ + @Log(title = "根据id批量删除", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除", notes = "根据id批量删除") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + dp2SpotConfigService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(Dp2SpotConfig.class); + List list = util.importExcel(file.getInputStream()); + dp2SpotConfigService.importData(list, updateSupport); + return AjaxResult.success(); + } + + + /** + * 导出 + */ + @ApiOperation(value = "导出") + @PostMapping(value = "/export") + public void export(@RequestBody Dp2SpotConfigQO qo) { + dp2SpotConfigService.export(qo); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2ViewPowerAlarmController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2ViewPowerAlarmController.java new file mode 100644 index 0000000..81568e5 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2ViewPowerAlarmController.java @@ -0,0 +1,81 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.Dp2ViewPowerAlarm; +import com.ruoyi.eastcom_yw.domain.dto.Dp2ViewPowerAlarmDTO; +import com.ruoyi.eastcom_yw.domain.qo.Dp2ViewPowerAlarmQO; +import com.ruoyi.eastcom_yw.domain.qo.Dp2ViewWirelessAlarmQO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2ViewPowerAlarmVO; +import com.ruoyi.eastcom_yw.service.Dp2ViewPowerAlarmService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import java.util.List; + +/** +*

+ * 前端控制器 + *

+* +* @author wqx +* @since 2023-08-31 +*/ +@Api(tags = "城市侧动环") +@RestController +@RequestMapping("/eastcom_yw/dp2ViewPowerAlarm") +@Slf4j +@RequiredArgsConstructor +public class Dp2ViewPowerAlarmController extends BaseController { + + private final Dp2ViewPowerAlarmService dp2ViewPowerAlarmService; + + /** + * 列表 + */ + @ApiOperation(value = "列表", notes = "列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody Dp2ViewPowerAlarmQO qo) { + List list = dp2ViewPowerAlarmService.getData(qo); + return getDataTable(list); + } + + + /** + * 分页列表 + */ + @ApiOperation(value = "分页列表", notes = "分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody Dp2ViewPowerAlarmQO qo) { + PageInfo page = dp2ViewPowerAlarmService.getDataByPage(qo); + return getDataTable(page.getList(),page.getTotal()); + } + + + + + /** + * 导出 + */ + @ApiOperation(value = "导出") + @PostMapping(value = "/export") + public void export(@RequestBody Dp2ViewPowerAlarmQO qo){ + dp2ViewPowerAlarmService.export(qo); + } + + + + + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2ViewWirelessAlarmController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2ViewWirelessAlarmController.java new file mode 100644 index 0000000..6e48dd8 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/Dp2ViewWirelessAlarmController.java @@ -0,0 +1,84 @@ +package com.ruoyi.web.controller.eastcom_yw; +; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.Dp2ViewWirelessAlarm; +import com.ruoyi.eastcom_yw.domain.dto.Dp2ViewWirelessAlarmDTO; +import com.ruoyi.eastcom_yw.domain.qo.Dp2ViewWirelessAlarmQO; +import com.ruoyi.eastcom_yw.domain.vo.Dp2ViewWirelessAlarmVO; +import com.ruoyi.eastcom_yw.service.Dp2ViewWirelessAlarmService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + + import org.springframework.stereotype.Controller; +import org.springframework.web.multipart.MultipartFile; + + +import javax.validation.Valid; +import java.util.List; + +/** +*

+ * 前端控制器 + *

+* +* @author wqx +* @since 2023-09-01 +*/ +@Api(tags = "城市侧无线") +@RestController +@RequestMapping("/eastcom_yw/dp2ViewWirelessAlarm") +@Slf4j +@RequiredArgsConstructor +public class Dp2ViewWirelessAlarmController extends BaseController { + + private final Dp2ViewWirelessAlarmService dp2ViewWirelessAlarmService; + + /** + * 列表 + */ + @ApiOperation(value = "列表", notes = "列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody Dp2ViewWirelessAlarmQO qo) { + + List list = dp2ViewWirelessAlarmService.getData(qo); + return getDataTable(list); + } + + + /** + * 分页列表 + */ + @ApiOperation(value = "分页列表", notes = "分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody Dp2ViewWirelessAlarmQO qo) { + PageInfo page = dp2ViewWirelessAlarmService.getDataByPage(qo); + return getDataTable(page.getList(),page.getTotal()); + } + + + + /** + * 导出 + */ + @ApiOperation(value = "导出") + @PostMapping(value = "/export") + public void export(@RequestBody Dp2ViewWirelessAlarmQO qo){ + dp2ViewWirelessAlarmService.export(qo); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/DpSceneConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/DpSceneConfigController.java new file mode 100644 index 0000000..faa78c7 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/DpSceneConfigController.java @@ -0,0 +1,154 @@ +package com.ruoyi.web.controller.eastcom_yw; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.DpSceneConfig; +import com.ruoyi.eastcom_yw.domain.dto.DpSceneConfigDTO; +import com.ruoyi.eastcom_yw.domain.qo.DpSceneConfigQO; +import com.ruoyi.eastcom_yw.domain.vo.DpSceneConfigVO; +import com.ruoyi.eastcom_yw.service.DpSceneConfigService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + + import org.springframework.stereotype.Controller; +import org.springframework.web.multipart.MultipartFile; + + +import javax.validation.Valid; +import java.util.List; + +/** +*

+ * 前端控制器 + *

+* +* @author yqf +* @since 2023-04-12 +*/ +@Api(tags = "阈值管理") +@RestController +@RequestMapping("/eastcom_yw/dpSceneConfig") +@Slf4j +@RequiredArgsConstructor +public class DpSceneConfigController extends BaseController { + + private final DpSceneConfigService dpSceneConfigService; + + /** + * 列表 + */ + @ApiOperation(value = "列表", notes = "列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody DpSceneConfigQO qo) { + List list = dpSceneConfigService.getData(qo); + return getDataTable(list); + } + + + /** + * 分页列表 + */ + @ApiOperation(value = "分页列表", notes = "分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody DpSceneConfigQO qo) { + IPage page = dpSceneConfigService.getDataByPage(qo); + return getDataTable(page.getRecords(),page.getTotal()); + } + + /** + * 获取详情 + */ + @ApiOperation(value = "详情", notes = "详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(dpSceneConfigService.fetchById(id)); + } + + /** + * 新增或修改 + */ + @Log(title = "新增或修改", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改", notes = "新增或修改") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated DpSceneConfigDTO dto) { + dpSceneConfigService.saveOrUpdate(dto); + return AjaxResult.success(); + } + + /** + * 根据id删除 + */ + @Log(title = "根据id删除", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除", notes = "根据id删除") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + dpSceneConfigService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除 + */ + @Log(title = "根据id批量删除", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除", notes = "根据id批量删除") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + dpSceneConfigService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(DpSceneConfig.class); + List list = util.importExcel(file.getInputStream()); + dpSceneConfigService.importData(list, updateSupport); + return AjaxResult.success(); + } + + + /** + * 导出 + */ + @ApiOperation(value = "导出") + @PostMapping(value = "/export") + public void export(@RequestBody DpSceneConfigQO qo){ + dpSceneConfigService.export(qo); + } + + + /** + * 颜色下拉框 + */ + @ApiOperation(value = "颜色下拉框", notes = "颜色下拉框") + @GetMapping(value = "/listColor") + public AjaxResult listColor() { + List list = dpSceneConfigService.listColor(); + return AjaxResult.success(list); + } + + /** + * 指标名下拉框 + */ + @ApiOperation(value = "指标名下拉框", notes = "指标名下拉框") + @GetMapping(value = "/listKpiName") + public AjaxResult listKpiName() { + List list = dpSceneConfigService.listKpiName(); + return AjaxResult.success(list); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/LargeScreenController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/LargeScreenController.java new file mode 100644 index 0000000..0fee89e --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/LargeScreenController.java @@ -0,0 +1,101 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.ruoyi.common.annotation.Anonymous; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.ip.IpUtils; +import com.ruoyi.eastcom_yw.domain.model.AppEntity; +import com.ruoyi.eastcom_yw.service.LargeScreenService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author los + */ +@Api("大屏信息列表查询接口") +@RestController +@RequestMapping("/eastcom_yw/largeScreen") +@RequiredArgsConstructor +@Anonymous +public class LargeScreenController extends BaseController { + + private final LargeScreenService largeScreenService; + + @ApiOperation("任务管理列表查询") + @PostMapping("/taskMange/list") + public AjaxResult getTaskMangeList(HttpServletRequest request, AppEntity appEntity) { + String ipAddr = IpUtils.getIpAddr(request); + if (!largeScreenService.validate(ipAddr, appEntity)) { + return new AjaxResult(HttpStatus.UNAUTHORIZED, "not authorized.", null); + } + return AjaxResult.success(largeScreenService.getTaskManageList()); + } + + @ApiOperation("赛事列表查询") + @PostMapping("/match/list") + public AjaxResult getMatchList(HttpServletRequest request, AppEntity appEntity) { + String ipAddr = IpUtils.getIpAddr(request); + if (!largeScreenService.validate(ipAddr, appEntity)) { + return new AjaxResult(HttpStatus.UNAUTHORIZED, "not authorized.", null); + } + return AjaxResult.success(largeScreenService.getMatchList()); + } + + @ApiOperation("赛事赛程列表查询") + @PostMapping("/raceSchedule/list") + public AjaxResult getRaceScheduleList(HttpServletRequest request, AppEntity appEntity) { + String ipAddr = IpUtils.getIpAddr(request); + if (!largeScreenService.validate(ipAddr, appEntity)) { + return new AjaxResult(HttpStatus.UNAUTHORIZED, "not authorized.", null); + } + return AjaxResult.success(largeScreenService.getRaceScheduleList()); + } + + @ApiOperation("奖牌榜列表查询") + @PostMapping("/medal/list") + public AjaxResult getMedalList(HttpServletRequest request, AppEntity appEntity) { + String ipAddr = IpUtils.getIpAddr(request); + if (!largeScreenService.validate(ipAddr, appEntity)) { + return new AjaxResult(HttpStatus.UNAUTHORIZED, "not authorized.", null); + } + return AjaxResult.success(largeScreenService.getMedalList()); + } + + @ApiOperation("新闻信息列表查询") + @PostMapping("/news/list") + public AjaxResult getNewsList(HttpServletRequest request, AppEntity appEntity) { + String ipAddr = IpUtils.getIpAddr(request); + if (!largeScreenService.validate(ipAddr, appEntity)) { + return new AjaxResult(HttpStatus.UNAUTHORIZED, "not authorized.", null); + } + return AjaxResult.success(largeScreenService.getNewsList()); + } + + @ApiOperation("告警TOP明细列表查询") + @PostMapping("/alarmTop/list") + public AjaxResult getAlarmTopList(HttpServletRequest request, AppEntity appEntity) { + String ipAddr = IpUtils.getIpAddr(request); + if (!largeScreenService.validate(ipAddr, appEntity)) { + return new AjaxResult(HttpStatus.UNAUTHORIZED, "not authorized.", null); + } + return AjaxResult.success(largeScreenService.getAlarmTopList()); + } + + @ApiOperation("告警统计列表查询") + @PostMapping("/alarmStatistics/list") + public AjaxResult getAlarmStatisticsList(HttpServletRequest request, AppEntity appEntity) { + String ipAddr = IpUtils.getIpAddr(request); + if (!largeScreenService.validate(ipAddr, appEntity)) { + return new AjaxResult(HttpStatus.UNAUTHORIZED, "not authorized.", null); + } + return AjaxResult.success(largeScreenService.getAlarmStatisticsList()); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/WeatherController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/WeatherController.java new file mode 100644 index 0000000..0ffb07e --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/WeatherController.java @@ -0,0 +1,29 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.service.WeatherService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Api("爬取天气数据") +@RestController +@RequestMapping("/eastcom_yw/weather") +public class WeatherController { + + @Autowired + private WeatherService weatherService; + + /** + * 获取场馆天气详情 + */ + @ApiOperation(value = "获取场馆天气详情", notes = "获取场馆天气详情") + @GetMapping(value = "/fetchById/{venueId}") + public AjaxResult fetchById(@PathVariable Long venueId) { + return AjaxResult.success(weatherService.fetchById(venueId)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwAlarmController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwAlarmController.java new file mode 100644 index 0000000..99fca1e --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwAlarmController.java @@ -0,0 +1,1068 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.ArrayUtil; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; + +import com.baomidou.mybatisplus.core.toolkit.ArrayUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.dto.HandleDataDTO; +import com.ruoyi.common.core.domain.dto.json.UserInfo; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.DictUtils; + +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.common.utils.ip.IpUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.common.constant.AlarmConstants; +import com.ruoyi.eastcom_yw.common.constant.CacheConstants; +import com.ruoyi.eastcom_yw.domain.HmAlarmDerive; +import com.ruoyi.eastcom_yw.domain.YwAlarmOprateLog; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTONoPage; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmHangupLogDTO; + +import com.ruoyi.eastcom_yw.domain.model.StepInfo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmNewNumVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmViewVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmVo; +import com.ruoyi.eastcom_yw.mapper.YwAlarmMapper; +import com.ruoyi.eastcom_yw.domain.yw_alarm_deal_log; +import com.ruoyi.eastcom_yw.mapper.yw_alarm_deal_logMapper; +import com.ruoyi.eastcom_yw.service.*; +import com.ruoyi.generator.util.GenUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import javafx.scene.Scene; +import org.springframework.beans.factory.annotation.Autowired; + +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletResponse; +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * + * @author jkj + * @since 2023-01-12 + */ + +@Api("告警信息管理") +@RestController +@RequestMapping("/eastcom_yw/alarm") +public class YwAlarmController extends BaseController { + + @Autowired + private YwAlarmViewService ywAlarmViewService; + + @Autowired + private YwAlarmDHService ywAlarmDHService; + + @Autowired + private YwAlarmCSService ywAlarmCSService; + + @Autowired + private YwAlarmWXService ywAlarmWXService; + + @Autowired + private YwSceneService yw_sceneService; + + @Autowired + private YwAlarmService ywAlarmService; + + @Autowired + private YwAlarmHangupLogService ywAlarmHangupLogService; + + @Autowired + private YwAlarmOprateLogService ywAlarmOprateLogService; + + @Autowired + private RedisCache redisCache; + + @Autowired + private yw_alarm_deal_logMapper alarm_deal_logMapper; + + @Autowired + private CommonService commonService; + + @Autowired + private YwAlarmMapper ywAlarmMapper; + + @Autowired + private HmAlarmDeriveService hmAlarmDeriveService; + + //列表和告警数量组合的查询太慢,弃用 + @ApiOperation("根据条件获取告警") + @PostMapping("/newlist2") + public TableDataInfo newlist1(@RequestBody YwAlarmDTO alarmDTO) + { + SysUser user = getLoginUser().getUser(); + alarmDTO.setUserId(user.getUserId()); + if(ObjectUtils.isNotEmpty(alarmDTO.getIsRefresh())) + { + //1自动刷新,0是手动刷新 + if(0==alarmDTO.getIsRefresh()) { + //如果是用户点击的查询,保存当前用户查询的场馆,便于用户重新登录后自动勾选场馆查询 + redisCache.setCacheObject(CacheConstants.YW_ALARM_LAST_VENUES + getUserId(), alarmDTO.getVenues(), 3, TimeUnit.DAYS); + } + } + //如果没有传入场馆就用当前登录用户的配置的场馆 + if (alarmDTO.getVenues().size()==0) { +// boolean isAll = user.isAdmin(user); +// alarmDTO.setIsAll(isAll); +// //管理员不需要设置场馆 +// if(!isAll) { +// List venueList = new ArrayList(); +// yw_sceneService.getVenueByUser(user).forEach( +// venue -> { +// venueList.add(venue.getId()); +// } +// ); +// alarmDTO.setVenues(venueList); +// } + List lstScene = yw_sceneService.getVenueByUserCanNoData(user,false); + + if(lstScene.isEmpty()) + { + alarmDTO.setIsAll(true); + } + + if(!lstScene.isEmpty()) + { + List venueList = new ArrayList(); + for(YwScene ywScene : lstScene) { + venueList.add(ywScene.getId()); + } + alarmDTO.setVenues(venueList); + } + } + TableDataInfo resData = null; + + if(!alarmDTO.getAlarmType().isEmpty()) + { + if("tel".equals(alarmDTO.getAlarmType())) + { + alarmDTO.setAlarmType("voip"); + } + if(GenUtils.arraysContains(AlarmConstants.ALARMS,alarmDTO.getAlarmType())) + { + if(alarmDTO.getPageNum()<=0) + { + alarmDTO.setPageNum(1); + } + if(alarmDTO.getPageSize()<=0) + { + alarmDTO.setPageSize(10); + } + String siteType = alarmDTO.getSiteType(); + + if(!"wx".equals(alarmDTO.getAlarmType())) + { + alarmDTO.setSiteType(null); + } + + List list = null; + try { + list = ywAlarmViewService.getYwAlarmByDto(alarmDTO); + } + catch (Exception ex) + { + throw new ServiceException("告警查询异常"); + } + resData = getDataTable(list); + HashMap alarmNewNum =new HashMap<>(); + //20230329 JKJ 全量告警 不需要去获取当前用户没点击过的告警数量,提高查询效率 + //实时告警 + if("0".equals(alarmDTO.getAlarmStatus())) { + + YwAlarmDTONoPage alarmNoPage = new YwAlarmDTONoPage(); + BeanUtils.copyBeanProp(alarmNoPage, alarmDTO); + alarmNoPage.setSiteType(siteType); + alarmNoPage.setAlarmType("wx"); + alarmNewNum.put("wx",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + //其它类型没有网络类型 + alarmNoPage.setSiteType(null); + alarmNoPage.setAlarmType("cs"); + alarmNewNum.put("cs",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("dh"); + alarmNewNum.put("dh",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("agis"); + alarmNewNum.put("agis",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("wifi"); + alarmNewNum.put("wifi",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("voip"); + Long voipNum = ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage); + alarmNewNum.put("voip",voipNum); + //前端用的是tel + alarmNewNum.put("tel",voipNum); + } + else + { + alarmNewNum.put("cs", 0L); + alarmDTO.setAlarmType("dh"); + alarmNewNum.put("dh", 0L); + alarmDTO.setAlarmType("wx"); + alarmNewNum.put("wx", 0L); + alarmDTO.setAlarmType("agis"); + alarmNewNum.put("agis", 0L); + alarmDTO.setAlarmType("wifi"); + alarmNewNum.put("wifi", 0L); + alarmDTO.setAlarmType("voip"); + alarmNewNum.put("voip", 0L); + } + resData.setMaps(alarmNewNum); + return resData; + } + throw new ServiceException("告警类型未接入"); + } + throw new ServiceException("告警类型不允许为空"); + } + + + @ApiOperation("根据条件获取告警") + @PostMapping("/newlist3") + public TableDataInfo newlist3(@RequestBody YwAlarmDTO alarmDTO) + { + SysUser user = getLoginUser().getUser(); + alarmDTO.setUserId(user.getUserId()); + if(ObjectUtils.isNotEmpty(alarmDTO.getIsRefresh())) + { + //1自动刷新,0是手动刷新 + if(0==alarmDTO.getIsRefresh()) { + //如果是用户点击的查询,保存当前用户查询的场馆,便于用户重新登录后自动勾选场馆查询 + redisCache.setCacheObject(CacheConstants.YW_ALARM_LAST_VENUES + getUserId(), alarmDTO.getVenues(), 3, TimeUnit.DAYS); + } + } + //如果没有传入场馆就用当前登录用户的配置的场馆 + if (alarmDTO.getVenues().size()==0) { +// boolean isAll = user.isAdmin(user); +// alarmDTO.setIsAll(isAll); +// //管理员不需要设置场馆 +// if(!isAll) { +// List venueList = new ArrayList(); +// yw_sceneService.getVenueByUser(user).forEach( +// venue -> { +// venueList.add(venue.getId()); +// } +// ); +// alarmDTO.setVenues(venueList); +// } + List lstScene = yw_sceneService.getVenueByUserCanNoData(user,false); + + if(lstScene.isEmpty()) + { + alarmDTO.setIsAll(true); + } + + if(!lstScene.isEmpty()) + { + List venueList = new ArrayList(); + for(YwScene ywScene : lstScene) { + venueList.add(ywScene.getId()); + } + alarmDTO.setVenues(venueList); + } + } + TableDataInfo resData = null; + + if(!alarmDTO.getAlarmType().isEmpty()) + { + if("tel".equals(alarmDTO.getAlarmType())) + { + alarmDTO.setAlarmType("voip"); + } + if(GenUtils.arraysContains(AlarmConstants.ALARMS,alarmDTO.getAlarmType())) + { + if(alarmDTO.getPageNum()<=0) + { + alarmDTO.setPageNum(1); + } + if(alarmDTO.getPageSize()<=0) + { + alarmDTO.setPageSize(10); + } +// if(StringUtils.isEmpty(alarmDTO.getOrderBy())) +// { +// alarmDTO.setOrderBy(" t1.alarm_time desc"); +// } + + String siteType = alarmDTO.getSiteType(); + + if(!"wx".equals(alarmDTO.getAlarmType())) + { + alarmDTO.setSiteType(null); + } + + List list = null; + try { + list = ywAlarmViewService.getYwAlarmByDto(alarmDTO); + } + catch (Exception ex) + { + throw new ServiceException("告警查询异常"); + } + resData = getDataTable(list); +// HashMap alarmNewNum =new HashMap<>(); + //20230329 JKJ 全量告警 不需要去获取当前用户没点击过的告警数量,提高查询效率 + //实时告警 +// if("0".equals(alarmDTO.getAlarmStatus())) { + +// YwAlarmDTONoPage alarmNoPage = new YwAlarmDTONoPage(); +// BeanUtils.copyBeanProp(alarmNoPage, alarmDTO); +// alarmNoPage.setSiteType(siteType); +// alarmNoPage.setAlarmType("wx"); +// alarmNewNum.put("wx",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); +// //其它类型没有网络类型 +// alarmNoPage.setSiteType(null); +// alarmNoPage.setAlarmType("cs"); +// alarmNewNum.put("cs",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); +// alarmNoPage.setAlarmType("dh"); +// alarmNewNum.put("dh",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); +// alarmNoPage.setAlarmType("agis"); +// alarmNewNum.put("agis",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); +// alarmNoPage.setAlarmType("wifi"); +// alarmNewNum.put("wifi",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); +// alarmNoPage.setAlarmType("voip"); +// Long voipNum = ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage); +// alarmNewNum.put("voip",voipNum); +// //前端用的是tel +// alarmNewNum.put("tel",voipNum); +// } +// else +// { +// alarmNewNum.put("cs", 0L); +// alarmDTO.setAlarmType("dh"); +// alarmNewNum.put("dh", 0L); +// alarmDTO.setAlarmType("wx"); +// alarmNewNum.put("wx", 0L); +// alarmDTO.setAlarmType("agis"); +// alarmNewNum.put("agis", 0L); +// alarmDTO.setAlarmType("wifi"); +// alarmNewNum.put("wifi", 0L); +// alarmDTO.setAlarmType("voip"); +// alarmNewNum.put("voip", 0L); +// } +// resData.setMaps(alarmNewNum); + return resData; + } + throw new ServiceException("告警类型未接入"); + } + throw new ServiceException("告警类型不允许为空"); + } + + @ApiOperation("根据条件未恢复告警数量") + @PostMapping("/num") + public HashMap newlistNum(@RequestBody YwAlarmDTO alarmDTO) { + SysUser user = getLoginUser().getUser(); + alarmDTO.setUserId(user.getUserId()); + + //如果没有传入场馆就用当前登录用户的配置的场馆 + if (alarmDTO.getVenues().size() == 0) { +// boolean isAll = user.isAdmin(user); +// alarmDTO.setIsAll(isAll); +// //管理员不需要设置场馆 +// if (!isAll) { +// List venueList = new ArrayList(); +// yw_sceneService.getVenueByUser(user).forEach( +// venue -> { +// venueList.add(venue.getId()); +// } +// ); +// alarmDTO.setVenues(venueList); +// } + List lstScene = yw_sceneService.getVenueByUserCanNoData(user,false); + + if(lstScene.isEmpty()) + { + alarmDTO.setIsAll(true); + } + + if(!lstScene.isEmpty()) + { + List venueList = new ArrayList(); + for(YwScene ywScene : lstScene) { + venueList.add(ywScene.getId()); + } + alarmDTO.setVenues(venueList); + } + } + if (!alarmDTO.getAlarmType().isEmpty()) { + if ("tel".equals(alarmDTO.getAlarmType())) { + alarmDTO.setAlarmType("voip"); + } + if (GenUtils.arraysContains(AlarmConstants.ALARMS, alarmDTO.getAlarmType())) { + + String siteType = alarmDTO.getSiteType(); + + if(!"wx".equals(alarmDTO.getAlarmType())) + { + alarmDTO.setSiteType(null); + } + + HashMap alarmNewNum = new HashMap<>(); + if ("0".equals(alarmDTO.getAlarmStatus())) { + + YwAlarmDTONoPage alarmNoPage = new YwAlarmDTONoPage(); + BeanUtils.copyBeanProp(alarmNoPage, alarmDTO); + alarmNoPage.setSiteType(siteType); + alarmNoPage.setAlarmType("wx"); + alarmNewNum.put("wx", ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + //其它类型没有网络类型 + alarmNoPage.setSiteType(null); + alarmNoPage.setAlarmType("cs"); + alarmNewNum.put("cs", ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("dh"); + alarmNewNum.put("dh", ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("agis"); + alarmNewNum.put("agis", ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("wifi"); + alarmNewNum.put("wifi", ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("voip"); + Long voipNum = ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage); + alarmNewNum.put("voip", voipNum); + //前端用的是tel + alarmNewNum.put("tel", voipNum); + } else { + alarmNewNum.put("cs", 0L); + alarmDTO.setAlarmType("dh"); + alarmNewNum.put("dh", 0L); + alarmDTO.setAlarmType("wx"); + alarmNewNum.put("wx", 0L); + alarmDTO.setAlarmType("agis"); + alarmNewNum.put("agis", 0L); + alarmDTO.setAlarmType("wifi"); + alarmNewNum.put("wifi", 0L); + alarmDTO.setAlarmType("voip"); + alarmNewNum.put("voip", 0L); + } + return alarmNewNum; + } + throw new ServiceException("告警类型未接入"); + } + throw new ServiceException("告警类型不允许为空"); + } + + @ApiOperation("根据条件获取告警") + @PostMapping("/list") + public TableDataInfo newlist2(@RequestBody YwAlarmDTO alarmDTO) + { + alarmDTO.setIsAPP(false); + + SysUser user = getLoginUser().getUser(); + + if(ObjectUtils.isNotEmpty(alarmDTO.getIsRefresh())) + { + //1自动刷新,0是手动刷新 + if(0==alarmDTO.getIsRefresh()) { + //如果是用户点击的查询,保存当前用户查询的场馆,便于用户重新登录后自动勾选场馆查询 + redisCache.setCacheObject(CacheConstants.YW_ALARM_LAST_VENUES + getUserId(), alarmDTO.getVenues(), 3, TimeUnit.DAYS); + } + } + + //如果没有传入场馆就用当前登录用户的配置的场馆 + if (alarmDTO.getVenues().size()==0) { + boolean isAll= user.isAdmin(user); + alarmDTO.setIsAll(isAll); + if(!isAll) { + List venueList = new ArrayList(); + yw_sceneService.getVenueByUser(user).forEach( + venue -> { + venueList.add(venue.getId()); + } + ); + alarmDTO.setVenues(venueList); + } + + } + + alarmDTO.setUserId(user.getUserId()); + + TableDataInfo resData = null; + //获取告警数据 + if("wx".equals(alarmDTO.getAlarmType())) + { + resData = ywAlarmWXService.GetAlarmList(alarmDTO); + } + + if("cs".equals(alarmDTO.getAlarmType())) + { + resData = ywAlarmCSService.GetAlarmList(alarmDTO); + } + + if("dh".equals(alarmDTO.getAlarmType())) + { + resData = ywAlarmDHService.GetAlarmList(alarmDTO);; + } + + if(ObjectUtils.isEmpty(resData)) + { + throw new ServiceException("数据未接入"); + } + + alarmDTO.setPageNum(1); + HashMap alarmNewNum =new HashMap<>(); + alarmDTO.setAlarmType("cs"); + alarmNewNum.put("cs",ywAlarmViewService.getYwAlarmNewNumByDto(alarmDTO)); + alarmDTO.setAlarmType("dh"); + alarmNewNum.put("dh",ywAlarmViewService.getYwAlarmNewNumByDto(alarmDTO)); + alarmDTO.setAlarmType("wx"); + alarmNewNum.put("wx",ywAlarmViewService.getYwAlarmNewNumByDto(alarmDTO)); + resData.setMaps(alarmNewNum); + + return resData; + } + + + @ApiOperation("根据用户ID获取最新的告警数量") + @PostMapping("/newAlarmNum") + public AjaxResult newAlarmNum(@RequestBody YwAlarmDTO alarmDTO) + { + //20230316 jkj 管理员类的不加判断场馆的条件,所有场馆的数据 + SysUser user = getLoginUser().getUser(); + + //获取告警数据 + List ywAlarmNewNumVos= ywAlarmViewService.GetNewAlarmNum(user.getUserId(),user.isAdmin(user)); + + return AjaxResult.success("操作成功",JSONObject.toJSONString(ywAlarmNewNumVos)); + + + } + + @ApiOperation("根据用户ID获取最新的告警数量") + @GetMapping("/newAlarmNum/{userId}") + public AjaxResult newAlarmNum(@PathVariable String userId) + { + +// Long longUserId=Long.parseLong(userId); + //20230316 jkj 管理员类的不加判断场馆的条件,所有场馆的数据 + SysUser user = getLoginUser().getUser(); + + //获取告警数据 + List ywAlarmNewNumVos= ywAlarmViewService.GetNewAlarmNum(user.getUserId(),user.isAdmin(user)); + + return AjaxResult.success("操作成功",JSONObject.toJSONString(ywAlarmNewNumVos)); + + + } + + @Log(title = "导出告警列表数据", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(@RequestBody YwAlarmDTO alarmDTO) throws IllegalAccessException { + + alarmDTO.setPageNum(1); + alarmDTO.setPageSize(Integer.MAX_VALUE); + + //非APP端 + alarmDTO.setIsAPP(false); + + alarmDTO.setIsExport(true); + + SysUser user = getLoginUser().getUser(); + + alarmDTO.setUserId(user.getUserId()); + + if(ObjectUtils.isEmpty(alarmDTO.getVenues())) + { + boolean isAll = user.isAdmin(user); + alarmDTO.setIsAll(isAll); + if (!isAll) { + List venueList = new ArrayList(); + yw_sceneService.getVenueByUser(user).forEach( + venue -> { + venueList.add(venue.getId()); + } + ); + alarmDTO.setVenues(venueList); + } + } + + if(ObjectUtils.isNotEmpty(alarmDTO.getVenues())) { + //如果没有传入场馆就用当前登录用户的配置的场馆 + if (alarmDTO.getVenues().size() == 0) { + boolean isAll = user.isAdmin(user); + alarmDTO.setIsAll(isAll); + if (!isAll) { + List venueList = new ArrayList(); + yw_sceneService.getVenueByUser(user).forEach( + venue -> { + venueList.add(venue.getId()); + } + ); + alarmDTO.setVenues(venueList); + } + } + } + + if(!alarmDTO.getAlarmType().isEmpty()) { + + if("tel".equals(alarmDTO.getAlarmType())) + { + alarmDTO.setAlarmType("voip"); + } + + String alarmlabel = DictUtils.getDictLabel("yw_alarm_specialty", alarmDTO.getAlarmType()); + + if (GenUtils.arraysContains(AlarmConstants.ALARMS, alarmDTO.getAlarmType())) { + + List list = ywAlarmViewService.getYwAlarmByDto(alarmDTO); + + if(!"wx".equals(alarmDTO.getAlarmType())) + { + alarmDTO.setSiteType(null); + } + + //序号 + int i= 1; + + for (YwAlarmViewVo vo : list) + { + + vo.setId(i); + vo.setSiteNameExport(vo.getSite_name()); + vo.setNetNameExport(vo.getNet_name()); + + LocalDateTime start = LocalDateTimeUtil.parse(vo.getStart(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + + LocalDateTime clear = LocalDateTimeUtil.now(); + + if(StringUtils.isNotEmpty(vo.getEnd())) + { + clear = LocalDateTimeUtil.parse(vo.getEnd(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + } + + Duration between = LocalDateTimeUtil.between(start, clear); + + vo.setDuration(between.toHours()+"小时"+ between.toMinutes()%60+"分钟"); + + if(StringUtils.isNotEmpty(vo.getRecord())) + { + String rec = ""; + JSONArray jsonArray = JSONArray.parseArray(vo.getRecord()); + for (int j = 0; j< jsonArray.size(); j++) { + JSONObject jsonObject = jsonArray.getJSONObject(j); + if(StringUtils.isNotEmpty(jsonObject.getString("title"))&&StringUtils.isNotEmpty( jsonObject.getString("info"))) + { + String title = jsonObject.getString("title"); + String info = jsonObject.getString("info"); + rec += title + "\r\n" + info + "\r\n"; + } + } + vo.setRecordExport(rec); + } + i++; + } + + ExcelUtil util = new ExcelUtil(YwAlarmViewVo.class); + //改EXCEL的字段名,无法穿透父类字段 + util.hideColumn("site_name","net_name"); + switch (alarmDTO.getAlarmType()) + { + case "wx": + util.setExcelAnnotationValue("siteNameExport","name","基站名称",YwAlarmViewVo.class); + util.setExcelAnnotationValue("netNameExport","name","网元名称",YwAlarmViewVo.class); + break; + case "cs": + util.setExcelAnnotationValue("siteNameExport","name","设备名称",YwAlarmViewVo.class); + util.setExcelAnnotationValue("netNameExport","name","端口号",YwAlarmViewVo.class); + break; + case "dh": + util.setExcelAnnotationValue("siteNameExport","name","基站名称",YwAlarmViewVo.class); + util.setExcelAnnotationValue("netNameExport","name","设备名称",YwAlarmViewVo.class); + break; + case "agis": + case "wifi": + case "voip": + util.setExcelAnnotationValue("siteNameExport","name","网元名称",YwAlarmViewVo.class); + util.setExcelAnnotationValue("netNameExport","name","端口",YwAlarmViewVo.class); + break; + } + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + + util.exportExcel(response, list, alarmlabel+"主告警数据"); + + return; + } + throw new ServiceException("告警类型未接入"); + } + throw new ServiceException("告警类型不允许为空"); + } + + @Log(title = "告警列表数据", businessType = BusinessType.EXPORT) + @PostMapping("/exportDetail") + public void exportDetail(@RequestBody YwAlarmDTO alarmDTO) throws IllegalAccessException { + + alarmDTO.setPageNum(1); + alarmDTO.setPageSize(Integer.MAX_VALUE); + + //非APP端 + alarmDTO.setIsAPP(false); + + alarmDTO.setIsExport(true); + + SysUser user = getLoginUser().getUser(); + + alarmDTO.setUserId(user.getUserId()); + + if(ObjectUtils.isEmpty(alarmDTO.getVenues())) + { + boolean isAll = user.isAdmin(user); + alarmDTO.setIsAll(isAll); + if (!isAll) { + List venueList = new ArrayList(); + yw_sceneService.getVenueByUser(user).forEach( + venue -> { + venueList.add(venue.getId()); + } + ); + alarmDTO.setVenues(venueList); + } + } + + if(ObjectUtils.isNotEmpty(alarmDTO.getVenues())) { + //如果没有传入场馆就用当前登录用户的配置的场馆 + if (alarmDTO.getVenues().size() == 0) { + boolean isAll = user.isAdmin(user); + alarmDTO.setIsAll(isAll); + if (!isAll) { + List venueList = new ArrayList(); + yw_sceneService.getVenueByUser(user).forEach( + venue -> { + venueList.add(venue.getId()); + } + ); + alarmDTO.setVenues(venueList); + } + } + } + + if(!alarmDTO.getAlarmType().isEmpty()) { + + if("tel".equals(alarmDTO.getAlarmType())) + { + alarmDTO.setAlarmType("voip"); + } + + String alarmlabel = DictUtils.getDictLabel("yw_alarm_specialty", alarmDTO.getAlarmType()); + + if (GenUtils.arraysContains(AlarmConstants.ALARMS, alarmDTO.getAlarmType())) { + + if(!"wx".equals(alarmDTO.getAlarmType())) + { + alarmDTO.setSiteType(null); + } + + List list = ywAlarmViewService.getYwAlarmByDto(alarmDTO); + + List newList = new ArrayList<>(); + + for (YwAlarmViewVo vo : list) + { + int i=1; + for(YwAlarmVo chird : vo.getAlarmchildren()) + { + chird.setId(i); + i++; + } + + newList.addAll(vo.getAlarmchildren()); + } + + for (YwAlarmVo vo : newList) + { + + LocalDateTime start = LocalDateTimeUtil.parse(vo.getStart(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + + LocalDateTime clear = LocalDateTimeUtil.now(); + + if(StringUtils.isNotEmpty(vo.getEnd())) + { + clear = LocalDateTimeUtil.parse(vo.getEnd(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + } + + Duration between = LocalDateTimeUtil.between(start, clear); + + vo.setDuration(between.toHours()+"小时"+ between.toMinutes()%60+"分钟"); + + } + + + ExcelUtil util = new ExcelUtil(YwAlarmVo.class); + + switch (alarmDTO.getAlarmType()) + { + case "wx": + util.setExcelAnnotationValue("site_name","name","基站名称",YwAlarmVo.class); + util.setExcelAnnotationValue("net_name","name","网元名称",YwAlarmVo.class); + break; + case "cs": + util.setExcelAnnotationValue("site_name","name","设备名称",YwAlarmVo.class); + util.setExcelAnnotationValue("net_name","name","端口号",YwAlarmVo.class); + break; + case "dh": + util.setExcelAnnotationValue("site_name","name","基站名称",YwAlarmVo.class); + util.setExcelAnnotationValue("net_name","name","设备名称",YwAlarmVo.class); + break; + case "agis": + case "wifi": + case "voip": + util.setExcelAnnotationValue("site_name","name","网元名称",YwAlarmVo.class); + util.setExcelAnnotationValue("net_name","name","端口",YwAlarmVo.class); + break; + } + + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + + util.exportExcel(response, newList, alarmlabel+"告警明细数据"); + + return; + } + throw new ServiceException("告警类型未接入"); + } + throw new ServiceException("告警类型不允许为空"); + } + + + @ApiOperation("根据processId获取告警详情") + @GetMapping("/info/{processId}") + public TableDataInfo info(@PathVariable String processId) + { + return getDataTable(ywAlarmViewService.GetAlarmInfoList(processId,false)); + } + + @ApiOperation("根据GroupId获取告警详情") + @GetMapping("/info/group/{groupId}") + public TableDataInfo infoByGroup(@PathVariable String groupId) + { + return getDataTable(ywAlarmViewService.getYwAlarmInfoListByGroup(groupId,false)); + } + + @Log(title = "告警挂起记录", businessType = BusinessType.INSERT) + @ApiOperation("根据条件新增告警挂起的记录") + @PostMapping("/insert/hanguplog") + public AjaxResult list(@RequestBody YwAlarmHangupLogDTO ywAlarmHangupLogDTO) throws Exception + { + try + { + if(ObjectUtils.isEmpty(ywAlarmHangupLogDTO.getHangupUserId())) + { + SysUser user = getLoginUser().getUser(); + ywAlarmHangupLogDTO.setHangupUserId(user.getUserId()); + } + if(ywAlarmHangupLogService.insertYwAlarmHangupLog(ywAlarmHangupLogDTO)) + { + return AjaxResult.success(); + } + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + return AjaxResult.error(); + } + + @ApiOperation("获取告警问题") + @GetMapping("/question") + public TableDataInfo getAlarmQuestion(String spec) + { + return getDataTable(ywAlarmService.getYwAlarmQuestionList(spec)); + } + + @Log(title = "用户查询告警记录", businessType = BusinessType.INSERT) + @ApiOperation("告警操作") + @PostMapping("/operate") + public AjaxResult add(@RequestBody YwAlarmOprateLog ywAlarmOprateLog) + { + if(ywAlarmOprateLogService.saveOrUpdate(ywAlarmOprateLog)){ + return success(); + } + return error(); + } + + @Log(title = "用户回填告警", businessType = BusinessType.UPDATE) + @ApiOperation("告警回填反馈人和反馈时间") + @PostMapping("/feedback") + public AjaxResult feedback(@RequestBody YwAlarmDTO ywAlarmDTO) + { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + yw_alarm_deal_log yw_alarm_deal_log =new yw_alarm_deal_log(); + yw_alarm_deal_log.setDealUser(ywAlarmDTO.getDealUser()); + yw_alarm_deal_log.setDealStatus(ywAlarmDTO.getDealStatus()); + updateWrapper.eq("flw_processid", ywAlarmDTO.getProcessId()); + if(alarm_deal_logMapper.update(yw_alarm_deal_log,updateWrapper)>0){ + return success(); + } + return error(); + } + + @Log(title = "用户手工恢复告警", businessType = BusinessType.INSERT) + @ApiOperation("告警恢复时间") + @PostMapping("/alarmClear") + public AjaxResult alarmClear(@RequestBody YwAlarmDTO alarmDTO) + { + boolean res = ywAlarmService.YwAlarmClear(alarmDTO); + if(res) + { + return success(); + } + return error(); + } + + @Log(title = "源告警关闭", businessType = BusinessType.UPDATE) + @ApiOperation("源告警关闭") + @PostMapping("/alarmClose") + public AjaxResult originAlarmClose(@RequestBody YwAlarmDTO alarmDTO) + { + boolean res = ywAlarmService.YwAlarmClose(alarmDTO); + if(res) + { + return success(); + } + return error(); + } + + @Log(title = "用户手工恢复告警批量关闭", businessType = BusinessType.UPDATE) + @ApiOperation("用户手工恢复告警批量关闭") + @PostMapping("/alarmClearBatch") + @Transactional + public AjaxResult alarmClearBatch(@RequestBody List lstAlarmDTO) + { + for (YwAlarmDTO ywAlarmDTO : lstAlarmDTO) + { + boolean res = ywAlarmService.YwAlarmClear(ywAlarmDTO); + if(!res) + { + return error(); + } + } + return success(); + } + + + @Log(title = "告警记录", businessType = BusinessType.UPDATE) + @ApiOperation("告警记录") + @PostMapping("/record") + public AjaxResult record(@RequestBody YwAlarmDTO ywAlarmDTO) + { + if(ObjectUtils.isEmpty(ywAlarmDTO.getRecord())) + { + return AjaxResult.error("记录内容不允许为空"); + } + // String text_record = ywAlarmDTO.getRecords().stream().collect(Collectors.joining("##@##")); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + yw_alarm_deal_log yw_alarm_deal_log =new yw_alarm_deal_log(); + yw_alarm_deal_log.setRecord(ywAlarmDTO.getRecord()); + updateWrapper.eq("group_id", ywAlarmDTO.getAlarmId()); + updateWrapper.eq("is_new","0"); + if(alarm_deal_logMapper.update(yw_alarm_deal_log,updateWrapper)>0){ + return success(); + } + return error(); + } + + @Log(title = "批量告警记录阶段处理", businessType = BusinessType.UPDATE) + @ApiOperation("批量告警记录阶段处理") + @PostMapping("/recordBatch") + public AjaxResult recordBatch(@RequestBody YwAlarmDTO ywAlarmDTO) + { + if(ObjectUtils.isEmpty(ywAlarmDTO.getAlarmIds()) || ObjectUtils.isEmpty(ywAlarmDTO.getStepInfo())) + { + return AjaxResult.error("缺少处理的参数"); + } + + if(ywAlarmDTO.getAlarmIds().length == 0) + { + return AjaxResult.error("alarmIds没有值"); + } + + if(StringUtils.isEmpty(ywAlarmDTO.getStepInfo().getTitle())||StringUtils.isEmpty(ywAlarmDTO.getStepInfo().getInfo())) + { + return AjaxResult.error("stepInfo没有值"); + } + + for(Long alarmId : ywAlarmDTO.getAlarmIds()) + { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("group_id", alarmId); + queryWrapper.eq("is_new","0"); + List lstAlarm = alarm_deal_logMapper.selectList(queryWrapper); + if(lstAlarm.isEmpty()) + { + continue; + } + String record = lstAlarm.get(0).getRecord(); + JSONArray arrayRecord = new JSONArray(); + if(StringUtils.isNotEmpty(record)) + { + arrayRecord = JSONArray.parseArray(record); + } + JSONObject jsonRecord = new JSONObject(); + jsonRecord.put("title",ywAlarmDTO.getStepInfo().getTitle()); + jsonRecord.put("info",ywAlarmDTO.getStepInfo().getInfo()); + arrayRecord.add(jsonRecord); + record = JSONArray.toJSONString(arrayRecord); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + yw_alarm_deal_log yw_alarm_deal_log =new yw_alarm_deal_log(); + yw_alarm_deal_log.setRecord(record); + updateWrapper.eq("group_id", alarmId); + updateWrapper.eq("is_new","0"); + alarm_deal_logMapper.update(yw_alarm_deal_log,updateWrapper); + } + return success(); + } + + @ApiOperation("告警回填反馈人和反馈时间") + @GetMapping("/alarmBriefing") + public AjaxResult alarmBriefing() + { + ywAlarmService.eastcomYwSendAlarmBriefingSchedule(); + return AjaxResult.success(); + } + + @ApiOperation("查询亚运衍生告警") + @PostMapping("/hmAlarmDerive/list") + public TableDataInfo derivelist(@RequestBody YwAlarmDTO alarmDTO) { + startPage(); + return getDataTable(hmAlarmDeriveService.getAlarmDerive(alarmDTO)); + } + + + @ApiOperation("查询亚运衍生告警") + @PostMapping("/hmAlarmDerive/export") + public void deriveExport(@RequestBody YwAlarmDTO alarmDTO) throws IllegalAccessException { + alarmDTO.setPageNum(1); + alarmDTO.setPageSize(Integer.MAX_VALUE); + List list = hmAlarmDeriveService.getAlarmDerive(alarmDTO); + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + ExcelUtil util = new ExcelUtil(HmAlarmDerive.class); + util.exportExcel(response, list, "亚运事件告警"); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwDrsConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwDrsConfigController.java new file mode 100644 index 0000000..ea3b4d7 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwDrsConfigController.java @@ -0,0 +1,124 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwDrsConfig; +import com.ruoyi.eastcom_yw.domain.dto.YwDrsConfigDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwDrsConfigQO; +import com.ruoyi.eastcom_yw.domain.vo.YwDrsConfigVO; +import com.ruoyi.eastcom_yw.service.YwDrsConfigService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + *

+ * DRS配置表 前端控制器 + *

+ * + * @author ck + * @since 2023-06-13 + */ +@Api(tags = "DRS配置表") +@RestController +@RequestMapping("/eastcom_yw/ywDrsConfig") +@Slf4j +@RequiredArgsConstructor +public class YwDrsConfigController extends BaseController { + + private final YwDrsConfigService ywDrsConfigService; + + /** + * DRS配置表列表 + */ + @ApiOperation(value = "DRS配置表列表", notes = "DRS配置表列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody YwDrsConfigQO qo) { + List list = ywDrsConfigService.getData(qo); + return getDataTable(list); + } + + + /** + * DRS配置表分页列表 + */ + @ApiOperation(value = "DRS配置表分页列表", notes = "DRS配置表分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody YwDrsConfigQO qo) { + PageInfo page = ywDrsConfigService.getDataByPage(qo); + return getDataTable(page.getList(), page.getTotal()); + } + + /** + * 获取DRS配置表详情 + */ + @ApiOperation(value = "DRS配置表详情", notes = "DRS配置表详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(ywDrsConfigService.fetchById(id)); + } + + /** + * 新增或修改DRS配置表 + */ + @Log(title = "新增或修改DRS配置表", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改DRS配置表", notes = "新增或修改DRS配置表") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated YwDrsConfigDTO dto) { + ywDrsConfigService.saveOrUpdate(dto); + return AjaxResult.success(); + } + + /** + * 根据id删除DRS配置表 + */ + @Log(title = "根据id删除DRS配置表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除DRS配置表", notes = "根据id删除DRS配置表") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + ywDrsConfigService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除DRS配置表 + */ + @Log(title = "根据id批量删除DRS配置表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除DRS配置表", notes = "根据id批量删除DRS配置表") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + ywDrsConfigService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "DRS配置表导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwDrsConfig.class); + List list = util.importExcel(file.getInputStream()); + ywDrsConfigService.importData(list, updateSupport); + return AjaxResult.success(); + } + + + /** + * DRS配置表导出 + */ + @ApiOperation(value = "DRS配置表导出") + @PostMapping(value = "/export") + public void export(@RequestBody YwDrsConfigQO qo) { + ywDrsConfigService.export(qo); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwDrsTempTaskController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwDrsTempTaskController.java new file mode 100644 index 0000000..f26545f --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwDrsTempTaskController.java @@ -0,0 +1,142 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.dto.YwDrsTempTaskDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwDrsTempTaskQO; +import com.ruoyi.eastcom_yw.domain.vo.YwDrsTempTaskVO; +import com.ruoyi.eastcom_yw.service.YwDrsTempTaskService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDate; +import java.util.List; + +/** + *

+ * DRS临时任务表 前端控制器 + *

+ * + * @author ck + * @since 2023-06-13 + */ +@Api(tags = "DRS临时任务表") +@RestController +@RequestMapping("/eastcom_yw/ywDrsTempTask") +@Slf4j +@RequiredArgsConstructor +public class YwDrsTempTaskController extends BaseController { + + private final YwDrsTempTaskService ywDrsTempTaskService; + + /** + * DRS临时任务表列表 + */ + @ApiOperation(value = "DRS临时任务表列表", notes = "DRS临时任务表列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody YwDrsTempTaskQO qo) { + List list = ywDrsTempTaskService.getData(qo); + return getDataTable(list); + } + + + /** + * DRS临时任务表分页列表 + */ + @ApiOperation(value = "DRS临时任务表分页列表", notes = "DRS临时任务表分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody YwDrsTempTaskQO qo) { + PageInfo page = ywDrsTempTaskService.getDataByPage(qo); + return getDataTable(page.getList(), page.getTotal()); + } + + /** + * 获取DRS临时任务表详情 + */ + @ApiOperation(value = "DRS临时任务表详情", notes = "DRS临时任务表详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(ywDrsTempTaskService.fetchById(id)); + } + + + @GetMapping(value = "/test") + public String test() { + return "5555"; + } + + /** + * 新增或修改DRS临时任务表 + */ + @Log(title = "新增或修改DRS临时任务表", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改DRS临时任务表", notes = "新增或修改DRS临时任务表") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated YwDrsTempTaskDTO dto) { + ywDrsTempTaskService.saveOrUpdate(dto); + return AjaxResult.success(); + } + + /** + * 根据id删除DRS临时任务表 + */ + @Log(title = "根据id删除DRS临时任务表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除DRS临时任务表", notes = "根据id删除DRS临时任务表") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + ywDrsTempTaskService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除DRS临时任务表 + */ + @Log(title = "根据id批量删除DRS临时任务表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除DRS临时任务表", notes = "根据id批量删除DRS临时任务表") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + ywDrsTempTaskService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @ApiOperation(value = "DRS临时任务表导入") + @Log(title = "DRS临时任务表导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwDrsTempTaskVO.class); + List list = util.importExcel(file.getInputStream()); + return ywDrsTempTaskService.importData(list, updateSupport); + } + + + /** + * DRS临时任务表导出 + */ + @ApiOperation(value = "DRS临时任务表导出") + @Log(title = "DRS临时任务表导出", businessType = BusinessType.EXPORT) + @PostMapping(value = "/export") + public void export(@RequestBody YwDrsTempTaskQO qo) { + ywDrsTempTaskService.export(qo); + } + + + /** + * DRS预览 + */ + @ApiOperation(value = "DRS预览", notes = "DRS预览") + @GetMapping(value = "/drsPreview/{venueId}/{date}") + public TableDataInfo drsPreview(@PathVariable("venueId") Long venueId, @PathVariable("date") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date) { + return getDataTable(ywDrsTempTaskService.drsPreview(venueId,date)); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwKpiConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwKpiConfigController.java new file mode 100644 index 0000000..a12b736 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwKpiConfigController.java @@ -0,0 +1,135 @@ +package com.ruoyi.web.controller.eastcom_yw; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwKpiConfig; +import com.ruoyi.eastcom_yw.domain.dto.YwKpiConfigDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwKpiConfigQO; +import com.ruoyi.eastcom_yw.domain.vo.YwKpiConfigVO; +import com.ruoyi.eastcom_yw.service.YwKpiConfigService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + + import org.springframework.stereotype.Controller; +import org.springframework.web.multipart.MultipartFile; + + +import javax.validation.Valid; +import java.util.List; + +/** +*

+ * 指标字段阈值配置表 前端控制器 + *

+* +* @author yqf +* @since 2023-04-11 +*/ +@Api(tags = "指标字段阈值配置表") +@RestController +@RequestMapping("/eastcom_yw/ywKpiConfig") +@Slf4j +@RequiredArgsConstructor +public class YwKpiConfigController extends BaseController { + + private final YwKpiConfigService ywKpiConfigService; + + /** + * 指标字段阈值配置表列表 + */ + @ApiOperation(value = "指标字段阈值配置表列表", notes = "指标字段阈值配置表列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody YwKpiConfigQO qo) { + List list = ywKpiConfigService.getData(qo); + return getDataTable(list); + } + + + /** + * 指标字段阈值配置表分页列表 + */ + @ApiOperation(value = "指标字段阈值配置表分页列表", notes = "指标字段阈值配置表分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody YwKpiConfigQO qo) { + IPage page = ywKpiConfigService.getDataByPage(qo); + return getDataTable(page.getRecords(),page.getTotal()); + } + + /** + * 获取指标字段阈值配置表详情 + */ + @ApiOperation(value = "指标字段阈值配置表详情", notes = "指标字段阈值配置表详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(ywKpiConfigService.fetchById(id)); + } + + /** + * 新增或修改指标字段阈值配置表 + */ + @Log(title = "新增或修改指标字段阈值配置表", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改指标字段阈值配置表", notes = "新增或修改指标字段阈值配置表") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated YwKpiConfigDTO dto) { + ywKpiConfigService.saveOrUpdate(dto); + return AjaxResult.success(); + } + + /** + * 根据id删除指标字段阈值配置表 + */ + @Log(title = "根据id删除指标字段阈值配置表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除指标字段阈值配置表", notes = "根据id删除指标字段阈值配置表") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + ywKpiConfigService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除指标字段阈值配置表 + */ + @Log(title = "根据id批量删除指标字段阈值配置表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除指标字段阈值配置表", notes = "根据id批量删除指标字段阈值配置表") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + ywKpiConfigService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "指标字段阈值配置表导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwKpiConfig.class); + List list = util.importExcel(file.getInputStream()); + ywKpiConfigService.importData(list, updateSupport); + return AjaxResult.success(); + } + + + /** + * 指标字段阈值配置表导出 + */ + @ApiOperation(value = "指标字段阈值配置表导出") + @PostMapping(value = "/export") + public void export(@RequestBody YwKpiConfigQO qo){ + ywKpiConfigService.export(qo); + } + + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwKpiController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwKpiController.java new file mode 100644 index 0000000..430a2a7 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwKpiController.java @@ -0,0 +1,366 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.alibaba.fastjson2.JSONWriter; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.github.pagehelper.PageInfo; +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import com.ruoyi.common.annotation.Anonymous; +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.eastcom_yw.common.constant.KpiConstants; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.qo.DpKpiMonitorQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellMonitorQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiMinQO; +import com.ruoyi.eastcom_yw.domain.vo.*; +import com.ruoyi.eastcom_yw.service.*; +import com.ruoyi.sunlm.domain.class_dp_scene_control; +import com.ruoyi.sunlm.domain.class_dp_scene_seat_info; +import com.ruoyi.sunlm.mapper.DpApiMapper; +import com.ruoyi.sunlm.mapper.dpYayunMapper; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.text.StringEscapeUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author yqf + * @date 2023/4/11 + */ +@Api(tags = "性能指标") +@RestController +@RequestMapping("/eastcom_yw") +@Slf4j +@RequiredArgsConstructor +public class YwKpiController extends BaseController { + + + private final PmKpi4gCellService pmKpi4gCellService; + + private final PmKpi5gCellService pmKpi5gCellService; + + + private final PmKpi4gMinService pmKpi4gMinService; + + private final PmKpi5gMinService pmKpi5gMinService; + + private final PmKpiMonitorCellService pmKpiMonitorCellService; + + private final YwSceneService ywSceneService; + + @Resource + DpApiMapper dpApiMapper; + + /** + * 场馆小区级15分钟指标分页列表 + */ + @ApiOperation(value = "场馆小区级15分钟指标分页列表", notes = "场馆小区级15分钟指标分页列表") + @RequestMapping(value = "/kpi/getFifteenList", method = RequestMethod.POST) + public TableDataInfo getFifteenList(@Validated @RequestBody PmKpiCellQO qo) { + if(null == qo.getVenueid()){ + SysUser user = SecurityUtils.getLoginUser().getUser(); +// //场馆集合 +// if (!user.isAdmin(user)) { +// List ywScenes = ywSceneService.getVenueByUser(user); +// Long[] venueIds = ywScenes.stream().map(YwScene::getId).toArray(Long[]::new); +// Integer[] sceneIds = new Integer[venueIds.length]; +// for (int i = 0; i < venueIds.length; i++) { +// sceneIds[i] = venueIds[i].intValue(); +// } +// qo.setVenueIds(sceneIds); +// } + List lstScene = ywSceneService.getVenueByUserCanNoData(user,false); + if(!lstScene.isEmpty()) + { + Long[] venueIds = lstScene.stream().map(YwScene::getId).toArray(Long[]::new); + Integer[] sceneIds = new Integer[venueIds.length]; + for (int i = 0; i < venueIds.length; i++) { + sceneIds[i] = venueIds[i].intValue(); + } + qo.setVenueIds(sceneIds); + } + } + if (qo.getNetType().equals(KpiConstants.YW_NETTYPE_4G)) { + IPage page = pmKpi4gCellService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } else { + IPage page = pmKpi5gCellService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } + } + + + /** + * 场馆小区级15分钟指标导出 + */ + @ApiOperation(value = "场馆小区级15分钟指标导出") + @PostMapping(value = "/kpi/exportFifteenList") + public void exportFifteenList(@Validated @RequestBody PmKpiCellQO qo) { + if(null == qo.getVenueid()){ + SysUser user = SecurityUtils.getLoginUser().getUser(); + //场馆集合 + if (!user.isAdmin(user)) { + List ywScenes = ywSceneService.getVenueByUser(user); + Long[] venueIds = ywScenes.stream().map(YwScene::getId).toArray(Long[]::new); + Integer[] sceneIds = new Integer[venueIds.length]; + for (int i = 0; i < venueIds.length; i++) { + sceneIds[i] = venueIds[i].intValue(); + } + qo.setVenueIds(sceneIds); + } + } + if (qo.getNetType().equals(KpiConstants.YW_NETTYPE_4G)) { + pmKpi4gCellService.export(qo); + } else { + pmKpi5gCellService.export(qo); + } + + } + + + /** + * 场馆小区级1分钟指标分页列表 + */ + @ApiOperation(value = "场馆小区级1分钟指标分页列表", notes = "场馆小区级1分钟指标分页列表") + @RequestMapping(value = "/kpi/getOneMinList", method = RequestMethod.POST) + public TableDataInfo getOneMinList(@Validated @RequestBody PmKpiMinQO qo) { + if(null == qo.getVenueid()){ + SysUser user = SecurityUtils.getLoginUser().getUser(); + //场馆集合 + if (!user.isAdmin(user)) { + List ywScenes = ywSceneService.getVenueByUser(user); + Long[] venueIds = ywScenes.stream().map(YwScene::getId).toArray(Long[]::new); + Integer[] sceneIds = new Integer[venueIds.length]; + for (int i = 0; i < venueIds.length; i++) { + sceneIds[i] = venueIds[i].intValue(); + } + qo.setVenueIds(sceneIds); + } + } + if (qo.getNetType().equals(KpiConstants.YW_NETTYPE_4G)) { + IPage page = pmKpi4gMinService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } else { + IPage page = pmKpi5gMinService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } + } + + + /** + * 场馆小区级1分钟指标导出 + */ + @ApiOperation(value = "场馆小区级1分钟指标导出") + @PostMapping(value = "/kpi/exportOneList") + public void exportOneList(@Validated @RequestBody PmKpiMinQO qo) { + if(null == qo.getVenueid()){ + SysUser user = SecurityUtils.getLoginUser().getUser(); + //场馆集合 + if (!user.isAdmin(user)) { + List ywScenes = ywSceneService.getVenueByUser(user); + Long[] venueIds = ywScenes.stream().map(YwScene::getId).toArray(Long[]::new); + Integer[] sceneIds = new Integer[venueIds.length]; + for (int i = 0; i < venueIds.length; i++) { + sceneIds[i] = venueIds[i].intValue(); + } + qo.setVenueIds(sceneIds); + } + } + + if (qo.getNetType().equals(KpiConstants.YW_NETTYPE_4G)) { + pmKpi4gMinService.export(qo); + } else { + pmKpi5gMinService.export(qo); + } + + } + + @ApiOperation(value = "指标监控分页查询") + @PostMapping(value = "/kpi/getMonitorCellList") + public TableDataInfo getMonitorCellList(@Validated @RequestBody PmKpiCellMonitorQO qo) { + if(null == qo.getSceneid()){ + SysUser user = SecurityUtils.getLoginUser().getUser(); + //场馆集合 + if (!user.isAdmin(user)) { + List ywScenes = ywSceneService.getVenueByUser(user); + Long[] venueIds = ywScenes.stream().map(YwScene::getId).toArray(Long[]::new); + Integer[] sceneIds = new Integer[venueIds.length]; + for (int i = 0; i < venueIds.length; i++) { + sceneIds[i] = venueIds[i].intValue(); + } + qo.setSceneids(sceneIds); + } + } + PageInfo page = pmKpiMonitorCellService.getMonitorCellList(qo); + return getDataTable(page.getList(), page.getTotal()); + + + } + + + @ApiOperation(value = "场内坐席数据接口") + @GetMapping(value = "/daping/get_seat_data") + @Anonymous + public TableDataInfo getSeatData(@RequestParam(required = false) Integer sceneid, + @RequestParam(required = false) String nettype, + @RequestParam(required = false) String datatype, + @RequestParam(required = false) String kpiname, + HttpServletRequest request) { + DpKpiMonitorQO qo = new DpKpiMonitorQO(); + class_dp_scene_control dpData = dpApiMapper.get_scene_control(); + if (null != sceneid) { + qo.setSceneid(sceneid); + } + if (null != nettype && !nettype.equals("")) { + qo.setNettype(nettype); + } else { + qo.setNettype(dpData.getNettype()); + } + if (null != datatype && !datatype.equals("")) { + qo.setDatatype(datatype); + } else { + qo.setDatatype(dpData.getMintype() + "分钟"); + } + if (null != kpiname && !kpiname.equals("")) { + qo.setKpiname(kpiname); + } else { + qo.setKpiname(dpData.getKpiname()); + } + + //用于演示版本控制 + Integer getsceneruntype = dpApiMapper.getsceneruntype(); + if(getsceneruntype == 0){ + //取特定时间表数据 + LocalDateTime maxtime = dpApiMapper.getmaxtime(); + qo.setSceneruntype(KpiConstants.YW_SCENE_RUNTYPE); + qo.setDatatype(KpiConstants.YW_DATATYPE_15); + qo.setMaxtime(maxtime); + } + + PageInfo page = pmKpiMonitorCellService.getDpMonitorCellList(qo); + return getDataTable(page.getList(), page.getTotal()); + + } + + + @ApiOperation(value = "场外点数据接口") + @GetMapping(value = "/daping/get_point_data") + @Anonymous + public TableDataInfo getPointData(@RequestParam(required = false) Integer sceneid, + @RequestParam(required = false) String nettype, + @RequestParam(required = false) String datatype, + @RequestParam(required = false) String kpiname, + HttpServletRequest request) { + DpKpiMonitorQO qo = new DpKpiMonitorQO(); + class_dp_scene_control dpData = dpApiMapper.get_scene_control(); + if (null != sceneid) { + qo.setSceneid(sceneid); + } + if (null != nettype && !nettype.equals("")) { + qo.setNettype(nettype); + } else { + qo.setNettype(dpData.getNettype()); + } + if (null != datatype && !datatype.equals("")) { + qo.setDatatype(datatype); + } else { + qo.setDatatype(dpData.getMintype() + "分钟"); + } + if (null != kpiname && !kpiname.equals("")) { + qo.setKpiname(kpiname); + } else { + qo.setKpiname(dpData.getKpiname()); + } + qo.setSeatno(KpiConstants.QUERYSEAT); + + //用于演示版本控制 + Integer getsceneruntype = dpApiMapper.getsceneruntype(); + if(getsceneruntype == 0){ + //取特定时间表数据 + LocalDateTime maxtime = dpApiMapper.getmaxtime(); + qo.setSceneruntype(KpiConstants.YW_SCENE_RUNTYPE); + qo.setDatatype(KpiConstants.YW_DATATYPE_15); + qo.setMaxtime(maxtime); + } + + PageInfo page = pmKpiMonitorCellService.getDpMonitorCellList(qo); + return getDataTable(page.getList(), page.getTotal()); + + } + + /** + * 修改大屏控制查询接口 + * + * @param dpcSeneControlVo 实体对象 + * @return 修改结果 + */ + @PutMapping(value = "/kpi/updateDpcSeneControl") + public AjaxResult updateDpcSeneControl(@Validated @RequestBody DpcSeneControlVo dpcSeneControlVo) { + return AjaxResult.success(pmKpiMonitorCellService.updateDpcSeneControl(dpcSeneControlVo)); + } + + + /** + * 获取4G最新有数据的时间 + * + * @return + */ + @GetMapping(value = "/kpi/getLastTime") + @RepeatSubmit(enable = false,interval = 1000) + public Map getLastTime(){ + + Long[] venueIds = null; + SysUser user = SecurityUtils.getLoginUser().getUser(); + //场馆集合 + if (!user.isAdmin(user)) { + List ywScenes = ywSceneService.getVenueByUser(user); + venueIds = ywScenes.stream().map(YwScene::getId).toArray(Long[]::new); + } + + return pmKpi4gCellService.getLastTime(venueIds); + } + + /** + * 简报打印数据 + * + * @return + */ + @PostMapping(value = "/kpi/getReportKpi") + public AjaxResult getReportKpi(@RequestBody PmKpiCellMonitorQO qo) { + KpiVenueReportVo reportKpi = pmKpiMonitorCellService.getReportKpi(qo.getSceneid(), qo.getStarttime(), qo.getEndtime(),60); + return AjaxResult.success(reportKpi); + } + + + /** + * 简报打印json数据 + * + * @return + */ + @PostMapping(value = "/kpi/getReportKpiByJson") + public AjaxResult getReportKpiByJson(@RequestBody PmKpiCellMonitorQO qo) { + JSONObject reportKpi = pmKpiMonitorCellService.getReportKpiByJson(qo.getSceneid(), qo.getStarttime(), qo.getEndtime(),15); + return AjaxResult.success(reportKpi); + } + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwMaterialsBatchController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwMaterialsBatchController.java new file mode 100644 index 0000000..2530f2c --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwMaterialsBatchController.java @@ -0,0 +1,142 @@ +package com.ruoyi.web.controller.eastcom_yw; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import com.ruoyi.cmcc_gm.domain.YwMaterialsInform; +import com.ruoyi.cmcc_gm.service.YwMaterialsBatchService; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * 物资批次表(YwMaterialsBatch)表控制层 + * + * @author makejava + * @since 2023-04-10 15:37:55 + */ +@RestController +@RequestMapping("/eastcom_yw/ywMaterialsBatch") +public class YwMaterialsBatchController extends BaseController { + /** + * 服务对象 + */ + @Resource + private YwMaterialsBatchService ywMaterialsBatchService; + + /** + * 分页查询所有数据 + * + * @param page 分页对象 + * @param ywMaterialsBatch 查询实体 + * @return 所有数据 + */ + @GetMapping + public AjaxResult selectAll(Page page, YwMaterialsBatch ywMaterialsBatch) { + return AjaxResult.success(this.ywMaterialsBatchService.page(page, new QueryWrapper<>(ywMaterialsBatch))); + } + + /** + * 通过主键查询单条数据 + * + * @param id 主键 + * @return 单条数据 + */ + @GetMapping("{id}") + public AjaxResult selectOne(@PathVariable Serializable id) { + return AjaxResult.success(this.ywMaterialsBatchService.getById(id)); + } + + /** + * 新增数据 + * + * @param ywMaterialsBatch 实体对象 + * @return 新增结果 + */ + @PostMapping + public AjaxResult insert(@RequestBody YwMaterialsBatch ywMaterialsBatch) { + return AjaxResult.success(this.ywMaterialsBatchService.save(ywMaterialsBatch)); + } + + /** + * 修改数据 + * + * @param ywMaterialsBatch 实体对象 + * @return 修改结果 + */ + @PutMapping + public AjaxResult update(@RequestBody YwMaterialsBatch ywMaterialsBatch) { + return AjaxResult.success(this.ywMaterialsBatchService.updateById(ywMaterialsBatch)); + } + + /** + * 删除数据 + * + * @param idList 主键结合 + * @return 删除结果 + */ + @DeleteMapping + public AjaxResult delete(@RequestParam("idList") List idList) { + return AjaxResult.success(this.ywMaterialsBatchService.removeByIds(idList)); + } + + @PostMapping("/import") + public AjaxResult importXls(@RequestBody Map map) throws Exception { + + String path; + String orderId; + + try { + path = map.get("path"); + orderId = map.get("orderid"); + } catch (Exception e) { + return AjaxResult.error("参数不一致"); + } + + if (StringUtils.isEmpty(path)) { + return AjaxResult.error("参数校验不通过"); + } + + String realPath = RuoYiConfig.getProfile() + path.replaceFirst("/profile", ""); + File file = new File(realPath); + if (file.isDirectory()) { + return AjaxResult.error("只能传文件类型"); + } + if (!file.exists()) { + return AjaxResult.error("文件不存在"); + } + FileInputStream fileInputStream = null; + List y; + try { + fileInputStream = new FileInputStream(file); + ExcelUtil util = new ExcelUtil<>(YwMaterialsInform.class); + y = util.importExcel(fileInputStream); + } catch (Exception e) { + e.printStackTrace(); + return AjaxResult.error(); + } finally { + if (fileInputStream != null) { + try { + fileInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return ywMaterialsBatchService.importExcel(orderId, y, file); + } + +} + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeBriefingController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeBriefingController.java new file mode 100644 index 0000000..583707c --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeBriefingController.java @@ -0,0 +1,189 @@ +package com.ruoyi.web.controller.eastcom_yw; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwNoticeBriefing; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeBriefingDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeBriefingQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeBriefingVO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeModelVO; +import com.ruoyi.eastcom_yw.service.YwNoticeBriefingService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知通告简报计划表 前端控制器 + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Api(tags = "通知通告简报计划表") +@RestController +@RequestMapping("/eastcom_yw/ywNoticeBriefing") +@Slf4j +@RequiredArgsConstructor +public class YwNoticeBriefingController extends BaseController { + + private final YwNoticeBriefingService ywNoticeBriefingService; + + /** + * 通知通告简报计划表列表 + */ + @ApiOperation(value = "通知通告简报计划表列表", notes = "通知通告简报计划表列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody YwNoticeBriefingQO qo) { + List list = ywNoticeBriefingService.getData(qo); + return getDataTable(list); + } + + + /** + * 通知通告简报计划表分页列表 + */ + @ApiOperation(value = "通知通告简报计划表分页列表", notes = "通知通告简报计划表分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody YwNoticeBriefingQO qo) { + IPage page = ywNoticeBriefingService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } + + /** + * 获取通知通告简报计划表详情 + */ + @ApiOperation(value = "通知通告简报计划表详情", notes = "通知通告简报计划表详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(ywNoticeBriefingService.fetchById(id)); + } + + /** + * 新增或修改通知通告简报计划表 + */ + @Log(title = "新增或修改通知通告简报计划表", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改通知通告简报计划表", notes = "新增或修改通知通告简报计划表") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated YwNoticeBriefingDTO dto) { + ywNoticeBriefingService.saveOrUpdate(dto); + return AjaxResult.success(); + } + + /** + * 启用停用简报 + */ + @Log(title = "启用停用简报", businessType = BusinessType.INSERT) + @ApiOperation(value = "启用停用简报", notes = "启用停用简报") + @PostMapping(value = "/onOrOff") + public AjaxResult onOrOff(@RequestBody @Validated YwNoticeBriefingDTO dto) { + YwNoticeBriefing ywNoticeBriefing = new YwNoticeBriefing(); + ywNoticeBriefing.setId(dto.getId()); + ywNoticeBriefing.setSysNormalDisable(dto.getSysNormalDisable()); + ywNoticeBriefingService.updateById(ywNoticeBriefing); + return AjaxResult.success(); + } + + /** + * 根据id删除通知通告简报计划表 + */ + @Log(title = "根据id删除通知通告简报计划表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除通知通告简报计划表", notes = "根据id删除通知通告简报计划表") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + ywNoticeBriefingService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除通知通告简报计划表 + */ + @Log(title = "根据id批量删除通知通告简报计划表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除通知通告简报计划表", notes = "根据id批量删除通知通告简报计划表") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + ywNoticeBriefingService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "通知通告简报计划表导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwNoticeBriefingVO.class); + List list = util.importExcel(file.getInputStream()); + return ywNoticeBriefingService.importData(list, updateSupport); + } + + + /** + * 通知通告简报计划表导出 + */ + @ApiOperation(value = "通知通告简报计划表导出") + @PostMapping(value = "/export") + public void export(@RequestBody YwNoticeBriefingQO qo) { + ywNoticeBriefingService.export(qo); + } + + /** + * 返回新增简报定制时可选模板 + */ + @Log(title = "返回新增简报定制时可选模板", businessType = BusinessType.OTHER) + @ApiOperation(value = "返回新增简报定制时可选模板", notes = "返回新增简报定制时可选模板") + @GetMapping(value = "/getModel") + public AjaxResult getModel(@RequestParam(required = false) Long venueId,@RequestParam(required = false) String modelSuitType) { + List model = ywNoticeBriefingService.getModel(venueId,modelSuitType); + return AjaxResult.success(model); + } + + + /** + * 当前时间段场馆级简报 + */ + @ApiOperation(value = "当前时间段场馆级简报") + @GetMapping(value = "/getData/{venueId}") + public AjaxResult getData(@PathVariable Long venueId) { + String s = ywNoticeBriefingService.getJson(venueId, 15).toJSONString(); + return AjaxResult.success(s); + } + + /** + * 当前时间段场馆级简报 + */ + @ApiOperation(value = "当前时间段场馆级简报") + @GetMapping(value = "/assemblyVenueBriefing/{venueId}/{time}/{modelId}") + public String assemblyVenueBriefing(@PathVariable Long venueId,@PathVariable String time,@PathVariable Long modelId) { + return ywNoticeBriefingService.assemblyVenueBriefing(LocalDateTime.parse(time),venueId,60,modelId); + } + + /** + * 当前时间段场馆级简报JSON + */ + @ApiOperation(value = "当前时间段场馆级简报JSON") + @GetMapping(value = "/assemblyVenueBriefingJSON/{venueId}/{time}") + public String assemblyVenueBriefingJSON(@PathVariable Long venueId,@PathVariable String time) { + return ywNoticeBriefingService.assemblyVenueJsonToGetURL(LocalDateTime.parse(time),venueId,60); + } + + /** + * 当前时间段地市级简报 + */ + @ApiOperation(value = "当前时间段地市级简报") + @GetMapping(value = "/assemblyCityBriefing/{city}/{time}") + public String assemblyCityBriefing(@PathVariable String city,@PathVariable String time) { + return ywNoticeBriefingService.assemblyCityBriefing(LocalDateTime.parse(time),city,60,1L); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeHandworkController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeHandworkController.java new file mode 100644 index 0000000..1a8f104 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeHandworkController.java @@ -0,0 +1,124 @@ +package com.ruoyi.web.controller.eastcom_yw; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwNoticeHandwork; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeHandworkDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeHandworkQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeHandworkVO; +import com.ruoyi.eastcom_yw.service.YwNoticeHandworkService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + *

+ * 通知通告手工通知计划表 前端控制器 + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Api(tags = "通知通告手工通知计划表") +@RestController +@RequestMapping("/eastcom_yw/ywNoticeHandwork") +@Slf4j +@RequiredArgsConstructor +public class YwNoticeHandworkController extends BaseController { + + private final YwNoticeHandworkService ywNoticeHandworkService; + + /** + * 通知通告手工通知计划表列表 + */ + @ApiOperation(value = "通知通告手工通知计划表列表", notes = "通知通告手工通知计划表列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody YwNoticeHandworkQO qo) { + List list = ywNoticeHandworkService.getData(qo); + return getDataTable(list); + } + + + /** + * 通知通告手工通知计划表分页列表 + */ + @ApiOperation(value = "通知通告手工通知计划表分页列表", notes = "通知通告手工通知计划表分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody YwNoticeHandworkQO qo) { + IPage page = ywNoticeHandworkService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } + + /** + * 获取通知通告手工通知计划表详情 + */ + @ApiOperation(value = "通知通告手工通知计划表详情", notes = "通知通告手工通知计划表详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(ywNoticeHandworkService.fetchById(id)); + } + + /** + * 新增或修改通知通告手工通知计划表 + */ + @Log(title = "新增或修改通知通告手工通知计划表", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改通知通告手工通知计划表", notes = "新增或修改通知通告手工通知计划表") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated YwNoticeHandworkDTO dto) { + Long id = ywNoticeHandworkService.saveOrUpdate(dto); + return AjaxResult.success(id); + } + + /** + * 根据id删除通知通告手工通知计划表 + */ + @Log(title = "根据id删除通知通告手工通知计划表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除通知通告手工通知计划表", notes = "根据id删除通知通告手工通知计划表") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + ywNoticeHandworkService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除通知通告手工通知计划表 + */ + @Log(title = "根据id批量删除通知通告手工通知计划表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除通知通告手工通知计划表", notes = "根据id批量删除通知通告手工通知计划表") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + ywNoticeHandworkService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "通知通告手工通知计划表导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwNoticeHandwork.class); + List list = util.importExcel(file.getInputStream()); + return ywNoticeHandworkService.importData(list, updateSupport); + } + + + /** + * 通知通告手工通知计划表导出 + */ + @ApiOperation(value = "通知通告手工通知计划表导出") + @PostMapping(value = "/export") + public void export(@RequestBody YwNoticeHandworkQO qo) { + ywNoticeHandworkService.export(qo); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeHandworkdetailController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeHandworkdetailController.java new file mode 100644 index 0000000..f6e5746 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeHandworkdetailController.java @@ -0,0 +1,124 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwNoticeHandworkdetail; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeHandworkdetailDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeHandworkdetailQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeHandworkdetailVO; +import com.ruoyi.eastcom_yw.service.YwNoticeHandworkdetailService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + *

+ * 通知通告手工通知审核表 前端控制器 + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Api(tags = "通知通告手工通知审核表") +@RestController +@RequestMapping("/eastcom_yw/ywNoticeHandworkdetail") +@Slf4j +@RequiredArgsConstructor +public class YwNoticeHandworkdetailController extends BaseController { + + private final YwNoticeHandworkdetailService ywNoticeHandworkdetailService; + + /** + * 通知通告手工通知审核表列表 + */ + @ApiOperation(value = "通知通告手工通知审核表列表", notes = "通知通告手工通知审核表列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody YwNoticeHandworkdetailQO qo) { + List list = ywNoticeHandworkdetailService.getData(qo); + return getDataTable(list); + } + + + /** + * 通知通告手工通知审核表分页列表 + */ + @ApiOperation(value = "通知通告手工通知审核表分页列表", notes = "通知通告手工通知审核表分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody YwNoticeHandworkdetailQO qo) { + IPage page = ywNoticeHandworkdetailService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } + + /** + * 获取通知通告手工通知审核表详情 + */ + @ApiOperation(value = "通知通告手工通知审核表详情", notes = "通知通告手工通知审核表详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(ywNoticeHandworkdetailService.fetchById(id)); + } + + /** + * 新增或修改通知通告手工通知审核表 + */ + @Log(title = "新增或修改通知通告手工通知审核表", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改通知通告手工通知审核表", notes = "新增或修改通知通告手工通知审核表") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated YwNoticeHandworkdetailDTO dto) { + ywNoticeHandworkdetailService.saveOrUpdate(dto); + return AjaxResult.success(); + } + + /** + * 根据id删除通知通告手工通知审核表 + */ + @Log(title = "根据id删除通知通告手工通知审核表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除通知通告手工通知审核表", notes = "根据id删除通知通告手工通知审核表") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + ywNoticeHandworkdetailService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除通知通告手工通知审核表 + */ + @Log(title = "根据id批量删除通知通告手工通知审核表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除通知通告手工通知审核表", notes = "根据id批量删除通知通告手工通知审核表") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + ywNoticeHandworkdetailService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "通知通告手工通知审核表导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwNoticeHandworkdetail.class); + List list = util.importExcel(file.getInputStream()); + ywNoticeHandworkdetailService.importData(list, updateSupport); + return AjaxResult.success(); + } + + + /** + * 通知通告手工通知审核表导出 + */ + @ApiOperation(value = "通知通告手工通知审核表导出") + @PostMapping(value = "/export") + public void export(@RequestBody YwNoticeHandworkdetailQO qo) { + ywNoticeHandworkdetailService.export(qo); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeListController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeListController.java new file mode 100644 index 0000000..cf8209d --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeListController.java @@ -0,0 +1,124 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwNoticeList; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeListDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeListQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeListVO; +import com.ruoyi.eastcom_yw.service.YwNoticeListService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + *

+ * 通知通告记录表 前端控制器 + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Api(tags = "通知通告记录表") +@RestController +@RequestMapping("/eastcom_yw/ywNoticeList") +@Slf4j +@RequiredArgsConstructor +public class YwNoticeListController extends BaseController { + + private final YwNoticeListService ywNoticeListService; + + /** + * 通知通告记录表列表 + */ + @ApiOperation(value = "通知通告记录表列表", notes = "通知通告记录表列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody YwNoticeListQO qo) { + List list = ywNoticeListService.getData(qo); + return getDataTable(list); + } + + + /** + * 通知通告记录表分页列表 + */ + @ApiOperation(value = "通知通告记录表分页列表", notes = "通知通告记录表分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody YwNoticeListQO qo) { + IPage page = ywNoticeListService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } + + /** + * 获取通知通告记录表详情 + */ + @ApiOperation(value = "通知通告记录表详情", notes = "通知通告记录表详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(ywNoticeListService.fetchById(id)); + } + + /** + * 新增或修改通知通告记录表 + */ + @Log(title = "新增或修改通知通告记录表", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改通知通告记录表", notes = "新增或修改通知通告记录表") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated YwNoticeListDTO dto) { + ywNoticeListService.saveOrUpdate(dto); + return AjaxResult.success(); + } + + /** + * 根据id删除通知通告记录表 + */ + @Log(title = "根据id删除通知通告记录表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除通知通告记录表", notes = "根据id删除通知通告记录表") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + ywNoticeListService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除通知通告记录表 + */ + @Log(title = "根据id批量删除通知通告记录表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除通知通告记录表", notes = "根据id批量删除通知通告记录表") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + ywNoticeListService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "通知通告记录表导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwNoticeList.class); + List list = util.importExcel(file.getInputStream()); + ywNoticeListService.importData(list, updateSupport); + return AjaxResult.success(); + } + + + /** + * 通知通告记录表导出 + */ + @ApiOperation(value = "通知通告记录表导出") + @PostMapping(value = "/export") + public void export(@RequestBody YwNoticeListQO qo) { + ywNoticeListService.export(qo); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeModelController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeModelController.java new file mode 100644 index 0000000..9b0379c --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeModelController.java @@ -0,0 +1,192 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwNoticeModel; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeModelDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeModelQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeModelVO; +import com.ruoyi.eastcom_yw.service.YwNoticeModelService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + *

+ * 通知通告模板表 前端控制器 + *

+ * + * @author ck + * @since 2023-04-07 + */ +@Api(tags = "通知通告模板表") +@RestController +@RequestMapping("/eastcom_yw/ywNoticeModel") +@Slf4j +@RequiredArgsConstructor +public class YwNoticeModelController extends BaseController { + + private final YwNoticeModelService ywNoticeModelService; + + /** + * 通知通告模板表列表 + *

+ * showdoc + * + * @param + * @return {"code":"0","message":"操作成功","data": {}} + * @catalog 通知通告模板表/通知通告模板表管理 + * @title 通知通告模板表列表 + * @description 通知通告模板表列表 + * @method POST + * @url /api/happyCanteen/list + * @return_param + */ + @ApiOperation(value = "通知通告模板表列表", notes = "通知通告模板表列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody YwNoticeModelQO qo) { + List list = ywNoticeModelService.getData(qo); + return getDataTable(list); + } + + + /** + * 通知通告模板表分页列表 + *

+ * showdoc + * + * @param + * @return {"code":"0","message":"操作成功","data": {}} + * @catalog 通知通告模板表/通知通告模板表管理 + * @title 通知通告模板表分页列表 + * @description 通知通告模板表分页列表 + * @method POST + * @url /api/happyCanteen/pageList + * @return_param + */ + @ApiOperation(value = "通知通告模板表分页列表", notes = "通知通告模板表分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody YwNoticeModelQO qo) { + IPage page = ywNoticeModelService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } + + /** + * 获取通知通告模板表详情 + *

+ * showdoc + * + * @param + * @return {"code":"0","message":"操作成功","data": {}} + * @catalog 通知通告模板表/通知通告模板表管理 + * @title 获取通知通告模板表详情 + * @description 获取通知通告模板表详情 + * @method Get + * @url /api/happyCanteen/fetchById/{id} + * @return_param + */ + @ApiOperation(value = "通知通告模板表详情", notes = "通知通告模板表详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(ywNoticeModelService.fetchById(id)); + } + + /** + * 新增或修改通知通告模板表 + *

+ * showdoc + * + * @param + * @return {"code":"0","message":"操作成功","data": {}} + * @catalog 通知通告模板表/通知通告模板表管理 + * @title 新增或修改通知通告模板表 + * @description 新增或修改通知通告模板表 + * @method POST + * @url /api/happyCanteen/saveOrUpdate + * @return_param + */ + @Log(title = "新增或修改通知通告模板表", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改通知通告模板表", notes = "新增或修改通知通告模板表") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated YwNoticeModelDTO dto) { + ywNoticeModelService.saveOrUpdate(dto); + return AjaxResult.success(); + } + + /** + * 根据id删除通知通告模板表 + *

+ * showdoc + * + * @param + * @return {"code":"0","message":"操作成功","data": {}} + */ + @Log(title = "根据id删除通知通告模板表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除通知通告模板表", notes = "根据id删除通知通告模板表") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + ywNoticeModelService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除通知通告模板表 + *

+ * showdoc + * + * @param + * @return {"code":"0","message":"操作成功","data": {}} + * @catalog 通知通告模板表/通知通告模板表管理 + * @title 根据id批量删除通知通告模板表 + * @description 根据id批量删除通知通告模板表 + * @method POST + * @url /api/happyCanteen/deleteByIdBatch + * @return_param + */ + @Log(title = "根据id批量删除通知通告模板表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除通知通告模板表", notes = "根据id批量删除通知通告模板表") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + ywNoticeModelService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "通知通告模板表导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwNoticeModel.class); + List list = util.importExcel(file.getInputStream()); + return ywNoticeModelService.importData(list, updateSupport); + } + + /** + * 通知通告模板表导出 + *

+ * showdoc + * + * @param + * @catalog 通知通告模板表/通知通告模板表管理 + * @title 通知通告模板表导出 + * @description 通知通告模板表导出 + * @method POST + * @url /api/happyCanteen/export + * @return_param + */ + @ApiOperation(value = "通知通告模板表导出") + @PostMapping(value = "/export") + public void export(@RequestBody YwNoticeModelQO qo) { + ywNoticeModelService.export(qo); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeObjectController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeObjectController.java new file mode 100644 index 0000000..72acdfa --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeObjectController.java @@ -0,0 +1,138 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwNoticeObject; +import com.ruoyi.eastcom_yw.domain.dto.YwNoticeObjectDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeObjectQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeObjectVO; +import com.ruoyi.eastcom_yw.service.YwNoticeObjectService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + *

+ * 通知通告对象表 前端控制器 + *

+ * + * @author ck + * @since 2023-04-11 + */ +@Api(tags = "通知通告对象表") +@RestController +@RequestMapping("/eastcom_yw/ywNoticeObject") +@Slf4j +@RequiredArgsConstructor +public class YwNoticeObjectController extends BaseController { + + private final YwNoticeObjectService ywNoticeObjectService; + + /** + * 通知通告对象表列表 + */ + @ApiOperation(value = "通知通告对象表列表", notes = "通知通告对象表列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody YwNoticeObjectQO qo) { + List list = ywNoticeObjectService.getData(qo); + return getDataTable(list); + } + + + /** + * 通知通告对象表分页列表 + */ + @ApiOperation(value = "通知通告对象表分页列表", notes = "通知通告对象表分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody YwNoticeObjectQO qo) { + IPage page = ywNoticeObjectService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } + + /** + * 返回前端所需对象列表 + */ + @ApiOperation(value = "返回前端所需对象列表", notes = "返回前端所需对象列表") + @RequestMapping(value = "allObject", method = RequestMethod.GET) + public TableDataInfo allObject() { + Map map = ywNoticeObjectService.allObject(); + TableDataInfo tableDataInfo = new TableDataInfo(); + tableDataInfo.setMaps((HashMap)map); + return tableDataInfo; + } + + /** + * 获取通知通告对象表详情 + */ + @ApiOperation(value = "通知通告对象表详情", notes = "通知通告对象表详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(ywNoticeObjectService.fetchById(id)); + } + + /** + * 新增或修改通知通告对象表 + */ + @Log(title = "新增或修改通知通告对象表", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改通知通告对象表", notes = "新增或修改通知通告对象表") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated YwNoticeObjectDTO dto) { + ywNoticeObjectService.saveOrUpdate(dto); + return AjaxResult.success(); + } + + /** + * 根据id删除通知通告对象表 + */ + @Log(title = "根据id删除通知通告对象表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除通知通告对象表", notes = "根据id删除通知通告对象表") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + ywNoticeObjectService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除通知通告对象表 + */ + @Log(title = "根据id批量删除通知通告对象表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除通知通告对象表", notes = "根据id批量删除通知通告对象表") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + ywNoticeObjectService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "通知通告对象表导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwNoticeObjectVO.class); + List list = util.importExcel(file.getInputStream()); + return ywNoticeObjectService.importData(list, updateSupport); + } + + + /** + * 通知通告对象表导出 + */ + @ApiOperation(value = "通知通告对象表导出") + @PostMapping(value = "/export") + public void export(@RequestBody YwNoticeObjectQO qo) { + ywNoticeObjectService.export(qo); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeUserController.java new file mode 100644 index 0000000..2bb3f89 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwNoticeUserController.java @@ -0,0 +1,272 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import cn.hutool.core.date.LocalDateTimeUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.cmcc_gm.common.enums.OrderStatus; +import com.ruoyi.cmcc_gm.common.enums.OrderType; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSearchDTO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsOrderLogVo; +import com.ruoyi.cmcc_gm.service.YwMaterialsOrderLogService; +import com.ruoyi.common.annotation.Anonymous; +import com.ruoyi.common.constant.TaskConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.common.enums.FlowDealStatus; +import com.ruoyi.eastcom_yw.common.enums.WireTaskType; +import com.ruoyi.eastcom_yw.domain.YwWireTaskLog; +import com.ruoyi.eastcom_yw.domain.dto.YwDataDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeModelQO; +import com.ruoyi.eastcom_yw.domain.vo.YwNoticeModelVO; +import com.ruoyi.eastcom_yw.mapper.YwNoticeUserMapper; +import com.ruoyi.eastcom_yw.service.*; +import com.ruoyi.eastcom_yw.domain.SysNotice; + +import com.ruoyi.system.service.ISysUserService; +import com.ruoyi.eastcom_yw.service.SysNoticeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.commons.text.StringSubstitutor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * + * @author jkj + * @since 2023-01-12 + */ + +@Api("告警信息管理") +@RestController +@RequestMapping("/eastcom_yw") +public class YwNoticeUserController extends BaseController { + + @Autowired + private YwNoticeUserMapper ywNoticeUserMapper; + + @Autowired + private YwMaterialsOrderLogService ywMaterialsOrderLogService; + + @Autowired + private YwWireTaskLogService ywWireTaskLogService; + + @Autowired + private SysNoticeService sysNoticeService; + + @Autowired + private YwNoticeModelService ywNoticeModelService; + + @Autowired + private ISysUserService userService; + + +// @Log(title = "工作流站内提醒", businessType = BusinessType.INSERT) + //这里加日志会因为没有登录用户导致报错 + @ApiOperation("根据流程ID发送当前需要提醒的用户") + @GetMapping("/notice") + @Anonymous + public AjaxResult notice(String flwId,String taskId,String groupId,String type) + { + Map valuesMap = new HashMap(); + SysNotice notice=new SysNotice(); + + Long userId = 0L; + + if(type.contains(TaskConstants.WIRE)) + { + //获取布线的任务信息 + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper(); + lambdaQueryWrapper.eq(YwWireTaskLog::getFlwProcessid,flwId); + + List wires = ywWireTaskLogService.list(lambdaQueryWrapper); + + if(wires.isEmpty()) + { + logger.error(flwId+"没有查询到相关的布线任务"); + return AjaxResult.error(flwId+"没有查询到相关的布线任务"); + } + + YwWireTaskLog wire = wires.get(0); + + String wireLabel = WireTaskType.getLabelByCode(wire.getTaskType()); + + notice.setNoticeTitle("场馆" + wireLabel + "任务下发通知"); + String noticeContent = "提醒:${场馆名称}${任务类型}任务${布线工单号}已流转到你处,请及时处理"; + + //获取布线需要提醒的内容 + YwNoticeModelQO ywNoticeModelQO = new YwNoticeModelQO(); + ywNoticeModelQO.setModelScene("-1"); + if(wire.getTaskType() == 1) { + ywNoticeModelQO.setModelScene("9"); + } + if(wire.getTaskType() == 2) { + ywNoticeModelQO.setModelScene("10"); + } + List noticeModelVOList = ywNoticeModelService.getData(ywNoticeModelQO); + + if(!noticeModelVOList.isEmpty()) + { + notice.setNoticeTitle(noticeModelVOList.get(0).getModelName()); + noticeContent = noticeModelVOList.get(0).getModelContent(); + } + + if(wire.getDealStatus().equals(FlowDealStatus.BUSINESS_STATUS_3.getCode())) + { + //找到被驳回的处理人 + String [] roles = wire.getRoleKey().split(","); + Long venueId = wire.getVenueId(); + for(String role : roles) + { + groupId = venueId+"|"+role; + } + + noticeContent = "提醒:${场馆名称}${任务类型}任务${布线工单号}已驳回,请及时处理"; + } + + + valuesMap.put("场馆名称", wire.getVenueName()); + valuesMap.put("布线工单号", wire.getWireTaskId()); + + + valuesMap.put("任务类型", wireLabel); + + + StringSubstitutor sub = new StringSubstitutor(valuesMap); + String content= sub.replace(noticeContent); + notice.setNoticeContent(content); + notice.setNoticeType("3"); + + } + else if(type.contains(TaskConstants.MATERIAL)) + { + + YwMaterialsSearchDTO dto =new YwMaterialsSearchDTO(); + dto.setFlwId(flwId); + List orders = ywMaterialsOrderLogService.selectMaterialsOrderLog(dto); + + if(orders.isEmpty()) + { + logger.error(flwId+"没有查询到相关的物资工单"); + return AjaxResult.error(flwId+"没有查询到相关的物资工单"); + } + + YwMaterialsOrderLogVo order = orders.get(0); + + String orderTypelabel = OrderType.getLabelByCode(order.getOrderType()); + +// TOdo:物资的通知模板内容不够准确,暂不用 + notice.setNoticeTitle(orderTypelabel + "提醒"); + //获取布线需要提醒的内容 +// YwNoticeModelQO ywNoticeModelQO = new YwNoticeModelQO(); +// List noticeModelVOList = ywNoticeModelService.getData(ywNoticeModelQO); + + String noticeContent = ""; + + valuesMap.put("场馆名称", order.getInVenueName()); + + if (order.getOrderType() == OrderType.TK.getCode() || order.getOrderType() == OrderType.CK.getCode()) { + valuesMap.put("场馆名称", order.getOutVenueName()); + } + + valuesMap.put("工单类型",orderTypelabel); + valuesMap.put("工单号", order.getOrderId()); + + if(order.getDealStatus().equals(FlowDealStatus.BUSINESS_STATUS_3.getCode())) + { + userId = order.getApplyId(); + noticeContent = "提醒:${场馆名称}提交的${工单类型}申请${工单号}被驳回,请修改后重新提交申请"; + } + + if(!order.getDealStatus().equals(FlowDealStatus.BUSINESS_STATUS_3.getCode())) { + + if(order.getTaskStatus().equals(OrderStatus.DSH.getCode())) + { + userId = order.getCheckId(); + noticeContent = "提醒:${场馆名称}已提交${工单类型}申请${工单号},你有新的审核任务"; + } + + if(order.getTaskStatus().equals(OrderStatus.YSH.getCode())) + { + if (order.getOrderType() == OrderType.TK.getCode() || order.getOrderType() == OrderType.CK.getCode()|| order.getOrderType() == OrderType.DB.getCode()) { + noticeContent = "提醒:${工单号}已流转到你处,你有新的${工单类型}的出库任务"; + } + + if (order.getOrderType() == OrderType.SL.getCode() || order.getOrderType() == OrderType.RK.getCode()) { + noticeContent = "提醒:${工单号}已流转到你处,你有新的${工单类型}的入库任务"; + } + } + + if(order.getTaskStatus().equals(OrderStatus.YCK.getCode())) + { + noticeContent = "提醒:${工单号}已流转到你处,你有新的${工单类型}的入库任务"; + } + + + } + + StringSubstitutor sub = new StringSubstitutor(valuesMap); + String content= sub.replace(noticeContent); + notice.setNoticeContent(content); + notice.setNoticeType("3"); + } + + notice.setCreateTime(LocalDateTimeUtil.now()); + notice.setStatus("0"); + notice.setCreateBy("sys"); + + if(notice.getNoticeType().equals("3")) { + + String phoneNumber = ""; + + if(!groupId.contains("|")) + { + try { + SysUser user = userService.selectUserById(userId); + if(ObjectUtils.isNotEmpty(user)) { + phoneNumber = user.getPhonenumber(); + } + } + catch(Exception ex) { + logger.error(flwId+"出错了,groupId不正确"); + return AjaxResult.error(flwId+"出错了,groupId不正确"); + } + } + else + { + //中心库相关的人员,特殊处理,取全部的用户 + if(groupId.contains("centerstorage")) + { + groupId = groupId.split("\\|")[1]; + } + phoneNumber = ywNoticeUserMapper.getPhoneByGroupId(groupId); + } + + if (StringUtils.isEmpty(phoneNumber)) { + logger.error(flwId + "没有相关提醒人员,无法发送短信"); + return AjaxResult.error(flwId + "没有相关提醒人员,无法发送短信"); + } + + if (StringUtils.isNotEmpty(phoneNumber)) { + notice.setExpSendTime(LocalDateTimeUtil.now()); + notice.setReciveUserPhone(phoneNumber); + sysNoticeService.save(notice); + } + } + + return AjaxResult.success(); + } + + @PostMapping("/isRead") + public AjaxResult isRead(@RequestBody YwDataDTO ywDataDTO) + { + return toAjax(sysNoticeService.isReadNotice(ywDataDTO.getIds())); + } + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwRoutInspectLogController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwRoutInspectLogController.java new file mode 100644 index 0000000..baa081a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwRoutInspectLogController.java @@ -0,0 +1,39 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectLog; +import com.ruoyi.eastcom_yw.service.YwRoutInspectLogService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author los + */ +@Api("巡检计划反馈接口") +@RestController +@RequestMapping("/eastcom_yw/routInspectLog") +@RequiredArgsConstructor +public class YwRoutInspectLogController extends BaseController { + + private final YwRoutInspectLogService ywRoutInspectLogService; + + @ApiOperation("修改") + @PutMapping("") + public AjaxResult update(@RequestBody YwRoutInspectLog log) { + try { + ywRoutInspectLogService.updateLog(log); + + return AjaxResult.success(); + } catch (Exception e) { + e.printStackTrace(); + return AjaxResult.error(e.getMessage()); + } + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwRoutInspectPlanController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwRoutInspectPlanController.java new file mode 100644 index 0000000..776d44b --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwRoutInspectPlanController.java @@ -0,0 +1,297 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.poi.EasyPoiExcelUtil; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectConfig; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectPlan; +import com.ruoyi.eastcom_yw.domain.dto.YwInspectPlanExportDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwInspectStatDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwInspectTaskDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSignLogDTO; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectConfigParam; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectPlanParam; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectStatParam; +import com.ruoyi.eastcom_yw.domain.vo.YwInspectLogVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneVo; +import com.ruoyi.eastcom_yw.service.YwRoutInspectConfigService; +import com.ruoyi.eastcom_yw.service.YwRoutInspectPlanService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.apache.commons.collections.MapUtils; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.rmi.ServerException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @author huamile + */ +@Api("巡检计划管理") +@RestController +@RequestMapping("/eastcom_yw/routInspectPlan") +@RequiredArgsConstructor +public class YwRoutInspectPlanController extends BaseController { + + private final YwRoutInspectPlanService ywRoutInspectPlanService; + private final YwRoutInspectConfigService ywRoutInspectConfigService; + + private final YwSceneService yw_sceneService; + + @ApiOperation("获取巡检计划列表") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwRoutInspectConfigParam param) { + param = (YwRoutInspectConfigParam) yw_sceneService.validateUserVenues(param,YwRoutInspectConfigParam.class,"venueIds"); + try { + List list = ywRoutInspectPlanService.getList(param); + return getDataTable(list); + } + catch(Exception ex) + { + throw new ServiceException("查询异常,请稍后再试"); + } + } + + @ApiOperation("获取巡检记录列表") + @PostMapping("/plan/list") + public TableDataInfo planList(@RequestBody YwRoutInspectPlanParam param) { + try { + param = (YwRoutInspectPlanParam) yw_sceneService.validateUserVenues(param, YwRoutInspectPlanParam.class, "venueIds"); + return ywRoutInspectPlanService.getPlanList(param); + } + catch(Exception ex) + { + throw new ServiceException("查询异常,请稍后再试"); + } + } + + @ApiOperation("根据条件获取巡检任务统计汇总") + @PostMapping("/stat") + public AjaxResult stat(@RequestBody YwRoutInspectStatParam param) { + param = (YwRoutInspectStatParam) yw_sceneService.validateUserVenues(param,YwRoutInspectStatParam.class,"venueIds"); + try { + Map data = ywRoutInspectPlanService.getStatData(param); + return AjaxResult.success(data); + } + catch(Exception ex) + { + return AjaxResult.error("查询异常,请稍后再试"); + } + } + + @ApiOperation("根据条件获取巡检任务统计列表") + @PostMapping("/stat/list") + public AjaxResult statList(@RequestBody YwRoutInspectStatParam param) { + param = (YwRoutInspectStatParam) yw_sceneService.validateUserVenues(param,YwRoutInspectStatParam.class,"venueIds"); + try { + Map map = ywRoutInspectPlanService.getStatListData(param); + return AjaxResult.success(map); + } + catch(Exception ex) + { + return AjaxResult.error("查询异常,请稍后再试"); + } + } + + @ApiOperation("根据条件获取巡检结果统计汇总") + @PostMapping("/resultStat") + public AjaxResult resultStat(@RequestBody YwRoutInspectStatParam param) { + param = (YwRoutInspectStatParam) yw_sceneService.validateUserVenues(param,YwRoutInspectStatParam.class,"venueIds"); + try { + Map data = ywRoutInspectPlanService.getResultStatData(param); + return AjaxResult.success(data); + } + catch(Exception ex) + { + return AjaxResult.error("查询异常,请稍后再试"); + } + } + + @ApiOperation("根据条件获取巡检结果统计列表") + @PostMapping("/resultStat/list") + public AjaxResult resultStatList(@RequestBody YwRoutInspectStatParam param) { + param = (YwRoutInspectStatParam) yw_sceneService.validateUserVenues(param,YwRoutInspectStatParam.class,"venueIds"); + try { + Map map = ywRoutInspectPlanService.getResultStatListData(param); + return AjaxResult.success(map); + } + catch(Exception ex) + { + return AjaxResult.error("查询异常,请稍后再试"); + } + } + + @ApiOperation("根据processId获取巡检详情") + @GetMapping("/info/{processId}") + public TableDataInfo info(@PathVariable String processId) { + try { + return getDataTable(ywRoutInspectPlanService.getRoutInspectInfoList(processId)); + } + catch(Exception ex) + { + throw new ServiceException("查询异常,请稍后再试"); + } + } + + @ApiOperation("查巡检配置参数") + @PostMapping("/inspectConfigList") + public TableDataInfo inspectConfigList(@RequestBody YwRoutInspectConfigParam param) { + try { + List list = ywRoutInspectConfigService.getInspectConfigList(param); + return getDataTable(list); + } + catch(Exception ex) + { + throw new ServiceException("查询异常,请稍后再试"); + } + } + + @Log(title = "巡检计划", businessType = BusinessType.INSERT) + @ApiOperation("新增巡检计划") + @PostMapping + public AjaxResult create(@RequestBody YwInspectTaskDTO dto) { + try { + return ywRoutInspectPlanService.create(dto); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("根据jobNo查询巡检记录状态") + @GetMapping("/checkIfEdit") + public AjaxResult checkIfEdit(@RequestParam(name = "jobNo") String jobNo) { + try { + if (ywRoutInspectPlanService.checkPlanStatus(jobNo)) { + return AjaxResult.error("任务处理中,无法修改。"); + } else { + return AjaxResult.success(); + } + } catch (Exception e) { + e.printStackTrace(); + return AjaxResult.error(e.getMessage()); + } + } + + @Log(title = "巡检计划", businessType = BusinessType.UPDATE) + @ApiOperation("编辑巡检计划") + @PutMapping + public AjaxResult update(@RequestBody YwInspectTaskDTO dto) { + try { + if (ywRoutInspectPlanService.checkPlanStatus(dto.getYwRoutInspectPlan().getJobNo())) { + return AjaxResult.error("巡检记录已生成,无法修改。"); + } + ywRoutInspectPlanService.updatePlan(dto); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @Log(title = "巡检计划", businessType = BusinessType.DELETE) + @ApiOperation("删除巡检计划") + @DeleteMapping("/{ids}") + public AjaxResult delete(@PathVariable String[] ids) { + try { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.in(YwRoutInspectPlan::getJobNo, ids); + ywRoutInspectPlanService.remove(wrapper); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("导出巡检任务列表") + @PostMapping("/export") + public void export(YwRoutInspectConfigParam param, HttpServletRequest request, HttpServletResponse response) { + param = (YwRoutInspectConfigParam) yw_sceneService.validateUserVenues(param,YwRoutInspectConfigParam.class,"venueIds"); + ywRoutInspectPlanService.export(param, request, response); + } + + @ApiOperation("导出巡检计划列表") + @PostMapping("/plan/export") + public void planExport(YwRoutInspectPlanParam param, HttpServletRequest request, HttpServletResponse response) { + param = (YwRoutInspectPlanParam) yw_sceneService.validateUserVenues(param,YwRoutInspectPlanParam.class,"venueIds"); + ywRoutInspectPlanService.planExport(param, request, response); + } + + @ApiOperation("根据条件获取巡检任务统计汇总") + @PostMapping("/stat/export") + public void statExport(YwRoutInspectStatParam param, HttpServletRequest request, HttpServletResponse response) { + + param = (YwRoutInspectStatParam) yw_sceneService.validateUserVenues(param,YwRoutInspectStatParam.class,"venueIds"); + + param.setPageNum(1); + param.setPageSize(Integer.MAX_VALUE); + param.setExport(true); + List list = new ArrayList<>(); + Map dataAll = ywRoutInspectPlanService.getStatData(param); + YwInspectStatDTO all = new YwInspectStatDTO(); + all.setVenueName("全部"); + all.setAllNum(MapUtils.getInteger(dataAll, "numOfAllPlan")); + all.setCompletedNum(MapUtils.getInteger(dataAll, "numOfCompletedPlan")); + all.setRate(MapUtils.getDouble(dataAll, "rate")); + + Map resultDataAll = ywRoutInspectPlanService.getResultStatData(param); + all.setResultAllNum(MapUtils.getInteger(resultDataAll, "numOfAllPlan")); + all.setResulNormalNum(MapUtils.getInteger(resultDataAll, "numOfNoQuPlan")); + all.setResulRate(MapUtils.getDouble(resultDataAll, "rate")); + + list.add(all); + + Map dataList = ywRoutInspectPlanService.getStatListData(param); + + Map resultDataList = ywRoutInspectPlanService.getResultStatListData(param); + + List listStat = (List) dataList.get("list"); + + List resultListStat = (List) resultDataList.get("list"); + + + if (!listStat.isEmpty()) { + for (YwInspectStatDTO ywInspectStatDTO : listStat) { + ywInspectStatDTO.setRate(ywInspectStatDTO.getRate() * 100); + } + if (resultListStat.isEmpty()) { + for (YwInspectStatDTO statDTO : listStat) { + list.add(statDTO); + } + } + + if (!resultListStat.isEmpty()) { + for (YwInspectStatDTO statDTO : listStat) { + for (YwInspectStatDTO resultStatDTO : resultListStat) { + if (statDTO.getVenueName().equals(resultStatDTO.getVenueName())) { + statDTO.setResultAllNum(resultStatDTO.getAllNum()); + statDTO.setResulRate(resultStatDTO.getRate() * 100); + statDTO.setResulNormalNum(resultStatDTO.getCompletedNum()); + } + } + list.add(statDTO); + } + } + } + + ExcelUtil util = new ExcelUtil<>(YwInspectStatDTO.class); + util.exportExcel(response, list, "巡检任务统计"); + +// EasyPoiExcelUtil.exportExcel("巡检统计", YwInspectStatDTO.class, list, request, response); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwRoutInspectQuestionConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwRoutInspectQuestionConfigController.java new file mode 100644 index 0000000..afdb397 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwRoutInspectQuestionConfigController.java @@ -0,0 +1,86 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectQuestionConfig; +import com.ruoyi.eastcom_yw.domain.param.YwInspectQuestionConfigParam; +import com.ruoyi.eastcom_yw.service.YwRoutInspectQuestionConfigService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.Arrays; +import java.util.List; + +/** + * @author huamile + */ +@Api("巡检问题类型管理") +@RestController +@RequestMapping("/eastcom_yw/routInspectQuestionConfig") +@RequiredArgsConstructor +public class YwRoutInspectQuestionConfigController extends BaseController { + + private final YwRoutInspectQuestionConfigService ywRoutInspectQuestionConfigService; + + @ApiOperation("获取巡检问题类型列表") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwInspectQuestionConfigParam param) { + List list = ywRoutInspectQuestionConfigService.getlist(param); + return getDataTable(list); + } + + @Log(title = "巡检问题类型", businessType = BusinessType.INSERT) + @ApiOperation("新增巡检问题类型") + @PostMapping + public AjaxResult create(@Valid @RequestBody YwRoutInspectQuestionConfig ywRoutInspectQuestionConfig) { + try { + ywRoutInspectQuestionConfigService.create(ywRoutInspectQuestionConfig); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @Log(title = "巡检问题类型", businessType = BusinessType.UPDATE) + @ApiOperation("编辑巡检问题类型") + @PutMapping + public AjaxResult update(@Valid @RequestBody YwRoutInspectQuestionConfig ywRoutInspectQuestionConfig) { + try { + ywRoutInspectQuestionConfigService.updateByPrimaryKeySelective(ywRoutInspectQuestionConfig); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @Log(title = "巡检问题类型", businessType = BusinessType.DELETE) + @ApiOperation("删除巡检问题类型") + @DeleteMapping("/{ids}") + public AjaxResult delete(@PathVariable Long[] ids) { + try { + ywRoutInspectQuestionConfigService.removeByIds(Arrays.asList(ids)); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @Log(title = "巡检问题类型", businessType = BusinessType.EXPORT) + @ApiOperation("导出巡检问题类型列表") + @PostMapping("/export") + public void export(YwInspectQuestionConfigParam param, HttpServletRequest request, HttpServletResponse response) { + ywRoutInspectQuestionConfigService.export(param, request, response); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneAlarmController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneAlarmController.java new file mode 100644 index 0000000..74198d0 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneAlarmController.java @@ -0,0 +1,80 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.eastcom_yw.domain.YwSceneAlarm; +import com.ruoyi.eastcom_yw.domain.param.YwSceneAlarmParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneAlarmVo; +import com.ruoyi.eastcom_yw.service.YwSceneAlarmService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; +import java.util.List; + +/** + * @author huamile + */ +@Api("场馆告警配置管理") +@RestController +@RequestMapping("/eastcom_yw/sceneAlarm") +@RequiredArgsConstructor +public class YwSceneAlarmController extends BaseController { + + private final YwSceneAlarmService ywSceneAlarmService; + + @ApiOperation("获取场馆告警配置列表") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwSceneAlarmParam param) { + List list = ywSceneAlarmService.getList(param); + return getDataTable(list); + } + + @ApiOperation("新增场馆告警配置") + @PostMapping + public AjaxResult create(@RequestBody YwSceneAlarm ywSceneAlarm) { + try { + ywSceneAlarmService.create(ywSceneAlarm); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("编辑场馆告警配置") + @PutMapping + public AjaxResult update(@RequestBody YwSceneAlarm ywSceneAlarm) { + try { + ywSceneAlarmService.updateByPrimaryKeySelective(ywSceneAlarm); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("删除场馆告警配置") + @DeleteMapping("/{ids}") + public AjaxResult delete(@PathVariable Long[] ids) { + try { + ywSceneAlarmService.removeByIds(Arrays.asList(ids)); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("导出场馆告警配置列表") + @PostMapping("/export") + public void export(YwSceneAlarmParam param, HttpServletRequest request, HttpServletResponse response) { + ywSceneAlarmService.export(param,request,response); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneCalendarController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneCalendarController.java new file mode 100644 index 0000000..2b75879 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneCalendarController.java @@ -0,0 +1,93 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneCalendarDTO; +import com.ruoyi.eastcom_yw.domain.param.YwSceneCalendarParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneCalendar2Vo; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneCalendarVo; +import com.ruoyi.eastcom_yw.service.YwSceneCalendarService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; +import java.util.List; + +/** + * @author huamile + */ +@Api("场馆赛事配置管理") +@RestController +@RequestMapping("/eastcom_yw/sceneCalendar") +@RequiredArgsConstructor +public class YwSceneCalendarController extends BaseController { + + private final YwSceneCalendarService ywSceneCalendarService; + + @ApiOperation("获取场馆赛事配置列表") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwSceneCalendarParam param) { + List list = ywSceneCalendarService.getList(param); + return getDataTable(list); + } + + @ApiOperation("新增场馆赛事配置") + @PostMapping + public AjaxResult create(@RequestBody YwSceneCalendarDTO dto) { + try { + ywSceneCalendarService.create(dto); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("编辑场馆赛事配置") + @PutMapping + public AjaxResult update(@RequestBody YwSceneCalendarDTO dto) { + try { + ywSceneCalendarService.updateByPrimaryKeySelective(dto); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("删除场馆赛事配置") + @DeleteMapping("/{ids}") + public AjaxResult delete(@PathVariable Long[] ids) { + try { + ywSceneCalendarService.removeByIds(Arrays.asList(ids)); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @RequestMapping(method = RequestMethod.POST, path = "/import") + @ApiOperation("导入赛事配置") + public AjaxResult importSceneCalendar(@RequestPart("file") MultipartFile file, @RequestParam("sceneBigId") Long sceneBigId, @RequestParam("importType") String importType) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwSceneCalendar2Vo.class); + + List vos = util.importExcel(file.getInputStream()); + return ywSceneCalendarService.importSceneCalendar(vos, sceneBigId, importType); + + } + + @ApiOperation("导出场馆赛事配置列表") + @PostMapping("/export") + public void export(YwSceneCalendarParam param, HttpServletRequest request, HttpServletResponse response) { + ywSceneCalendarService.export(param, request, response); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneController.java new file mode 100644 index 0000000..839cc9e --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneController.java @@ -0,0 +1,254 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import cn.hutool.core.collection.ListUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ArrayUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.cmcc_gm.domain.YwMaterialsStock; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSearchDTO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsVo; +import com.ruoyi.cmcc_gm.service.YwMaterialsStockService; +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwWireTaskLog; +import com.ruoyi.eastcom_yw.domain.dto.YwDataDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSignLogDTO; +import com.ruoyi.eastcom_yw.domain.param.YwSceneParam; +import com.ruoyi.eastcom_yw.domain.vo.SceneBaseStation; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementAgis; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneVo; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.eastcom_yw.service.YwWireTaskLogService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author jkj + * @since 2023-01-12 + */ +@Api("场馆信息管理") +@RestController +@RequestMapping("/eastcom_yw/venue") +public class YwSceneController extends BaseController { + + @Autowired + private YwSceneService yw_sceneService; + + @Autowired + private YwMaterialsStockService ywMaterialsStockService; + + @Autowired + private YwWireTaskLogService ywWireTaskLogService; + + @ApiOperation("获取场馆数据") + @GetMapping("/list/redis") + public AjaxResult listAll() throws Exception { + return AjaxResult.success(yw_sceneService.selectVenues()); + } + + @ApiOperation("获取当前登录用户关联的场馆数据") + @GetMapping("/list/all") + public TableDataInfo listAll(Long sceneBigId) throws Exception { + if (ObjectUtils.isEmpty(sceneBigId)) { + throw new Exception("场景号不能为空"); + } + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(YwScene::getSceneBigId, sceneBigId); + return getDataTable(yw_sceneService.list(queryWrapper)); + } + + @ApiOperation("获取当前登录用户关联的场馆数据") + @GetMapping("/list") + @RepeatSubmit(enable = false, interval = 1000) + public TableDataInfo list(Long sceneBigId) throws Exception { + SysUser user = getLoginUser().getUser(); + if (ObjectUtils.isNotEmpty(user)) { + List list = yw_sceneService.getVenueByUser(user, sceneBigId); + return getDataTable(list); + } else { + throw new Exception("获取当前用户失败"); + } + } + + @ApiOperation("根据场馆和角色获取相关的用户") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwDataDTO ywDataDTO) { + List list = yw_sceneService.getSysUserByVenueAndOther(ywDataDTO); + return getDataTable(list); + } + + @ApiOperation("根据场馆ID获取场馆") + @GetMapping(value = {"/", "/{venueId}"}) + public TableDataInfo listByVenue(@PathVariable(value = "venueId", required = false) Long venueId) { + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.eq(YwScene::getId, venueId); + List list = yw_sceneService.list(lambdaQueryWrapper); + + return getDataTable(list); + } + + @ApiOperation("获取场馆信息列表") + @PostMapping("/msgList") + public TableDataInfo msgList(@RequestBody YwSceneParam param) { + param = (YwSceneParam) yw_sceneService.validateUserVenues(param,YwSceneParam.class,"venueIds"); + List list = yw_sceneService.msgList(param); + return getDataTable(list); + } + + @ApiOperation("新增场馆") + @PostMapping + public AjaxResult create(@RequestBody YwSceneDTO dto) { + try { + yw_sceneService.create(dto); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("编辑场馆信息") + @PutMapping + public AjaxResult update(@RequestBody YwSceneDTO dto) { + try { + yw_sceneService.updateByPrimaryKeySelective(dto); + + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("删除场馆") + @DeleteMapping("/{ids}") + @Transactional + public AjaxResult delete(@PathVariable Long[] ids) { + try { + + //是否存在布线 + LambdaQueryWrapper queryWire = new LambdaQueryWrapper<>(); + queryWire.in(YwWireTaskLog::getVenueId,ids); + List lstWire = ywWireTaskLogService.list(queryWire); + if (lstWire.size() > 0) { + return AjaxResult.error("场馆已存在布线数据,无法删除"); + } + //20230515 + //判断场馆是否存在物资,有物资则不让删除 + YwMaterialsSearchDTO dto = new YwMaterialsSearchDTO(); + dto.setStoreIds(ids); + List list = ywMaterialsStockService.getMaterialsStock(dto); + if (list.size() > 0) { + for(YwMaterialsVo stock : list) + { + if(stock.getAvailSum()!=null) + { + if(stock.getAvailSum()>0) { + return AjaxResult.error("场馆已存在物资数据,无法删除"); + } + } + + if(stock.getInWaySum()!=null) + { + if(stock.getInWaySum()>0) { + return AjaxResult.error("场馆已存在物资数据,无法删除"); + } + } + + if(stock.getOutWaySum()!=null) + { + if(stock.getOutWaySum()>0) { + return AjaxResult.error("场馆已存在物资数据,无法删除"); + } + } + } + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.in(YwMaterialsStock::getMaterialStoreId,ids); + ywMaterialsStockService.remove(query); + } + yw_sceneService.delByIds(Arrays.asList(ids)); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("导出场馆信息列表") + @PostMapping("/export") + public void export(YwSceneParam param, HttpServletRequest request, HttpServletResponse response) { + param = (YwSceneParam) yw_sceneService.validateUserVenues(param,YwSceneParam.class,"venueIds"); + yw_sceneService.exportReal(param, request, response); + } + + @ApiOperation("导出场馆信息列表,可供导入") + @PostMapping("/exportReal") + public void exportReal(YwSceneParam param, HttpServletRequest request, HttpServletResponse response) { + param = (YwSceneParam) yw_sceneService.validateUserVenues(param,YwSceneParam.class,"venueIds"); + yw_sceneService.exportReal(param, request, response); + } + + @ApiOperation("导出场景相关配置") + @PostMapping("/export/{sceneBigId}") + public void bigSceneExport(@PathVariable Long sceneBigId, HttpServletRequest request, HttpServletResponse response) { + yw_sceneService.bigSceneExport(sceneBigId, request, response); + } + + @ApiOperation("导出场景相关配置新增模板") + @PostMapping("/export/template") + public void exportTemplate(HttpServletRequest request, HttpServletResponse response) { + yw_sceneService.exportTemplate(request, response); + } + + @ApiOperation("导入场景相关配置") + @PostMapping("/import") + public void importSceneBigConfig(@RequestPart("file") MultipartFile file) throws Exception { + yw_sceneService.importSceneBigConfig(file); + } + + @ApiOperation("场馆导入") + @PostMapping("/importScene") + public AjaxResult importYWScene(@RequestPart("file") MultipartFile file, @RequestParam Long sceneBigId, @RequestParam String importType) throws Exception { + + // 解析上传的文件 + ExcelUtil util = new ExcelUtil<>(YwSceneDTO.class); + List sceneList = util.importExcel(file.getInputStream()); + + return yw_sceneService.importYWScene(sceneList, sceneBigId, importType); + + } + + @ApiOperation("导入场馆静态数据") + @PostMapping("/importStationByScene") + public AjaxResult importStationByScene(@RequestPart("file") MultipartFile file, + @RequestParam(name = "sceneBigId") Long sceneBigId, + @RequestParam(name = "sceneId") Long sceneId) throws Exception { + try { + yw_sceneService.importStationByScene(file, sceneBigId, sceneId); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + + } + +} + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneMatchController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneMatchController.java new file mode 100644 index 0000000..d9da8a0 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneMatchController.java @@ -0,0 +1,40 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.param.YwSceneMatchParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneMatchVo; +import com.ruoyi.eastcom_yw.service.YwSceneMatchService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@Api("赛程") +@RestController +@RequiredArgsConstructor +@RequestMapping("/eastcom_yw/sceneMatch") +public class YwSceneMatchController extends BaseController { + + private final YwSceneMatchService ywSceneMatchService; + + @PostMapping("/import") + @ApiOperation("导入") + public AjaxResult importMatch(@RequestPart("file") MultipartFile file, Long sceneBigId, String importType) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwSceneMatchVo.class); + List vos = util.importExcel(file.getInputStream()); + return ywSceneMatchService.importMatch(vos, sceneBigId, importType); + } + + @ApiOperation("查询") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwSceneMatchParam param) { + return getDataTable(ywSceneMatchService.list(param)); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementAgisController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementAgisController.java new file mode 100644 index 0000000..beacbad --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementAgisController.java @@ -0,0 +1,93 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementAgisParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementAgis; +import com.ruoyi.eastcom_yw.service.YwSceneNetelementAgisService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author los + */ +@Api(tags = "网元-AGIS") +@RestController +@RequestMapping("/eastcom_yw/sceneNetelementAgis") +@RequiredArgsConstructor +public class YwSceneNetelementAgisController extends BaseController { + + private final YwSceneNetelementAgisService ywSceneNetelementAgisService; + + private final YwSceneService ywSceneService; + + @ApiOperation("查询") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwSceneNetelementAgisParam para) { + List list = ywSceneNetelementAgisService.list(para); + + return getDataTable(list); + } + + @ApiOperation("导出") + @PostMapping("/export") + public void export(YwSceneNetelementAgisParam para, HttpServletResponse response) { + + para.setPageNum(1); + para.setPageSize(Integer.MAX_VALUE); + + List list = ywSceneNetelementAgisService.list(para); + + ExcelUtil util = new ExcelUtil<>(YwSceneNetelementAgis.class); + util.hideColumn("reason"); + util.exportExcel(response, list, "专网网元导出"); + } + + @Log(title = "导入agis的网元清单", businessType = BusinessType.INSERT) + @ApiOperation("导入") + @PostMapping("/importAgis") + public AjaxResult importAgis(@RequestPart("file") MultipartFile file, + @RequestParam(name = "sceneBigId") Long sceneBigId, + @RequestParam(name = "opType", defaultValue = "2") String opType, + @RequestParam(name = "sceneId", required = false) Long sceneId) throws Exception { + + String sceneName = null; + + if ("1".equals(opType) && ObjectUtils.isEmpty(sceneId)) { + throw new ServiceException("单场馆导入,场馆ID不能为空"); + } + + if (ObjectUtils.isNotEmpty(sceneId)) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(YwScene::getSceneBigId, sceneBigId).eq(YwScene::getId, sceneId); + YwScene one = ywSceneService.getOne(queryWrapper, false); + if (ObjectUtils.isEmpty(one)) { + throw new ServiceException("该场景下不存在该场馆"); + } else { + sceneName = one.getVenueName(); + } + } + + ExcelUtil util = new ExcelUtil<>(YwSceneNetelementAgis.class); + List cs = util.importExcel(file.getInputStream()); + + return ywSceneNetelementAgisService.importAgis(cs, sceneBigId, opType, sceneName); + + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementController.java new file mode 100644 index 0000000..b35056f --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementController.java @@ -0,0 +1,84 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.eastcom_yw.domain.YwSceneNetelement; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementParam; +import com.ruoyi.eastcom_yw.service.YwSceneNetelementService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; +import java.util.List; + +/** + * @author huamile + */ +@Api("场馆网元配置管理") +@RestController +@RequestMapping("/eastcom_yw/sceneNetelement") +@RequiredArgsConstructor +public class YwSceneNetelementController extends BaseController { + + private final YwSceneNetelementService ywSceneNetelementService; + + @ApiOperation("获取场馆网元配置列表") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwSceneNetelementParam param) { + List list = ywSceneNetelementService.getList(param); + return getDataTable(list); + } + + @Log(title = "新增场馆网元配置", businessType = BusinessType.INSERT) + @ApiOperation("新增场馆网元配置") + @PostMapping + public AjaxResult create(@RequestBody YwSceneNetelement ywSceneNetelement) { + try { + ywSceneNetelementService.create(ywSceneNetelement); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @Log(title = "编辑场馆网元配置", businessType = BusinessType.UPDATE) + @ApiOperation("编辑场馆网元配置") + @PutMapping + public AjaxResult update(@RequestBody YwSceneNetelement ywSceneNetelement) { + try { + ywSceneNetelementService.updateByPrimaryKeySelective(ywSceneNetelement); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @Log(title = "删除场馆网元配置", businessType = BusinessType.DELETE) + @ApiOperation("删除场馆网元配置") + @DeleteMapping("/{ids}") + public AjaxResult delete(@PathVariable Long[] ids) { + try { + ywSceneNetelementService.removeByIds(Arrays.asList(ids)); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("导出场馆网元配置列表") + @PostMapping("/export") + public void export(YwSceneNetelementParam param, HttpServletRequest request, HttpServletResponse response) { + ywSceneNetelementService.export(param,request,response); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementCsController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementCsController.java new file mode 100644 index 0000000..8597442 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementCsController.java @@ -0,0 +1,88 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementCsParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementCs; +import com.ruoyi.eastcom_yw.service.YwSceneNetelementCsService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +@Api(tags = "亚运-传输SPN-OYN-PTN") +@RestController +@RequestMapping("/eastcom_yw/sceneNetelementCs") +@RequiredArgsConstructor +public class YwSceneNetelementCsController extends BaseController { + + private final YwSceneNetelementCsService ywSceneNetelementCsService; + + private final YwSceneService ywSceneService; + + @ApiOperation("查询") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwSceneNetelementCsParam param) { + List list = ywSceneNetelementCsService.list(param); + return getDataTable(list); + } + + @ApiOperation("导出") + @PostMapping("/export") + public void export(YwSceneNetelementCsParam para, HttpServletResponse response) { + + para.setPageNum(1); + para.setPageSize(Integer.MAX_VALUE); + List list = ywSceneNetelementCsService.list(para); + + ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); + util.hideColumn("reason"); + util.exportExcel(response, list, "传输网元导出"); + } + + @Log(title = "导入传输的网元清单", businessType = BusinessType.INSERT) + @ApiOperation("导入") + @PostMapping("/importCS") + public AjaxResult importCs(@RequestPart("file") MultipartFile file, + @RequestParam(name = "sceneBigId") Long sceneBigId, + @RequestParam(name = "opType", defaultValue = "2") String opType, + @RequestParam(name = "sceneId", required = false) Long sceneId) throws Exception { + + String sceneName = null; + + if ("1".equals(opType) && ObjectUtils.isEmpty(sceneId)) { + throw new ServiceException("单场馆导入,场馆ID不能为空"); + } + + if (ObjectUtils.isNotEmpty(sceneId)) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(YwScene::getSceneBigId, sceneBigId).eq(YwScene::getId, sceneId); + YwScene one = ywSceneService.getOne(queryWrapper, false); + if (ObjectUtils.isEmpty(one)) { + throw new ServiceException("该场景下不存在该场馆"); + } else { + sceneName = one.getVenueName(); + } + } + + ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); + List cs = util.importExcel(file.getInputStream()); + + return ywSceneNetelementCsService.importCs(cs, sceneBigId, opType, sceneName); + + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementDhController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementDhController.java new file mode 100644 index 0000000..496bb72 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementDhController.java @@ -0,0 +1,89 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementDhParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementDh; +import com.ruoyi.eastcom_yw.service.YwSceneNetelementDhService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +@Api(tags = "网元-动环") +@RestController +@RequestMapping("/eastcom_yw/sceneNetelementDh") +@RequiredArgsConstructor +public class YwSceneNetelementDhController extends BaseController { + + private final YwSceneNetelementDhService ywSceneNetelementDhService; + + private final YwSceneService ywSceneService; + + @ApiOperation("查询") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwSceneNetelementDhParam para) { + List list = ywSceneNetelementDhService.list(para); + + return getDataTable(list); + } + + @ApiOperation("导出") + @PostMapping("/export") + public void export(YwSceneNetelementDhParam para, HttpServletResponse response) { + + para.setPageNum(1); + para.setPageSize(Integer.MAX_VALUE); + List list = ywSceneNetelementDhService.list(para); + + ExcelUtil util = new ExcelUtil<>(YwSceneNetelementDh.class); + util.hideColumn("reason"); + util.exportExcel(response, list, "动环网元导出"); + } + + @Log(title = "导入动环的网元清单", businessType = BusinessType.INSERT) + @ApiOperation("导入") + @PostMapping("/importDh") + public AjaxResult importDh(@RequestPart("file") MultipartFile file, + @RequestParam(name = "sceneBigId") Long sceneBigId, + @RequestParam(name = "opType", defaultValue = "2") String opType, + @RequestParam(name = "sceneId", required = false) Long sceneId) throws Exception { + + String sceneName = null; + + if ("1".equals(opType) && ObjectUtils.isEmpty(sceneId)) { + throw new ServiceException("单场馆导入,场馆ID不能为空"); + } + + if (ObjectUtils.isNotEmpty(sceneId)) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(YwScene::getSceneBigId, sceneBigId).eq(YwScene::getId, sceneId); + YwScene one = ywSceneService.getOne(queryWrapper, false); + if (ObjectUtils.isEmpty(one)) { + throw new ServiceException("该场景下不存在该场馆"); + } else { + sceneName = one.getVenueName(); + } + } + + ExcelUtil util = new ExcelUtil<>(YwSceneNetelementDh.class); + List cs = util.importExcel(file.getInputStream()); + + return ywSceneNetelementDhService.importDh(cs, sceneBigId, opType, sceneName); + + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementWxController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementWxController.java new file mode 100644 index 0000000..c074634 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNetelementWxController.java @@ -0,0 +1,140 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.annotation.Anonymous; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.param.YwSceneNetelementWxParam; +import com.ruoyi.eastcom_yw.domain.vo.WholeAreaAssureCellSheet; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNetelementWx; +import com.ruoyi.eastcom_yw.service.YwSceneNetelementWxService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.List; + +@Api(tags = "网元-无线") +@RestController +@RequestMapping("/eastcom_yw/sceneNetelementWx") +@RequiredArgsConstructor +public class YwSceneNetelementWxController extends BaseController { + + private final YwSceneNetelementWxService ywSceneNetelementWxService; + + private final YwSceneService ywSceneService; + + @ApiOperation("查询") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwSceneNetelementWxParam para) { + List list = ywSceneNetelementWxService.list(para); + + return getDataTable(list); + } + + @ApiOperation("查询") + @PostMapping("/list2") + @Anonymous + public TableDataInfo list2(@RequestBody YwSceneNetelementWxParam para) { + if (para.getPageNum() == null || para.getPageSize() == null) { + para.setPageNum(1); + para.setPageSize(Integer.MAX_VALUE); + } + List list = ywSceneNetelementWxService.list2(para); + return getDataTable(list); + } + + @ApiOperation("导出") + @PostMapping("/export") + public void export(YwSceneNetelementWxParam para, HttpServletResponse response) { + + para.setPageNum(1); + para.setPageSize(Integer.MAX_VALUE); + List list = ywSceneNetelementWxService.list(para); + + ExcelUtil util = new ExcelUtil<>(YwSceneNetelementWx.class); + util.hideColumn("reason"); + util.exportExcel(response, list, "无线网元导出"); + } + + @Log(title = "导入无线的网元清单", businessType = BusinessType.INSERT) + @ApiOperation("导入") + @PostMapping("/importWx") + public AjaxResult importWx(@RequestPart("file") MultipartFile file, + @RequestParam(name = "sceneBigId") Long sceneBigId, + @RequestParam(name = "opType", defaultValue = "2") String opType, + @RequestParam(name = "sceneId", required = false) Long sceneId) throws Exception { + + String sceneName = null; + + if ("1".equals(opType) && ObjectUtils.isEmpty(sceneId)) { + throw new ServiceException("单场馆导入,场馆ID不能为空"); + } + + if (ObjectUtils.isNotEmpty(sceneId)) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(YwScene::getSceneBigId, sceneBigId).eq(YwScene::getId, sceneId); + YwScene one = ywSceneService.getOne(queryWrapper, false); + if (ObjectUtils.isEmpty(one)) { + throw new ServiceException("该场景下不存在该场馆"); + } else { + sceneName = one.getVenueName(); + } + } + + ExcelUtil util = new ExcelUtil<>(YwSceneNetelementWx.class); + List cs = util.importExcel(file.getInputStream()); + + return ywSceneNetelementWxService.importWx(cs, sceneBigId, opType, sceneName); + + } + + + @ApiOperation("查询小区") + @GetMapping("/listCell") + public TableDataInfo listCell(Long sceneId) { + YwSceneNetelementWxParam param = new YwSceneNetelementWxParam(); + if (null != sceneId) { + param.setSceneId(sceneId); + } else { + SysUser user = SecurityUtils.getLoginUser().getUser(); + //场馆集合 + if (!user.isAdmin(user)) { + List ywScenes = ywSceneService.getVenueByUser(user); + Long[] venueIds = ywScenes.stream().map(YwScene::getId).toArray(Long[]::new); + param.setSceneIds(venueIds); + } + } + + List list = ywSceneNetelementWxService.listCell(param); + return getDataTable(list); + } + + @ApiOperation("查询坐席") + @GetMapping("/listSeat") + public TableDataInfo listSeat(Long sceneId) { + if (null == sceneId) { + throw new ServiceException("请先选择场馆id!"); + } + List list = ywSceneNetelementWxService.listSeat(sceneId); + return getDataTable(list); + } + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNoticeinfoController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNoticeinfoController.java new file mode 100644 index 0000000..50b13d7 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneNoticeinfoController.java @@ -0,0 +1,190 @@ +package com.ruoyi.web.controller.eastcom_yw; + + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneNoticeinfoSearchDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneNoticeinfo; +import com.ruoyi.eastcom_yw.service.YwSceneNoticeinfoService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * (YwSceneNoticeinfo)表控制层 + * + * @author lee + * @since 2023-05-23 10:10:05 + */ +@RestController +@RequestMapping("/eastcom_yw/ywSceneNoticeinfo") +public class YwSceneNoticeinfoController extends BaseController { + + /** + * 服务对象 + */ + @Resource + private YwSceneNoticeinfoService ywSceneNoticeinfoService; + + @Resource + private YwSceneService ywSceneService; + + /** + * 分页查询所有数据 + * + * @param ywSceneNoticeinfo 查询实体 + * @return 所有数据 + */ + @PostMapping("/list") + public TableDataInfo selectAll(@RequestBody YwSceneNoticeinfoSearchDTO ywSceneNoticeinfo) { + SysUser user = SecurityUtils.getLoginUser().getUser(); + if (!user.isAdmin(user)) { + ywSceneNoticeinfo.setUserId(user.getUserId()); + } + PageUtils.startPage(ywSceneNoticeinfo, YwSceneNoticeinfoSearchDTO.class); + return getDataTable(ywSceneNoticeinfoService.getNoticeinfoBySearch(ywSceneNoticeinfo)); + } + + /** + * 重置总和 + */ + @GetMapping("/reset") + public AjaxResult reset() { + ywSceneNoticeinfoService.reset(false); + return AjaxResult.success(); + } + + /** + * 重新统计实际网元数后保存,并重置总和 + */ + @GetMapping("/statisticsNetNum") + public AjaxResult statisticsNetNum() { + ywSceneNoticeinfoService.statisticsNetNum(); + return AjaxResult.success(); + } + + /** + * 按条件导出数据 + * + * @param ywSceneNoticeinfo 查询实体 + */ + @PostMapping("/export") + public void export(YwSceneNoticeinfoSearchDTO ywSceneNoticeinfo, HttpServletResponse response) { + ywSceneNoticeinfo.setPageNum(1); + ywSceneNoticeinfo.setPageSize(Integer.MAX_VALUE); + SysUser user = SecurityUtils.getLoginUser().getUser(); + if (!user.isAdmin(user)) { + ywSceneNoticeinfo.setUserId(user.getUserId()); + } + List noticeinfoBySearch = ywSceneNoticeinfoService.getNoticeinfoBySearch(ywSceneNoticeinfo); + for (YwSceneNoticeinfo bySearch : noticeinfoBySearch) { + bySearch.setFrontuserStr(!"null".equalsIgnoreCase(String.valueOf(bySearch.getFrontuser())) ? String.valueOf(bySearch.getFrontuser()) : ""); + bySearch.setBackuserStr(!"null".equalsIgnoreCase(String.valueOf(bySearch.getBackuser())) ? String.valueOf(bySearch.getBackuser()) : ""); + bySearch.setEmergencycarStr(!"null".equalsIgnoreCase(String.valueOf(bySearch.getEmergencycar())) ? String.valueOf(bySearch.getEmergencycar()) : ""); + bySearch.setEmergencyWarehouseStr(!"null".equalsIgnoreCase(String.valueOf(bySearch.getEmergencyWarehouse())) ? String.valueOf(bySearch.getEmergencyWarehouse()) : ""); + bySearch.setAgisNetNumStr(!"null".equalsIgnoreCase(String.valueOf(bySearch.getAgisNetNum())) ? String.valueOf(bySearch.getAgisNetNum()) : ""); + bySearch.setWxNetNumStr(!"null".equalsIgnoreCase(String.valueOf(bySearch.getWxNetNum())) ? String.valueOf(bySearch.getWxNetNum()) : ""); + bySearch.setDhNetNumStr(!"null".equalsIgnoreCase(String.valueOf(bySearch.getDhNetNum())) ? String.valueOf(bySearch.getDhNetNum()) : ""); + bySearch.setAgisNumStr(!"null".equalsIgnoreCase(String.valueOf(bySearch.getAgisNum())) ? String.valueOf(bySearch.getAgisNum()) : ""); + bySearch.setWifiNetNumStr(!"null".equalsIgnoreCase(String.valueOf(bySearch.getWifiNetNum())) ? String.valueOf(bySearch.getWifiNetNum()) : ""); + bySearch.setVoipNetNumStr(!"null".equalsIgnoreCase(String.valueOf(bySearch.getVoipNetNum())) ? String.valueOf(bySearch.getVoipNetNum()) : ""); + bySearch.setInternetNetNumStr(!"null".equalsIgnoreCase(String.valueOf(bySearch.getInternetNetNum())) ? String.valueOf(bySearch.getInternetNetNum()) : ""); + bySearch.setPublicTransportEquipNumStr(!"null".equalsIgnoreCase(String.valueOf(bySearch.getPublicTransportEquipNum())) ? String.valueOf(bySearch.getPublicTransportEquipNum()) : ""); + bySearch.setPublicInterfaceRingNumStr(!"null".equalsIgnoreCase(String.valueOf(bySearch.getPublicInterfaceRingNum())) ? String.valueOf(bySearch.getPublicInterfaceRingNum()) : ""); + bySearch.setPrivateTransportEquipNumStr(!"null".equalsIgnoreCase(String.valueOf(bySearch.getPrivateTransportEquipNum())) ? String.valueOf(bySearch.getPrivateTransportEquipNum()) : ""); + bySearch.setPrivateInterfaceRingNumStr(!"null".equalsIgnoreCase(String.valueOf(bySearch.getPrivateInterfaceRingNum())) ? String.valueOf(bySearch.getPrivateInterfaceRingNum()) : ""); + bySearch.setSupportcarStr(StringUtils.nonNullString(bySearch.getSupportcar())); + bySearch.setDictEquipNumStr(StringUtils.nonNullString(bySearch.getDictEquipNum())); + bySearch.setEmergencyCommunicationCarStr(StringUtils.nonNullString(bySearch.getEmergencyCommunicationCar())); + bySearch.setEmergencyElectricCarStr(StringUtils.nonNullString(bySearch.getEmergencyElectricCar())); + bySearch.setEmergencyRepairCarStr(StringUtils.nonNullString(bySearch.getEmergencyRepairCar())); + bySearch.setWifiSpareStr(StringUtils.nonNullString(bySearch.getWifiSpare())); + bySearch.setDredgeSpareStr(StringUtils.nonNullString(bySearch.getDredgeSpare())); + bySearch.setTransSpareStr(StringUtils.nonNullString(bySearch.getTransSpare())); + bySearch.setPublicPowerEquipStr(StringUtils.nonNullString(bySearch.getPublicPowerEquip())); + bySearch.setPrivatePowerEquipStr(StringUtils.nonNullString(bySearch.getPrivatePowerEquip())); + } + ExcelUtil util = new ExcelUtil<>(YwSceneNoticeinfo.class); + util.hideColumn("reason"); + util.exportExcel(response, noticeinfoBySearch, "数据"); + } + + /** + * 新增数据 + * + * @param ywSceneNoticeinfo 实体对象 + * @return 新增结果 + */ + @PostMapping + public AjaxResult insert(@RequestBody YwSceneNoticeinfo ywSceneNoticeinfo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(YwScene::getVenueName, ywSceneNoticeinfo.getSceneName()).eq(YwScene::getSceneBigId, 1); + YwScene one = ywSceneService.getOne(queryWrapper, false); + if (ObjectUtils.isEmpty(one)) { + throw new ServiceException("场馆不存在。"); + } else { + ywSceneNoticeinfo.setSceneId(one.getId()); + } + + YwSceneNoticeinfoSearchDTO ywSceneNoticeinfoSearchDTO = new YwSceneNoticeinfoSearchDTO(); + ywSceneNoticeinfoSearchDTO.setSceneName(ywSceneNoticeinfo.getSceneName()); + List noticeinfoBySearch = ywSceneNoticeinfoService.getNoticeinfoBySearch(ywSceneNoticeinfoSearchDTO); + if (CollectionUtils.isNotEmpty(noticeinfoBySearch)) { + throw new ServiceException("场馆重复。"); + } + + return AjaxResult.success(this.ywSceneNoticeinfoService.save(ywSceneNoticeinfo)); + } + + /** + * 修改数据 + * + * @param ywSceneNoticeinfo 实体对象 + * @return 修改结果 + */ + @PutMapping + public AjaxResult update(@RequestBody YwSceneNoticeinfo ywSceneNoticeinfo) { + return AjaxResult.success(this.ywSceneNoticeinfoService.updateById(ywSceneNoticeinfo)); + } + + /** + * 删除数据 + * + * @param idList 主键结合 + * @return 删除结果 + */ + @DeleteMapping + public AjaxResult delete(@RequestParam("idList") List idList) { + return AjaxResult.success(this.ywSceneNoticeinfoService.removeByIds(idList)); + } + + /** + * 批量导入 + * + * @param file 文件 + * @return 导入结果 + */ + @PostMapping("/import") + public AjaxResult batchImport(@RequestPart(name = "file") MultipartFile file, @RequestParam(name = "importType") String importType) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwSceneNoticeinfo.class); + List ywSceneNoticeinfos = util.importExcel(file.getInputStream()); + return ywSceneNoticeinfoService.batchImport(ywSceneNoticeinfos, importType); + } + +} + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwScenePictureController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwScenePictureController.java new file mode 100644 index 0000000..e876620 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwScenePictureController.java @@ -0,0 +1,118 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.service.YwScenePictureService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author los + */ +@Api(tags = "场馆画像") +@RestController +@RequestMapping("/eastcom_yw/scenePicture") +@RequiredArgsConstructor +public class YwScenePictureController extends BaseController { + + private final YwScenePictureService service; + + /** + * 任务管理统计 + * + * @param id 场馆id + * @return 返回数据 + */ + @ApiOperation(value = "任务管理统计", notes = "任务管理统计") + @PostMapping("/listTaskManage") + public AjaxResult listTaskManage(@RequestParam("sceneId") Long id) { + return AjaxResult.success(service.listTaskManage2(id,false)); + } + + /** + * 人员签到统计 + * + * @param id 场馆id + * @return 返回数据 + */ + @ApiOperation(value = "人员签到统计", tags = "人员签到统计") + @PostMapping("/listSign") + public AjaxResult listSign(@RequestParam("sceneId") Long id) { + return AjaxResult.success(service.listSign(id)); + } + + /** + * 场馆基本信息 + * + * @param id 场馆id + * @return 返回数据 + */ + @ApiOperation(value = "场馆基本信息", tags = "场馆基本信息") + @PostMapping("/baseInfo") + public AjaxResult listMatchTop3(@RequestParam("sceneId") Long id) { + return AjaxResult.success(service.listMatchTop3(id)); + } + + /** + * 场馆告警 + * + * @param id 场馆id + * @return 返回数据 + */ + @ApiOperation(value = "场馆告警", tags = "场馆告警") + @PostMapping("/alarm") + public AjaxResult listAlarm(@RequestParam("sceneId") Long id) { + return AjaxResult.success(service.listAlarm(id)); + } + + /** + * 场馆Kpi指标 + * + * @param id 场馆id + * @param typeId 网络类型 1 --> 4g 2 --> 5g + * @return 数据 + */ + @ApiOperation(value = "场馆性能(15分粒度)", tags = "场馆性能(15分粒度)") + @PostMapping("/kpi") + public AjaxResult listKPI(@RequestParam("sceneId") Long id, @RequestParam("typeId") String typeId) { + return AjaxResult.success(service.listKPI(id, typeId)); + } + + @ApiOperation(value = "场馆性能(15分粒度)", tags = "场馆性能(15分粒度)") + @PostMapping("/kpi2") + public AjaxResult listKPIALL(@RequestParam("sceneId") Long id) { + return AjaxResult.success(service.listKPIALL(id)); + } + + + /** + * + * @param id 场馆id + * @param type 1-AGIS 2-互联网 3-固话 + * @return + */ + @ApiOperation(value = "场馆性能-专网", tags = "场馆性能-专网") + @PostMapping("/listNetKpi") + public AjaxResult listNetKpi(@RequestParam("sceneId") Long id,@RequestParam("type") Integer type) { + return service.listNetKpi(id,type); + } + + + /** + * + * @param id 场馆id + * @param type 1-环路浏量 2-光功率 + * @return + */ + @ApiOperation(value = "场馆性能-传输", tags = "场馆性能-传输") + @PostMapping("/listTransKpi") + public AjaxResult listTransKpi(@RequestParam("sceneId") Long id,@RequestParam("type") Integer type) { + return service.listTransKpi(id,type); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneTestDataController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneTestDataController.java new file mode 100644 index 0000000..000b3c1 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneTestDataController.java @@ -0,0 +1,40 @@ +package com.ruoyi.web.controller.eastcom_yw; + + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.service.YwSceneTestDataService; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * (YwSceneTestData)表控制层 + * + * @author lee + * @since 2023-04-26 18:41:32 + */ +@RestController +@RequestMapping("/eastcom_yw/daping") +public class YwSceneTestDataController extends BaseController { + + /** + * 服务对象 + */ + @Resource + private YwSceneTestDataService ywSceneTestDataService; + + /** + * 分页查询所有数据 + * + * @return 所有数据 + */ + @GetMapping("/get_test_data") + public AjaxResult selectAll() { + return AjaxResult.success(ywSceneTestDataService.getList()); + } + +} + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneUserController.java new file mode 100644 index 0000000..888fa62 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSceneUserController.java @@ -0,0 +1,135 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.ruoyi.common.annotation.Anonymous; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.SysUserImp; +import com.ruoyi.eastcom_yw.domain.YwSceneUser; +import com.ruoyi.eastcom_yw.domain.param.SysUserParam; +import com.ruoyi.eastcom_yw.domain.vo.SysUserVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneUserVo; +import com.ruoyi.eastcom_yw.domain.param.YwSceneUserParam; +import com.ruoyi.eastcom_yw.service.YwSceneUserService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author huamile + */ +@Api("场馆人员配置管理") +@RestController +@RequestMapping("/eastcom_yw/sceneUser") +@RequiredArgsConstructor +public class YwSceneUserController extends BaseController { + + private final YwSceneUserService ywSceneUserService; + + @ApiOperation("获取场馆人员配置列表") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwSceneUserParam param) { + List list = ywSceneUserService.getList(param); + return getDataTable(list); + } + + @ApiOperation("新增场馆人员配置") + @PostMapping + public AjaxResult create(@RequestBody YwSceneUser ywSceneUser) { + try { + ywSceneUserService.create(ywSceneUser); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("编辑场馆人员配置") + @PutMapping + public AjaxResult update(@RequestBody YwSceneUser ywSceneUser) { + try { + ywSceneUserService.updateByPrimaryKeySelective(ywSceneUser); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("删除场馆人员配置") + @DeleteMapping("/{ids}") + public AjaxResult delete(@PathVariable Long[] ids) { + try { + ywSceneUserService.removeByIds(Arrays.asList(ids)); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("导出场馆人员配置列表") + @PostMapping("/export") + public void export(YwSceneUserParam param, HttpServletRequest request, HttpServletResponse response) { + ywSceneUserService.export(param, request, response); + } + + @ApiOperation("查询标准人员列表") + @PostMapping("/listSysUserAppendScene") + public TableDataInfo list(@RequestBody SysUserParam para) { + List list = ywSceneUserService.listSysUser(para); + for (SysUserVo sysUser : list) { + String[] venueIds = new String[0]; + String[] venueNames = new String[0]; + String[] roless = new String[0]; + if (StringUtils.isNotEmpty(sysUser.getStrVenueIds())) { + venueIds = sysUser.getStrVenueIds().split("\\|"); + } + if (StringUtils.isNotEmpty(sysUser.getStrVenueNames())) { + venueNames = sysUser.getStrVenueNames().split("\\|"); + } + if (StringUtils.isNotEmpty(sysUser.getStrRoles())) { + roless = sysUser.getStrRoles().split("\\|"); + } + sysUser.setVenueNames(venueNames); + + sysUser.setVenueIds(venueIds); + sysUser.setRoleNames(roless); + } + + return getDataTable(list); + } + + @ApiOperation("导入标准人员列表") + @PostMapping("/importSysUserAppendScene") + public AjaxResult importSysUser(@RequestPart("file") MultipartFile file, + @RequestParam("sceneBigId") Long sceneBigId, + @RequestParam("importType") String importType) throws Exception { + + ExcelUtil util = new ExcelUtil<>(SysUserImp.class); + List imps = util.importExcel(file.getInputStream()); + + return ywSceneUserService.importSysUser(imps, sceneBigId, importType); + + } + + @ApiOperation("导出场馆人员配置列表,可供导入") + @PostMapping("/exportForImport") + public void exportForImport(SysUserParam para, HttpServletRequest request, HttpServletResponse response) { + ywSceneUserService.exportForImport(para, request, response); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSignController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSignController.java new file mode 100644 index 0000000..6e1e0a3 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSignController.java @@ -0,0 +1,312 @@ +package com.ruoyi.web.controller.eastcom_yw; + + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.utils.reflect.ReflectUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwSignLog; +import com.ruoyi.eastcom_yw.domain.dto.YwSignInDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSignLogDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSignPlanDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSignPlanUserDTO; +import com.ruoyi.eastcom_yw.domain.param.YwSignPlanParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSignLogStaticVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSignLogVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSignPlanVo; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.eastcom_yw.service.YwSignLogService; +import com.ruoyi.eastcom_yw.service.YwSignLogViewService; +import com.ruoyi.eastcom_yw.service.YwSignPlanService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + + +/** + * + * @author jkj + * @since 2023-01-14 + */ +@Api("签到信息管理") +@RestController +@RequestMapping("/eastcom_yw/sign") +public class YwSignController extends BaseController { + + @Autowired + private YwSignLogService ywSignLogService; + + @Autowired + private YwSignPlanService ywSignPlanService; + + + @Autowired + private YwSignLogViewService ywSignLogViewService; + + @Autowired + private YwSceneService yw_sceneService; + + @ApiOperation("获取签到") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwSignLogDTO ywSignLogDTO) + { + ywSignLogDTO = (YwSignLogDTO) yw_sceneService.validateUserVenues(ywSignLogDTO,YwSignLogDTO.class,"venueIds"); + TableDataInfo resData=ywSignLogViewService.getSignLog(ywSignLogDTO); + return getDataTable(resData.getRows(),resData.getTotal()); + } + + @ApiOperation("获取签到统计") + @PostMapping("/static/list") + public TableDataInfo static_list(@RequestBody YwSignLogDTO ywSignLogDTO) + { + ywSignLogDTO.setIsExport(false); + ywSignLogDTO = (YwSignLogDTO) yw_sceneService.validateUserVenues(ywSignLogDTO,YwSignLogDTO.class,"venueIds"); + List list=ywSignLogViewService.getSignLogStatic(ywSignLogDTO); + return getDataTable(list); + } + + @ApiOperation("获取签到计划") + @PostMapping("/plan/list") + public TableDataInfo plan_list(@RequestBody YwSignPlanDTO ywSignPlanDTO) + { + ywSignPlanDTO.setIsExport(false); + ywSignPlanDTO = (YwSignPlanDTO) yw_sceneService.validateUserVenues(ywSignPlanDTO,YwSignPlanDTO.class,"venueIds"); + TableDataInfo resData= ywSignPlanService.getSignPlan(ywSignPlanDTO); + return getDataTable(resData.getRows(),resData.getTotal()); + } + + @Log(title = "签到计划", businessType = BusinessType.INSERT) + @ApiOperation("新增签到计划") + @PostMapping("/plan/insert") + public AjaxResult palnInsert(@RequestBody YwSignPlanParam ywSignPlanParam) + { + + Boolean res = false; + + String strError = ""; + + try + { + if(ObjectUtils.isEmpty(ywSignPlanParam.getTimePeriods())) + { + YwSignPlanDTO ywSignPlanDTO =new YwSignPlanDTO(); + + BeanUtils.copyBeanProp(ywSignPlanDTO,ywSignPlanParam); + + res = ywSignPlanService.insertSignPlan(ywSignPlanDTO); + + if(!res) + { + strError = ywSignPlanDTO.getSignDates()[0]+" "+ywSignPlanDTO.getBeginTime()+" "+ywSignPlanDTO.getEndTime()+"相同场馆存在时间重叠"; + } + } + + + if(ObjectUtils.isNotEmpty(ywSignPlanParam.getTimePeriods())) + { + + for(YwSignPlanUserDTO ywSignPlanUserDTO : ywSignPlanParam.getTimePeriods()) + { + YwSignPlanDTO ywSignPlanDTO =new YwSignPlanDTO(); + + BeanUtils.copyBeanProp(ywSignPlanDTO,ywSignPlanParam); + + ywSignPlanDTO.setBeginTime(ywSignPlanUserDTO.getBeginTime()); + + ywSignPlanDTO.setEndTime(ywSignPlanUserDTO.getEndTime()); + + ywSignPlanDTO.setSignUsers(StringUtils.join(ywSignPlanUserDTO.getSignUsers(),",")); + + res = ywSignPlanService.insertSignPlan(ywSignPlanDTO); + + if(!res) + { + strError = ywSignPlanDTO.getSignDates()[0]+" "+ywSignPlanDTO.getBeginTime()+" "+ywSignPlanDTO.getEndTime()+"相同场馆存在时间重叠"; + break; + } + } + } + + if(res) + { + return AjaxResult.success(); + } + else + { + return AjaxResult.error(strError); + } + + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + + } + + @Log(title = "签到计划", businessType = BusinessType.UPDATE) + @ApiOperation("修改签到计划") + @PostMapping("/plan/update") + public AjaxResult palnUpdate(@RequestBody YwSignPlanParam ywSignPlanParam) + { + try + { + if(ObjectUtils.isEmpty(ywSignPlanParam.getTimePeriods())) + { + YwSignPlanDTO ywSignPlanDTO =new YwSignPlanDTO(); + BeanUtils.copyBeanProp(ywSignPlanDTO,ywSignPlanParam); + ywSignPlanService.updateSignPlan(ywSignPlanDTO); + return AjaxResult.success(); + } + + if(ObjectUtils.isNotEmpty(ywSignPlanParam.getTimePeriods())) + { + + for(YwSignPlanUserDTO ywSignPlanUserDTO : ywSignPlanParam.getTimePeriods()) + { + + YwSignPlanDTO ywSignPlanDTO =new YwSignPlanDTO(); + + BeanUtils.copyBeanProp(ywSignPlanDTO,ywSignPlanParam); + + ywSignPlanDTO.setBeginTime(ywSignPlanUserDTO.getBeginTime()); + + ywSignPlanDTO.setEndTime(ywSignPlanUserDTO.getEndTime()); + + ywSignPlanDTO.setSignUsers(StringUtils.join(ywSignPlanUserDTO.getSignUsers(),",")); + + ywSignPlanService.updateSignPlan(ywSignPlanDTO); + + } + } + + return AjaxResult.success(); + + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + + } + + @Log(title = "签到计划", businessType = BusinessType.DELETE) + @ApiOperation("删除签到计划") + @DeleteMapping("/plan/{id}") + public AjaxResult palnDelete(@PathVariable Long id) + { + try + { + ywSignPlanService.deleteSignPlan(id); + return AjaxResult.success(); + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + + } + + @ApiOperation("根据用户ID获取该用户的签到") + @GetMapping(value = { "/", "/{userId}" }) + public TableDataInfo list(@PathVariable(value = "userId", required = false) Long userId) + { + LambdaQueryWrapper lambdaQueryWrapper=new LambdaQueryWrapper<>(); + lambdaQueryWrapper.eq(YwSignLog::getUserId,userId); + List list = ywSignLogService.list(lambdaQueryWrapper); + return getDataTable(list); + } + + @Log(title = "批量签到", businessType = BusinessType.UPDATE) + @ApiOperation("后端批量签到") + @PostMapping("/signIn") + public AjaxResult signIn(@RequestBody YwSignInDTO ywSignInDTO) + { + try + { +// SysUser user = getLoginUser().getUser(); +// ywSignInDTO.setUserId(user.getUserId()); + ywSignLogService.SignIn(ywSignInDTO); + return AjaxResult.success(); + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + + } + + @Log(title = "签到计划导入", businessType = BusinessType.IMPORT) + @PostMapping("/plan/import") + public AjaxResult importData(MultipartFile file, Boolean updateSupport,Long sceneBigId) throws Exception + { + ExcelUtil util = new ExcelUtil(YwSignPlanDTO.class); + List signPlanList = util.importExcel(file.getInputStream()); + return ywSignPlanService.importSignPlan(signPlanList,updateSupport,sceneBigId); +// return success(message); + } + + @Log(title = "签到记录导出", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response,YwSignLogDTO ywSignLogDTO) throws IllegalAccessException { + ywSignLogDTO.setIsExport(true); + ywSignLogDTO = (YwSignLogDTO) yw_sceneService.validateUserVenues(ywSignLogDTO,YwSignLogDTO.class,"venueIds"); + TableDataInfo resData=ywSignLogViewService.getSignLog(ywSignLogDTO); + List list = ReflectUtils.toList(resData.getRows(),YwSignLogVo.class); + ExcelUtil util = new ExcelUtil(YwSignLogVo.class); + util.exportExcel(response, list, "签到数据"); + } + + @Log(title = "签到计划导出", businessType = BusinessType.EXPORT) + @PostMapping("/plan/export") + public void exportPlan(YwSignPlanDTO ywSignPlanDTO,HttpServletResponse response) throws IllegalAccessException { + ywSignPlanDTO.setIsExport(true); + ywSignPlanDTO = (YwSignPlanDTO) yw_sceneService.validateUserVenues(ywSignPlanDTO,YwSignPlanDTO.class,"venueIds"); + TableDataInfo resData=ywSignPlanService.getSignPlan(ywSignPlanDTO); + List list = ReflectUtils.toList(resData.getRows(), YwSignPlanVo.class); + ExcelUtil util = new ExcelUtil(YwSignPlanVo.class); + util.exportExcel(response, list, "签到计划数据"); + } + + @Log(title = "签到统计导出", businessType = BusinessType.EXPORT) + @PostMapping("/static/export") + public void exportStatic(HttpServletResponse response,YwSignLogDTO ywSignLogDTO) throws IllegalAccessException { + ywSignLogDTO.setIsExport(true); + ywSignLogDTO = (YwSignLogDTO) yw_sceneService.validateUserVenues(ywSignLogDTO,YwSignLogDTO.class,"venueIds"); + List list=ywSignLogViewService.getSignLogStatic(ywSignLogDTO); + ExcelUtil util = new ExcelUtil(YwSignLogStaticVo.class); + util.exportExcel(response, list, "签到统计数据"); + } + + @Log(title = "签到统计/签到记录导出", businessType = BusinessType.EXPORT) + @PostMapping("/static/exportSign") + public void exportSign(HttpServletResponse response,YwSignLogDTO ywSignLogDTO) throws IllegalAccessException { + ywSignLogDTO.setIsExport(true); + ywSignLogDTO = (YwSignLogDTO) yw_sceneService.validateUserVenues(ywSignLogDTO,YwSignLogDTO.class,"venueIds"); + TableDataInfo resData=ywSignLogViewService.getSignLog(ywSignLogDTO); + List list = ReflectUtils.toList(resData.getRows(),YwSignLogVo.class); + ExcelUtil util = new ExcelUtil(YwSignLogVo.class); + util.exportExcel(response, list, "签到数据"); + } + + + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSparePartsController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSparePartsController.java new file mode 100644 index 0000000..b4e20f4 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwSparePartsController.java @@ -0,0 +1,125 @@ +package com.ruoyi.web.controller.eastcom_yw; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwSpareParts; +import com.ruoyi.eastcom_yw.domain.dto.YwSparePartsDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwSparePartsQO; +import com.ruoyi.eastcom_yw.domain.vo.YwSparePartsVO; +import com.ruoyi.eastcom_yw.service.YwSparePartsService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + *

+ * 亚运备件表 前端控制器 + *

+ * + * @author yqf + * @since 2023-08-31 + */ +@Api(tags = "亚运备件管理") +@RestController +@RequestMapping("/eastcom_yw/ywSpareParts") +@Slf4j +@RequiredArgsConstructor +public class YwSparePartsController extends BaseController { + + private final YwSparePartsService ywSparePartsService; + + /** + * 亚运备件表列表 + */ + @ApiOperation(value = "亚运备件表列表", notes = "亚运备件表列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody YwSparePartsQO qo) { + List list = ywSparePartsService.getData(qo); + return getDataTable(list); + } + + + /** + * 亚运备件表分页列表 + */ + @ApiOperation(value = "亚运备件表分页列表", notes = "亚运备件表分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody YwSparePartsQO qo) { + IPage page = ywSparePartsService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } + + /** + * 获取亚运备件表详情 + */ + @ApiOperation(value = "亚运备件表详情", notes = "亚运备件表详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(ywSparePartsService.fetchById(id)); + } + + /** + * 新增或修改亚运备件表 + */ + @Log(title = "新增或修改亚运备件表", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改亚运备件表", notes = "新增或修改亚运备件表") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated YwSparePartsDTO dto) { + ywSparePartsService.saveOrUpdate(dto); + return AjaxResult.success(); + } + + /** + * 根据id删除亚运备件表 + */ + @Log(title = "根据id删除亚运备件表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除亚运备件表", notes = "根据id删除亚运备件表") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + ywSparePartsService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除亚运备件表 + */ + @Log(title = "根据id批量删除亚运备件表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除亚运备件表", notes = "根据id批量删除亚运备件表") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + ywSparePartsService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "亚运备件表导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwSparePartsDTO.class); + List list = util.importExcel(file.getInputStream()); + ywSparePartsService.importData(list); + return AjaxResult.success(); + } + + + /** + * 亚运备件表导出 + */ + @ApiOperation(value = "亚运备件表导出") + @PostMapping(value = "/export") + public void export(@RequestBody YwSparePartsQO qo) { + ywSparePartsService.export(qo); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwWireTaskLogController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwWireTaskLogController.java new file mode 100644 index 0000000..990b208 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/eastcom_yw/YwWireTaskLogController.java @@ -0,0 +1,418 @@ +package com.ruoyi.web.controller.eastcom_yw; + +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.cmcc_gm.common.enums.OrderType; +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import com.ruoyi.cmcc_gm.domain.YwMaterialsOrderLog; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsInformRedisVo; +import com.ruoyi.cmcc_gm.service.YwMaterialsBatchService; +import com.ruoyi.cmcc_gm.service.YwMaterialsInformService; +import com.ruoyi.cmcc_gm.service.YwMaterialsOrderLogService; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.XmlDocToDocxUtil; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.utils.poi.WordUtil; +import com.ruoyi.common.utils.reflect.ReflectUtils; +import com.ruoyi.eastcom_yw.common.enums.WireTaskSubType; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwWireTaskLog; +import com.ruoyi.eastcom_yw.domain.dto.YwSignLogDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwWireTaskLogDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwSignLogVo; +import com.ruoyi.eastcom_yw.domain.vo.YwWireTaskLogVo; +import com.ruoyi.eastcom_yw.mapper.YwWireTaskLogMapper; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.eastcom_yw.service.YwWireTaskLogService; +import com.ruoyi.sunlm.domain.class_scene_match; +import com.ruoyi.sunlm.mapper.dpConfigMapper; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.docx4j.Docx4J; +import org.docx4j.openpackaging.packages.WordprocessingMLPackage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.*; +import java.util.stream.Collectors; + + +/** + * + * @author jkj + * @since 2023-01-12 + */ + +@Api("综合布线") +@RestController +@RequestMapping("/eastcom_yw/wireTask") +public class YwWireTaskLogController extends BaseController { + + @Autowired + private YwWireTaskLogService ywWireTaskLogService; + + @Autowired + private YwWireTaskLogMapper ywWireTaskLogMapper; + + @Autowired + private YwMaterialsOrderLogService ywMaterialsOrderLogService; + + @Autowired + private YwMaterialsBatchService ywMaterialsBatchService; + + @Autowired + private YwMaterialsInformService ywMaterialsInformService; + + @Resource + dpConfigMapper MydpConfigMapper; + + @Autowired + private YwSceneService yw_sceneService; + + @Log(title = "布线记录", businessType = BusinessType.INSERT) + @ApiOperation("布线记录") + @PostMapping("/insert") + public AjaxResult insert(@RequestBody YwWireTaskLogDTO ywWireTaskLogDTO) + { + try + { + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywWireTaskLogDTO.getWireTaskName()), YwWireTaskLog::getWireTaskName, ywWireTaskLogDTO.getWireTaskName()); + + if(ywWireTaskLogService.list(lambdaQueryWrapper).size()>0) + { + return AjaxResult.error("任务名称在该场馆或其他场馆已存在"); + } + + String res = ywWireTaskLogService.insertWireTaskLogReWireTaskId(ywWireTaskLogDTO); + if(StringUtils.isNotEmpty(res)) + { + return AjaxResult.success("新增布线日志成功",res); + } + else + { + return AjaxResult.error("新增布线日志失败"); + } + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + + } + + @Log(title = "布线记录", businessType = BusinessType.UPDATE) + @ApiOperation("布线记录") + @PostMapping("/update") + public AjaxResult update(@RequestBody YwWireTaskLogDTO ywWireTaskLogDTO) + { + try + { + boolean res = ywWireTaskLogService.updateWireTaskLog(ywWireTaskLogDTO); + if(res) + { + return AjaxResult.success(); + } + else + { + return AjaxResult.error("修改布线日志失败"); + } + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + + } + + @Log(title = "布线记录", businessType = BusinessType.DELETE) + @PostMapping("/delete") + public AjaxResult remove(@RequestBody YwWireTaskLogDTO ywWireTaskLogDTO) + { + try + { + boolean res = ywWireTaskLogService.deleteWireTaskLog(ywWireTaskLogDTO); + if(res) + { + return AjaxResult.success(); + } + else + { + return AjaxResult.error("删除布线日志失败"); + } + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + } + + //预留。后期删除 + @Log(title = "布线记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{wireTaskId}") + public AjaxResult remove(@PathVariable String wireTaskId) + { + try + { + YwWireTaskLogDTO ywWireTaskLogDTO=new YwWireTaskLogDTO(); + ywWireTaskLogDTO.setWireTaskId(wireTaskId); + + boolean res = ywWireTaskLogService.deleteWireTaskLog(ywWireTaskLogDTO); + if(res) + { + return AjaxResult.success(); + } + else + { + return AjaxResult.error("删除布线日志失败"); + } + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + } + + + @ApiOperation("获取场馆布线记录") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwWireTaskLogDTO ywWireTaskLogDTO) throws Exception { + ywWireTaskLogDTO = (YwWireTaskLogDTO) yw_sceneService.validateUserVenues(ywWireTaskLogDTO,YwWireTaskLogDTO.class,"venueIds"); + TableDataInfo resData = ywWireTaskLogService.getWireTaskLog(ywWireTaskLogDTO); + return getDataTable(resData.getRows(), resData.getTotal()); + } + + @Log(title = "导出场馆布线记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, YwWireTaskLogDTO ywWireTaskLogDTO) throws IllegalAccessException { + ywWireTaskLogDTO.setIsExport(true); + // ywWireTaskLogDTO.setPageNum(1); + ywWireTaskLogDTO.setPageSize(-1); + ywWireTaskLogDTO = (YwWireTaskLogDTO) yw_sceneService.validateUserVenues(ywWireTaskLogDTO,YwWireTaskLogDTO.class,"venueIds"); + TableDataInfo resData = ywWireTaskLogService.getWireTaskLog(ywWireTaskLogDTO); + List list = ReflectUtils.toList(resData.getRows(), YwWireTaskLogVo.class); + ExcelUtil util = new ExcelUtil(YwWireTaskLogVo.class); + util.exportExcel(response, list, "场馆布线数据"); + } + + + + + @ApiOperation("生成报告") + @PostMapping("/report") + public AjaxResult report(@RequestBody YwWireTaskLogDTO ywWireTaskLogDTO) throws Exception { + + if(StringUtils.isEmpty(ywWireTaskLogDTO.getWireTaskId())) + { + return AjaxResult.error("布线任务号不允许为空"); + } + + ywWireTaskLogDTO.setTaskType(2); + + //查询找布线,更新文件地址是拆线 + LambdaQueryWrapper wireTaskQuery = new LambdaQueryWrapper<>(); + wireTaskQuery.eq(YwWireTaskLog::getWireTaskId,ywWireTaskLogDTO.getWireTaskId()); +// wireTaskQuery.eq(YwWireTaskLog::getTaskType,1); + List wireTaskLogList = ywWireTaskLogService.list(wireTaskQuery); + + if(wireTaskLogList.isEmpty()) + { + return AjaxResult.error("没有找到这个布线任务"); + } + + if(wireTaskLogList.size() != 2) + { + return AjaxResult.error("布线任务未拆线"); + } + + Optional ywWireTaskLogCX = wireTaskLogList.stream().filter(x -> x.getTaskType() == 2 && "4".equals(x.getDealStatus())).findFirst(); + + if(!ywWireTaskLogCX.isPresent()) + { + return AjaxResult.error("拆线的流程还没结束"); + } + + Optional ywWireTaskLog = wireTaskLogList.stream().filter(x -> x.getTaskType() == 1 && "4".equals(x.getDealStatus())).findFirst(); + + Map dataMap = new HashMap<>(16); + dataMap.put("name", "\r \r"); + dataMap.put("beginTime", "\r \r"); + dataMap.put("endTime", "\r \r"); + dataMap.put("type", "\r \r"); + dataMap.put("taskSub", "\r \r"); + dataMap.put("venueName", "\r \r"); + + if(StringUtils.isNotEmpty(ywWireTaskLog.get().getMatchId())) + { + // int matchId = Integer.parseInt(ywWireTaskLog.get().getMatchId()); + //获取赛程信息 + class_scene_match match = MydpConfigMapper.getscenematch2(ywWireTaskLog.get().getMatchId(),ywWireTaskLog.get().getVenueId()); + + if(ObjectUtils.isNotEmpty(match)) + { + dataMap.put("name", match.taskName); + dataMap.put("beginTime",DateUtils.parseDateToStr("MM月dd日",match.getBeginTime())); + dataMap.put("endTime", DateUtils.parseDateToStr("MM月dd日",match.getEndTime())); + dataMap.put("type", DictUtils.getDictLabel("yw_match_type", match.getTaskType())); + } + } + + if(ObjectUtils.isNotEmpty(ywWireTaskLog.get().getTaskSubType())) + { + String strTaskSub = WireTaskSubType.getLabelByCode(ywWireTaskLog.get().getTaskSubType()); + if(StringUtils.isNotEmpty(strTaskSub)) + { + dataMap.put("taskSub",strTaskSub); + } + } + + if(StringUtils.isNotEmpty(ywWireTaskLog.get().getVenueName())) + { + dataMap.put("venueName", ywWireTaskLog.get().getVenueName()); + } + + List> noList = new ArrayList<>(); + int size = 7; + for (int i = 0; i < size; i++) { + Map map = new HashMap<>(16); + map.put("id", ""); + map.put("materialName", ""); + map.put("materialSmallClass", ""); + map.put("materialStand", ""); + map.put("materialUnit", ""); + map.put("sum", ""); + noList.add(map); + } + + dataMap.put("agisList", noList); + dataMap.put("wifiList", noList); + dataMap.put("voipList", noList); + +// 获取物资信息 + LambdaQueryWrapper materialOrderQuery = new LambdaQueryWrapper<>(); + materialOrderQuery.eq(YwMaterialsOrderLog::getWireTaskId, ywWireTaskLogDTO.getWireTaskId()); + +//必须场馆一致 + materialOrderQuery.eq(YwMaterialsOrderLog::getOutStoreVenue, ywWireTaskLog.get().getVenueId()); + + + //限制必须是工程出库数据 + materialOrderQuery.eq(YwMaterialsOrderLog::getOrderType, OrderType.CK.getCode()); + + List ywMaterialsOrderLogs = ywMaterialsOrderLogService.list(materialOrderQuery); + + if(!ywMaterialsOrderLogs.isEmpty()) + { + List> taskList = new ArrayList<>(); + + String[] arrOrderId = ywMaterialsOrderLogs.stream().map(YwMaterialsOrderLog::getOrderId).toArray(String[]::new); + + //获取物资批量数据 + System.out.println(JSONObject.toJSONString(arrOrderId)); + + QueryWrapper wrapper = new QueryWrapper() + .select("material_code,sum(sum) as sum") + .in("orderid",arrOrderId) + .groupBy("material_code"); + +// List> materialsBatchList = ywMaterialsBatchService.listMaps(wrapper); + List materialsBatchList = ywMaterialsBatchService.list(wrapper); + + //从缓存取物资信息 + List materialInfos = ywMaterialsInformService.getMaterials(); + + int i=1; + +// for (Map ywMaterialsBatch : materialsBatchList) { + for (YwMaterialsBatch ywMaterialsBatch : materialsBatchList) { + Optional materialInfoFilter = materialInfos.stream().filter(x -> ywMaterialsBatch.getMaterialCode().equals(x.getWzbh())).findFirst(); + + if(!materialInfoFilter.isPresent()) + { + continue; + } + + Map map = new HashMap<>(16); + map.put("id", i); + map.put("materialName", materialInfoFilter.get().getWzmc() ); + map.put("materialSmallClass",materialInfoFilter.get().getXl()); + map.put("materialStand",materialInfoFilter.get().getGgxh()); + map.put("materialUnit", materialInfoFilter.get().getWzdw()); + map.put("sum", ywMaterialsBatch.getSum()); + taskList.add(map); + i++; + + } + + if(WireTaskSubType.AGIS.getCode().equals(ywWireTaskLog.get().getTaskSubType())) { + dataMap.put("agisList", taskList); + } + + if(WireTaskSubType.INTERNET.getCode().equals(ywWireTaskLog.get().getTaskSubType())) { + dataMap.put("wifiList", taskList); + } + + if(WireTaskSubType.VOIP.getCode().equals(ywWireTaskLog.get().getTaskSubType())) { + dataMap.put("voipList", taskList); + } + + } + + WordUtil word = new WordUtil(); + + String fileName = ywWireTaskLogDTO.getWireTaskId() + "_布线任务报告_" + DateUtils.dateTime(); + +// String xmlFileName = fileName + ".xml"; + String wordFileName = fileName + ".docx"; +// String genPath = RuoYiConfig.getDownloadPath() + xmlFileName; + String wordPath = RuoYiConfig.getDownloadPath() + wordFileName; + String savePath = wordPath.replace(RuoYiConfig.getProfile(),Constants.RESOURCE_PREFIX); +// logger.info(wordPath); + try { + + boolean res = word.createWord(dataMap, "wireReportTemplate.ftl", wordPath); + + if(res){ + + res = XmlDocToDocxUtil.invoke(wordPath); + + if(res) + { + ywWireTaskLogDTO.setReport(savePath); + + //回填地址到表 + ywWireTaskLogMapper.updateWireTaskReport(ywWireTaskLogDTO); + + return AjaxResult.success(savePath); + } + + } + } + catch (Exception ex){ + return AjaxResult.error(ex.getMessage()); + } + + return AjaxResult.error(); + + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java new file mode 100644 index 0000000..12391c5 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java @@ -0,0 +1,122 @@ +package com.ruoyi.web.controller.monitor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisCallback; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.domain.SysCache; + +/** + * 缓存监控 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/cache") +public class CacheController +{ + @Autowired + private RedisTemplate redisTemplate; + + private final static List caches = new ArrayList(); + { + caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息")); + caches.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "配置信息")); + caches.add(new SysCache(CacheConstants.SYS_DICT_KEY, "数据字典")); + caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码")); + caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交")); + caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理")); + caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数")); + caches.add(new SysCache(CacheConstants.SMS_ERR_CNT_KEY, "短信错误次数")); + caches.add(new SysCache(CacheConstants.DP_DATA, "大屏数据")); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping() + public AjaxResult getInfo() throws Exception + { + Properties info = (Properties) redisTemplate.execute((RedisCallback) connection -> connection.info()); + Properties commandStats = (Properties) redisTemplate.execute((RedisCallback) connection -> connection.info("commandstats")); + Object dbSize = redisTemplate.execute((RedisCallback) connection -> connection.dbSize()); + + Map result = new HashMap<>(3); + result.put("info", info); + result.put("dbSize", dbSize); + + List> pieList = new ArrayList<>(); + commandStats.stringPropertyNames().forEach(key -> { + Map data = new HashMap<>(2); + String property = commandStats.getProperty(key); + data.put("name", StringUtils.removeStart(key, "cmdstat_")); + data.put("value", StringUtils.substringBetween(property, "calls=", ",usec")); + pieList.add(data); + }); + result.put("commandStats", pieList); + return AjaxResult.success(result); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping("/getNames") + public AjaxResult cache() + { + return AjaxResult.success(caches); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping("/getKeys/{cacheName}") + public AjaxResult getCacheKeys(@PathVariable String cacheName) + { + Set cacheKeys = redisTemplate.keys(cacheName + "*"); + return AjaxResult.success(cacheKeys); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping("/getValue/{cacheName}/{cacheKey}") + public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey) + { + String cacheValue = redisTemplate.opsForValue().get(cacheKey); + SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue); + return AjaxResult.success(sysCache); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @DeleteMapping("/clearCacheName/{cacheName}") + public AjaxResult clearCacheName(@PathVariable String cacheName) + { + Collection cacheKeys = redisTemplate.keys(cacheName + "*"); + redisTemplate.delete(cacheKeys); + return AjaxResult.success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @DeleteMapping("/clearCacheKey/{cacheKey}") + public AjaxResult clearCacheKey(@PathVariable String cacheKey) + { + redisTemplate.delete(cacheKey); + return AjaxResult.success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @DeleteMapping("/clearCacheAll") + public AjaxResult clearCacheAll() + { + Collection cacheKeys = redisTemplate.keys("*"); + redisTemplate.delete(cacheKeys); + return AjaxResult.success(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ServerController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ServerController.java new file mode 100644 index 0000000..cc805ad --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ServerController.java @@ -0,0 +1,27 @@ +package com.ruoyi.web.controller.monitor; + +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.framework.web.domain.Server; + +/** + * 服务器监控 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/server") +public class ServerController +{ + @PreAuthorize("@ss.hasPermi('monitor:server:list')") + @GetMapping() + public AjaxResult getInfo() throws Exception + { + Server server = new Server(); + server.copyTo(); + return AjaxResult.success(server); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java new file mode 100644 index 0000000..e0175f4 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java @@ -0,0 +1,82 @@ +package com.ruoyi.web.controller.monitor; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.framework.web.service.SysPasswordService; +import com.ruoyi.system.domain.SysLogininfor; +import com.ruoyi.system.service.ISysLogininforService; + +/** + * 系统访问记录 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/logininfor") +public class SysLogininforController extends BaseController +{ + @Autowired + private ISysLogininforService logininforService; + + @Autowired + private SysPasswordService passwordService; + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')") + @GetMapping("/list") + public TableDataInfo list(SysLogininfor logininfor) + { + startPage(); + List list = logininforService.selectLogininforList(logininfor); + return getDataTable(list); + } + + @Log(title = "登录日志", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysLogininfor logininfor) + { + List list = logininforService.selectLogininforList(logininfor); + ExcelUtil util = new ExcelUtil(SysLogininfor.class); + util.exportExcel(response, list, "登录日志"); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") + @Log(title = "登录日志", businessType = BusinessType.DELETE) + @DeleteMapping("/{infoIds}") + public AjaxResult remove(@PathVariable Long[] infoIds) + { + return toAjax(logininforService.deleteLogininforByIds(infoIds)); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") + @Log(title = "登录日志", businessType = BusinessType.CLEAN) + @DeleteMapping("/clean") + public AjaxResult clean() + { + logininforService.cleanLogininfor(); + return success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')") + @Log(title = "账户解锁", businessType = BusinessType.OTHER) + @GetMapping("/unlock/{userName}") + public AjaxResult unlock(@PathVariable("userName") String userName) + { + passwordService.clearLoginRecordCache(userName); + return success(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java new file mode 100644 index 0000000..6ca78cf --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java @@ -0,0 +1,69 @@ +package com.ruoyi.web.controller.monitor; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.SysOperLog; +import com.ruoyi.system.service.ISysOperLogService; + +/** + * 操作日志记录 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/operlog") +public class SysOperlogController extends BaseController +{ + @Autowired + private ISysOperLogService operLogService; + + @PreAuthorize("@ss.hasPermi('monitor:operlog:list')") + @GetMapping("/list") + public TableDataInfo list(SysOperLog operLog) + { + startPage(); + List list = operLogService.selectOperLogList(operLog); + return getDataTable(list); + } + + @Log(title = "操作日志", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('monitor:operlog:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysOperLog operLog) + { + List list = operLogService.selectOperLogList(operLog); + ExcelUtil util = new ExcelUtil(SysOperLog.class); + util.exportExcel(response, list, "操作日志"); + } + + @Log(title = "操作日志", businessType = BusinessType.DELETE) + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") + @DeleteMapping("/{operIds}") + public AjaxResult remove(@PathVariable Long[] operIds) + { + return toAjax(operLogService.deleteOperLogByIds(operIds)); + } + + @Log(title = "操作日志", businessType = BusinessType.CLEAN) + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") + @DeleteMapping("/clean") + public AjaxResult clean() + { + operLogService.cleanOperLog(); + return success(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java new file mode 100644 index 0000000..1128b69 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java @@ -0,0 +1,145 @@ +package com.ruoyi.web.controller.monitor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.constant.HttpStatus; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.domain.SysUserOnline; +import com.ruoyi.system.service.ISysUserOnlineService; + +/** + * 在线用户监控 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/online") +public class SysUserOnlineController extends BaseController +{ + @Autowired + private ISysUserOnlineService userOnlineService; + + @Autowired + private RedisCache redisCache; + + @GetMapping("/listNum") + public TableDataInfo listNum() + { + Collection keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); + List userOnlineList = new ArrayList(); + for (String key : keys) + { + LoginUser user = redisCache.getCacheObject(key); + + if(ObjectUtils.isEmpty(user)) + { + continue; + } + + if(ObjectUtils.isEmpty(user.getUserId())) + { + continue; + } + + //去除重复用户 + if(!userOnlineList.isEmpty()) + { + Long userNum = userOnlineList.stream().filter(x->x.getUserId().equals(user.getUserId())).count(); + if(userNum>0) + { + continue; + } + } + userOnlineList.add(user); + } + TableDataInfo rspData = new TableDataInfo(); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setMsg("查询成功"); + rspData.setTotal(userOnlineList.size()); + return rspData; + } + +// @PreAuthorize("@ss.hasPermi('monitor:online:list')") + @GetMapping("/list") + public TableDataInfo list(String ipaddr, String userName) + { + Collection keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); + List userOnlineList = new ArrayList(); + for (String key : keys) + { + LoginUser user = redisCache.getCacheObject(key); + +// //去除重复用户 +// if(!userOnlineList.isEmpty()) +// { +// Long userNum = userOnlineList.stream().filter(x->x.getUserId().equals(user.getUserId())).count(); +// if(userNum>0) +// { +// continue; +// } +// } + + if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) + { + if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) + { + userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user)); + } + } + else if (StringUtils.isNotEmpty(ipaddr)) + { + if (StringUtils.equals(ipaddr, user.getIpaddr())) + { + userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user)); + } + } + else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser())) + { + if (StringUtils.equals(userName, user.getUsername())) + { + userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user)); + } + } + else + { + userOnlineList.add(userOnlineService.loginUserToUserOnline(user)); + } + } + Collections.reverse(userOnlineList); + userOnlineList.removeAll(Collections.singleton(null)); + return getDataTable(userOnlineList); + } + + /** + * 强退用户 + */ + @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')") + @Log(title = "在线用户", businessType = BusinessType.FORCE) + @DeleteMapping("/{tokenId}") + public AjaxResult forceLogout(@PathVariable String tokenId) + { + redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId); + return success(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/DpApiController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/DpApiController.java new file mode 100644 index 0000000..ba5b2d1 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/DpApiController.java @@ -0,0 +1,53 @@ +package com.ruoyi.web.controller.sunlm; + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.sunlm.domain.class_dp_scene_seat_detail; +import com.ruoyi.sunlm.domain.class_dp_scene_seat_info; +import com.ruoyi.sunlm.mapper.DpApiMapper; +import com.ruoyi.sunlm.mapper.dpYayunMapper; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.constraints.NotNull; +import java.util.ArrayList; +import java.util.List; + +/** + * @author yqf + * @date 2023/4/18 + */ +@RestController +@CrossOrigin +@RequestMapping("/eastcom_yw/daping") +public class DpApiController extends BaseController { + + @Resource + DpApiMapper dpApiMapper; //直接在这里引用数据库操作层(MAPPER),就不用写Service层了! + + + //region --------------------------------------------------------------------------------------------获取dp_scene_seat_info数据 + //-------------------------------------------- + @ApiOperation("获取get_seat_info表信息 sceneid:场馆ID") + @GetMapping(value = "/get_seat_info") + public AjaxResult get_scene_seat_info(@NotNull(message = "sceneid不饿能为空") @RequestParam int sceneid) + { + class_dp_scene_seat_info dpData=new class_dp_scene_seat_info(); + dpData = dpApiMapper.get_scene_seat_info(sceneid); + return success(dpData); + } + //endregion + + //region --------------------------------------------------------------------------------------------获取dp_scene_seat_detail数据 + //-------------------------------------------- + @ApiOperation("获取get_seat_info表信息 sceneid:场馆ID") + @GetMapping(value = "/get_seat_detail") + public AjaxResult get_seat_detail(@NotNull(message = "sceneid不饿能为空") @RequestParam int sceneid) + { + List dpData=new ArrayList<>(); + dpData = dpApiMapper.get_seat_detail(sceneid); + return success(dpData); + } + //endregion +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/dpConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/dpConfigController.java new file mode 100644 index 0000000..abc08ef --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/dpConfigController.java @@ -0,0 +1,983 @@ +package com.ruoyi.web.controller.sunlm; + +import java.util.ArrayList; +import java.util.List; + +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.sunlm.domain.*; +import com.ruoyi.sunlm.entity.*; +import com.ruoyi.sunlm.mapper.dpConfigMapper; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.page.TableDataInfo; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +/** + * 参数配置 信息操作处理 + * + * @author ruoyi + * Spring Security提供了Spring EL表达式,允许我们在定义接口访问的方法上面添加注解,来控制访问权限 + * + * 方法 参数 描述 + * hasPermi String 验证用户是否具备某权限 + * lacksPermi String 验证用户是否不具备某权限,与hasPermi逻辑相反 + * hasAnyPermi String 验证用户是否具有以下任意一个权限 + * hasRole String 判断用户是否拥有某个权限 + * lacksRole String 验证用户是否不具备某个权限,与hasRole逻辑相反 + * hasAnyRoles String 验证用户是否具有以下任意一个角色,多个逗号分隔 + + */ + +@RestController +@CrossOrigin +@RequestMapping("/eastcom_yw/config") + +public class dpConfigController extends BaseController +{ + @Resource + dpConfigMapper MydpConfigMapper; //直接在这里引用数据库操作层(MAPPER),就不用写Service层了! + + @Resource + YwSceneService ywSceneService; + + //region --------------------------------------------------------------------------------------------场景增删改查接口 + //--------------------------------------------获取大场馆列表 + @ApiOperation("根据场景ID获取场景") + @GetMapping(value = "/getscenebig/{sceneid}") + public AjaxResult getscenebig(@PathVariable int sceneid, HttpServletRequest request) + { + class_scene_big_config scenebig=new class_scene_big_config(); + scenebig = MydpConfigMapper.getscenebig(sceneid); + return success(scenebig); + } + + @ApiOperation("根据查询条件获取场景") + @GetMapping(value = "/getscenebiglist") + @RepeatSubmit(enable = false,interval = 1000) + public TableDataInfo getscenebiglists(scene_big_entity_list jsonObject, HttpServletRequest request) + { + List scenebig=new ArrayList(); + String name=jsonObject.name==null?"":jsonObject.name; + List status=jsonObject.status==null?new ArrayList():jsonObject.status; + String remark=jsonObject.remark==null?"":jsonObject.remark; + int pagenumber=jsonObject.pageNum; + int pagesize=jsonObject.pageSize; + scenebig = MydpConfigMapper.getscenebiglists(name,status,remark,pagenumber,pagesize); + Long total=MydpConfigMapper.getscenebiglistscnt(name,status,remark); + return getDataTable(scenebig,total); + } + + @ApiOperation("根据查询条件导出场景") + @PostMapping("/exportscenebiglist") + public void exportscenebiglist(HttpServletResponse response, scene_big_entity_list jsonObject) + { + List scenebig=new ArrayList(); + String name=jsonObject.name==null?"":jsonObject.name; + List status=jsonObject.status==null?new ArrayList():jsonObject.status; + String remark=jsonObject.remark==null?"":jsonObject.remark; + int pagenumber=1; //jsonObject.pageNum==0?1:jsonObject.pageNum; + int pagesize=100000; //jsonObject.pageSize==0?100000:jsonObject.pageSize; + + scenebig = MydpConfigMapper.getscenebiglists(name,status,remark,pagenumber,pagesize); + ExcelUtil util = new ExcelUtil(class_scene_big_config.class); + util.exportExcel(response, scenebig, "场景数据"); + } + + //----------------------------------------------新增大场馆 + public int getscenebigbyName(String name) + { + int counts= MydpConfigMapper.getscenebigbyName(name); + return counts; + } + + @ApiOperation("新建场景") + @PostMapping(value = "/newscenebig") + public AjaxResult newscenebig(@RequestBody scene_big_entity_new jsonObject, HttpServletRequest request) + { + String sRet=""; + String name=jsonObject.name==null?"":jsonObject.name; + String status=jsonObject.status==null?"":jsonObject.status; + String username=jsonObject.createBy==null?"":jsonObject.createBy; + String remark=jsonObject.remark==null?"":jsonObject.remark; + //--------------需要判断是否已经存在同名的记录 + if (getscenebigbyName(name)>0) + { + return AjaxResult.error("场景"+name+"已存在!"); + } + //-------------- + try { + MydpConfigMapper.NewSceneBig(name,status,username,remark); + sRet = "新增成功"; + } catch (Exception e) { + sRet = "新增失败:"+e.getMessage(); + } + //--------------------------------- + return sRet.equals("新增成功")?AjaxResult.success(sRet):AjaxResult.error(sRet); + } + + //----------------------------------------------修改大场馆 + public int getscenebigbyNameForUpdate(String name,int id) + { + int counts= MydpConfigMapper.getscenebigbyNameForUpdate(name,id); + return counts; + } + + @ApiOperation("修改场景") + @PutMapping(value = "/updatescenebig") + public AjaxResult updatescenebig(@RequestBody scene_big_entity_upt jsonObject, HttpServletRequest request) + { + String sRet=""; + int id=jsonObject.id; + String status=jsonObject.status==null?"":jsonObject.status; + String name=jsonObject.name==null?"":jsonObject.name; + String remark=jsonObject.remark==null?"":jsonObject.remark; + String username=jsonObject.updateBy==null?"":jsonObject.updateBy; + //--------------需要判断是否已经存在同名的记录 + if (getscenebigbyNameForUpdate(name,id)>0) + { + return AjaxResult.error("场景"+name+"已存在!"); + } + try { + MydpConfigMapper.UpdateSceneBig(id,name,status,username,remark); + //修改成功后,缓存更新一下 + ywSceneService.loadingVenueCache(); + sRet = "修改成功"; + } catch (Exception e) { + sRet = "修改失败:"+e.getMessage(); + } + //--------------------------------- + return sRet.equals("修改成功")?AjaxResult.success(sRet):AjaxResult.error(sRet); + } + + //----------------------------------------------删除大场馆 + @ApiOperation("删除场景") + @DeleteMapping(value = "/deletescenebig/{sceneid}") + public AjaxResult deletescenebig(@PathVariable int[] sceneid,HttpServletRequest request) + { + String sRet=""; + try { + for (int i=0;i scenecalendar=new ArrayList(); + + String scenebigid=jsonObject.sceneBigId==null?getSceneStatusIs2():jsonObject.sceneBigId; + List sceneid=jsonObject.sceneIds==null?new ArrayList():jsonObject.sceneIds; + String matchtype=jsonObject.matchType==null?"":jsonObject.matchType; + String matchname=jsonObject.matchName==null?"":jsonObject.matchName; + String status=jsonObject.status==null?"":jsonObject.status; + String matchremark=jsonObject.matchRemark==null?"":jsonObject.matchRemark; + String matchdate=jsonObject.matchDate==null?"":jsonObject.matchDate; + String goldpoint=jsonObject.goldPoint==null?"":jsonObject.goldPoint; + + int pagenumber=jsonObject.pageNum; + int pagesize=jsonObject.pageSize; + scenecalendar= MydpConfigMapper.getscenecalendarlists(scenebigid,sceneid,matchtype,matchname,status,matchremark,pagenumber,pagesize,matchdate,goldpoint); + Long total=MydpConfigMapper.getscenecalendarlistscnt(scenebigid,sceneid,matchtype,matchname,status,matchremark,matchdate,goldpoint); + return getDataTable(scenecalendar,total); + } + + @ApiOperation("根据查询条件导出赛事") + @PostMapping("/exportscenecalendarlist") + public void exportscenecalendarlist(HttpServletResponse response, scene_calendar_entity_list jsonObject) + { + List scenecalendar=new ArrayList(); + + String scenebigid=jsonObject.sceneBigId==null?getSceneStatusIs2():jsonObject.sceneBigId; + List sceneid=jsonObject.sceneIds==null?new ArrayList():jsonObject.sceneIds; + String matchtype=jsonObject.matchType==null?"":jsonObject.matchType; + String matchname=jsonObject.matchName==null?"":jsonObject.matchName; + String status=jsonObject.status==null?"":jsonObject.status; + String matchremark=jsonObject.matchRemark==null?"":jsonObject.matchRemark; + String matchdate=jsonObject.matchDate==null?"":jsonObject.matchDate; + String goldpoint=jsonObject.goldPoint==null?"":jsonObject.goldPoint; + + int pagenumber=1;//jsonObject.pageNum==0?1:jsonObject.pageNum; + int pagesize=100000;//jsonObject.pageSize==0?100000:jsonObject.pageSize; + + scenecalendar = MydpConfigMapper.getscenecalendarlists(scenebigid,sceneid,matchtype,matchname,status,matchremark,pagenumber,pagesize,matchdate,goldpoint); + scenecalendar.forEach((x)->{ + x.setMatchType(DictUtils.getDictLabel("yw_match_type", x.getMatchType())); + if ("1".equals(x.getStatus())) { + x.setStatus("停用"); + } else if ("0".equals(x.getStatus())) { + x.setStatus("启用"); + } + }); + ExcelUtil util = new ExcelUtil(class_scene_calendar.class); + util.exportExcel(response, scenecalendar, "赛事数据"); + } + + //----------------------------------------------新增赛事 + public int getscenecalendarbyName(int sceneId,String name) + { + int counts= MydpConfigMapper.getscenecalendarbyName(sceneId,name); + return counts; + } + + @ApiOperation("新建赛事") + @PostMapping(value = "/newscenecalendar") + public AjaxResult newscenecalendar(@RequestBody scene_calendar_entity_new jsonObject, HttpServletRequest request) + { + String sRet=""; + + int sceneid=jsonObject.sceneId; + String matchtype=jsonObject.matchType==null?"":jsonObject.matchType; + String matchname=jsonObject.matchName==null?"":jsonObject.matchName; + String status=jsonObject.status==null?"":jsonObject.status; + String matchremark=jsonObject.matchRemark==null?"":jsonObject.matchRemark; + + String beginTime=jsonObject.beginTime==null?"00:00":jsonObject.beginTime; + String endTime=jsonObject.endTime==null?"00:00":jsonObject.endTime; + String matchDate=jsonObject.matchDate==null?"2000-01-01":jsonObject.matchDate; + String goldpoint=jsonObject.goldPoint==null?"":jsonObject.goldPoint; + + //--------------需要判断是否已经存在同名的记录 + /*if (getscenecalendarbyName(sceneid,matchname)>0) + { + return AjaxResult.error("赛事"+matchname+"已存在!"); + }*/ + //-------------- + try { + MydpConfigMapper.NewScenecalendar(sceneid,matchtype,matchname,status,matchremark,beginTime,endTime,matchDate,goldpoint); + sRet = "新增成功"; + } catch (Exception e) { + sRet = "新增失败:"+e.getMessage(); + } + //--------------------------------- + return sRet.equals("新增成功")?AjaxResult.success(sRet):AjaxResult.error(sRet); + } + + //----------------------------------------------修改赛事信息 + public int getscenecalendarbyNameForUpdate(int sceneId,String name,int id) + { + int counts= MydpConfigMapper.getscenecalendarbyNameForUpdate(sceneId,name,id); + return counts; + } + + @ApiOperation("修改赛事") + @PutMapping(value = "/updatescenecalendar") + public AjaxResult updatescenecalendar(@RequestBody scene_calendar_entity_upt jsonObject, HttpServletRequest request) + { + String sRet=""; + int id=jsonObject.id; + int sceneid=jsonObject.sceneId; + String matchtype=jsonObject.matchType==null?"":jsonObject.matchType; + String matchname=jsonObject.matchName==null?"":jsonObject.matchName; + String status=jsonObject.status==null?"":jsonObject.status; + String matchremark=jsonObject.matchRemark==null?"":jsonObject.matchRemark; + + String beginTime=jsonObject.beginTime==null?"00:00":jsonObject.beginTime; + String endTime=jsonObject.endTime==null?"00:00":jsonObject.endTime; + String matchDate=jsonObject.matchDate==null?"2000-01-01":jsonObject.matchDate; + String goldpoint=jsonObject.goldPoint==null?"":jsonObject.goldPoint; + + //--------------需要判断是否已经存在同名的记录 + /*if (getscenecalendarbyNameForUpdate(sceneid,matchname,id)>0) + { + return AjaxResult.error("赛事"+matchname+"已存在!"); + }*/ + + try { + MydpConfigMapper.UpdateScenecalendar(id,sceneid,matchtype,matchname,status,matchremark,beginTime,endTime,matchDate,goldpoint); + sRet = "修改成功"; + } catch (Exception e) { + sRet = "修改失败:"+e.getMessage(); + } + //--------------------------------- + return sRet.equals("修改成功")?AjaxResult.success(sRet):AjaxResult.error(sRet); + } + + //----------------------------------------------删除赛事 + @ApiOperation("删除赛事") + @DeleteMapping(value = "/deletescenecalendar/{matchid}") + public AjaxResult deletescenecalendar(@PathVariable int[] matchid,HttpServletRequest request) + { + String sRet=""; + try { + for (int i=0;i(); + sceneteam.dutyScene=new ArrayList(); + sceneteam = MydpConfigMapper.getsceneteam(teamid); + //---------------------- + sceneteam.user=MydpConfigMapper.getsceneteam_user(teamid); + sceneteam.dutyScene=MydpConfigMapper.getsceneteam_dutyscene(teamid); + //---------------------- + return success(sceneteam); + } + + //----------------------------获取当前场景ID + public String getSceneStatusIs2() + { + return MydpConfigMapper.getSceneBigIs2(); + } + + @ApiOperation("根据查询条件获取施工单位") + @PostMapping(value = "/getsceneteamlist") + public TableDataInfo getsceneteamlists(@RequestBody class_scene_team_list jsonObject, HttpServletRequest request) + { + List sceneteam=new ArrayList(); + String scenebigid=jsonObject.sceneBigId==null?getSceneStatusIs2():jsonObject.sceneBigId; + + String specialty=jsonObject.specialty==null?"":jsonObject.specialty; + String venderName=jsonObject.venderName==null?"":jsonObject.venderName; + String status=jsonObject.status==null?"":jsonObject.status; + String county=jsonObject.county==null?"":jsonObject.county; + String city=jsonObject.county==null?"":jsonObject.city; + List sceneIds=jsonObject.sceneIds==null?new ArrayList():jsonObject.sceneIds; + + int pagenumber=jsonObject.pageNum; + int pagesize=jsonObject.pageSize; + sceneteam= MydpConfigMapper.getsceneteamlists(scenebigid,specialty,venderName,status,county,city,sceneIds,pagenumber,pagesize); + Long total=MydpConfigMapper.getsceneteamlistscnt(scenebigid,specialty,venderName,status,county,city,sceneIds); + //---------------------- + for (int i=0;i(); + sceneteam.get(i).dutyScene=new ArrayList(); + //---------------------- + sceneteam.get(i).user=MydpConfigMapper.getsceneteam_user(sceneteam.get(i).id); + sceneteam.get(i).dutyScene=MydpConfigMapper.getsceneteam_dutyscene(sceneteam.get(i).id); + //----------------------- + String sNames=""; + for (int m=0;m0) && (sNames.substring(sNames.length() - 1).equals(","))) + { + sNames = sNames.substring(0, sNames.length() - 1) ; // 去掉最后一个逗号 + sceneteam.get(i).dutySceneNames = sNames; + } + } + //----------------------- + return getDataTable(sceneteam,total); + } + + @ApiOperation("根据查询条件导出施工单位") + @PostMapping("/exportsceneteamlist") + public void exportsceneteamlist(HttpServletResponse response,class_scene_team_list jsonObject) + { + + List sceneteam=new ArrayList(); + String scenebigid=jsonObject.sceneBigId==null?getSceneStatusIs2():jsonObject.sceneBigId; + + String specialty=jsonObject.specialty==null?"":jsonObject.specialty; + String venderName=jsonObject.venderName==null?"":jsonObject.venderName; + String status=jsonObject.status==null?"":jsonObject.status; + String county=jsonObject.county==null?"":jsonObject.county; + String city=jsonObject.county==null?"":jsonObject.city; + List sceneIds=jsonObject.sceneIds==null?new ArrayList():jsonObject.sceneIds; + + int pagenumber=1; //jsonObject.pageNum==0?1:jsonObject.pageNum; + int pagesize=100000; //jsonObject.pageSize==0?100000:jsonObject.pageSize; + + sceneteam = MydpConfigMapper.getsceneteamlists(scenebigid,specialty,venderName,status,county,city,sceneIds,pagenumber,pagesize); + //----------------------- + for (int i=0;i(); + sceneteam.get(i).dutyScene=new ArrayList(); + //---------------------- + sceneteam.get(i).user=MydpConfigMapper.getsceneteam_user(sceneteam.get(i).id); + sceneteam.get(i).dutyScene=MydpConfigMapper.getsceneteam_dutyscene(sceneteam.get(i).id); + //----------------------- + String sNames=""; + for (int m=0;m0) && (sNames.substring(sNames.length() - 1).equals(","))) + { + sNames = sNames.substring(0, sNames.length() - 1) ; // 去掉最后一个逗号 + sceneteam.get(i).dutySceneNames = sNames; + } + } + + ExcelUtil util = new ExcelUtil(class_scene_team.class); + util.exportExcel(response, sceneteam, "施工单位数据"); + } + + + //----------------------------------------------新增施工单位 + public int getsceneteambyName(String vendername) + { + int counts= MydpConfigMapper.getsceneteambyName(vendername); + return counts; + } + + @ApiOperation("新建施工单位") + @PostMapping(value = "/newsceneteam") + public AjaxResult newsceneteam(@RequestBody class_scene_team_new jsonObject, HttpServletRequest request) + { + String sRet=""; + + int sceneBigId=jsonObject.sceneBigId==0?Integer.parseInt(getSceneStatusIs2()):jsonObject.sceneBigId; + + String specialty=jsonObject.specialty==null?"":jsonObject.specialty; + String venderName=jsonObject.venderName==null?"":jsonObject.venderName; + String status=jsonObject.status==null?"":jsonObject.status; + String county=jsonObject.county==null?"":jsonObject.county; + String city=jsonObject.county==null?"":jsonObject.city; + String remark=jsonObject.remark==null?"":jsonObject.remark; + + List dutySceneIds=jsonObject.dutySceneIds==null?new ArrayList():jsonObject.dutySceneIds; + // List userIds=jsonObject.userIds; + + //--------------需要判断是否已经存在同名的记录 + if (getsceneteambyName(venderName)>0) + { + return AjaxResult.error("施工单位"+venderName+"已存在!"); + } + //-------------- + try { + MydpConfigMapper.NewSceneteam(sceneBigId,specialty,venderName,status,county,city,remark,dutySceneIds); + sRet = "新增成功"; + } catch (Exception e) { + sRet = "新增失败:"+e.getMessage(); + } + //--------------------------------- + return sRet.equals("新增成功")?AjaxResult.success(sRet):AjaxResult.error(sRet); + } + + //--------------------------修改施工单位信息 + public int getsceneteambyNameForUpdate(String vendername,int id) + { + int counts= MydpConfigMapper.getsceneteambyNameForUpdate(vendername,id); + return counts; + } + + @ApiOperation("修改施工单位") + @PutMapping(value = "/updatesceneteam") + public AjaxResult updatesceneteam(@RequestBody class_scene_team_upt jsonObject, HttpServletRequest request) + { + String sRet=""; + int id=jsonObject.id; + int sceneBigId=jsonObject.sceneBigId==0?Integer.parseInt(getSceneStatusIs2()):jsonObject.sceneBigId; + + String specialty=jsonObject.specialty==null?"":jsonObject.specialty; + String venderName=jsonObject.venderName==null?"":jsonObject.venderName; + String status=jsonObject.status==null?"":jsonObject.status; + String county=jsonObject.county==null?"":jsonObject.county; + String city=jsonObject.county==null?"":jsonObject.city; + String remark=jsonObject.remark==null?"":jsonObject.remark; + + List dutySceneIds=jsonObject.dutySceneIds==null?new ArrayList():jsonObject.dutySceneIds; + // List userIds=jsonObject.userIds; + //--------------需要判断是否已经存在同名的记录 + if (getsceneteambyNameForUpdate(venderName,id)>0) + { + return AjaxResult.error("施工单位"+venderName+"已存在!"); + } + + try { + MydpConfigMapper.UpdateSceneteam(id,sceneBigId,specialty,venderName,status,county,city,remark,dutySceneIds); + sRet = "修改成功"; + } catch (Exception e) { + sRet = "修改失败:"+e.getMessage(); + } + //--------------------------------- + return sRet.equals("修改成功")?AjaxResult.success(sRet):AjaxResult.error(sRet); + } + + //----------------------------------------------删除施工单位 + @ApiOperation("删除施工单位") + @DeleteMapping(value = "/deletesceneteam/{teamid}") + public AjaxResult deletesceneteam(@PathVariable int[] teamid,HttpServletRequest request) + { + String sRet=""; + try { + for (int i=0;i publicnews=new ArrayList(); + String scenebigid=jsonObject.sceneBigId==null?getSceneStatusIs2():jsonObject.sceneBigId; + String title=jsonObject.title==null?"":jsonObject.title; + + String content=jsonObject.content==null?"":jsonObject.content; + int pagenumber=jsonObject.pageNum; + int pagesize=jsonObject.pageSize; + + publicnews = MydpConfigMapper.getpublicnewslists(scenebigid,title,content,pagenumber,pagesize); + Long total=MydpConfigMapper.getpublicnewslistscnt(scenebigid,title,content); + return getDataTable(publicnews,total); + } + + @ApiOperation("根据查询条件导出公众新闻") + @PostMapping("/exportpublicnewslist") + public void exportpublicnewslist(HttpServletResponse response, class_public_news_list jsonObject) + { + List publicnews=new ArrayList(); + String scenebigid=jsonObject.sceneBigId==null?getSceneStatusIs2():jsonObject.sceneBigId; + String title=jsonObject.title==null?"":jsonObject.title; + + String content=jsonObject.content==null?"":jsonObject.content; + + int pagenumber=1; //jsonObject.pageNum==0?1:jsonObject.pageNum; + int pagesize=100000; //jsonObject.pageSize==0?100000:jsonObject.pageSize; + + publicnews = MydpConfigMapper.getpublicnewslists(scenebigid,title,content,pagenumber,pagesize); + ExcelUtil util = new ExcelUtil(class_public_news.class); + util.exportExcel(response, publicnews, "公众新闻数据"); + } + + //----------------------------------------------新增公众新闻 + public int getpublicnewsbyName(String sceneBigId,String title) + { + int counts= MydpConfigMapper.getpublicnewsbyName(Integer.parseInt(sceneBigId),title); + return counts; + } + + @ApiOperation("新建公众新闻") + @PostMapping(value = "/newpublicnews") + public AjaxResult newpublicnews(@RequestBody class_public_news_new jsonObject, HttpServletRequest request) + { + String sRet=""; + String scenebigid=jsonObject.sceneBigId==null?getSceneStatusIs2():jsonObject.sceneBigId; + String title=jsonObject.title==null?"":jsonObject.title; + String url=jsonObject.contentUrl==null?"":jsonObject.contentUrl; + String content=jsonObject.content==null?"":jsonObject.content; + String username=jsonObject.updateBy==null?"":jsonObject.updateBy; + //--------------需要判断是否已经存在同名的记录 + if (getpublicnewsbyName(scenebigid,title)>0) + { + return AjaxResult.error("新闻标题"+title+"已存在!"); + } + //-------------- + try { + MydpConfigMapper.Newpublicnews(Integer.parseInt(scenebigid),title,url,content,username); + sRet = "新增成功"; + } catch (Exception e) { + sRet = "新增失败:"+e.getMessage(); + } + //--------------------------------- + return sRet.equals("新增成功")?AjaxResult.success(sRet):AjaxResult.error(sRet); + } + + //----------------------------------------------修改 + public int getpublicnewsbyNameForUpdate(String sceneBigId,String title,int id) + { + int counts= MydpConfigMapper.getpublicnewsbyNameForUpdate(Integer.parseInt(sceneBigId),title,id); + return counts; + } + + @ApiOperation("修改公众新闻") + @PutMapping(value = "/updatepublicnews") + public AjaxResult updatepublicnews(@RequestBody class_public_news_upt jsonObject, HttpServletRequest request) + { + String sRet=""; + int id=jsonObject.id; + String scenebigid=jsonObject.sceneBigId==null?getSceneStatusIs2():jsonObject.sceneBigId; + String title=jsonObject.title==null?"":jsonObject.title; + String url=jsonObject.contentUrl==null?"":jsonObject.contentUrl; + String content=jsonObject.content==null?"":jsonObject.content; + String username=jsonObject.updateBy==null?"":jsonObject.updateBy; + //----------------------------------------- + if (getpublicnewsbyNameForUpdate(scenebigid,title,id)>0) + { + return AjaxResult.error("新闻标题"+title+"已存在!"); + } + try { + MydpConfigMapper.UpdatePublicNews(id,Integer.parseInt(scenebigid),title,url,content,username); + sRet = "修改成功"; + } catch (Exception e) { + sRet = "修改失败:"+e.getMessage(); + } + //--------------------------------- + return sRet.equals("修改成功")?AjaxResult.success(sRet):AjaxResult.error(sRet); + } + + //----------------------------------------------删除 + @ApiOperation("删除公众新闻") + @DeleteMapping(value = "/deletepublicnews/{newsid}") + public AjaxResult deletepublicnews(@PathVariable int[] newsid,HttpServletRequest request) + { + String sRet=""; + try { + for (int i=0;i medalstand=new ArrayList(); + String scenebigid=jsonObject.sceneBigId==null?getSceneStatusIs2():jsonObject.sceneBigId; + String areaName=jsonObject.areaName==null?"":jsonObject.areaName; + + int pagenumber=jsonObject.pageNum; + int pagesize=jsonObject.pageSize; + + medalstand = MydpConfigMapper.getmedalstandlists(scenebigid,areaName,pagenumber,pagesize); + Long total=MydpConfigMapper.getmedalstandlistscnt(scenebigid,areaName); + return getDataTable(medalstand,total); + } + + @ApiOperation("根据查询条件导出奖牌榜") + @PostMapping("/exportmedalstandlist") + public void exportmedalstandlist(HttpServletResponse response, class_medal_stand_list jsonObject) + { + List medalstand=new ArrayList(); + String scenebigid=jsonObject.sceneBigId==null?getSceneStatusIs2():jsonObject.sceneBigId; + String areaName=jsonObject.areaName==null?"":jsonObject.areaName; + + int pagenumber=1; //jsonObject.pageNum==0?1:jsonObject.pageNum; + int pagesize=100000; //jsonObject.pageSize==0?100000:jsonObject.pageSize; + + medalstand = MydpConfigMapper.getmedalstandlists(scenebigid,areaName,pagenumber,pagesize); + ExcelUtil util = new ExcelUtil(class_medal_stand.class); + util.exportExcel(response, medalstand, "奖牌榜数据"); + } + + //----------------------------------------------新增 + public int getmedalstandbyName(String sceneBigId,String areaName) + { + int scenebigid=Integer.parseInt(sceneBigId); + int counts= MydpConfigMapper.getmedalstandbyName(scenebigid,areaName); + return counts; + } + + ////TEST : {"areaName":"CHAOXIAN","goldCount":10,"silverCount":1,"bronzeCount":10,"medalsCount":21,"updateBy":"ME"} + @ApiOperation("新建奖牌榜") + @PostMapping(value = "/newmedalstand") + public AjaxResult newmedalstand(@RequestBody class_medal_stand_new jsonObject, HttpServletRequest request) + { + String sRet=""; + String scenebigid=jsonObject.sceneBigId==null?getSceneStatusIs2():jsonObject.sceneBigId; + String areaName=jsonObject.areaName==null?"":jsonObject.areaName; + String goldCount=jsonObject.goldCount==null?"0":jsonObject.goldCount; + String silverCount=jsonObject.silverCount==null?"0":jsonObject.silverCount; + String medalsCount=jsonObject.medalsCount==null?"0":jsonObject.medalsCount; + String bronzeCount=jsonObject.bronzeCount==null?"0":jsonObject.bronzeCount; + String username=jsonObject.updateBy==null?"":jsonObject.updateBy; + //--------------需要判断是否已经存在同名的记录 + if (getmedalstandbyName(scenebigid,areaName)>0) + { + return AjaxResult.error("国家或地区"+areaName+"已存在!"); + } + //-------------- + try { + MydpConfigMapper.Newmedalstand(Integer.parseInt(scenebigid),areaName,Integer.parseInt(goldCount), + Integer.parseInt(silverCount),Integer.parseInt(bronzeCount),Integer.parseInt(medalsCount),username); + sRet = "新增成功"; + } catch (Exception e) { + sRet = "新增失败:"+e.getMessage(); + } + //--------------------------------- + return sRet.equals("新增成功")?AjaxResult.success(sRet):AjaxResult.error(sRet); + } + + //----------------------------------------------修改 + //TEST : {"id":3,"areaName":"中国","goldCount":20,"silverCount":1,"bronzeCount":10,"medalsCount":31,"updateBy":"ME"} + + public int getmedalstandbyNameForUpdate(String sceneBigId,String areaName,int id) + { + int scenebigid=Integer.parseInt(sceneBigId); + int counts= MydpConfigMapper.getmedalstandbyNameForUpdate(scenebigid,areaName,id); + return counts; + } + + @ApiOperation("修改奖牌榜") + @PutMapping(value = "/updatemedalstand") + public AjaxResult updatemedalstand(@RequestBody class_medal_stand_upt jsonObject, HttpServletRequest request) + { + String sRet=""; + int id=jsonObject.id; + String scenebigid=jsonObject.sceneBigId==null?getSceneStatusIs2():jsonObject.sceneBigId; + String areaName=jsonObject.areaName==null?"":jsonObject.areaName; + String goldCount=jsonObject.goldCount==null?"0":jsonObject.goldCount; + String silverCount=jsonObject.silverCount==null?"0":jsonObject.silverCount; + String medalsCount=jsonObject.medalsCount==null?"0":jsonObject.medalsCount; + String bronzeCount=jsonObject.bronzeCount==null?"0":jsonObject.bronzeCount; + String username=jsonObject.updateBy==null?"":jsonObject.updateBy; + //--------------需要判断是否已经存在同名的记录 + if (getmedalstandbyNameForUpdate(scenebigid,areaName,id)>0) + { + return AjaxResult.error("国家或地区"+areaName+"已存在!"); + } + try { + MydpConfigMapper.Updatemedalstand(id,Integer.parseInt(scenebigid),areaName,Integer.parseInt(goldCount), + Integer.parseInt(silverCount),Integer.parseInt(bronzeCount),Integer.parseInt(medalsCount),username); + sRet = "修改成功"; + } catch (Exception e) { + sRet = "修改失败:"+e.getMessage(); + } + //--------------------------------- + return sRet.equals("修改成功")?AjaxResult.success(sRet):AjaxResult.error(sRet); + } + + //----------------------------------------------删除 + @ApiOperation("删除奖牌榜") + @DeleteMapping(value = "/deletemedalstand/{medalid}") + public AjaxResult deletemedalstand(@PathVariable int[] medalid,HttpServletRequest request) + { + String sRet=""; + try { + for (int i=0;i scenematch=new ArrayList(); + + String scenebigid=jsonObject.sceneBigId==null?getSceneStatusIs2():jsonObject.sceneBigId; + List sceneid=jsonObject.sceneIds==null?new ArrayList():jsonObject.sceneIds; + String taskName=jsonObject.taskName==null?"":jsonObject.taskName; + String taskStatus=jsonObject.taskStatus==null?"":jsonObject.taskStatus; + String taskdate=jsonObject.taskDate==null?"":jsonObject.taskDate; + + String tasktype=jsonObject.taskType==null?"":jsonObject.taskType; + + int pagenumber=jsonObject.pageNum; + int pagesize=jsonObject.pageSize; + scenematch= MydpConfigMapper.getscenematchlists(scenebigid,sceneid,taskName,taskStatus,taskdate,tasktype,pagenumber,pagesize); + + Long total=MydpConfigMapper.getscenematchlistscnt(scenebigid,sceneid,taskName,taskStatus,taskdate,tasktype); + return getDataTable(scenematch,total); + } + + @ApiOperation("根据查询条件导出赛程") + @PostMapping("/exportscenematchlist") + public void exportscenematchlist(HttpServletResponse response, scene_match_entity_list jsonObject) + { + List scenematch=new ArrayList(); + + String scenebigid=jsonObject.sceneBigId==null?getSceneStatusIs2():jsonObject.sceneBigId; + List sceneid=jsonObject.sceneIds==null?new ArrayList():jsonObject.sceneIds; + String taskName=jsonObject.taskName==null?"":jsonObject.taskName; + String taskStatus=jsonObject.taskStatus==null?"":jsonObject.taskStatus; + String taskdate=jsonObject.taskDate==null?"":jsonObject.taskDate; + + String tasktype=jsonObject.taskType==null?"":jsonObject.taskType; + + int pagenumber=1;//jsonObject.pageNum==0?1:jsonObject.pageNum; + int pagesize=100000;//jsonObject.pageSize==0?100000:jsonObject.pageSize; + + scenematch = MydpConfigMapper.getscenematchlists(scenebigid,sceneid,taskName,taskStatus,taskdate,tasktype,pagenumber,pagesize); + scenematch.forEach((x)->{ + x.setTaskType(DictUtils.getDictLabel("yw_match_type", x.getTaskType()));}); + ExcelUtil util = new ExcelUtil(class_scene_match.class); + util.exportExcel(response, scenematch, "赛程数据"); + } + + //----------------------------------------------新增 + public int getscenematchbyName(int sceneId,String name) + { + int counts= MydpConfigMapper.getscenematchbyName(sceneId,name); + return counts; + } + + @ApiOperation("新建赛程") + @PostMapping(value = "/newscenematch") + public AjaxResult newscenematch(@RequestBody scene_match_entity_new jsonObject, HttpServletRequest request) + { + String sRet=""; + + int sceneid=jsonObject.sceneId; + String taskName=jsonObject.taskName==null?"":jsonObject.taskName; + String taskStatus=jsonObject.taskStatus==null?"":jsonObject.taskStatus; + + String taskType=jsonObject.taskType==null?"":jsonObject.taskType; + + String beginTime=jsonObject.beginTime==null?"00:00":jsonObject.beginTime; + String endTime=jsonObject.endTime==null?"00:00":jsonObject.endTime; + String createBy=jsonObject.createBy==null?"":jsonObject.createBy; + + //--------------需要判断是否已经存在同名的记录 + if (getscenematchbyName(sceneid,taskName)>0) + { + return AjaxResult.error("赛程"+taskName+"已存在!"); + } + //-------------- + try { + MydpConfigMapper.NewScenematch(sceneid,taskName,taskStatus,taskType,beginTime,endTime,createBy); + sRet = "新增成功"; + } catch (Exception e) { + sRet = "新增失败:"+e.getMessage(); + } + //--------------------------------- + return sRet.equals("新增成功")?AjaxResult.success(sRet):AjaxResult.error(sRet); + } + + //----------------------------------------------修改信息 + public int getscenematchbyNameForUpdate(int sceneId,String name,int id) + { + int counts= MydpConfigMapper.getscenematchbyNameForUpdate(sceneId,name,id); + return counts; + } + + @ApiOperation("修改赛程") + @PutMapping(value = "/updatescenematch") + public AjaxResult updatescenematch(@RequestBody scene_match_entity_upt jsonObject, HttpServletRequest request) + { + String sRet=""; + int id=jsonObject.id; + int sceneid=jsonObject.sceneId; + + String taskName=jsonObject.taskName==null?"":jsonObject.taskName; + String taskStatus=jsonObject.taskStatus==null?"":jsonObject.taskStatus; + + String taskType=jsonObject.taskType==null?"":jsonObject.taskType; + + String beginTime=jsonObject.beginTime==null?"00:00":jsonObject.beginTime; + String endTime=jsonObject.endTime==null?"00:00":jsonObject.endTime; + String updateBy=jsonObject.updateBy==null?"":jsonObject.updateBy; + + //--------------需要判断是否已经存在同名的记录 + if (getscenematchbyNameForUpdate(sceneid,taskName,id)>0) + { + return AjaxResult.error("赛程"+taskName+"已存在!"); + } + try { + MydpConfigMapper.UpdateScenematch(id,sceneid,taskName,taskStatus,taskType,beginTime,endTime,updateBy); + sRet = "修改成功"; + } catch (Exception e) { + sRet = "修改失败:"+e.getMessage(); + } + //--------------------------------- + return sRet.equals("修改成功")?AjaxResult.success(sRet):AjaxResult.error(sRet); + } + + //----------------------------------------------删除 + @ApiOperation("删除赛程") + @DeleteMapping(value = "/deletescenematch/{matchid}") + public AjaxResult deletescenematch(@PathVariable int[] matchid,HttpServletRequest request) + { + String sRet=""; + try { + for (int i=0;i alarmlist = new ArrayList<>(); + String key = CacheConstants.YW_TRANS_ALARM; + if (redisCache.hasKey(key)) { + alarmlist = redisCache.getCacheObject(key); + } else { + alarmlist = dpNewYayunChuanDongMapper.get_trans_alarms_list(level, sceneid, alarmtype); + } + alarmlist = alarmlist.stream().filter(e -> e.getAlarmtype().equals(alarmtype)).collect(Collectors.toList()); + alarmlist = alarmlist.stream().limit(20).collect(Collectors.toList()); + return success(alarmlist); + } + //endregion + + + //region --------------------------------------------------------------------------------------------传动:机房环境告警 + @ApiOperation("传动:机房环境告警清单,level:1 全域,2 城区,3 场馆;sceneid:场馆id(根据需要传)") + @GetMapping(value = "/get_machineroom_alarms_list") + public AjaxResult get_machineroom_alarms_list( + @RequestParam int level, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid, + HttpServletRequest request) { + List alarmlist = new ArrayList(); //结构通用 + String key = CacheConstants.YW_MACHINEROOM_ALARM; + if (redisCache.hasKey(key)) { + alarmlist = redisCache.getCacheObject(key); + } else { + alarmlist = dpNewYayunChuanDongMapper.get_machineroom_alarms_all_list(); + } + return success(alarmlist); + } + //endregion + + + //region -------------------------------------------------------------------------------------------传动:环路流量TOP5 + @ApiOperation("传动:环路流量TOP5统计,level:1 全域,2 城区,3 场馆;sceneid:场馆id(根据需要传)") + @GetMapping(value = "/get_huanlu_top5") + public AjaxResult get_huanlu_top5(@RequestParam int level, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid, + HttpServletRequest request) { + List alarmlist = new ArrayList<>(); //结构通用 + String key = CacheConstants.YW_GB_TOP5; + if (redisCache.hasKey(key)) { + alarmlist = redisCache.getCacheObject(key); + } else { + alarmlist = dpNewYayunChuanDongMapper.get_huanlu_top5_all(); + } + return success(alarmlist); + } + //endregion + + + //region --------------------------------------------------------------------------------------------传动:光功率清单 + @ApiOperation("传动:光功率清单清单,level:1 全域,2 城区,3 场馆;sceneid:场馆id(根据需要传)") + @GetMapping(value = "/get_opticalpower_list") + public AjaxResult get_opticalpower_list( + @RequestParam int level, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid, + HttpServletRequest request) { + List list = new ArrayList(); + String key = CacheConstants.YW_OPTICALPOWER; + if (redisCache.hasKey(key)) { + list = redisCache.getCacheObject(key); + } else { + list = dpNewYayunChuanDongMapper.get_opticalpower_all_list(); + } + return success(list); + } + //endregion + + + //region --------------------------------------------------------------------------------------------传动:中间地图告警显示接口 + @ApiOperation("传动:中间地图告警显示接口: level:0: 全部,1 全域,2 城区 ") + @GetMapping(value = "/get_maps_all_trans_alarms") + public AjaxResult get_maps_all_trans_alarms(@RequestParam int level, HttpServletRequest request) { + List dpdata = new ArrayList(); + String key = CacheConstants.YW_TRANS_MAP; + if (redisCache.hasKey(key)) { + dpdata = redisCache.getCacheObject(key); + } else { + dpdata = dpNewYayunChuanDongMapper.get_maps_all_alarms(); + List alarmsList = dpNewYayunChuanDongMapper.get_maps_alarms_all_alarms(); + List poweralarmlist = dpNewYayunChuanDongMapper.get_machineroom_alarms_all_list(); + Map> map = new HashMap<>(); + Map> powermap = new HashMap<>(); + if (CollectionUtil.isNotEmpty(alarmsList)) { + map = alarmsList.stream().collect(Collectors.groupingBy(class_dp_map_alarms::getSceneid)); + } + + if (CollectionUtil.isNotEmpty(poweralarmlist)) { + powermap = poweralarmlist.stream().collect(Collectors.groupingBy(class_dp_2_power_alarm::get场馆id)); + } + + for (class_dp_4_maps_alarms dpdatum : dpdata) { + List alarms = new ArrayList<>(); + if (dpdatum.getAlarmcount() > 0) { + List sceneList = map.get(Long.valueOf(dpdatum.getVenueid())); + alarms.addAll(sceneList); + } + + if (CollectionUtil.isNotEmpty(powermap)) { + List powerlist = powermap.get(dpdatum.getVenueid() + ""); + if (CollectionUtil.isNotEmpty(powerlist)) { + for (class_dp_2_power_alarm powerAlarm : powerlist) { + class_dp_map_alarms alarm = new class_dp_map_alarms(); + BeanUtil.copyProperties(powerAlarm, alarm); + alarm.setMajor("动环"); + alarm.setHandlepeople(powerAlarm.get故障处理人()); + alarm.setSceneid(Long.valueOf(powerAlarm.get场馆id())); + alarm.setNetname(powerAlarm.getSiteName()); + alarms.add(alarm); + + } + dpdatum.setAlarmcount(dpdatum.getAlarmcount() + powerlist.size()); + dpdatum.setPowercount(powerlist.size()); + } + + } + dpdatum.setLists(alarms); + } + } + return success(dpdata); + } + //endregion + + + // 大屏的第三屏:专网 + + //region --------------------------------------------------------------------------------------------专网:传输告警清单 + @ApiOperation("专网:传输告警清单,level:1 全域,2 城区,3 场馆;sceneid:场馆id(根据需要传),alarmtype:告警类型:AGIS/WIFI/VOIP") + @GetMapping(value = "/get_net_alarms_list") + public AjaxResult get_net_alarms_list(@RequestParam int level, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") Long sceneid, + @RequestParam String alarmtype, + HttpServletRequest request) { + List alarmlist = new ArrayList<>(); + String key = CacheConstants.YW_NET_ALARM; + if (redisCache.hasKey(key)) { + alarmlist = redisCache.getCacheObject(key); + } else { + alarmlist = dpNewYayunZhuanWangMapper.get_net_alarms_all_list(); + } + alarmlist = alarmlist.stream().filter(e -> e.getAlarmtype().equals(alarmtype)).collect(Collectors.toList()); + if (level == 1 || level == 2) { + alarmlist = alarmlist.stream().limit(20).collect(Collectors.toList()); + } else { + alarmlist = alarmlist.stream().filter(e -> e.getSceneid().equals(sceneid)).limit(20).collect(Collectors.toList()); + } + return success(alarmlist); + } + //endregion + + + //region --------------------------------------------------------------------------------------------专网:中间地图告警显示接口 + @ApiOperation("专网:中间地图告警显示接口: level:0: 全部,1 全域,2 城区 ") + @GetMapping(value = "/get_maps_all_net_alarms") + public AjaxResult get_maps_all_net_alarms(@RequestParam int level, HttpServletRequest request) { + List dpdata = new ArrayList<>(); + String key = CacheConstants.YW_NET_MAP; + if (redisCache.hasKey(key)) { + dpdata = redisCache.getCacheObject(key); + } else { + dpdata = dpNewYayunZhuanWangMapper.get_maps_all_alarms(); + List alarmsList = dpNewYayunZhuanWangMapper.get_map_alarms_all_list(); + List linkAllList = dpNewYayunZhuanWangMapper.get_map_agis_link_all_list(); + List devAllList = dpNewYayunZhuanWangMapper.get_map_agis_dev_all_list(); + Map> map = new HashMap<>(); + Map> linkmap = new HashMap<>(); + Map> devmap = new HashMap<>(); + if (CollectionUtil.isNotEmpty(alarmsList)) { + map = alarmsList.stream().collect(Collectors.groupingBy(class_dp_map_alarms::getSceneid)); + } + if (CollectionUtil.isNotEmpty(linkAllList)) { + linkmap = linkAllList.stream().collect(Collectors.groupingBy(class_dp_map_agis_link_5mi::getVenueid)); + } + if (CollectionUtil.isNotEmpty(devAllList)) { + devmap = devAllList.stream().collect(Collectors.groupingBy(class_dp_map_agis_dev_15mi::getVenueid)); + } + for (class_dp_3_maps_alarms dpdatum : dpdata) { + if (dpdatum.getAlarmcount() > 0) { + List sceneList = map.get(Long.valueOf(dpdatum.getVenueid())); + dpdatum.setLists(sceneList); + } + if (CollectionUtil.isNotEmpty(linkmap)) { + dpdatum.setLinklists(linkmap.get(Long.valueOf(dpdatum.getVenueid()))); + } + if (CollectionUtil.isNotEmpty(devmap)) { + dpdatum.setDevlists(devmap.get(Long.valueOf(dpdatum.getVenueid()))); + } + } + } + return success(dpdata); + } + //endregion + + + //region--------------------------------------------------------------------------------------专网:大屏内外场坐席告警接口 + @ApiOperation(value = "专网:功能区的告警和性能输出") + @GetMapping("/get_code_net_alarms") + @Anonymous + public AjaxResult get_code_net_alarms( + @RequestParam int level, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid, + HttpServletRequest request) { + List codeList = new ArrayList<>(); + String key = CacheConstants.YW_NET_CODE_AGIS; + if (redisCache.hasKey(key)) { + codeList = redisCache.getCacheObject(key); + } else { + codeList = dpNewYayunZhuanWangMapper.get_code_all_list(); + List alarmList = dpNewYayunZhuanWangMapper.get_code_alarms_all_list(); + List devAllList = dpNewYayunZhuanWangMapper.get_code_agis_dev_all_list(); + Map> map = new HashMap<>(); + Map> devmap = new HashMap<>(); + + if (CollectionUtil.isNotEmpty(alarmList)) { + map = alarmList.stream().collect(Collectors.groupingBy(class_dp_map_alarms::getCode)); + } + + if (CollectionUtil.isNotEmpty(devAllList)) { + devmap = devAllList.stream().collect(Collectors.groupingBy(class_dp_map_agis_dev_15mi::getCode)); + } + + for (class_dp_2_code_net_alarms codeNetAlarm : codeList) { + if (CollectionUtil.isNotEmpty(map)) { + codeNetAlarm.setLists(map.get(codeNetAlarm.getCode())); + if (CollectionUtil.isNotEmpty(map.get(codeNetAlarm.getCode()))) { + codeNetAlarm.setAlarmcount(map.get(codeNetAlarm.getCode()).size()); + } + } + if (CollectionUtil.isNotEmpty(devmap)) { + codeNetAlarm.setKpilist(devmap.get(codeNetAlarm.getCode())); + } + } + } + return success(codeList); + } + //endregion + + + //region -------------------------------------------------------------------------------------专网:AGIS交换机利用率 + + @ApiOperation("专网:AGIS交换机利用率TOP5接口,level:1. 全域, 2:城区,3:场馆;sceneid:场馆id;typeid:1:cpu,2:ram") + @GetMapping(value = "/get_agis_switch") + public AjaxResult get_agis_switch( + @RequestParam int level, + @RequestParam int typeid, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid) { + String keyname = "dp_2_agis_switch_" + String.valueOf(level) + "_" + String.valueOf(typeid) + "_" + String.valueOf(sceneid); + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List lstData = redisCache.getCacheObject(keyname); + return success(lstData); + } + //--------------------------------------------------------------------读数据库 + List dpData = new ArrayList(); + dpData = dpNewYayunZhuanWangMapper.get_agis_switch(level, typeid, sceneid); + //---------------------- + //int cachesecond=getcachesecond(); + redisCache.setCacheObject(keyname, dpData, 58, TimeUnit.SECONDS); //数据放缓存 + return success(dpData); + } + //endregion + + //region -------------------------------------------------------------------------------------专网:AGIS链路带宽利用率 + + @ApiOperation("专网:AGIS链路带宽利用率TOP5接口,level:1. 全域, 2:城区,3:场馆;sceneid:场馆id;typeid:1:上行,2:下行") + @GetMapping(value = "/get_agis_bandwidth") + public AjaxResult get_agis_bandwidth( + @RequestParam int level, + @RequestParam int typeid, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid) { + String keyname = "dp_2_agis_bandwidth_" + String.valueOf(level) + "_" + String.valueOf(typeid) + "_" + String.valueOf(sceneid); + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List lstData = redisCache.getCacheObject(keyname); + return success(lstData); + } + //--------------------------------------------------------------------读数据库 + List dpData = new ArrayList(); + dpData = dpNewYayunZhuanWangMapper.get_agis_bandwidth(level, typeid, sceneid); + //---------------------- + //int cachesecond=getcachesecond(); + redisCache.setCacheObject(keyname, dpData, 58, TimeUnit.SECONDS); //数据放缓存 + return success(dpData); + } + //endregion + + //region -------------------------------------------------------------------------------------专网:AGIS链路利用率 + + @ApiOperation("专网:AGIS链路利用率TOP5接口,level:1. 全域, 2:城区,3:场馆;sceneid:场馆id;typeid:1:上行,2:下行") + @GetMapping(value = "/get_agis_link") + public AjaxResult get_agis_link( + @RequestParam int level, + @RequestParam int typeid, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid) { + String keyname = "dp_2_agis_link_" + String.valueOf(level) + "_" + String.valueOf(typeid) + "_" + String.valueOf(sceneid); + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List lstData = redisCache.getCacheObject(keyname); + return success(lstData); + } + //--------------------------------------------------------------------读数据库 + List dpData = new ArrayList(); + dpData = dpNewYayunZhuanWangMapper.get_agis_link(level, typeid, sceneid); + //---------------------- + //int cachesecond=getcachesecond(); + redisCache.setCacheObject(keyname, dpData, 58, TimeUnit.SECONDS); //数据放缓存 + return success(dpData); + } + //endregion + + //region -------------------------------------------------------------------------------------专网:互联网用户数 + + @ApiOperation("专网:互联网用户数TOP5接口,level:1. 全域, 2:城区") + @GetMapping(value = "/get_internet_usercount") + public AjaxResult get_internet_usercount( + @RequestParam int level) { + String keyname = "dp_2_internet_usercount_" + String.valueOf(level); + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List lstData = redisCache.getCacheObject(keyname); + return success(lstData); + } + //--------------------------------------------------------------------读数据库 + List dpData = new ArrayList(); + dpData = dpNewYayunZhuanWangMapper.get_internet_usercount(level); + //---------------------- + //int cachesecond=getcachesecond(); + redisCache.setCacheObject(keyname, dpData, 58, TimeUnit.SECONDS); //数据放缓存 + return success(dpData); + } + //endregion + + + // 大屏的第六屏:综合管理 + //region --------------------------------------------------------------------------------------------综合管理:(场馆页面) + + /** + * 场馆级统计数据 + * + * @param sceneid 场馆id + * @return 返回数据 + */ + @ApiOperation(value = "场馆级统计数据", notes = "场馆级统计数据") + @GetMapping("/getMsgByScene") + public AjaxResult getMsgByScene(@RequestParam("sceneid") Long sceneid) { + Map result = new HashMap<>(); + Long[] ids = new Long[]{2L, 25L, 42L}; + if (Arrays.asList(ids).contains(sceneid)) { + String key = CacheConstants.YW_COM_MANAGE_SCENE; + if (redisCache.hasKey(key)) { + Map map = redisCache.getCacheObject(key); + result = (Map) map.get("scene_" + sceneid); + } else { + result = getMassage(sceneid); + } + } else { + result = getMassage(sceneid); + } + return AjaxResult.success(result); + } + + private Map getMassage(Long sceneid) { + Map result = new HashMap<>(); + //场馆基本信息 + JSONObject baseinfo = ywScenePictureService.listMatchTop3(sceneid); + result.put("baseinfo", baseinfo); + //任务管理统计 + JSONObject task = ywScenePictureService.listTaskManage2(sceneid,true); + result.put("task", task); + //人员签到统计 + JSONObject sign = ywScenePictureService.listSign(sceneid); + result.put("sign", sign); + //drs管理 + LocalDate date = LocalDate.now(); + List drs = ywDrsTempTaskService.drsPreview(sceneid, date); + result.put("drs", drs); + return result; + } + //endregion + + + //region --------------------------------------------------------------------------------------------综合管理:场馆统计信息(全域和城区) + + @ApiOperation(value = "场馆统计信息", notes = "场馆统计信息") + @GetMapping("/get_statistics") + public AjaxResult getStatistics(@RequestParam int level, HttpServletRequest request) { + class_dp_5_scenesta result = new class_dp_5_scenesta(); + String key = CacheConstants.YW_COM_MANAGE_ALL; + if (redisCache.hasKey(key)) { + Map map = redisCache.getCacheObject(key); + result = (class_dp_5_scenesta) map.get("scenesta"); + } else { + result = dpNewYayunZongHeMapper.get_scene_sta(); + } + return AjaxResult.success(result); + } + //endregion + + //region --------------------------------------------------------------------------------------------综合管理:签到率top5(全域和城区) + + @ApiOperation(value = "签到率top5", notes = "签到率top5") + @GetMapping("/get_sign_top5") + public AjaxResult getSignTop5(@RequestParam int level, HttpServletRequest request) { + List result = new ArrayList<>(); + String key = CacheConstants.YW_COM_MANAGE_ALL; + if (redisCache.hasKey(key)) { + Map map = redisCache.getCacheObject(key); + result = (List) map.get("signrateTop5"); + } else { + result = dpNewYayunZongHeMapper.get_sign_top5(); + } + return AjaxResult.success(result); + } + //endregion + + //region --------------------------------------------------------------------------------------------综合管理:巡检率top5(全域和城区) + + @ApiOperation(value = "巡检率top5", notes = "巡检率top5") + @GetMapping("/get_routInspect_top5") + public AjaxResult getRoutInspectTop5(@RequestParam int level, HttpServletRequest request) { + List result = new ArrayList<>(); + String key = CacheConstants.YW_COM_MANAGE_ALL; + if (redisCache.hasKey(key)) { + Map map = redisCache.getCacheObject(key); + result = (List) map.get("inspectrateTop5"); + } else { + result = dpNewYayunZongHeMapper.get_inspect_top5(); + } + return AjaxResult.success(result); + } + //endregion + + //region --------------------------------------------------------------------------------------------综合管理:场馆联系人(全域和城区) + + @ApiOperation(value = "场馆联系人", notes = "场馆联系人") + @GetMapping("/get_contacts_list") + public AjaxResult getContactsList(@RequestParam int level, HttpServletRequest request) { + List result = new ArrayList<>(); + String key = CacheConstants.YW_COM_MANAGE_ALL; + if (redisCache.hasKey(key)) { + Map map = redisCache.getCacheObject(key); + result = (List) map.get("contacts"); + } else { + result = dpNewYayunZongHeMapper.get_scene_contacts_list(); + } + return AjaxResult.success(result); + } + //endregion + + + @PostMapping(value = "/updateTransAlarmsData") + public AjaxResult updateTransAlarmsData() { + try { + ywDpNewYayunService.eastcomUpdateTransAlarmsSchedule(); + } catch (Exception e) { + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + + @PostMapping(value = "/updateNetAlarmsData") + public AjaxResult updateNetAlarmsData() { + try { + ywDpNewYayunService.eastcomUpdateNetAlarmsSchedule(); + } catch (Exception e) { + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + + @PostMapping(value = "/UpdateComprehensiveManage") + public AjaxResult UpdateComprehensiveManage() { + try { + ywDpNewYayunService.eastcomUpdateComprehensiveManageSchedule(); + } catch (Exception e) { + return AjaxResult.error(); + } + return AjaxResult.success(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/dpNewYayunController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/dpNewYayunController.java new file mode 100644 index 0000000..b2fc1e8 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/dpNewYayunController.java @@ -0,0 +1,1909 @@ +package com.ruoyi.web.controller.sunlm; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DateTime; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.annotation.Anonymous; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.sunlm.domain.class_dp_btsinfo; +import com.ruoyi.sunlm.entity.class_public_news_new; +import com.ruoyi.sunlm.mapper.dpNewYayun_ChuanDong_Mapper; +import com.ruoyi.sunlm.service.NewPmKpiMonitorCellService; +import com.ruoyi.sunlm.daping.class_dp_2_scene_seat_detail; +import com.ruoyi.sunlm.daping.class_dp_2_scene_seat_info; +import com.ruoyi.sunlm.daping.dp3d.*; +import com.ruoyi.sunlm.daping.*; +import com.ruoyi.sunlm.daping.dp3d.NewDpKpiMonitorQO; +import com.ruoyi.sunlm.mapper.dpNewYayun_Gailan_Mapper; +import com.ruoyi.sunlm.mapper.dpNewYayun_Wuxian_Mapper; +import com.ruoyi.sunlm.mapper.dpNewYayun_Dict_Mapper; + + +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.apache.poi.ss.formula.functions.T; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import com.ruoyi.sunlm.mapper.NewDpApiMapper; + +@RestController +@CrossOrigin +@RequestMapping("/eastcom_yw/daping/new/") //2023。5.10,新版大屏的接口 +@RequiredArgsConstructor +public class dpNewYayunController extends BaseController +{ + + private final NewPmKpiMonitorCellService pmKpiMonitorCellService; + + @Resource + dpNewYayun_Gailan_Mapper MydpNewYayun_Gailan_Mapper; //直接在这里引用数据库操作层(MAPPER),就不用写Service层了! + + @Resource + dpNewYayun_Wuxian_Mapper MydpNewYayun_Wuxian_Mapper; //直接在这里引用数据库操作层(MAPPER),就不用写Service层了! + + @Resource + dpNewYayun_Dict_Mapper MydpNewYayun_Dict_Mapper; //直接在这里引用数据库操作层(MAPPER),就不用写Service层了! + + + @Resource + NewDpApiMapper dpNewApiMapper; + + + @Autowired + private RedisCache redisCache; + + @Autowired + private RedisTemplate redisTemplate; + + //@Value("${daping}") + //public String jobtype; //DEBUG //WORK , 发布到正式服务器改成 WORK, 连接公司服务器数据库时用 DEBUG, 在配置文件中配置 + + //region---------------------------------------------公共方法 + private String getDateTimeString(int day) + { + Calendar calendar = Calendar.getInstance(); //创建Calendar 的实例 + calendar.add(Calendar.DAY_OF_MONTH, day); //当前时间增减天数 + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日"); + String string = simpleDateFormat.format(calendar.getTime()); + return string; + } + + public int getmincontroltype(@RequestParam int areaid, + @RequestParam int sceneid) + { + return MydpNewYayun_Wuxian_Mapper.getmincontroltype(areaid,sceneid); + } + + public int getcachesecond() + { + String keyname="dp_1_cache_config"; + if (redisCache.hasKey(keyname)) { + int iret=1; + try + { + iret= redisCache.getCacheObject(keyname); + } + catch(Exception ee) { + } + return iret; + } + else { + class_dp_1_cache_config cache=MydpNewYayun_Gailan_Mapper.get_cache_config(); + int iret=1; + try + { + iret=cache.cachesecond; + } + catch(Exception ee) + { + } + redisCache.setCacheObject(keyname, iret,58, TimeUnit.SECONDS); //缓存 + return iret; + } + } + //endregion-------------------------------------------- + + + //region --------------------------------------------------------------------------------------------获得大屏缓存列表 + @ApiOperation("获得大屏缓存列表接口") + @GetMapping(value = "/getcachelist") + public AjaxResult getcachelist(HttpServletRequest request) + { + //-------------------------------------------------------------------读缓存 + Set keys = redisTemplate.keys("dp_*"); + List list=new ArrayList<>(); + for (String key : keys) { + String time=String.valueOf(redisTemplate.getExpire(key)); + list.add(key+" : 时效 "+time+" 秒"); + } + return success(list); + } + //endregion + + //region --------------------------------------------------------------------------------------------强制删除缓存 + @ApiOperation("强制删除缓存接口") + @GetMapping(value = "/deletecache") + public AjaxResult deletecache(@RequestParam String keyname,HttpServletRequest request) + { + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + redisCache.deleteObject(keyname); + return success("已清空缓存:"+keyname); + } + else + return success("不存在该缓存:"+keyname); + } + //endregion + + // 大屏的第一屏:概览 + + //region --------------------------------------------------------------------------------------------概览:无线退服统计 + @ApiOperation("概览:无线退服统计接口") + @GetMapping(value = "/get_wireless_outservice") + public AjaxResult get_wireless_outservice(HttpServletRequest request) + { + //-------------------------------------------------------------------读缓存 + String keyname="dp_1_wireless_outservice"; + if (redisCache.hasKey(keyname)) { + class_dp_1_outservice_wireless cacheData=redisCache.getCacheObject(keyname); + return success(cacheData); + } + //-------------------------------------------------------------------读数据库 + List dpdata=new ArrayList(); + //---------------------------- + String keyname2="dp_1_wireless_outservice_list"; + if (redisCache.hasKey(keyname2)) { + dpdata=redisCache.getCacheObject(keyname2); + } + else { + dpdata = MydpNewYayun_Gailan_Mapper.get_wireless_outservice(); + } + //--------------------------- + class_dp_1_outservice_wireless retdata=new class_dp_1_outservice_wireless(); + retdata.退服数2G= dpdata.get(0).退服数2G; + retdata.退服数4G= dpdata.get(0).退服数4G; + retdata.退服数5G= dpdata.get(0).退服数5G; + retdata.基站总数= dpdata.get(0).基站总数; + redisCache.setCacheObject(keyname, retdata,getcachesecond(), TimeUnit.SECONDS); //缓存 + return success(retdata); + } + //endregion + + //region --------------------------------------------------------------------------------------------概览:4/5G无线流量 + @ApiOperation("概览:4/5G无线流量接口,typeid:1:4G,2:5G") + @GetMapping(value = "/get_gbflow_wireless") + public AjaxResult get_gbflow_wireless( + @RequestParam int typeid, + HttpServletRequest request) + { + //-------------------------------------------------------------------读缓存 + + String keyname="dp_1_gbflow_wireless_"+String.valueOf(typeid); + if (redisCache.hasKey(keyname)) { + List cacheData = redisCache.getCacheObject(keyname); + return success(cacheData); + } + List dpData=new ArrayList(); + //------------------------------ + String keyname2="dp_1_gbflow_wireless_list_"+String.valueOf(typeid); + if (redisCache.hasKey(keyname2)) { + dpData = redisCache.getCacheObject(keyname2); + } + else { //-------------------------------------------------------------------读数据库 + dpData = MydpNewYayun_Gailan_Mapper.get_gbflow_wireless(typeid); + } + //----------------------------- + class_dp_1_gbflow_wireless myData=new class_dp_1_gbflow_wireless(); + myData.label=new ArrayList(); + myData.xaxis=new ArrayList(); + myData.value=new ArrayList(); + myData.value2=new ArrayList(); + //---------------------- + myData.label.add("今天(" + getDateTimeString(0) + ")"); + myData.label.add("昨天(" + getDateTimeString(-1) + ")"); + + float vlst1=0; + float vlst2=0; + for (int i=0;i0) vlst1=dpData.get(i).gb; + if ((dpData.get(i).gb==-1) && (i>0)) + myData.value.add(vlst1); + else if ((dpData.get(i).gb==-1) && (i==0)) + myData.value.add((float)0.00); + else + myData.value.add(dpData.get(i).gb); + } + else //前日 + { + myData.xaxis.add(dpData.get(i).adate); + if (dpData.get(i).gb>0) vlst2=dpData.get(i).gb; + if ((dpData.get(i).gb==-1) && (i>0)) + myData.value2.add(vlst2); + else if ((dpData.get(i).gb==-1) && (i==0)) + myData.value2.add((float)0.00); + else + myData.value2.add(dpData.get(i).gb); + } + } + //---------------------- + List lstData=new ArrayList(); + lstData.add(myData); + redisCache.setCacheObject(keyname, lstData,58, TimeUnit.SECONDS); //缓存 + return success(lstData); + } + //endregion + + //region --------------------------------------------------------------------------------------------概览:综合管理类统计 + @ApiOperation("概览:综合管理类统计接口") + @GetMapping(value = "/get_manage_counts") + public AjaxResult get_manage_counts(HttpServletRequest request) + { + + String keyname="dp_1_manage_counts"; + if (redisCache.hasKey(keyname)) { + class_dp_1_manage_counts cacheData = redisCache.getCacheObject(keyname); + return success(cacheData); + } + //--------------------------------------------------- + List dpdata=new ArrayList(); + String keyname2="dp_1_manage_counts_list"; + if (redisCache.hasKey(keyname2)) { + dpdata=redisCache.getCacheObject(keyname2); + } + else + { + dpdata = MydpNewYayun_Gailan_Mapper.get_manage_counts(); + } + //--------------------------------------------------- + class_dp_1_manage_counts retdata=new class_dp_1_manage_counts(); + if (retdata!=null) { + retdata.应签到数量 = dpdata.get(0).应签到数量; + retdata.实际签到数 = dpdata.get(0).实际签到数; + retdata.人员签到率 = dpdata.get(0).人员签到率; + retdata.巡检任务数 = dpdata.get(0).巡检任务数; + retdata.已巡检任务 = dpdata.get(0).已巡检任务; + retdata.巡检完成率 = dpdata.get(0).巡检完成率; + } + redisCache.setCacheObject(keyname, retdata,58, TimeUnit.SECONDS); //缓存 + return success(retdata); + } + //endregion + + //region --------------------------------------------------------------------------------------------概览:DICT设备和告警统计 + @ApiOperation("概览:DICT设备和告警统计接口") + @GetMapping(value = "/get_dict_counts") + public AjaxResult get_dict_counts(HttpServletRequest request) + { + + String keyname="dp_1_dict_counts"; + if (redisCache.hasKey(keyname)) { + class_dp_1_device_alarm_counts cacheData = redisCache.getCacheObject(keyname); + return success(cacheData); + } + //------------------------------------- + List dpdata=new ArrayList(); + String keyname2="dp_1_dict_counts_list"; + if (redisCache.hasKey(keyname2)) { + dpdata=redisCache.getCacheObject(keyname2); + } + else { + dpdata = MydpNewYayun_Gailan_Mapper.get_dict_counts(); + } + //------------------------------------ + class_dp_1_device_alarm_counts retdata=new class_dp_1_device_alarm_counts(); + retdata.设备数= dpdata.get(0).设备数; + retdata.告警总数= dpdata.get(0).告警总数; + redisCache.setCacheObject(keyname, retdata,58, TimeUnit.SECONDS); //缓存 + return success(retdata); + } + //endregion + + //region --------------------------------------------------------------------------------------------概览:动力传输类统计 + @ApiOperation("概览:动力传输类统计接口") + @GetMapping(value = "/get_trans_counts") + public AjaxResult get_trans_counts(HttpServletRequest request) + { + List dpdata = new ArrayList(); + + String keyname="dp_1_trans_counts"; + String keyname2="dp_1_trans_counts_list"; + //-----------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + dpdata = redisCache.getCacheObject(keyname); + } + else if (redisCache.hasKey(keyname2)) { + dpdata = redisCache.getCacheObject(keyname2); + } + else { //读数据库 + dpdata = MydpNewYayun_Gailan_Mapper.get_trans_counts(); + redisCache.setCacheObject(keyname, dpdata,58, TimeUnit.SECONDS); //缓存保留分钟 + } + //------------------------- + return success(dpdata); + } + //endregion + + //region --------------------------------------------------------------------------------------------概览:全网保障流量 + @ApiOperation("概览:全网保障传输环路流量接口") + @GetMapping(value = "/get_gbflow_huanlu") + public AjaxResult get_gbflow_huanlu(HttpServletRequest request) + { + + String keyname="dp_1_gbflow_huanlu"; + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List cacheData=redisCache.getCacheObject(keyname); + return success(cacheData); + } + //-------------------------------------------------------------------读数据库 + List dpData=new ArrayList(); + String keyname2="dp_1_gbflow_huanlu_list"; + if (redisCache.hasKey(keyname2)) { + dpData=redisCache.getCacheObject(keyname2); + } + else { + dpData = MydpNewYayun_Gailan_Mapper.get_gbflow_huanlu(); + } + //---------------------------------- + class_dp_1_gbflow_wireless myData=new class_dp_1_gbflow_wireless(); + myData.label=new ArrayList(); + myData.xaxis=new ArrayList(); + myData.value=new ArrayList(); + myData.value2=new ArrayList(); + //---------------------- + myData.label.add("今天(" + getDateTimeString(0) + ")"); + myData.label.add("昨天(" + getDateTimeString(-1) + ")"); + + float vlst1=0; + float vlst2=0; + for (int i=0;i0) vlst1=dpData.get(i).gb; + if ((dpData.get(i).gb==-1) && (i>0)) + myData.value.add(vlst1); + else if ((dpData.get(i).gb==-1) && (i==0)) + myData.value.add((float)0.00); + else + myData.value.add(dpData.get(i).gb); + } + else //前日 + { + myData.xaxis.add(dpData.get(i).adate); + if (dpData.get(i).gb>0) vlst2=dpData.get(i).gb; + if ((dpData.get(i).gb==-1) && (i>0)) + myData.value2.add(vlst2); + else if ((dpData.get(i).gb==-1) && (i==0)) + myData.value2.add((float)0.00); + else + myData.value2.add(dpData.get(i).gb); + } + } + //---------------------- + List lstData=new ArrayList(); + lstData.add(myData); + redisCache.setCacheObject(keyname, lstData,58, TimeUnit.SECONDS); //缓存保留 + return success(lstData); + } + //endregion + + //region--------------------------------------------------------------------------------------------概览:AGIS和互联网统计接口 + @ApiOperation("概览:AGIS和互联网统计接口") + @GetMapping(value = "/get_agis_internet_counts") + public AjaxResult get_agis_internet_counts(HttpServletRequest request) + { + List dpdata = new ArrayList(); + + String keyname="dp_1_agis_internet_counts"; + String keyname2="dp_1_agis_internet_counts_list"; + //-----------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + dpdata = redisCache.getCacheObject(keyname); + } + else if (redisCache.hasKey(keyname2)) { + dpdata = redisCache.getCacheObject(keyname2); + } + else { //读数据库 + dpdata = MydpNewYayun_Gailan_Mapper.get_agis_internet_counts(); + redisCache.setCacheObject(keyname, dpdata,58, TimeUnit.SECONDS); //缓存保留分钟 + } + return success(dpdata); + } + //endregion + + //region --------------------------------------------------------------------------------------------概览:中间地图告警显示接口 + @ApiOperation("概览:中间地图告警显示接口: level:0: 全部,1 全域,2 城区 ") + @GetMapping(value = "/get_maps_all_alarms") + public AjaxResult get_maps_all_alarms( + @RequestParam int level, + HttpServletRequest request) + { + + String keyname="dp_1_maps_all_alarms_"+String.valueOf(level); + if (redisCache.hasKey(keyname)) { + List cacheData = redisCache.getCacheObject(keyname); + return success(cacheData); + } + List dpdata=new ArrayList(); + //-------------------------------- + String keyname2="dp_1_maps_all_alarms_list_"+String.valueOf(level); ///"dp_1_maps_all_alarms_"+String.valueOf(level);??? + if (redisCache.hasKey(keyname2)) { + dpdata=redisCache.getCacheObject(keyname2); + } + else { + dpdata = MydpNewYayun_Gailan_Mapper.get_maps_all_alarms(level); + } + //-----------------------------------先把告警弹出列表取到缓存 + List alllists=new ArrayList(); + String keyname3="dp_1_maps_all_alarms_popup_list"; + if (redisCache.hasKey(keyname3)) { + alllists=redisCache.getCacheObject(keyname3); + } + else { + alllists = MydpNewYayun_Gailan_Mapper.get_maps_all_alarms_popup(); + } + //----------------------------------- + if (alllists.size()>0) { + for (int i = 0; i < dpdata.size(); i++) { + if (dpdata.get(i).alarmcount > 0) { + int venueid = Integer.parseInt(dpdata.get(i).venueid); + try { + List lists = alllists.stream().filter(x -> x.getSceneid() == venueid).collect(Collectors.toList()); + dpdata.get(i).lists = lists; + } + catch(Exception e) + { + dpdata.get(i).lists=new ArrayList(); + } + + } + } + } + //-------------------------------- + redisCache.setCacheObject(keyname, dpdata,getcachesecond(), TimeUnit.SECONDS); //缓存保留分钟 + return success(dpdata); + } + //endregion + + + // 大屏的第二屏:无线, 包括全域, 城区, 场馆 + + //region --------------------------------------------------------------------------------------------获取坐席中文名列表 + public List get_seat_chinesename(HttpServletRequest request) + { + return MydpNewYayun_Wuxian_Mapper.get_seat_chinesename(); + } + //endregion + + //region --------------------------------------------------------------------------------------------获取场馆列表 + @ApiOperation("获取场馆列表") + @GetMapping(value = "/getvenuelist") + public AjaxResult getvenuelist(HttpServletRequest request) + { + List dpvenue=new ArrayList(); + dpvenue = MydpNewYayun_Wuxian_Mapper.getvenuelists(); + return success(dpvenue); + } + //endregion + + //region --------------------------------------------------------------------------------------------获取景区列表,作废 + @ApiOperation("获取景区列表,和景区告警列表,spottypeid:景区大类ID ") + @GetMapping(value = "/getspotlist") + public AjaxResult getspotlist( + @RequestParam(value = "spottypeid", required = false, defaultValue = "0") int spottypeid, + HttpServletRequest request) + { + /* //---先分类 + List dpspottype=MydpNewYayun_Wuxian_Mapper.getspottypes(); ///获取大类 + List dpspots=new ArrayList(); + for (String spottype:dpspottype) + { + List dpspotdetail = MydpNewYayun_Wuxian_Mapper.getspotlist(spottype); + class_dp_2_spotlist spot=new class_dp_2_spotlist(); + spot.spottype=spottype; + spot.spotlist=dpspotdetail; + dpspots.add(spot); + } + return success(dpspots); */ + + //---------------不需要分类了 + List allalarmlist=new ArrayList(); + String keyname="dp_2_spot_wirelessalarms_popup_list"; + if (redisCache.hasKey(keyname)) { + allalarmlist=redisCache.getCacheObject(keyname); + } + else { + allalarmlist = MydpNewYayun_Wuxian_Mapper.get_spot_wirelessalarms_popup(); //景区的告警 + } + //--------------------------------------------------- + List dpspotdetail = MydpNewYayun_Wuxian_Mapper.getspotlist(spottypeid); + for (int i=0;i0) { + int spotid=dpspotdetail.get(i).spotId; + try { + List alarmlist = allalarmlist.stream().filter(x -> x.getSceneid() == spotid).collect(Collectors.toList()); //景区的告警 + dpspotdetail.get(i).lists = alarmlist; + } + catch(Exception e) + { + dpspotdetail.get(i).lists = new ArrayList(); + } + } + } + return success(dpspotdetail); + } + //endregion + + + //region --------------------------------------------------------------------------------------------无线:逻辑站退服清单 + @ApiOperation("无线:逻辑站退服清单,level:1 全域,2 城区,3 场馆; areaid:城区id(根据需要传);sceneid:场馆id(根据需要传)") + @GetMapping(value = "/get_wireless_alarms_list") + public AjaxResult get_wireless_alarms_list( + @RequestParam int level, + @RequestParam(value = "areaid", required = false, defaultValue = "0") int areaid, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid, + HttpServletRequest request) + { + String keyname="dp_2_wireless_alarms_list_"+String.valueOf(level)+"_"+String.valueOf(areaid)+"_"+String.valueOf(sceneid); + if (redisCache.hasKey(keyname)) { + List cacheData = redisCache.getCacheObject(keyname); + return success(cacheData); + } + List alarmlist=new ArrayList(); + alarmlist= MydpNewYayun_Wuxian_Mapper.get_wireless_alarms_list(level,areaid,sceneid); + redisCache.setCacheObject(keyname, alarmlist,getcachesecond(), TimeUnit.SECONDS); //缓存保留分钟 + return success(alarmlist); + } + //endregion + + //region --------------------------------------------------------------------------------------------无线:铁塔动环清单 + @ApiOperation("无线:铁塔动环清单,level:1 全域,2 城区,3 场馆; areaid:城区id(根据需要传);sceneid:场馆id(根据需要传)") + @GetMapping(value = "/get_power_alarms_list") + public AjaxResult get_power_alarms_list( + @RequestParam int level, + @RequestParam(value = "areaid", required = false, defaultValue = "0") int areaid, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid, + HttpServletRequest request) + { + String keyname="dp_2_power_alarms_list_"+String.valueOf(level)+"_"+String.valueOf(areaid)+"_"+String.valueOf(sceneid); + if (redisCache.hasKey(keyname)) { + List cacheData = redisCache.getCacheObject(keyname); + return success(cacheData); + } + List alarmlist=new ArrayList(); + alarmlist= MydpNewYayun_Wuxian_Mapper.get_power_alarms_list(level,areaid,sceneid); + redisCache.setCacheObject(keyname, alarmlist,getcachesecond(), TimeUnit.SECONDS); //缓存保留分钟 + return success(alarmlist); + } + //endregion + + //region -------------------------------------------------------------------------------------------无线:国际漫入漫出统计 + @ApiOperation("无线:国际漫入漫出统计,typeid=1 :国际漫入;typeid=2:国际漫出") + @GetMapping(value = "/get_roam_national") + public AjaxResult get_roam_national(@RequestParam int typeid, + HttpServletRequest request) + { + String keyname="dp_2_roam_national_"+String.valueOf(typeid); + if (redisCache.hasKey(keyname)) { + List cacheData = redisCache.getCacheObject(keyname); + return success(cacheData); + } + List dpData=new ArrayList(); + dpData = MydpNewYayun_Wuxian_Mapper.get_roam_national(typeid); + redisCache.setCacheObject(keyname, dpData,58, TimeUnit.SECONDS); //缓存保留分钟 + return success(dpData); + } + //endregion + + //region -------------------------------------------------------------------------------------------无线:省内漫入漫出统计 + @ApiOperation("无线:省内漫入漫出统计,typeid=1 :省内漫入;typeid=2:省内漫出") + @GetMapping(value = "/get_roam_inner") + public AjaxResult get_roam_inner(@RequestParam int typeid, + HttpServletRequest request) + { + String keyname="dp_2_roam_inner_"+String.valueOf(typeid); + if (redisCache.hasKey(keyname)) { + List cacheData = redisCache.getCacheObject(keyname); + return success(cacheData); + } + + List dpData=new ArrayList(); + dpData = MydpNewYayun_Wuxian_Mapper.get_roam_inner(typeid); + redisCache.setCacheObject(keyname, dpData,58, TimeUnit.SECONDS); //缓存保留分钟 + return success(dpData); + } + //endregion + + //region ---------------------------------------------------------------------------------------无线:区域用户数 + @ApiOperation("无线:区域用户数图表接口,typeid:1: 4G ,2: 5G,level:1 全域,2 城区,3 场馆; areaid:城区id(根据需要传);sceneid:场馆id(根据需要传)") + @GetMapping(value = "/get_area_usercounts") + public AjaxResult get_area_usercounts( + @RequestParam int level, + @RequestParam(value = "areaid", required = false, defaultValue = "0") int areaid, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid, + @RequestParam int typeid, + HttpServletRequest request) + { + //-------------------------------------------------------------------如果查询条件变了,需要清空缓存, 重新取数 + //-------------------------------------------------------------------读缓存 + String keyname="dp_2_area_usercounts_"+String.valueOf(level)+"_"+String.valueOf(areaid)+"_"+String.valueOf(sceneid)+"_"+String.valueOf(typeid); + if (redisCache.hasKey(keyname)) { + List lstData = redisCache.getCacheObject(keyname); + return success(lstData); + } + //--------------------------------------------------------------------读数据库 + List dpData=new ArrayList(); + dpData = MydpNewYayun_Wuxian_Mapper.get_area_usercounts(level,areaid,sceneid,typeid); + //------------------ + class_dp_2_usercounts myData=new class_dp_2_usercounts(); + myData.label=new ArrayList(); + myData.xaxis=new ArrayList(); + myData.value=new ArrayList(); + myData.value2=new ArrayList(); + //---------------------- + myData.label.add("今天(" + getDateTimeString(0) + ")"); + myData.label.add("昨天(" + getDateTimeString(-1) + ")"); + float vlst1=0; + float vlst2=0; + for (int i=0;i0) vlst1=dpData.get(i).value; + if ((dpData.get(i).value==-1) && (i>0)) + myData.value.add(vlst1); + else if ((dpData.get(i).value==-1) && (i==0)) + myData.value.add((float)0.00); + else + myData.value.add(dpData.get(i).value); + } + else //昨天数据 + { + if (dpData.get(i).value>0) vlst2=dpData.get(i).value; + myData.xaxis.add(dpData.get(i).datetime); + if ((dpData.get(i).value==-1) && (i>0)) + myData.value2.add(vlst2); + else if ((dpData.get(i).value==-1) && (i==0)) + myData.value2.add((float)0.00); + else + myData.value2.add(dpData.get(i).value); + } + } + //---------------------- + List lstData=new ArrayList(); + lstData.add(myData); + redisCache.setCacheObject(keyname, lstData, 58, TimeUnit.SECONDS); //数据放缓存 + return success(lstData); + } + //endregion + + //region --------------------------------------------------------------------------------------------无线:区域流量 + //-------------------------------------------- + @ApiOperation("无线:区域流量接口,typeid:1: 4G ,2: 5G,level:1 全域,2 城区,3 场馆; areaid:城区id(根据需要传);sceneid:场馆id(根据需要传)") + @GetMapping(value = "/get_area_gbflow") + public AjaxResult get_area_gbflow( + @RequestParam int level, + @RequestParam(value = "areaid", required = false, defaultValue = "0") int areaid, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid, + @RequestParam int typeid, + HttpServletRequest request) + { + String keyname="dp_2_area_gbflow_"+String.valueOf(level)+"_"+String.valueOf(areaid)+"_"+String.valueOf(sceneid)+"_"+String.valueOf(typeid); + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List lstData = redisCache.getCacheObject(keyname); + return success(lstData); + } + //--------------------------------------------------------------------读数据库 + List dpData=new ArrayList(); //这个类通用,不在新定义了 + //----------------------- + dpData = MydpNewYayun_Wuxian_Mapper.get_area_gbflow(level,areaid,sceneid,typeid); + //------------------ + class_dp_2_usercounts myData=new class_dp_2_usercounts(); + myData.label=new ArrayList(); + myData.xaxis=new ArrayList(); + myData.value=new ArrayList(); + myData.value2=new ArrayList(); + //---------------------- + myData.label.add("今天(" + getDateTimeString(0) + ")"); + myData.label.add("昨天(" + getDateTimeString(-1) + ")"); + float vlst1=0; + float vlst2=0; + for (int i=0;i0) vlst1=dpData.get(i).value; + if ((dpData.get(i).value==-1) && (i>0)) + myData.value.add(vlst1); + else if ((dpData.get(i).value==-1) && (i==0)) + myData.value.add((float)0.00); + else + myData.value.add(dpData.get(i).value); + } + else //昨天数据 + { + if (dpData.get(i).value>0) vlst2=dpData.get(i).value; + myData.xaxis.add(dpData.get(i).datetime); + if ((dpData.get(i).value==-1) && (i>0)) + myData.value2.add(vlst2); + else if ((dpData.get(i).value==-1) && (i==0)) + myData.value2.add((float)0.00); + else + myData.value2.add(dpData.get(i).value); + } + } + //---------------------- + List lstData=new ArrayList(); + lstData.add(myData); + redisCache.setCacheObject(keyname, lstData,58, TimeUnit.SECONDS); //数据放缓存 + return success(lstData); + } + //endregion + + //region -------------------------------------------------------------------------------------无线:上行Prb利用率TOP5 + //-------------------------------------------- + + @ApiOperation("无线:上行利用率TOP5接口,level:2:城区,3:场馆;typeid:1: 4G ,2: 5G, areaid:区域id ;sceneid:场馆id,inorout:0:全部,1:场内,2:场外,3:功能区") + @GetMapping(value = "/get_prb_uplink") + public AjaxResult get_prb_uplink( + @RequestParam int level, + @RequestParam(value = "areaid", required = false, defaultValue = "0") int areaid, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid, + @RequestParam int typeid, + @RequestParam(value = "inorout", required = false, defaultValue = "0") int inorout, + HttpServletRequest request) + { + int mintype=getmincontroltype(areaid,sceneid); //1分钟 ,15分钟 + String keyname="dp_2_prb_uplink_"+String.valueOf(level)+"_"+String.valueOf(areaid)+"_"+String.valueOf(sceneid)+"_" + +String.valueOf(typeid)+"_"+String.valueOf(inorout)+String.valueOf(mintype); + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List lstData = redisCache.getCacheObject(keyname); + return success(lstData); + } + //--------------------------------------------------------------------读数据库 + List dpData=new ArrayList(); + dpData=MydpNewYayun_Wuxian_Mapper.get_prb_uplink(level,areaid,sceneid,typeid,mintype,inorout); + //---------------------- + redisCache.setCacheObject(keyname, dpData,getcachesecond(), TimeUnit.SECONDS); //数据放缓存 + return success(dpData); + } + //endregion + + //region -----------------------------------------------------------------------------------------无线:下行Prb利用率TOP5 + //-------------------------------------------- + @ApiOperation("无线:下行Prb利用率TOP5接口,level:2:城区,3:场馆;typeid:1: 4G ,2: 5G, sceneid:场馆id,inorout:0:全部,1:场内,2:场外,3:功能区") + @GetMapping(value = "/get_prb_downlink") + public AjaxResult get_prb_downlink(@RequestParam int level, + @RequestParam(value = "areaid", required = false, defaultValue = "0") int areaid, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid, + @RequestParam int typeid, + @RequestParam(value = "inorout", required = false, defaultValue = "0") int inorout, + HttpServletRequest request) + { + int mintype=getmincontroltype(areaid,sceneid); //1分钟 ,15分钟 + String keyname="dp_2_prb_downlink_"+String.valueOf(level)+"_"+String.valueOf(areaid)+"_"+String.valueOf(sceneid)+"_" + +String.valueOf(typeid)+"_"+String.valueOf(inorout)+String.valueOf(mintype); + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List lstData = redisCache.getCacheObject(keyname); + return success(lstData); + } + + List dpData=new ArrayList(); + //--------------------------- + dpData=MydpNewYayun_Wuxian_Mapper.get_prb_downlink(level,areaid,sceneid,typeid,mintype,inorout); + //---------------------- + redisCache.setCacheObject(keyname, dpData,getcachesecond(), TimeUnit.SECONDS); //数据放缓存 + return success(dpData); + } + //endregion + + //region -------------------------------------------------------------------------------------无线:用户数TOP5 + @ApiOperation("无线:用户数TOP5接口,level:2:城区,3:场馆;typeid:1: 4G ,2: 5G, sceneid:场馆id,inorout:0:全部,1:场内,2:场外,3:功能区") + @GetMapping(value = "/get_user_data") + public AjaxResult get_user_data(@RequestParam int level, + @RequestParam(value = "areaid", required = false, defaultValue = "0") int areaid, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid, + @RequestParam int typeid, + @RequestParam(value = "inorout", required = false, defaultValue = "0") int inorout, + HttpServletRequest request) + { + int mintype=getmincontroltype(areaid,sceneid); //1分钟 ,15分钟 + String keyname="dp_2_user_data_"+String.valueOf(level)+"_"+String.valueOf(areaid)+"_"+String.valueOf(sceneid)+"_" + +String.valueOf(typeid)+"_"+String.valueOf(inorout)+String.valueOf(mintype); + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List lstData = redisCache.getCacheObject(keyname); + return success(lstData); + } + + List dpData=new ArrayList(); + //----------------------- + dpData=MydpNewYayun_Wuxian_Mapper.get_user_data(level,areaid,sceneid,typeid,mintype,inorout); + //---------------------- + redisCache.setCacheObject(keyname, dpData,getcachesecond(), TimeUnit.SECONDS); //数据放缓存 + return success(dpData); + } + //endregion + + //region ----------------------------------------------------------------------------------------无线:平均干扰TOP5 + @ApiOperation("无线:平均干扰TOP5接口, level:2:城区,3:场馆;typeid:1: 4G ,2: 5G, sceneid:场馆id,inorout:0:全部,1:场内,2:场外,3:功能区") + @GetMapping(value = "/get_avg_disturb") + public AjaxResult get_avg_disturb(@RequestParam int level, + @RequestParam(value = "areaid", required = false, defaultValue = "0") int areaid, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid, + @RequestParam int typeid, + @RequestParam(value = "inorout", required = false, defaultValue = "0") int inorout, + HttpServletRequest requestt) + { + int mintype=getmincontroltype(areaid,sceneid); //1分钟 ,15分钟 + String keyname="dp_2_avg_disturb_"+String.valueOf(level)+"_"+String.valueOf(areaid)+"_"+String.valueOf(sceneid)+"_" + +String.valueOf(typeid)+"_"+String.valueOf(inorout)+String.valueOf(mintype); + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List lstData = redisCache.getCacheObject(keyname); + return success(lstData); + } + + List dpData=new ArrayList(); + //--------------------------- + dpData=MydpNewYayun_Wuxian_Mapper.get_avg_disturb(level,areaid,sceneid,typeid,mintype,inorout); + redisCache.setCacheObject(keyname, dpData,getcachesecond(), TimeUnit.SECONDS); //数据放缓存 + return success(dpData); + } + //endregion + + //region --------------------------------------------------------------------------------------------无线:中间地图无线告警和性能显示接口 + @ApiOperation("无线:中间地图无线告警和性能显示接口: level:0: 全部,1 全域,2 城区;areaid:区域id:1:景区,2:交通枢纽,3:亚运村,4:功能中心,....,不填为默认城区 ") + @GetMapping(value = "/get_maps_wireless_alarms") + public AjaxResult get_maps_wireless_alarms( + @RequestParam int level, + @RequestParam(value = "areaid", required = false, defaultValue = "0") int areaid, + @RequestParam(value = "nettype", required = false, defaultValue = "5G") String nettype, + @RequestParam(value = "kpiname", required = false, defaultValue = "综合算法") String kpiname, + HttpServletRequest request) + { + String keyname="dp_2_maps_wireless_alarms_kpi_"+String.valueOf(level)+"_"+String.valueOf(areaid)+"_"+nettype+"_"+kpiname; + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List lstData = redisCache.getCacheObject(keyname); + return success(lstData); + } + List dpdata = new ArrayList(); + dpdata = MydpNewYayun_Wuxian_Mapper.get_maps_wireless_alarms(level,areaid); + //----------------------------------------------------------需要将所有告警先取来放在缓存里。 + String keyname2_1="dp_2_spot_wireless_alarms_popup_list"; //所有景区的告警 + String keyname2_2="dp_2_maps_wireless_alarms_popup_list"; //所有场馆的告警 + List alllists = new ArrayList(); + if ((level==2) && (areaid>0)) { + if (redisCache.hasKey(keyname2_1)) { + alllists=redisCache.getCacheObject(keyname2_1); + } + else { + alllists = MydpNewYayun_Wuxian_Mapper.get_spot_wirelessalarms_popup(); //景区的告警 + } + } + else if (((level==2) && (areaid==0)) || (level==1)) { + if (redisCache.hasKey(keyname2_2)) { + alllists=redisCache.getCacheObject(keyname2_2); + } + else { + alllists = MydpNewYayun_Wuxian_Mapper.get_maps_wireless_alarms_popup(); //场馆的告警 + } + } + //-------------------------------------------将KPI列表取到缓存 + List cellsall=new ArrayList(); + int mintype=15; + if ((level==2) && (areaid>0)) { + mintype=getmincontroltype(areaid,0); //1分钟 ,15分钟 + String keyname2="dp_2_maps_wireless_kpicells_list_"+nettype+"_"+String.valueOf(mintype); //dp_2_maps_wireless_kpicells_list_4G_1,.... + //------------------------ + if (redisCache.hasKey(keyname2)) + cellsall = redisCache.getCacheObject(keyname2); + else { + cellsall = MydpNewYayun_Wuxian_Mapper.get_maps_wireless_kpi_cells(nettype, mintype); + redisCache.setCacheObject(keyname2, cellsall,getcachesecond(), TimeUnit.SECONDS); + } + } + //---------------------------------------------------------- + for (int i=0;i0) { + List lists = new ArrayList(); + if ((level==2) && (areaid>0)) { + int spotid=Integer.parseInt(dpdata.get(i).venueid); + try { + lists = alllists.stream().filter(x -> x.getSceneid() == spotid).collect(Collectors.toList()); //景区 + } + catch(Exception e) + { + } + } + else { + int venueid=Integer.parseInt(dpdata.get(i).venueid); + try { + lists = alllists.stream().filter(x -> x.getSceneid() == venueid).collect(Collectors.toList()); //场馆 + } + catch(Exception e) + { + } + } + dpdata.get(i).lists = lists; + } + //----------------------------------------------取基站和小区数量 + String strsitecell=""; + List sitecellinfos=new ArrayList(); + String keyname_5="dp_2_site_cell_info_list"; + if (redisCache.hasKey(keyname_5)) + sitecellinfos=redisCache.getCacheObject(keyname_5); + else { + sitecellinfos = MydpNewYayun_Wuxian_Mapper.getsitecellinfo(); + redisCache.setCacheObject(keyname_5, sitecellinfos,getcachesecond(), TimeUnit.SECONDS); + } + if ((level==2) && (areaid>0)) { + int spotid = Integer.parseInt(dpdata.get(i).venueid); + if (sitecellinfos.size()>0) { + try { + sitecellinfos = sitecellinfos.stream().filter(x -> x.get类型().equals("场景")).filter(x -> x.get编号() == spotid).collect(Collectors.toList()); + } + catch(Exception e) + { + } + if (sitecellinfos.size()>0) + strsitecell = "2G基站数:" + String.valueOf(sitecellinfos.get(0).基站数2g) + " 个,2G小区数:" + String.valueOf(sitecellinfos.get(0).小区数2g) + + " 个,4G基站数:" + String.valueOf(sitecellinfos.get(0).基站数4g) + " 个,4G小区数:" + String.valueOf(sitecellinfos.get(0).小区数4g) + + " 个,5G基站数:" + String.valueOf(sitecellinfos.get(0).基站数5g) + " 个,5G小区数:" + String.valueOf(sitecellinfos.get(0).小区数5g)+" 个"; + } + } + else { + int sceneid = Integer.parseInt(dpdata.get(i).venueid); + if (sitecellinfos.size() > 0) { + try { + sitecellinfos = sitecellinfos.stream().filter(x -> x.get类型().equals("场馆")).filter(x -> x.get编号() == sceneid).collect(Collectors.toList()); + } + catch(Exception e) + { + } + if (sitecellinfos.size()>0) + strsitecell = "2G基站数:" + String.valueOf(sitecellinfos.get(0).基站数2g) + " 个,2G小区数:" + String.valueOf(sitecellinfos.get(0).小区数2g) + + " 个,4G基站数:" + String.valueOf(sitecellinfos.get(0).基站数4g) + " 个,4G小区数:" + String.valueOf(sitecellinfos.get(0).小区数4g) + + " 个,5G基站数:" + String.valueOf(sitecellinfos.get(0).基站数5g) + " 个,5G小区数:" + String.valueOf(sitecellinfos.get(0).小区数5g)+" 个"; + } + } + dpdata.get(i).sitecellinto=strsitecell; + //------------------------------------------取KPI + if ((level==2) && (areaid>0)) //展示景点 + { + class_dp_2_kpi_spot kpispot=new class_dp_2_kpi_spot(); + List kpi_spot_cells=new ArrayList(); + int spotid=Integer.parseInt(dpdata.get(i).venueid); + List cellspot=new ArrayList(); + try { + cellspot = cellsall.stream().filter(x -> x.get景区id() == spotid).collect(Collectors.toList()); + } + catch(Exception e) + { + } + //--------------------------------------根据指标进行排序,SCORE大的排在最前面 + if (kpiname.equals("综合算法")) + cellspot=cellspot.stream().sorted(Comparator.comparing(class_dp_2_kpi_spot_celldetail::getKpiZhsf,Comparator.reverseOrder())).collect(Collectors.toList()); + else if (kpiname.equals("上行Prb利用率")) + cellspot=cellspot.stream().sorted(Comparator.comparing(class_dp_2_kpi_spot_celldetail::getPrbUp,Comparator.reverseOrder())).collect(Collectors.toList()); + else if (kpiname.equals("下行Prb利用率")) + cellspot=cellspot.stream().sorted(Comparator.comparing(class_dp_2_kpi_spot_celldetail::getPrbDown,Comparator.reverseOrder())).collect(Collectors.toList()); + else if (kpiname.equals("最大用户数")) + cellspot=cellspot.stream().sorted(Comparator.comparing(class_dp_2_kpi_spot_celldetail::getMaxUser,Comparator.reverseOrder())).collect(Collectors.toList()); + else if (kpiname.equals("平均干扰值")) + cellspot=cellspot.stream().sorted(Comparator.comparing(class_dp_2_kpi_spot_celldetail::getAvgDisturb,Comparator.reverseOrder())).collect(Collectors.toList()); + //-------------------------------------- + int score=0; + String color=""; + //---------------------------------------------整个景区取最差小区的得分为其得分 + int icnt=cellspot.size(); //列表不能有太多的数据,20231003 + if (icnt>20) icnt=20; + //------------------------ + for (int m=0;m dpData=new ArrayList(); + dpData = dpNewApiMapper.get_seat_detail(sceneid); + return success(dpData); + } + //endregion + + //region--------------------------------------------------------------------------------------无线:3D大屏场内坐席接口 + @ApiOperation(value = "无线:3D场内坐席数据接口;sceneid:场馆ID;inorout:1,场内,2:场外,3:功能区,nettype:4G,5G,datatype:15分钟,1分钟;kpiname:指标名称") + @GetMapping(value = "/get_seat_data") + @Anonymous + public TableDataInfo getSeatData(@RequestParam Integer sceneid, //场馆id + @RequestParam String nettype, //4G ,5G + @RequestParam(value = "inorout", required = false, defaultValue = "0") String inorout, //场内场外,0: 全部, 1,场内,2:场外。3:功能区 + @RequestParam(required = false) String datatype, //由系统表控制 + @RequestParam(required = false) String kpiname, + HttpServletRequest request) { + NewDpKpiMonitorQO qo = new NewDpKpiMonitorQO(); + //class_dp_2_scene_control dpData = dpNewApiMapper.get_scene_control(); + //---------------------------------------------------------------------------update by sunlm , 指定场馆展示1分钟或15分钟指标 + class_dp_2_scene_control dpData = dpNewApiMapper.get_scene_control(sceneid); + String str_data_type=""; + //--------------------------------------------------------------------------- + if (null != sceneid) { + qo.setSceneid(sceneid); + } + if (null != nettype && !nettype.equals("")) { + qo.setNettype(nettype); + } else { + qo.setNettype(dpData.getNettype()); + } + + if (null != datatype && !datatype.equals("")) { + qo.setDatatype(datatype); + } else { + qo.setDatatype(dpData.getMintype() + "分钟"); + } + //---------------------------------------- + str_data_type=qo.getDatatype(); + str_data_type=str_data_type.replace("分钟",""); + //---------------------------------------- + + if (null != kpiname && !kpiname.equals("")) { + qo.setKpiname(kpiname); + } else { + qo.setKpiname(dpData.getKpiname()); + } + + qo.setInorout(inorout); //add by sunlm 2023-07-18 + + //------------------------------------------------- + + String keyname="dp_2_seat_data_"+String.valueOf(qo.getSceneid())+"_"+qo.getNettype()+"_"+str_data_type+"_"+qo.getKpiname()+"_"+String.valueOf(inorout); + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + PageInfo page = redisCache.getCacheObject(keyname); + return getDataTable(page.getList(), page.getTotal()); + } + //------------------------------------------------------------------------ + PageInfo page = pmKpiMonitorCellService.getDpMonitorCellList(qo); + redisCache.setCacheObject(keyname, page,getcachesecond(), TimeUnit.SECONDS); //数据放缓存 + return getDataTable(page.getList(), page.getTotal()); + + } + //endregion + + //region--------------------------------------------------------------------------------------无线:3D大屏场外点接口 + @ApiOperation(value = "无线:3D大屏场外点接口;sceneid:场馆ID;nettype:4G,5G,datatype:15分钟,1分钟;kpiname:指标名称") + @GetMapping(value = "/get_point_data") + @Anonymous + public TableDataInfo getPointData(@RequestParam Integer sceneid, + @RequestParam String nettype, + @RequestParam(required = false) String datatype, + @RequestParam(required = false) String kpiname, + HttpServletRequest request) { + NewDpKpiMonitorQO qo = new NewDpKpiMonitorQO(); + //class_dp_2_scene_control dpData = dpNewApiMapper.get_scene_control(); + //---------------------------------------------------------------------------update by sunlm , 指定场馆展示1分钟或15分钟指标 + class_dp_2_scene_control dpData = dpNewApiMapper.get_scene_control(sceneid); + String str_data_type=""; + //--------------------------------------------------------------------------- + if (null != sceneid) { + qo.setSceneid(sceneid); + } + if (null != nettype && !nettype.equals("")) { + qo.setNettype(nettype); + } else { + qo.setNettype(dpData.getNettype()); + } + if (null != datatype && !datatype.equals("")) { + qo.setDatatype(datatype); + } else { + qo.setDatatype(dpData.getMintype() + "分钟"); + } + //---------------------------------------- + str_data_type=qo.getDatatype(); + str_data_type=str_data_type.replace("分钟",""); + //---------------------------------------- + + if (null != kpiname && !kpiname.equals("")) { + qo.setKpiname(kpiname); + } else { + qo.setKpiname(dpData.getKpiname()); + } + qo.setSeatno(com.ruoyi.eastcom_yw.common.constant.KpiConstants.QUERYSEAT); + + qo.setInorout("4"); //场外点接口,P, add by sunlm 2023-07-18 + + //---------------------------------------- + String keyname="dp_2_point_data_"+String.valueOf(qo.getSceneid())+"_"+qo.getNettype()+"_"+str_data_type+"_"+qo.getKpiname(); + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + PageInfo page = redisCache.getCacheObject(keyname); + return getDataTable(page.getList(), page.getTotal()); + } + //----------------------------------------------------------------------- + PageInfo page = pmKpiMonitorCellService.getDpMonitorCellList(qo); + redisCache.setCacheObject(keyname, page,58, TimeUnit.SECONDS); //数据放缓存 + return getDataTable(page.getList(), page.getTotal()); + + } + //endregion + + //region--------------------------------------------------------------------------------------无线:3D大屏外场保障(牌子显示) + @ApiOperation(value = "无线:3D大屏外场保障(牌子显示),sceneid:场馆ID,typeid: 1: 4G,2: 5G ") + @GetMapping("/get_test_data") + @Anonymous + public AjaxResult get_test_data(@RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid, + @RequestParam(value = "typeid", required = false, defaultValue = "0") int typeid) { + String keyname="dp_2_test_data_"+String.valueOf(sceneid)+"_"+String.valueOf(typeid); + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List lstData = redisCache.getCacheObject(keyname); + return success(lstData); + } + //----------------------------------------------------------------------- + List jsonObjects = new ArrayList<>(); + List list = MydpNewYayun_Wuxian_Mapper.get_test_data(sceneid,typeid); + for (class_dp_2_scene_test_data SceneTestData : list) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("name", SceneTestData.getScenename()); + jsonObject.put("type", SceneTestData.getNettype()); + jsonObject.put("GPS", SceneTestData.getLat() + "," + SceneTestData.getLng()); + jsonObject.put("ConnectDelay", String.valueOf(SceneTestData.getConnectdelay())); + jsonObject.put("DLSpeed", String.valueOf(SceneTestData.getDlspeed())); + jsonObject.put("PageComplete", String.valueOf(SceneTestData.getPagecomplete())); + jsonObject.put("ULSpeed", String.valueOf(SceneTestData.getUlspeed())); + jsonObject.put("UpdateTime", null == SceneTestData.getUpdateTime() ? "" : DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", SceneTestData.getUpdateTime())); + jsonObjects.add(jsonObject); + } + redisCache.setCacheObject(keyname, jsonObjects,getcachesecond(), TimeUnit.SECONDS); //数据放缓存 + return AjaxResult.success(jsonObjects); + } + //endregion + + //region--------------------------------------------------------------------------------------无线:大屏外场告警接口 + @ApiOperation(value = "无线:大屏外场基站告警接口,sceneid:场馆ID") + @GetMapping("/get_bts_wireless_alarms") + @Anonymous + public AjaxResult get_bts_wireless_alarms( + @RequestParam int sceneid + ) + { + String keyname="dp_2_bts_wireless_alarms_"+String.valueOf(sceneid); + if (redisCache.hasKey(keyname)) { + List cacheData = redisCache.getCacheObject(keyname); + return success(cacheData); + } + List btslist=new ArrayList(); + btslist= MydpNewYayun_Wuxian_Mapper.get_bts_wireless_alarms_list(sceneid); + //---------------------------------------- + List allalarmlist=MydpNewYayun_Wuxian_Mapper.get_wireless_alarms_by_site(sceneid); + //---------------------------------------- + for (int i=0;i alarmlist=new ArrayList(); + try { + alarmlist=allalarmlist.stream().filter(x -> x.getReserved().equals(sitename)).collect(Collectors.toList()); + } + catch(Exception e) + { + } + btslist.get(i).lists=alarmlist; + } + redisCache.setCacheObject(keyname, btslist,getcachesecond(), TimeUnit.SECONDS); //缓存保留分钟 + return success(btslist); + } + //endregion + + //region--------------------------------------------------------------------------------------无线:大屏内外场坐席告警接口 + @ApiOperation(value = "无线:大屏内外场坐席告警接口,sceneid:场馆ID,inorout: 1:内场;2:外场;3:功能区") + @GetMapping("/get_seat_wireless_alarms") + @Anonymous + public AjaxResult get_seat_wireless_alarms( + @RequestParam int sceneid, + @RequestParam(value = "inorout", required = false, defaultValue = "0") int inorout + ) + { + String keyname="dp_2_seat_wireless_alarms_"+String.valueOf(sceneid)+"_"+String.valueOf(inorout); + if (redisCache.hasKey(keyname)) { + List cacheData = redisCache.getCacheObject(keyname); + return success(cacheData); + } + List seatlist=new ArrayList(); + seatlist= MydpNewYayun_Wuxian_Mapper.get_seat_wireless_alarms_list(sceneid,inorout); + //----------------------------------------- + List allalarmlist=MydpNewYayun_Wuxian_Mapper.get_wireless_alarms_by_seat(sceneid); + //------------------------------------------- + for (int i=0;i0) { + String seatid = seatlist.get(i).seatid; + List alarmlist = new ArrayList(); + try { + alarmlist=allalarmlist.stream().filter(x -> x.getReserved().equals(seatid)).collect(Collectors.toList()); + } + catch(Exception e) + { + } + seatlist.get(i).lists = alarmlist; + } + } + //------------------------------------- + redisCache.setCacheObject(keyname, seatlist,getcachesecond(), TimeUnit.SECONDS); //缓存保留分钟 + return success(seatlist); + } + //endregion + + //region ----------------------------------------------------------------------------------------无线:右小屏景点接口 + @ApiOperation("无线:右小屏景点接口,spottypeid: 景区大类: 1:景区,4:功能中心;typeid:1: 4G ,2: 5G") + @GetMapping(value = "/get_all_spot_top5") + public AjaxResult get_all_spot_top5(@RequestParam(value = "spottypeid", required = false, defaultValue = "0") int spottypeid,//景区大类 + @RequestParam int typeid, + HttpServletRequest request) + { + int mintype=getmincontroltype(spottypeid,0); //1分钟 ,15分钟 + + String keyname="dp_2_all_spot_top5_"+String.valueOf(spottypeid)+"_"+String.valueOf(typeid); + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List lstData = redisCache.getCacheObject(keyname); + return success(lstData); + } + //----------------------------------------------------------------------- + List dpAllData=new ArrayList(); + //--------------------------- + List dpspotdetail = MydpNewYayun_Wuxian_Mapper.getspotlist(spottypeid); //获得大类的细项 + for (class_dp_2_spotdetail spots:dpspotdetail) { + List lists=new ArrayList(); + //----------------------------------------------算出每个指标的TOP5 + class_dp_2_top5_spot spot=new class_dp_2_top5_spot(); + List top5=new ArrayList(); + top5 = MydpNewYayun_Wuxian_Mapper.get_all_spot_top5(spots.spotId,"上行Prb利用率", typeid, mintype); + spot.kpiname="上行Prb利用率"; + spot.top5=top5; + lists.add(spot); + //-------------- + spot=new class_dp_2_top5_spot(); + top5=new ArrayList(); + top5 = MydpNewYayun_Wuxian_Mapper.get_all_spot_top5(spots.spotId,"下行Prb利用率", typeid, mintype); + spot.kpiname="下行Prb利用率"; + spot.top5=top5; + lists.add(spot); + //--------------- + spot=new class_dp_2_top5_spot(); + top5=new ArrayList(); + top5 = MydpNewYayun_Wuxian_Mapper.get_all_spot_top5(spots.spotId,"最大用户数", typeid, mintype); + spot.kpiname="最大用户数"; + spot.top5=top5; + lists.add(spot); + //-------------- + spot=new class_dp_2_top5_spot(); + top5=new ArrayList(); + top5 = MydpNewYayun_Wuxian_Mapper.get_all_spot_top5(spots.spotId,"平均干扰值", typeid, mintype); + spot.kpiname="平均干扰值"; + spot.top5=top5; + lists.add(spot); + //-------------------------------------------------- + class_dp_2_top5_allspot allspot=new class_dp_2_top5_allspot(); + allspot.spotname=spots.spotName; + allspot.lists=lists; + dpAllData.add(allspot); + } + redisCache.setCacheObject(keyname, dpAllData,58, TimeUnit.SECONDS); //数据放缓存 + return success(dpAllData); + } + //endregion + + //region-------------------------------------------------------------------------------无线:保存MML指令 + /*{ + "orderid": 1, + "datatype": "1分钟", + "nettype": "5G", + "venueid": 2, + "venuename": "杭州奥体中心体育场", + "seatid": "B22", + "seatname": "", + "onekey": 0, + "color": "#00af57", + "score": 0.0, + "kpiname": "综合算法", + "celltype": null, + "stationno": 11544392, + "pointname": "H11544392-杭州滨江奥体主体育场中看台E1至L1-H5W-lampsite", + "pointid": "B22/B23/B24", + "longitude": 120.222995, + "latitude": 30.231595, + "celllist": [ + { + "nettype": "5G", + "venueid": 2, + "venuename": "杭州奥体中心体育场", + "坐席编号": "B22", + "cellcodeci": "47285829762", + "starttime": "2023-09-11 15:18:00", + "小区名称": "H11544392-杭州滨江奥体主体育场中看台E1至L1-H5W-lampsite-49610-中看台M5SF-130", + "最大用户数": { + "value": 0, + "maxvalue": null, + "color": "#00af57", + "score": 0.0, + "data": null + }, + "上行prb利用率": { + "value": 3.38, + "maxvalue": null, + "color": "#00af57", + "score": 0.0, + "data": null + }, + "下行prb利用率": { + "value": 7.41, + "maxvalue": null, + "color": "#00af57", + "score": 0.0, + "data": null + }, + "上行平均干扰": { + "value": -115.00, + "maxvalue": null, + "color": "#00af57", + "score": 0.0, + "data": null + }, + "endtime": "2023-09-11 15:18:00", + "综合得分": { + "value": 0, + "maxvalue": null, + "color": "#00af57", + "score": 0.0, + "data": null + }, + "stationno": 11544392, + "pointname": "H11544392-杭州滨江奥体主体育场中看台E1至L1-H5W-lampsite", + "pointid": "B22/B23/B24", + "longitude": 120.222995, + "latitude": 30.231595, + "小区频段": "NR-C", + "设备类型": "4T", + "带宽": 80, + "方位角": 360 + }, + { + "nettype": "5G", + "venueid": 2, + "venuename": "杭州奥体中心体育场", + "坐席编号": "B22", + "cellcodeci": "47285825668", + "starttime": "2023-09-11 15:18:00", + "小区名称": "H11544391-杭州滨江奥体主体育场中看台B2至L1-H5W-lampsite-26622-中看台M5SF-132", + "最大用户数": { + "value": 0, + "maxvalue": null, + "color": "#00af57", + "score": 0.0, + "data": null + }, + "上行prb利用率": { + "value": 4.03, + "maxvalue": null, + "color": "#00af57", + "score": 0.0, + "data": null + }, + "下行prb利用率": { + "value": 5.98, + "maxvalue": null, + "color": "#00af57", + "score": 0.0, + "data": null + }, + "上行平均干扰": { + "value": -114.00, + "maxvalue": null, + "color": "#00af57", + "score": 0.0, + "data": null + }, + "endtime": "2023-09-11 15:18:00", + "综合得分": { + "value": 0, + "maxvalue": null, + "color": "#00af57", + "score": 0.0, + "data": null + }, + "stationno": 11544391, + "pointname": "H11544391-杭州滨江奥体主体育场中看台B2至L1-H5W-lampsite", + "pointid": "B22/B23/B24", + "longitude": 120.223123, + "latitude": 30.232123, + "小区频段": "NR-D", + "设备类型": "4T", + "带宽": 100, + "方位角": 360 + } + ] + } + * */ + @ApiOperation("无线:保存MML指令 ") + @PostMapping(value = "/insert_mml_info") + public AjaxResult insert_mml_info(@RequestBody JSONObject jsonObject, HttpServletRequest request) + { + String sRet="保存成功"; + //------------------------------------- + List list=(List)jsonObject.get("celllist"); + Date currentTime = new Date(); + SimpleDateFormat formatter = new SimpleDateFormat("MMddHHmm"); + String dateString = formatter.format(currentTime); + int batchno=Integer.parseInt(dateString); //批次 + for (int i=0;i0 的,保存 + if (zhvalue>0) + sRet=MydpNewYayun_Wuxian_Mapper.insert_mml_info(cellname,prbup,prbdown,maxuser,zhvalue, + avgdisturb,batchno,sceneid,stattime,seatid,nettype); + } + //------------------------------------- + return sRet.equals("保存成功")?AjaxResult.success(sRet):AjaxResult.error(sRet); + } + //endregion + + //region -------------------------------------------------------------------------------------无线:高负荷小区TOP5 + //-------------------------------------------- + + @ApiOperation("无线:高负荷小区TOP5接口,typeid:1: 4G ,2: 5G") + @GetMapping(value = "/get_wireless_highload") + public AjaxResult get_wireless_highload( + @RequestParam int typeid, + HttpServletRequest request) + { + String keyname="dp_2_wireless_highload_"+String.valueOf(typeid); + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List lstData = redisCache.getCacheObject(keyname); + return success(lstData); + } + //--------------------------------------------------------------------读数据库 + List dpData=new ArrayList(); + dpData=MydpNewYayun_Wuxian_Mapper.get_wireless_highload(typeid); + //---------------------- + redisCache.setCacheObject(keyname, dpData,getcachesecond(), TimeUnit.SECONDS); //数据放缓存 + return success(dpData); + } + //endregion + + //region --------------------------------------------------------------------------------------------小区频段统计 + @ApiOperation("小区频段统计") + @GetMapping(value = "/get_freq_cnt") + public AjaxResult get_freq_cnt(@RequestParam int level, + @RequestParam(value = "areaid", required = false, defaultValue = "0") int areaid, + @RequestParam(value = "sceneid", required = false, defaultValue = "0") int sceneid, + @RequestParam int typeid, + HttpServletRequest request) + { + int mintype=getmincontroltype(areaid,sceneid); //1分钟 ,15分钟 + String keyname="dp_2_freq_cnt_"+String.valueOf(level)+"_"+String.valueOf(areaid)+"_"+String.valueOf(sceneid)+"_" + +String.valueOf(typeid)+"_"+String.valueOf(mintype); + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List lstData = redisCache.getCacheObject(keyname); + return success(lstData); + } + List dplist=new ArrayList(); + dplist = MydpNewYayun_Wuxian_Mapper.get_freq_cnt(level,areaid,sceneid,typeid,mintype); + redisCache.setCacheObject(keyname, dplist,getcachesecond(), TimeUnit.SECONDS); //数据放缓存 + return success(dplist); + } + //endregion + + //--------------------第六屏 DICT,包括全域/城区 + + //region ------------------------------------------------------------------------------------DICT:地图显示接口 + @ApiOperation("DICT:地图显示接口 ") + @GetMapping(value = "/get_maps_dict") + public AjaxResult get_maps_dict() + { + List dpData= MydpNewYayun_Dict_Mapper.get_dict_list(); + String keyname="dp_6_dict_map_alarm_list"; + List dpAlarm=new ArrayList(); + if (redisCache.hasKey(keyname)) { + dpAlarm = redisCache.getCacheObject(keyname); + } + else { + dpAlarm = MydpNewYayun_Dict_Mapper.get_map_alarm_list(); + redisCache.setCacheObject(keyname, dpAlarm,58, TimeUnit.SECONDS); //缓存保留分钟 + } + //-------------------------------------- + for (int i=0;i dpAlarm1=new ArrayList(); + try { + dpAlarm1=dpAlarm.stream().filter(x -> x.getCode().equals(areaname)).collect(Collectors.toList()); + } + catch(Exception e) + { + } + dpData.get(i).lists=dpAlarm1; + dpData.get(i).alarmcount=dpAlarm1.size(); + } + //--------------------------------------------------------- + return success(dpData); + } + //endregion + + //region --------------------------------------------------------------------------------------------DICT:监控类项目在线率 + @ApiOperation("DICT:监控类项目在线率") + @GetMapping(value = "/get_dict_monitor_project") + public AjaxResult get_dict_monitor_project(HttpServletRequest request) + { + String keyname="dp_6_dict_monitor_project_list"; + List projectlist=new ArrayList(); + if (redisCache.hasKey(keyname)) { + projectlist = redisCache.getCacheObject(keyname); + } + else { + projectlist= MydpNewYayun_Dict_Mapper.get_dict_monitor_project_list(); + redisCache.setCacheObject(keyname, projectlist,58, TimeUnit.SECONDS); //缓存保留分钟 + } + + class_dp_6_dict_project_statis dictstat=MydpNewYayun_Dict_Mapper.get_dict_monitor_project_stat(); + + class_dp_6_dict_kpi_monitor kpiproject=new class_dp_6_dict_kpi_monitor(); + kpiproject.lists=projectlist; + kpiproject.projecttotal=dictstat==null?0:dictstat.projectnum ;//projectlist.size(); + kpiproject.pointtotal=dictstat==null?0:dictstat.pointnumber ;//0; + kpiproject.guzhangtotal=dictstat==null?0:dictstat.guzhangshuliang;//0; + /* + for (int i=0;i alarmlist=new ArrayList(); + if (redisCache.hasKey(keyname)) { + alarmlist = redisCache.getCacheObject(keyname); + } + else { + alarmlist= MydpNewYayun_Dict_Mapper.get_dict_monitor_alarm_list(); + redisCache.setCacheObject(keyname, alarmlist,58, TimeUnit.SECONDS); //缓存保留分钟 + } + class_dp_6_dict_alarm_monitor alarmproject=new class_dp_6_dict_alarm_monitor(); + alarmproject.lists=alarmlist; + alarmproject.total=alarmlist.size(); + //----------------- + return success(alarmproject); + } + //endregion + + //region --------------------------------------------------------------------------------------------DICT:链路类项目告警 + @ApiOperation("DICT:链路类项目告警") + @GetMapping(value = "/get_dict_link_alarm") + public AjaxResult get_dict_link_alarm(HttpServletRequest request) + { + String keyname="dp_dict_link_alarm_list"; + List alarmlist=new ArrayList(); + if (redisCache.hasKey(keyname)) { + alarmlist = redisCache.getCacheObject(keyname); + } + else { + alarmlist= MydpNewYayun_Dict_Mapper.get_dict_link_alarm_list(); + redisCache.setCacheObject(keyname, alarmlist,58, TimeUnit.SECONDS); //缓存保留分钟 + } + //--------------------------------- + List zzalarmlist=new ArrayList(); + List tqalarmlist=new ArrayList(); + try + { + zzalarmlist = alarmlist.stream().filter(x -> x.get项目类型().equals("制证验证")).collect(Collectors.toList()); + } + catch (Exception ee) { + } + try + { + tqalarmlist = alarmlist.stream().filter(x -> x.get项目类型().equals("TQ安保")).collect(Collectors.toList()); + } + catch (Exception ee) { + } + //--------------------------------- + class_dp_6_dict_links links=new class_dp_6_dict_links(); + links.zhizhenglists=zzalarmlist; + links.teqinglists=tqalarmlist; + links.zhizhengtotal=zzalarmlist==null?0:zzalarmlist.size(); + links.teqingtotal=tqalarmlist==null?0:tqalarmlist.size(); + //----------------- + return success(links); + } + //endregion + + //region --------------------------------------------------------------------------------------------DICT:终端接入 + @ApiOperation("DICT:终端接入统计接口") + @GetMapping(value = "/get_dict_clientcount") + public AjaxResult get_dict_clientcount(HttpServletRequest request) + { + + String keyname="dp_6_dict_clientcount"; + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List cacheData=redisCache.getCacheObject(keyname); //相同的类结构 + return success(cacheData); + } + //-------------------------------------------------------------------读数据库 + List dpData= MydpNewYayun_Dict_Mapper.get_dict_clientcount(); + //---------------------------------- + class_dp_1_gbflow_wireless myData=new class_dp_1_gbflow_wireless(); + myData.label=new ArrayList(); + myData.xaxis=new ArrayList(); + myData.value=new ArrayList(); + myData.value2=new ArrayList(); + //---------------------- + myData.label.add("今天(" + getDateTimeString(0) + ")"); + myData.label.add("昨天(" + getDateTimeString(-1) + ")"); + + float vlst1=0; + float vlst2=0; + for (int i=0;i0) vlst1=dpData.get(i).gb; + if ((dpData.get(i).gb==-1) && (i>0)) + myData.value.add(vlst1); + else if ((dpData.get(i).gb==-1) && (i==0)) + myData.value.add((float)0.00); + else + myData.value.add(dpData.get(i).gb); + } + else //前日 + { + myData.xaxis.add(dpData.get(i).adate); + if (dpData.get(i).gb>0) vlst2=dpData.get(i).gb; + if ((dpData.get(i).gb==-1) && (i>0)) + myData.value2.add(vlst2); + else if ((dpData.get(i).gb==-1) && (i==0)) + myData.value2.add((float)0.00); + else + myData.value2.add(dpData.get(i).gb); + } + } + //---------------------- + List lstData=new ArrayList(); + lstData.add(myData); + redisCache.setCacheObject(keyname, lstData,58, TimeUnit.SECONDS); //缓存保留 + return success(lstData); + } + //endregion + + //region --------------------------------------------------------------------------------------------DICT:终端流量 + @ApiOperation("DICT:终端流量统计接口") + @GetMapping(value = "/get_dict_clientstream") + public AjaxResult get_dict_clientstream(HttpServletRequest request) + { + + String keyname="dp_6_dict_clientstream"; + //-------------------------------------------------------------------读缓存 + if (redisCache.hasKey(keyname)) { + List cacheData=redisCache.getCacheObject(keyname); //相同的类结构 + return success(cacheData); + } + //-------------------------------------------------------------------读数据库 + List dpData= MydpNewYayun_Dict_Mapper.get_dict_clientstream(); + //---------------------------------- + class_dp_1_gbflow_wireless myData=new class_dp_1_gbflow_wireless(); + myData.label=new ArrayList(); + myData.xaxis=new ArrayList(); + myData.value=new ArrayList(); + myData.value2=new ArrayList(); + //---------------------- + myData.label.add("今天(" + getDateTimeString(0) + ")"); + myData.label.add("昨天(" + getDateTimeString(-1) + ")"); + + float vlst1=0; + float vlst2=0; + for (int i=0;i0) vlst1=dpData.get(i).gb; + if ((dpData.get(i).gb==-1) && (i>0)) + myData.value.add(vlst1); + else if ((dpData.get(i).gb==-1) && (i==0)) + myData.value.add((float)0.00); + else + myData.value.add(dpData.get(i).gb); + } + else //前日 + { + myData.xaxis.add(dpData.get(i).adate); + if (dpData.get(i).gb>0) vlst2=dpData.get(i).gb; + if ((dpData.get(i).gb==-1) && (i>0)) + myData.value2.add(vlst2); + else if ((dpData.get(i).gb==-1) && (i==0)) + myData.value2.add((float)0.00); + else + myData.value2.add(dpData.get(i).gb); + } + } + //---------------------- + List lstData=new ArrayList(); + lstData.add(myData); + redisCache.setCacheObject(keyname, lstData,58, TimeUnit.SECONDS); //缓存保留 + return success(lstData); + } + //endregion + + //region --------------------------------------------------------------------------------------------DICT:AP设备数统计 + @ApiOperation("DICT:AP设备数统计") + @GetMapping(value = "/get_dict_ap_count") + public AjaxResult get_dict_ap_count(HttpServletRequest request) + { + + String keyname="dp_6_dict_ap_count"; + if (redisCache.hasKey(keyname)) { + class_dp_1_device_alarms_counts_ext cacheData = redisCache.getCacheObject(keyname); + return success(cacheData); + } + //------------------------------------- + List dpdata= MydpNewYayun_Dict_Mapper.get_dict_ap_count(); + //------------------------------------ + class_dp_1_device_alarms_counts_ext retdata=new class_dp_1_device_alarms_counts_ext(); + retdata.设备数1= dpdata.get(0).设备数1; + retdata.设备数2= dpdata.get(0).设备数2; + redisCache.setCacheObject(keyname, retdata,58, TimeUnit.SECONDS); //缓存 + return success(retdata); + } + //endregion + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/dpYayunController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/dpYayunController.java new file mode 100644 index 0000000..afed511 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sunlm/dpYayunController.java @@ -0,0 +1,422 @@ +package com.ruoyi.web.controller.sunlm; + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.sunlm.domain.*; +import com.ruoyi.sunlm.mapper.dpYayunMapper; +import com.ruoyi.sunlm.mapper.dpYayunReplayMapper; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.constraints.NotNull; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +@RestController +@CrossOrigin +@RequestMapping("/eastcom_yw/daping") + +public class dpYayunController extends BaseController +{ + @Resource + dpYayunMapper MydpYayunMapper; //直接在这里引用数据库操作层(MAPPER),就不用写Service层了! + + @Resource + dpYayunReplayMapper MydpYayunReplayMapper; //0428演示用 + + @Value("${daping}") + public String jobtype; //DEBUG //WORK , 发布到正式服务器改成 WORK, 连接公司服务器数据库时用 DEBUG, 在配置文件中配置 + + //-------------------------------------------- + public int getruntype() + { + return MydpYayunMapper.getruntype(); + } + + //region --------------------------------------------------------------------------------------------调用存储过程测试 + @GetMapping(value = "/calldbfunction") + public AjaxResult calldbfunction(HttpServletRequest request) + { + String sret = MydpYayunMapper.calldbfunction(); + List srets=new ArrayList(); + srets.add(sret); + return success(srets); + } + //endregion + + //region --------------------------------------------------------------------------------------------回放复位控制 + @ApiOperation("回放复位控制") + @PutMapping(value = "/resetreplay") + public AjaxResult resetreplay(HttpServletRequest request) + { + String sRet=""; + try { + MydpYayunReplayMapper.resetreplay(); + sRet = "复位成功"; + } catch (Exception e) { + sRet = "复位失败:"+e.getMessage(); + } + //--------------------------------- + return sRet.equals("复位成功")?AjaxResult.success(sRet):AjaxResult.error(sRet); + } + //endregion + + //region --------------------------------------------------------------------------------------------获取场馆列表 + @ApiOperation("获取场馆列表") + @GetMapping(value = "/getvenuelist") + public AjaxResult getvenuelist(HttpServletRequest request) + { + List dpvenue=new ArrayList(); + dpvenue = MydpYayunMapper.getvenuelists(); + return success(dpvenue); + } + //endregion + + //region --------------------------------------------------------------------------------------------左侧1图表 + private String getDateTimeString(int day) + { + Calendar calendar = Calendar.getInstance(); //创建Calendar 的实例 + calendar.add(Calendar.DAY_OF_MONTH, day); //当前时间增减天数 + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日"); + String string = simpleDateFormat.format(calendar.getTime()); + return string; + } + + + + //-------------------------------------------- + @ApiOperation("左侧1图表接口,typeid:1: 4G ,2: 5G, sceneid:场馆ID") + @GetMapping(value = "/get_left_1_data") + public AjaxResult get_left_1_data(@RequestParam int sceneid, @RequestParam int typeid,HttpServletRequest request) + { + List dpData=new ArrayList(); + logger.info(jobtype); + //---------------------------1:正式,0:演示 + int runtype=getruntype(); + if (runtype==1) + dpData = MydpYayunMapper.get_left_1_data(sceneid,typeid,jobtype); + else if (runtype==0) + dpData = MydpYayunReplayMapper.get_left_1_data(sceneid,typeid,jobtype); + //------------------ + class_dp_left_1 myData=new class_dp_left_1(); + myData.label=new ArrayList(); + myData.xaxis=new ArrayList(); + myData.value=new ArrayList(); + myData.value2=new ArrayList(); + //---------------------- + if (runtype==1) { + myData.label.add("今天(" + getDateTimeString(0) + ")"); + myData.label.add("昨天(" + getDateTimeString(-1) + ")"); + } + else + { + myData.label.add("当日"); + myData.label.add("前日"); + } + for (int i=0;i0)) + myData.value.add(dpData.get(i-1).value); + else if ((dpData.get(i).value==-1) && (i==0)) + myData.value.add((float)0.00); + else + myData.value.add(dpData.get(i).value); + } + else //昨天数据 + { + myData.xaxis.add(dpData.get(i).datetime); + if ((dpData.get(i).value==-1) && (i>0)) + myData.value2.add(dpData.get(i-1).value); + else if ((dpData.get(i).value==-1) && (i==0)) + myData.value2.add((float)0.00); + else + myData.value2.add(dpData.get(i).value); + } + } + //---------------------- + List lstData=new ArrayList(); + lstData.add(myData); + return success(lstData); + } + //endregion + + //region --------------------------------------------------------------------------------------------左侧2图表 + //-------------------------------------------- + @ApiOperation("左侧2图表接口,typeid:1: 4G ,2: 5G, sceneid:场馆ID") + @GetMapping(value = "/get_left_2_data") + public AjaxResult get_left_2_data(@RequestParam int sceneid, @RequestParam int typeid,HttpServletRequest request) + { + List dpData=new ArrayList(); + //----------------------- + int runtype=getruntype(); + if (runtype==1) + dpData = MydpYayunMapper.get_left_2_data(sceneid,typeid,jobtype); + else + dpData = MydpYayunReplayMapper.get_left_2_data(sceneid,typeid,jobtype); + //------------------ + class_dp_left_2 myData=new class_dp_left_2(); + myData.label=new ArrayList(); + myData.xaxis=new ArrayList(); + myData.value=new ArrayList(); + myData.value2=new ArrayList(); + //---------------------- + if (runtype==1) { + myData.label.add("今天(" + getDateTimeString(0) + ")"); + myData.label.add("昨天(" + getDateTimeString(-1) + ")"); + } + else + { + myData.label.add("当日"); + myData.label.add("前日"); + } + for (int i=0;i0)) + myData.value.add(dpData.get(i-1).value); + else if ((dpData.get(i).value==-1) && (i==0)) + myData.value.add((float)0.00); + else + myData.value.add(dpData.get(i).value); + } + else //昨天数据 + { + myData.xaxis.add(dpData.get(i).datetime); + if ((dpData.get(i).value==-1) && (i>0)) + myData.value2.add(dpData.get(i-1).value); + else if ((dpData.get(i).value==-1) && (i==0)) + myData.value2.add((float)0.00); + else + myData.value2.add(dpData.get(i).value); + } + } + //---------------------- + List lstData=new ArrayList(); + lstData.add(myData); + return success(lstData); + } + //endregion + + //region --------------------------------------------------------------------------------------------左侧3TOP5图表 + //-------------------------------------------- + public int getmincontroltype() + { + return MydpYayunMapper.getmincontroltype(); + } + + @ApiOperation("左侧3图表接口,typeid:1: 4G ,2: 5G, sceneid:场馆ID,areaid:0:全部小区,1:场内小区,2:场外小区") + @GetMapping(value = "/get_left_3_data") + public AjaxResult get_left_3_data(@RequestParam int sceneid, @RequestParam int typeid, + @RequestParam(value = "areaid", required = false, defaultValue = "0") int areaid, + HttpServletRequest request) + { + int mintype=getmincontroltype(); + List dpData=new ArrayList(); + //----------------------- + int runtype=getruntype(); + if (runtype==1) + dpData=MydpYayunMapper.get_left_3_data(sceneid,typeid,mintype,areaid,jobtype); + else + dpData=MydpYayunReplayMapper.get_left_3_data(sceneid,typeid,mintype,areaid,jobtype); + //---------------------- + return success(dpData); + } + //endregion + + //region --------------------------------------------------------------------------------------------右侧TOP5图表1 + //-------------------------------------------- + @ApiOperation("右侧TOP5图表1接口,typeid:1: 4G ,2: 5G, sceneid:场馆ID,areaid:0:全部小区,1:场内小区,2:场外小区") + @GetMapping(value = "/get_right_1_data") + public AjaxResult get_right_1_data(@RequestParam int sceneid, @RequestParam int typeid, + @RequestParam(value = "areaid", required = false, defaultValue = "0") int areaid, + HttpServletRequest request) + { + int mintype=getmincontroltype(); + List dpData=new ArrayList(); + int runtype=getruntype(); + if (runtype==1) + dpData=MydpYayunMapper.get_right_1_data(sceneid,typeid,mintype,areaid,jobtype); + else + dpData=MydpYayunReplayMapper.get_right_1_data(sceneid,typeid,mintype,areaid,jobtype); + //---------------------- + return success(dpData); + } + //endregion + + //region --------------------------------------------------------------------------------------------右侧TOP5图表2 + //-------------------------------------------- + @ApiOperation("右侧TOP5图表2接口,typeid:1: 4G ,2: 5G, sceneid:场馆ID,areaid:0:全部小区,1:场内小区,2:场外小区") + @GetMapping(value = "/get_right_2_data") + public AjaxResult get_right_2_data(@RequestParam int sceneid, @RequestParam int typeid, + @RequestParam(value = "areaid", required = false, defaultValue = "0") int areaid, + HttpServletRequest request) + { + int mintype=getmincontroltype(); + List dpData=new ArrayList(); + //--------------------------- + int runtype=getruntype(); + if (runtype==1) + dpData=MydpYayunMapper.get_right_2_data(sceneid,typeid,mintype,areaid,jobtype); + else + dpData=MydpYayunReplayMapper.get_right_2_data(sceneid,typeid,mintype,areaid,jobtype); + //---------------------- + return success(dpData); + } + //endregion + + //region --------------------------------------------------------------------------------------------右侧TOP5图表3 + //-------------------------------------------- + @ApiOperation("右侧TOP5图表3接口,typeid:1: 4G ,2: 5G, sceneid:场馆ID,areaid:0:全部小区,1:场内小区,2:场外小区") + @GetMapping(value = "/get_right_3_data") + public AjaxResult get_right_3_data(@RequestParam int sceneid, @RequestParam int typeid, + @RequestParam(value = "areaid", required = false, defaultValue = "0") int areaid, + HttpServletRequest request) + { + int mintype=getmincontroltype(); + List dpData=new ArrayList(); + //--------------------------- + int runtype=getruntype(); + if (runtype==1) + dpData=MydpYayunMapper.get_right_3_data(sceneid,typeid,mintype,areaid,jobtype); + else + dpData=MydpYayunReplayMapper.get_right_3_data(sceneid,typeid,mintype,areaid,jobtype); + //---------------------- + return success(dpData); + } + //endregion + + //region --------------------------------------------------------------------------------------------地图基站, 用新接口替换! + //-------------------------------------------- + @ApiOperation("地图基站接口, 用新接口替换!typeid:1: 4G ,2: 5G, sceneid:场馆ID") + @GetMapping(value = "/get_maps_data") + public AjaxResult get_maps_data(@RequestParam int sceneid, @RequestParam int typeid , @RequestParam String kpiname, HttpServletRequest request) + { + int mintype=getmincontroltype(); + class_dp_maps dpData=new class_dp_maps(); + //--------------------------- + int runtype=getruntype(); + if (runtype==1) + dpData = MydpYayunMapper.get_maps_data(sceneid,typeid); + else + dpData = MydpYayunReplayMapper.get_maps_data(sceneid,typeid); + //---------------------- + List dpBtss=new ArrayList(); + if (runtype==1) + dpBtss=MydpYayunMapper.get_bts_data(sceneid,typeid,kpiname,mintype,jobtype); + else + dpBtss=MydpYayunReplayMapper.get_bts_data(sceneid,typeid,kpiname,mintype,jobtype); + dpData.data=dpBtss; + //---------------------- + List lstData=new ArrayList(); + lstData.add(dpData); + return success(lstData); + } + //endregion + + //region --------------------------------------------------------------------------------------------顶部统计值,用新接口替换! + //--------------------------------------------去重 + /* + public static List removeDupliByName(List lists) { + Set pSet = new TreeSet<>((o1, o2) -> o1.compareTo(o2)); + pSet.addAll(lists); + return new ArrayList<>(pSet); + }*/ + + + public static List removeDupliByName(List list) { + HashSet h = new HashSet(list); + list.clear(); + list.addAll(h); + return list; + } + //---------------------------------------------- + + @ApiOperation("顶部统计值接口,用新接口替换!typeid:1: 4G ,2: 5G, sceneid:场馆ID, kpiname: 指标名(综合算法/最大用户数/上行Prb利用率/下行Prb利用率)") + @GetMapping(value = "/get_top_data") + public AjaxResult get_top_data(@RequestParam int sceneid, @RequestParam int typeid, @RequestParam String kpiname, HttpServletRequest request) + { + int mintype=getmincontroltype(); + List dpData; + //--------------------------- + int runtype=getruntype(); + if (runtype==1) + dpData = MydpYayunMapper.get_top_data(sceneid,typeid,kpiname,mintype,jobtype); + else + dpData = MydpYayunReplayMapper.get_top_data(sceneid,typeid,kpiname,mintype,jobtype); + + List red = dpData.stream().filter(x->"1".equals(x.getLevel())).map(class_dp_btsinfo::getName2).collect(Collectors.toList()); + List orange = dpData.stream().filter(x->"2".equals(x.getLevel())).map(class_dp_btsinfo::getName2).collect(Collectors.toList()); + List yellow = dpData.stream().filter(x->"3".equals(x.getLevel())).map(class_dp_btsinfo::getName2).collect(Collectors.toList()); + List green = dpData.stream().filter(x->"4".equals(x.getLevel())).map(class_dp_btsinfo::getName2).collect(Collectors.toList()); + + red=removeDupliByName(red); + orange=removeDupliByName(orange); + yellow=removeDupliByName(yellow); + green=removeDupliByName(green); + //---------------------------------------------- + class_dp_topinfo myData=new class_dp_topinfo(); + myData.red=red.size(); + myData.orange=orange.size(); + myData.yellow=yellow.size(); + myData.green=green.size(); + List lstData= new ArrayList<>(); + lstData.add(myData); + return success(lstData); + } + //endregion + + //region --------------------------------------------------------------------------------------------地图基站和统计值接口,合二为一 + //-------------------------------------------- + @ApiOperation("地图基站和统计值接口,合二为一,调用一次即可取得两个数据。typeid:1: 4G ,2: 5G, sceneid:场馆ID") + @GetMapping(value = "/get_maps_top_data") + public AjaxResult get_maps_top_data(@RequestParam int sceneid, @RequestParam int typeid , @RequestParam String kpiname, HttpServletRequest request) + { + int mintype=getmincontroltype(); + class_dp_maps_topinfo dpData=new class_dp_maps_topinfo(); + //--------------------------- + int runtype=getruntype(); + if (runtype==1) + dpData = MydpYayunMapper.get_maps_top_data(sceneid,typeid); + else + dpData = MydpYayunReplayMapper.get_maps_top_data(sceneid,typeid); + //---------------------- + List dpBtss=new ArrayList(); + if (runtype==1) + dpBtss=MydpYayunMapper.get_bts_1to2_data(sceneid,typeid,kpiname,mintype,jobtype); + else + dpBtss=MydpYayunReplayMapper.get_bts_1to2_data(sceneid,typeid,kpiname,mintype,jobtype); + + List red = dpBtss.stream().filter(x->"1".equals(x.getLevel())).map(class_dp_btsinfo::getName2).collect(Collectors.toList()); + List orange = dpBtss.stream().filter(x->"2".equals(x.getLevel())).map(class_dp_btsinfo::getName2).collect(Collectors.toList()); + List yellow = dpBtss.stream().filter(x->"3".equals(x.getLevel())).map(class_dp_btsinfo::getName2).collect(Collectors.toList()); + List green = dpBtss.stream().filter(x->"4".equals(x.getLevel())).map(class_dp_btsinfo::getName2).collect(Collectors.toList()); + + red=removeDupliByName(red); + orange=removeDupliByName(orange); + yellow=removeDupliByName(yellow); + green=removeDupliByName(green); + + dpData.total=new class_dp_topinfo(); + + dpData.total.red=red.size(); + dpData.total.orange=orange.size(); + dpData.total.yellow=yellow.size(); + dpData.total.green=green.size(); + + dpData.data=dpBtss; + //---------------------- + List lstData=new ArrayList(); + lstData.add(dpData); + return success(lstData); + } + //endregion + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysAppMenuController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysAppMenuController.java new file mode 100644 index 0000000..bf921d0 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysAppMenuController.java @@ -0,0 +1,118 @@ +package com.ruoyi.web.controller.system; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysAppMenu; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.service.ISysAppMenuService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 菜单信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/appMenu") +public class SysAppMenuController extends BaseController { + @Autowired + private ISysAppMenuService appMenuService; + + /** + * 获取菜单列表 + */ + @PreAuthorize("@ss.hasPermi('system:appMenu:list')") + @GetMapping("/list") + public AjaxResult list(SysAppMenu menu) { + List menus = appMenuService.selectMenuList(menu, getUserId()); + return success(menus); + } + + /** + * 根据菜单编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:appMenu:query')") + @GetMapping(value = "/{menuId}") + public AjaxResult getInfo(@PathVariable Long menuId) { + return success(appMenuService.selectMenuById(menuId)); + } + + /** + * 获取菜单下拉树列表 + */ + @GetMapping("/treeselect") + public AjaxResult treeselect(SysAppMenu menu) { + List menus = appMenuService.selectMenuList(menu, getUserId()); + return success(appMenuService.buildMenuTreeSelect(menus)); + } + + /** + * 加载对应角色菜单列表树 + */ + @GetMapping(value = "/roleMenuTreeselect/{roleId}/{menuCheckStrictly}") + public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId,@PathVariable("menuCheckStrictly")Boolean menuCheckStrictly) { + List menus = appMenuService.selectMenuList(getUserId()); + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", appMenuService.selectMenuListByRoleId(roleId,menuCheckStrictly)); + ajax.put("menus", appMenuService.buildMenuTreeSelect(menus)); + return ajax; + } + + /** + * 新增菜单 + */ + @PreAuthorize("@ss.hasPermi('system:appMenu:add')") + @Log(title = "菜单管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysAppMenu menu) { + if (UserConstants.NOT_UNIQUE.equals(appMenuService.checkMenuNameUnique(menu))) { + return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) { + return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + menu.setCreateBy(getUsername()); + return toAjax(appMenuService.insertMenu(menu)); + } + + /** + * 修改菜单 + */ + @PreAuthorize("@ss.hasPermi('system:appMenu:edit')") + @Log(title = "菜单管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysAppMenu menu) { + if (UserConstants.NOT_UNIQUE.equals(appMenuService.checkMenuNameUnique(menu))) { + return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) { + return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } else if (menu.getMenuId().equals(menu.getParentId())) { + return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己"); + } + menu.setUpdateBy(getUsername()); + return toAjax(appMenuService.updateMenu(menu)); + } + + /** + * 删除菜单 + */ + @PreAuthorize("@ss.hasPermi('system:appMenu:remove')") + @Log(title = "菜单管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{menuId}") + public AjaxResult remove(@PathVariable("menuId") Long menuId) { + if (appMenuService.hasChildByMenuId(menuId)) { + return warn("存在子菜单,不允许删除"); + } + if (appMenuService.checkMenuExistRole(menuId)) { + return warn("菜单已分配,不允许删除"); + } + return toAjax(appMenuService.deleteMenuById(menuId)); + } +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java new file mode 100644 index 0000000..d4f7c7a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java @@ -0,0 +1,136 @@ +package com.ruoyi.web.controller.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.SysConfig; +import com.ruoyi.system.service.ISysConfigService; + +/** + * 参数配置 信息操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/config") +public class SysConfigController extends BaseController +{ + @Autowired + private ISysConfigService configService; + + /** + * 获取参数配置列表 + */ + @PreAuthorize("@ss.hasPermi('system:config:list')") + @GetMapping("/list") + public TableDataInfo list(SysConfig config) + { + startPage(); + List list = configService.selectConfigList(config); + return getDataTable(list); + } + + @Log(title = "参数管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:config:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysConfig config) + { + List list = configService.selectConfigList(config); + ExcelUtil util = new ExcelUtil(SysConfig.class); + util.exportExcel(response, list, "参数数据"); + } + + /** + * 根据参数编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:config:query')") + @GetMapping(value = "/{configId}") + public AjaxResult getInfo(@PathVariable Long configId) + { + return success(configService.selectConfigById(configId)); + } + + /** + * 根据参数键名查询参数值 + */ + @GetMapping(value = "/configKey/{configKey}") + public AjaxResult getConfigKey(@PathVariable String configKey) + { + return success(configService.selectConfigByKey(configKey)); + } + + /** + * 新增参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:add')") + @Log(title = "参数管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysConfig config) + { + if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) + { + return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setCreateBy(getUsername()); + return toAjax(configService.insertConfig(config)); + } + + /** + * 修改参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:edit')") + @Log(title = "参数管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysConfig config) + { + if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) + { + return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setUpdateBy(getUsername()); + return toAjax(configService.updateConfig(config)); + } + + /** + * 删除参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:remove')") + @Log(title = "参数管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{configIds}") + public AjaxResult remove(@PathVariable Long[] configIds) + { + configService.deleteConfigByIds(configIds); + return success(); + } + + /** + * 刷新参数缓存 + */ + @PreAuthorize("@ss.hasPermi('system:config:remove')") + @Log(title = "参数管理", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + configService.resetConfigCache(); + return success(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java new file mode 100644 index 0000000..a320da7 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java @@ -0,0 +1,132 @@ +package com.ruoyi.web.controller.system; + +import java.util.List; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDept; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.service.ISysDeptService; + +/** + * 部门信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/dept") +public class SysDeptController extends BaseController +{ + @Autowired + private ISysDeptService deptService; + + /** + * 获取部门列表 + */ + @PreAuthorize("@ss.hasPermi('system:dept:list')") + @GetMapping("/list") + public AjaxResult list(SysDept dept) + { + List depts = deptService.selectDeptList(dept); + return success(depts); + } + + /** + * 查询部门列表(排除节点) + */ + @PreAuthorize("@ss.hasPermi('system:dept:list')") + @GetMapping("/list/exclude/{deptId}") + public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) + { + List depts = deptService.selectDeptList(new SysDept()); + depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + "")); + return success(depts); + } + + /** + * 根据部门编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:dept:query')") + @GetMapping(value = "/{deptId}") + public AjaxResult getInfo(@PathVariable Long deptId) + { + deptService.checkDeptDataScope(deptId); + return success(deptService.selectDeptById(deptId)); + } + + /** + * 新增部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:add')") + @Log(title = "部门管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDept dept) + { + if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) + { + return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + dept.setCreateBy(getUsername()); + return toAjax(deptService.insertDept(dept)); + } + + /** + * 修改部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:edit')") + @Log(title = "部门管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDept dept) + { + Long deptId = dept.getDeptId(); + deptService.checkDeptDataScope(deptId); + if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) + { + return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + else if (dept.getParentId().equals(deptId)) + { + return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己"); + } + else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0) + { + return error("该部门包含未停用的子部门!"); + } + dept.setUpdateBy(getUsername()); + return toAjax(deptService.updateDept(dept)); + } + + /** + * 删除部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:remove')") + @Log(title = "部门管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{deptId}") + public AjaxResult remove(@PathVariable Long deptId) + { + if (deptService.hasChildByDeptId(deptId)) + { + return warn("存在下级部门,不允许删除"); + } + if (deptService.checkDeptExistUser(deptId)) + { + return warn("部门存在用户,不允许删除"); + } + deptService.checkDeptDataScope(deptId); + return toAjax(deptService.deleteDeptById(deptId)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java new file mode 100644 index 0000000..6794948 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java @@ -0,0 +1,124 @@ +package com.ruoyi.web.controller.system; + +import java.util.ArrayList; +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.ruoyi.common.annotation.RepeatSubmit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.service.ISysDictDataService; +import com.ruoyi.system.service.ISysDictTypeService; + +/** + * 数据字典信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/dict/data") +public class SysDictDataController extends BaseController +{ + @Autowired + private ISysDictDataService dictDataService; + + @Autowired + private ISysDictTypeService dictTypeService; + + @PreAuthorize("@ss.hasPermi('system:dict:list')") + @GetMapping("/list") + public TableDataInfo list(SysDictData dictData) + { + startPage(); + List list = dictDataService.selectDictDataList(dictData); + return getDataTable(list); + } + + @Log(title = "字典数据", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:dict:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictData dictData) + { + List list = dictDataService.selectDictDataList(dictData); + ExcelUtil util = new ExcelUtil(SysDictData.class); + util.exportExcel(response, list, "字典数据"); + } + + /** + * 查询字典数据详细 + */ + @PreAuthorize("@ss.hasPermi('system:dict:query')") + @GetMapping(value = "/{dictCode}") + public AjaxResult getInfo(@PathVariable Long dictCode) + { + return success(dictDataService.selectDictDataById(dictCode)); + } + + /** + * 根据字典类型查询字典数据信息 + */ + @GetMapping(value = "/type/{dictType}") + @RepeatSubmit(enable = false,interval = 1000) + public AjaxResult dictType(@PathVariable String dictType) + { + List data = dictTypeService.selectDictDataByType(dictType); + if (StringUtils.isNull(data)) + { + data = new ArrayList(); + } + return success(data); + } + + /** + * 新增字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:add')") + @Log(title = "字典数据", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictData dict) + { + dict.setCreateBy(getUsername()); + return toAjax(dictDataService.insertDictData(dict)); + } + + /** + * 修改保存字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:edit')") + @Log(title = "字典数据", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictData dict) + { + dict.setUpdateBy(getUsername()); + return toAjax(dictDataService.updateDictData(dict)); + } + + /** + * 删除字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictCodes}") + public AjaxResult remove(@PathVariable Long[] dictCodes) + { + dictDataService.deleteDictDataByIds(dictCodes); + return success(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java new file mode 100644 index 0000000..d5ead57 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java @@ -0,0 +1,132 @@ +package com.ruoyi.web.controller.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDictType; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.service.ISysDictTypeService; + +/** + * 数据字典信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/dict/type") +public class SysDictTypeController extends BaseController +{ + @Autowired + private ISysDictTypeService dictTypeService; + + @PreAuthorize("@ss.hasPermi('system:dict:list')") + @GetMapping("/list") + public TableDataInfo list(SysDictType dictType) + { + startPage(); + List list = dictTypeService.selectDictTypeList(dictType); + return getDataTable(list); + } + + @Log(title = "字典类型", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:dict:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictType dictType) + { + List list = dictTypeService.selectDictTypeList(dictType); + ExcelUtil util = new ExcelUtil(SysDictType.class); + util.exportExcel(response, list, "字典类型"); + } + + /** + * 查询字典类型详细 + */ + @PreAuthorize("@ss.hasPermi('system:dict:query')") + @GetMapping(value = "/{dictId}") + public AjaxResult getInfo(@PathVariable Long dictId) + { + return success(dictTypeService.selectDictTypeById(dictId)); + } + + /** + * 新增字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:add')") + @Log(title = "字典类型", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictType dict) + { + if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) + { + return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setCreateBy(getUsername()); + return toAjax(dictTypeService.insertDictType(dict)); + } + + /** + * 修改字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:edit')") + @Log(title = "字典类型", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictType dict) + { + if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) + { + return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setUpdateBy(getUsername()); + return toAjax(dictTypeService.updateDictType(dict)); + } + + /** + * 删除字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictIds}") + public AjaxResult remove(@PathVariable Long[] dictIds) + { + dictTypeService.deleteDictTypeByIds(dictIds); + return success(); + } + + /** + * 刷新字典缓存 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + dictTypeService.resetDictCache(); + return success(); + } + + /** + * 获取字典选择框列表 + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List dictTypes = dictTypeService.selectDictTypeAll(); + return success(dictTypes); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysIndexController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysIndexController.java new file mode 100644 index 0000000..13007eb --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysIndexController.java @@ -0,0 +1,29 @@ +package com.ruoyi.web.controller.system; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.utils.StringUtils; + +/** + * 首页 + * + * @author ruoyi + */ +@RestController +public class SysIndexController +{ + /** 系统基础配置 */ + @Autowired + private RuoYiConfig ruoyiConfig; + + /** + * 访问首页,提示语 + */ + @RequestMapping("/") + public String index() + { + return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion()); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java new file mode 100644 index 0000000..b50c2b2 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java @@ -0,0 +1,226 @@ +package com.ruoyi.web.controller.system; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.annotation.RateLimiter; +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysMenu; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginBody; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.enums.LimitType; +import com.ruoyi.common.enums.OperatorType; +import com.ruoyi.common.enums.UserStatus; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.common.constant.CacheConstants; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.service.CommonService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.framework.web.service.SysLoginService; +import com.ruoyi.framework.web.service.SysPermissionService; +import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.domain.vo.SysUserInfoVo; +import com.ruoyi.system.service.ISysMenuService; +import com.ruoyi.system.service.ISysUserService; +import io.jsonwebtoken.Claims; +import io.swagger.annotations.ApiOperation; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * 登录验证 + * + * @author ruoyi + */ +@RestController +public class SysLoginController +{ + @Autowired + private SysLoginService loginService; + + @Autowired + private ISysMenuService menuService; + + @Autowired + private SysPermissionService permissionService; + + @Autowired + private YwSceneService ywSceneService; + + @Autowired + private ISysUserService userService; + + @Autowired + private TokenService tokenService; + + @Autowired + private RedisCache redisCache; + + @Autowired + private CommonService commonService; + + + private String key = com.ruoyi.common.constant.CacheConstants.ZXP_TOKEN; + + + /** + * 发送登录短信验证码 + * + * @param + * @return + */ + @PostMapping("/getLoginCode") + @ApiOperation(value = "发送登录短信验证码") + @RateLimiter(time = 3,count = 1,limitType= LimitType.IP) + @RepeatSubmit(interval = 60000,message = "1分钟内请勿重复提交") + @Log(title = "发送登录短信验证码日志", businessType = BusinessType.OTHER,operatorType= OperatorType.MANAGE) + public AjaxResult getCode(@RequestBody LoginBody loginBody) throws Exception { + return loginService.getCode(loginBody); + } + + /** + * 登录方法 + * + * @param loginBody 登录信息 + * @return 结果 + */ + @PostMapping("/login") + @RateLimiter(time = 3,count = 1,limitType= LimitType.IP) + @Log(title = "发送登录日志", businessType = BusinessType.OTHER,operatorType= OperatorType.MANAGE) + public AjaxResult login(@RequestBody LoginBody loginBody) + { + AjaxResult ajax = AjaxResult.success(); + + String token =""; + + // 生成令牌 + if("1".equals(loginBody.getLoginType())) + { + token = loginService.loginByPhone(loginBody.getPhone(),loginBody.getCode(), + loginBody.getUuid(), UserConstants.PC); + } + else + { + token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), + loginBody.getUuid()); + } + + ajax.put(Constants.TOKEN, token); + + + return ajax; + } + + + + /** + * 自动登录方法 + * + */ + @GetMapping("/autoLogin") + public AjaxResult autoLogin() + { + String token = redisCache.getCacheObject(key); + + if (ObjectUtils.isEmpty(token)) { + SysUser user = userService.selectUserByUserName("bigscreen"); + LoginUser loginUser = new LoginUser(); + loginUser.setUserId(user.getUserId()); + loginUser.setUser(user); +// token = commonService.getToken("bigscreen", "Supp0rt.zjnmc"); + token = tokenService.createToken(loginUser); + //不过期 + redisCache.setCacheObject(key, token); + return AjaxResult.success("获取成功", token); + } + + if (StringUtils.isNotEmpty(token)) { + try { + if (tokenService.isLogin(token)) { + return AjaxResult.success("获取成功", token); + } + else + { + SysUser user = userService.selectUserByUserName("bigscreen"); + LoginUser loginUser = new LoginUser(); + loginUser.setUserId(user.getUserId()); + loginUser.setUser(user); + //不过期 + token = tokenService.createToken(loginUser); + redisCache.setCacheObject(key, token); + return AjaxResult.success("获取成功", token); + } + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + + } + + return AjaxResult.error("获取失败"); + } + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @GetMapping("getInfo") + @RepeatSubmit(enable = false,interval = 1000) + public AjaxResult getInfo() + { + SysUser user = SecurityUtils.getLoginUser().getUser(); + // 角色集合 + Set roles = permissionService.getRolePermission(user); + // 权限集合 + Set permissions = permissionService.getMenuPermission(user); + + SysUserInfoVo userInfo = userService.getUserInfo(user.getUserName()); + + List last_search_venues = new ArrayList(); + + if(redisCache.hasKey(CacheConstants.YW_ALARM_LAST_VENUES + user.getUserId())) { + last_search_venues = redisCache.getCacheObject(CacheConstants.YW_ALARM_LAST_VENUES + user.getUserId()); + } + + AjaxResult ajax = AjaxResult.success(); + ajax.put("user", user); + ajax.put("roles", roles); + ajax.put("permissions", permissions); + //20230116新增获取获取用户的场馆 + List lstScene =ywSceneService.getVenueByUserCanNoData(user,false); + ajax.put("venues",lstScene); + ajax.put("searchvenues", last_search_venues); + ajax.put("userInfo", userInfo); + return ajax; + } + + /** + * 获取路由信息 + * + * @return 路由信息 + */ + @GetMapping("getRouters") + public AjaxResult getRouters() + { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuTreeByUserId(userId); + return AjaxResult.success(menuService.buildMenus(menus)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java new file mode 100644 index 0000000..4e5c064 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java @@ -0,0 +1,142 @@ +package com.ruoyi.web.controller.system; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysMenu; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.service.ISysMenuService; + +/** + * 菜单信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/menu") +public class SysMenuController extends BaseController +{ + @Autowired + private ISysMenuService menuService; + + /** + * 获取菜单列表 + */ + @PreAuthorize("@ss.hasPermi('system:menu:list')") + @GetMapping("/list") + public AjaxResult list(SysMenu menu) + { + List menus = menuService.selectMenuList(menu, getUserId()); + return success(menus); + } + + /** + * 根据菜单编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:menu:query')") + @GetMapping(value = "/{menuId}") + public AjaxResult getInfo(@PathVariable Long menuId) + { + return success(menuService.selectMenuById(menuId)); + } + + /** + * 获取菜单下拉树列表 + */ + @GetMapping("/treeselect") + public AjaxResult treeselect(SysMenu menu) + { + List menus = menuService.selectMenuList(menu, getUserId()); + return success(menuService.buildMenuTreeSelect(menus)); + } + + /** + * 加载对应角色菜单列表树 + */ + @GetMapping(value = "/roleMenuTreeselect/{roleId}/{menuCheckStrictly}") + public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId,@PathVariable("menuCheckStrictly") Boolean menuCheckStrictly) + { + List menus = menuService.selectMenuList(getUserId()); + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId,menuCheckStrictly)); + ajax.put("menus", menuService.buildMenuTreeSelect(menus)); + return ajax; + } + + /** + * 新增菜单 + */ + @PreAuthorize("@ss.hasPermi('system:menu:add')") + @Log(title = "菜单管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysMenu menu) + { + if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) + { + return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) + { + return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + menu.setCreateBy(getUsername()); + return toAjax(menuService.insertMenu(menu)); + } + + /** + * 修改菜单 + */ + @PreAuthorize("@ss.hasPermi('system:menu:edit')") + @Log(title = "菜单管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysMenu menu) + { + if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + else if (menu.getMenuId().equals(menu.getParentId())) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己"); + } + menu.setUpdateBy(getUsername()); + return toAjax(menuService.updateMenu(menu)); + } + + /** + * 删除菜单 + */ + @PreAuthorize("@ss.hasPermi('system:menu:remove')") + @Log(title = "菜单管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{menuId}") + public AjaxResult remove(@PathVariable("menuId") Long menuId) + { + if (menuService.hasChildByMenuId(menuId)) + { + return warn("存在子菜单,不允许删除"); + } + if (menuService.checkMenuExistRole(menuId)) + { + return warn("菜单已分配,不允许删除"); + } + return toAjax(menuService.deleteMenuById(menuId)); + } +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java new file mode 100644 index 0000000..48c7b50 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java @@ -0,0 +1,140 @@ +package com.ruoyi.web.controller.system; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.SysNotice; +import com.ruoyi.eastcom_yw.domain.dto.SysNoticeDTO; +import com.ruoyi.eastcom_yw.domain.qo.SysNoticeQO; +import com.ruoyi.eastcom_yw.domain.vo.SysNoticeVO; +import com.ruoyi.eastcom_yw.service.SysNoticeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + *

+ * 通知公告表 前端控制器 + *

+ * + * @author ck + * @since 2023-04-14 + */ +@Api(tags = "通知公告表") +@RestController +@RequestMapping("/eastcom_yw/sysNotice") +@Slf4j +@RequiredArgsConstructor +public class SysNoticeController extends BaseController { + + private final SysNoticeService sysNoticeService; + + /** + * 通知公告表列表 + */ + @ApiOperation(value = "通知公告表列表", notes = "通知公告表列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody SysNoticeQO qo) { + List list = sysNoticeService.getData(qo); + return getDataTable(list); + } + + + /** + * 通知公告表分页列表 + */ + @ApiOperation(value = "通知公告表分页列表", notes = "通知公告表分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody SysNoticeQO qo) { + IPage page = sysNoticeService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } + + /** + * 获取通知公告表详情 + */ + @ApiOperation(value = "通知公告表详情", notes = "通知公告表详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(sysNoticeService.fetchById(id)); + } + + /** + * 新增或修改通知公告表 + */ + @Log(title = "新增或修改通知公告表", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改通知公告表", notes = "新增或修改通知公告表") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated SysNoticeDTO dto) { + sysNoticeService.saveOrUpdate(dto); + return AjaxResult.success(); + } + + /** + * 根据id删除通知公告表 + */ + @Log(title = "根据id删除通知公告表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除通知公告表", notes = "根据id删除通知公告表") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + sysNoticeService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除通知公告表 + */ + @Log(title = "根据id批量删除通知公告表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除通知公告表", notes = "根据id批量删除通知公告表") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + sysNoticeService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "通知公告表导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(SysNotice.class); + List list = util.importExcel(file.getInputStream()); + sysNoticeService.importData(list, updateSupport); + return AjaxResult.success(); + } + + + /** + * 通知公告表导出 + */ + @ApiOperation(value = "通知公告表导出") + @PostMapping(value = "/export") + public void export(@RequestBody SysNoticeQO qo) { + sysNoticeService.export(qo); + } + + @GetMapping("/listByUser/{reciveUserId}") + public TableDataInfo listByUser(@PathVariable("reciveUserId") Long reciveUserId) + { + List list = sysNoticeService.selectNoticeListByUser(reciveUserId); + return getDataTable(list); + } + + /** + * 立刻发送手工通知简报 + */ + @ApiOperation(value = "立刻发送手工通知简报") + @PostMapping(value = "/saveAndSendBriefing") + public AjaxResult saveAndSendBriefing(@RequestBody @Validated SysNoticeDTO dto) { + sysNoticeService.saveAndSendBriefing(dto); + return AjaxResult.success(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java new file mode 100644 index 0000000..1223524 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java @@ -0,0 +1,130 @@ +package com.ruoyi.web.controller.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.SysPost; +import com.ruoyi.system.service.ISysPostService; + +/** + * 岗位信息操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/post") +public class SysPostController extends BaseController +{ + @Autowired + private ISysPostService postService; + + /** + * 获取岗位列表 + */ + @PreAuthorize("@ss.hasPermi('system:post:list')") + @GetMapping("/list") + public TableDataInfo list(SysPost post) + { + startPage(); + List list = postService.selectPostList(post); + return getDataTable(list); + } + + @Log(title = "岗位管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:post:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysPost post) + { + List list = postService.selectPostList(post); + ExcelUtil util = new ExcelUtil(SysPost.class); + util.exportExcel(response, list, "岗位数据"); + } + + /** + * 根据岗位编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:post:query')") + @GetMapping(value = "/{postId}") + public AjaxResult getInfo(@PathVariable Long postId) + { + return success(postService.selectPostById(postId)); + } + + /** + * 新增岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:add')") + @Log(title = "岗位管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysPost post) + { + if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setCreateBy(getUsername()); + return toAjax(postService.insertPost(post)); + } + + /** + * 修改岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:edit')") + @Log(title = "岗位管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysPost post) + { + if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setUpdateBy(getUsername()); + return toAjax(postService.updatePost(post)); + } + + /** + * 删除岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:remove')") + @Log(title = "岗位管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{postIds}") + public AjaxResult remove(@PathVariable Long[] postIds) + { + return toAjax(postService.deletePostByIds(postIds)); + } + + /** + * 获取岗位选择框列表 + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List posts = postService.selectPostAll(); + return success(posts); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java new file mode 100644 index 0000000..ae7259f --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java @@ -0,0 +1,183 @@ +package com.ruoyi.web.controller.system; + +import com.ruoyi.common.config.MinioConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.FileUploadUtils; +import com.ruoyi.common.utils.file.MimeTypeUtils; +import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.service.ISysUserService; + +/** + * 个人信息 业务处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/user/profile") +public class SysProfileController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private TokenService tokenService; + + /** + * 个人信息 + */ + @GetMapping + public AjaxResult profile() + { + LoginUser loginUser = getLoginUser(); + SysUser user = loginUser.getUser(); + AjaxResult ajax = AjaxResult.success(user); + ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername())); + ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername())); + return ajax; + } + + /** + * 修改用户 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult updateProfile(@RequestBody SysUser user) + { + LoginUser loginUser = getLoginUser(); + SysUser sysUser = loginUser.getUser(); +// //20230327 防止越权修改账号的姓名,手机号码,需要验证修改的用户是否当前用户 +// if(!user.getPhonenumber().equals(sysUser.getPhonenumber())) +// { +// return error("只能修改当前登录用户的用户信息"); +// } + //用户名和手机号码不允许改 + user.setUserName(null); + user.setPhonenumber(null); + user.setNickName(null); + user.setUserType(null); + user.setEmail(null); + user.setSex(null); + user.setStatus(null); + user.setLoginIp(null); + user.setLoginDate(null); + user.setCreateBy(null); + user.setRemark(null); + user.setCity(null); + user.setCounty(null); + user.setDistinctArea(null); +// if (StringUtils.isNotEmpty(user.getPhonenumber()) +// && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) +// { +// return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); +// } +// if (StringUtils.isNotEmpty(user.getEmail()) +// && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) +// { +// return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); +// } + user.setUserId(sysUser.getUserId()); + user.setPassword(null); + user.setDeptId(null); + if (userService.updateUserProfile(user) > 0) + { + sysUser.setFirstPage(user.getFirstPage()); + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改个人信息异常,请联系管理员"); + } + + /** + * 重置密码 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PutMapping("/updatePwd") + public AjaxResult updatePwd(String oldPassword, String newPassword) + { + LoginUser loginUser = getLoginUser(); + String userName = loginUser.getUsername(); + String password = loginUser.getPassword(); + if (!SecurityUtils.matchesPassword(oldPassword, password)) + { + return error("修改密码失败,旧密码错误"); + } + if (SecurityUtils.matchesPassword(newPassword, password)) + { + return error("新密码不能与旧密码相同"); + } + if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0) + { + // 更新缓存用户密码 + loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword)); + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改密码异常,请联系管理员"); + } + + /** + * 头像上传 + */ + @Log(title = "用户头像", businessType = BusinessType.UPDATE) + @PostMapping("/avatar") + public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception + { + if (!file.isEmpty()) + { + LoginUser loginUser = getLoginUser(); + String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION); + if (userService.updateUserAvatar(loginUser.getUsername(), avatar)) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("imgUrl", avatar); + // 更新缓存用户头像 + loginUser.getUser().setAvatar(avatar); + tokenService.setLoginUser(loginUser); + return ajax; + } + } + return error("上传图片异常,请联系管理员"); + } + + @Log(title = "用户头像", businessType = BusinessType.UPDATE) + @PostMapping("/avatarMinio") + public AjaxResult avatarMinio(@RequestParam("avatarfile") MultipartFile file) throws Exception + { + if (!file.isEmpty()) + { + LoginUser loginUser = getLoginUser(); + String avatar = FileUploadUtils.uploadMinio("avatar", file, MimeTypeUtils.IMAGE_EXTENSION); + avatar = avatar.replace(MinioConfig.getUrl(),"/profile/"); + if (userService.updateUserAvatar(loginUser.getUsername(), avatar)) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("imgUrl", avatar); + // 更新缓存用户头像 + loginUser.getUser().setAvatar(avatar); + tokenService.setLoginUser(loginUser); + return ajax; + } + } + return error("上传图片异常,请联系管理员"); + } + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java new file mode 100644 index 0000000..fe19249 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java @@ -0,0 +1,38 @@ +package com.ruoyi.web.controller.system; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.model.RegisterBody; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.web.service.SysRegisterService; +import com.ruoyi.system.service.ISysConfigService; + +/** + * 注册验证 + * + * @author ruoyi + */ +@RestController +public class SysRegisterController extends BaseController +{ + @Autowired + private SysRegisterService registerService; + + @Autowired + private ISysConfigService configService; + + @PostMapping("/register") + public AjaxResult register(@RequestBody RegisterBody user) + { + if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) + { + return error("当前系统没有开启注册功能!"); + } + String msg = registerService.register(user); + return StringUtils.isEmpty(msg) ? success() : error(msg); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java new file mode 100644 index 0000000..2d37d8f --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java @@ -0,0 +1,282 @@ +package com.ruoyi.web.controller.system; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDept; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.framework.web.service.SysPermissionService; +import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.domain.SysUserRole; +import com.ruoyi.system.service.ISysDeptService; +import com.ruoyi.system.service.ISysMenuService; +import com.ruoyi.system.service.ISysRoleService; +import com.ruoyi.system.service.ISysUserService; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 角色信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/role") +public class SysRoleController extends BaseController +{ + @Autowired + private ISysRoleService roleService; + + @Autowired + private TokenService tokenService; + + @Autowired + private SysPermissionService permissionService; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysDeptService deptService; + + @Autowired + private ISysMenuService menuService; + +// @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/list") + public TableDataInfo list(SysRole role) + { + startPage(); + List list = roleService.selectRoleList(role); + return getDataTable(list); + } + + @Log(title = "角色管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:role:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysRole role) + { + List list = roleService.selectRoleList(role); + + list.forEach( + role1 -> + { + List menus = menuService.selectMenuNameListByRoleId(role1.getRoleId()); + role1.setStrMenuNames(StringUtils.join(menus,",")); + } + ); + + ExcelUtil util = new ExcelUtil(SysRole.class); + util.exportExcel(response, list, "角色数据"); + } + + /** + * 根据角色编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping(value = "/{roleId}") + public AjaxResult getInfo(@PathVariable Long roleId) + { + roleService.checkRoleDataScope(roleId); + return success(roleService.selectRoleById(roleId)); + } + + /** + * 新增角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:add')") + @Log(title = "角色管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysRole role) + { + if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setCreateBy(getUsername()); + return toAjax(roleService.insertRole(role)); + + } + + /** + * 修改保存角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping + @Transactional + public AjaxResult edit(@Validated @RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + + role.setUpdateBy(getUsername()); + //删除所有用户,再重新绑定 + roleService.deleteAuthUsers(role.getRoleId(), null); + if(ObjectUtils.isNotEmpty(role.getUserIds())) { + if (role.getUserIds().length > 0) { + roleService.insertAuthUsers(role.getRoleId(), role.getUserIds()); + } + } + + if (roleService.updateRole(role) > 0) + { + // 更新缓存用户权限 + LoginUser loginUser = getLoginUser(); + if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin()) + { + loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser())); + loginUser.setAppPermissions(permissionService.getAppMenuPermission(loginUser.getUser())); + loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName())); + tokenService.setLoginUser(loginUser); + } + return success(); + } + return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员"); + } + + /** + * 修改保存数据权限 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping("/dataScope") + public AjaxResult dataScope(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + return toAjax(roleService.authDataScope(role)); + } + + /** + * 状态修改 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + role.setUpdateBy(getUsername()); + return toAjax(roleService.updateRoleStatus(role)); + } + + /** + * 删除角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:remove')") + @Log(title = "角色管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{roleIds}") + public AjaxResult remove(@PathVariable Long[] roleIds) + { + return toAjax(roleService.deleteRoleByIds(roleIds)); + } + + /** + * 获取角色选择框列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + return success(roleService.selectRoleAll()); + } + + /** + * 查询已分配用户角色列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/authUser/allocatedList") + public TableDataInfo allocatedList(SysUser user) + { + startPage(); + List list = userService.selectAllocatedList(user); + return getDataTable(list); + } + + /** + * 查询未分配用户角色列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/authUser/unallocatedList") + public TableDataInfo unallocatedList(SysUser user) + { + startPage(); + List list = userService.selectUnallocatedList(user); + return getDataTable(list); + } + + /** + * 取消授权用户 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancel") + public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole) + { + return toAjax(roleService.deleteAuthUser(userRole)); + } + + /** + * 批量取消授权用户 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancelAll") + public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds) + { + return toAjax(roleService.deleteAuthUsers(roleId, userIds)); + } + + /** + * 批量选择用户授权 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/selectAll") + public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds) + { + roleService.checkRoleDataScope(roleId); + return toAjax(roleService.insertAuthUsers(roleId, userIds)); + } + + /** + * 获取对应角色部门树列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping(value = "/deptTree/{roleId}") + public AjaxResult deptTree(@PathVariable("roleId") Long roleId) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId)); + ajax.put("depts", deptService.selectDeptTreeList(new SysDept())); + return ajax; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java new file mode 100644 index 0000000..5eed519 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java @@ -0,0 +1,542 @@ +package com.ruoyi.web.controller.system; + +import cn.hutool.core.util.StrUtil; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.*; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.enums.UserStatus; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwSceneUser; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.eastcom_yw.service.YwSceneUserService; +import com.ruoyi.framework.web.service.SysPermissionService; +import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.domain.SysUserRole; +import com.ruoyi.system.mapper.SysUserMapper; +import com.ruoyi.system.service.*; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 用户信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/user") +@Transactional +public class SysUserController extends BaseController { + @Autowired + private ISysUserService userService; + + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysDeptService deptService; + + @Autowired + private ISysPostService postService; + + @Autowired + private YwSceneUserService ywSceneUserService; + + + @Autowired + private SysPermissionService permissionService; + + @Autowired + private TokenService tokenService; + + @Autowired + private RedisCache redisCache; + + @Autowired + private RedisTemplate redisTemplate; + + @Autowired + private ISysDictDataService dictDataService; + + @Autowired + private YwSceneService ywSceneService; + + @Autowired + private SysUserMapper sysUserMapper; + + + /** + * 获取用户列表 + */ +// @PreAuthorize("@ss.hasPermi('system:user:list')") + @GetMapping("/list") + public TableDataInfo list(SysUser user) { + startPage(); + List list = userService.selectUserList(user); + + if(list.size()>0) + { + + List lstUserId = list.stream().map(SysUser::getUserId).collect(Collectors.toList()); + + // List listScene = ywSceneUserService.getVenuesByUserIds(lstUserId); + + List listRole = roleService.selectRolesByUserIds(lstUserId); + + for(SysUser sysUser:list) { + + if(StringUtils.isNotEmpty(sysUser.getUserVenueId())) + { + String[] arrNames = sysUser.getUserVenue().split(","); + + Long[] arr_ids = ArrayUtils.toObject(Arrays.stream(sysUser.getUserVenueId().split(",")).mapToLong(a->Long.parseLong(a)).toArray()); + + List venueNames = new ArrayList<>(); + for(String venueName : arrNames) + { + venueNames.add(venueName); + } + + sysUser.setVenueNames(venueNames); + sysUser.setVenueIds(arr_ids); + } + +// List lstSceneId = listScene.stream().filter(r -> r.getUserId().equals(sysUser.getUserId())).map(YwSceneUser::getSceneId).collect(Collectors.toList()); +// int userSceneNum = lstSceneId.size(); +// if(userSceneNum>0) +// { +// Long[] arr_ids = new Long[userSceneNum]; +// lstSceneId.toArray(arr_ids); +// List venueNames = listScene.stream().filter(r -> r.getUserId().equals(sysUser.getUserId())).map(YwSceneUser::getVenueName).collect(Collectors.toList()); +//// String[] arrNames = new String[venueNames.size()]; +// sysUser.setVenueIds(arr_ids); +// sysUser.setVenueNames(venueNames); +// } + else + { + sysUser.setVenueIds(new Long[0]); + sysUser.setVenueNames(new ArrayList()); + } + + List roleNames = listRole.stream().filter(r -> r.getUserId().equals(sysUser.getUserId())).map(SysUserRole::getRoleName).collect(Collectors.toList()); + if(roleNames.size()>0) { +// String[] arrRoleNames = new String[roleNames.size()]; + sysUser.setRoleNames(roleNames); + } + else + { + sysUser.setRoleNames(new ArrayList()); + } + if (StringUtils.isNotEmpty(sysUser.getBelongArea())) { + sysUser.setBelongArea(DictUtils.getDictLabel("yw_belong_area", sysUser.getBelongArea())); + } + + } + } + + return getDataTable(list); + } + + @PostMapping("/listAll") + public TableDataInfo listALL(@RequestBody SysUser user) { + List list = userService.selectUserListALL(user); + return getDataTable(list); + } + + + @GetMapping("/specList") + public AjaxResult specList(SysUser user) { + HashMap> map = userService.selectUserSpecList(user); + return success(map); + } + + + @Log(title = "用户管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:user:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysUser user) { + List list = userService.selectUserList(user); + + list.forEach( + sysUser -> { + List listScene = ywSceneUserService.getVenuesByUserId(sysUser.getUserId()); + List venueNames = new ArrayList<>(); + List venueBelong = new ArrayList<>(); + listScene.forEach( + ywSceneUserVo -> { + venueNames.add(ywSceneUserVo.getVenueName()); + if (StringUtils.isNotEmpty(ywSceneUserVo.getBelongArea())) { + String label = DictUtils.getDictLabel("yw_belong_area", ywSceneUserVo.getBelongArea()); + venueBelong.add(label); + } + } + ); + sysUser.setStrVenueNames(StringUtils.join(venueNames, ",")); + sysUser.setStrBelongArea(StringUtils.join(venueBelong, ",")); + List listRole = roleService.selectRolesByUserId2(sysUser.getUserId()); + List roleNames = new ArrayList<>(); + listRole.forEach( + role -> { + roleNames.add(role.getRoleName()); + } + ); + //设置角色 + sysUser.setStrRoles(StringUtils.join(roleNames, ",")); + + if (StringUtils.isNotEmpty(sysUser.getUserType())) { + //设置用户专业 + String label = DictUtils.getDictLabel("yw_specialty", sysUser.getUserType()); + sysUser.setUserType(label); + } + + //对city和county进行转中文 + if (StringUtils.isNotEmpty(sysUser.getCity())) { + String label = DictUtils.getDictLabel("yw_city", sysUser.getCity()); + sysUser.setCity(label); + } + if (StringUtils.isNotEmpty(sysUser.getCounty())) { + String label = DictUtils.getDictLabel("yw_county", sysUser.getCounty()); + sysUser.setCounty(label); + } + //场馆分区转 + if (StringUtils.isNotEmpty(sysUser.getDistinctArea())) { + String label = DictUtils.getDictLabel("yw_belong_area", sysUser.getDistinctArea()); + sysUser.setDistinctArea(label); + } + //所属公司转 + if (StringUtils.isNotEmpty(sysUser.getYwUserBelong())) { + String label = DictUtils.getDictLabel("yw_user_belong", sysUser.getYwUserBelong()); + sysUser.setYwUserBelong(label); + } + + } + ); + + ExcelUtil util = new ExcelUtil(SysUser.class); + util.exportExcel(response, list, "用户数据"); + } + + @Log(title = "用户管理", businessType = BusinessType.IMPORT) + @PreAuthorize("@ss.hasPermi('system:user:import')") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil(SysUser.class); + List userList = util.importExcel(file.getInputStream()); + String operName = getUsername(); + String message = userService.importUser(userList, updateSupport, operName); + return success(message); + } + + @PostMapping("/importTemplate") + public void importTemplate(HttpServletResponse response) { + ExcelUtil util = new ExcelUtil(SysUser.class); + util.importTemplateExcel(response, "用户数据"); + } + + /** + * 根据用户编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:user:query')") + @GetMapping(value = {"/", "/{userId}"}) + public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) { + userService.checkUserDataScope(userId); + AjaxResult ajax = AjaxResult.success(); + List roles = roleService.selectRoleAll(); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + ajax.put("posts", postService.selectPostAll()); + if (StringUtils.isNotNull(userId)) { + SysUser sysUser = userService.selectUserById(userId); + ajax.put(AjaxResult.DATA_TAG, sysUser); + ajax.put("postIds", postService.selectPostListByUserId(userId)); + ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList())); + } + return ajax; + } + + /** + * 新增用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:add')") + @Log(title = "用户管理", businessType = BusinessType.INSERT) + @PostMapping + @Transactional + public AjaxResult add(@Validated @RequestBody SysUser user) { + if (StringUtils.isNotEmpty(user.getPhonenumber()) + && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) { + return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); + } else if (StringUtils.isNotEmpty(user.getEmail()) + && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) { + return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setCreateBy(getUsername()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + + //假定是可以看到所有场馆的角色,那么就不需要设置区县 +// if(user.isAdmin()) +// { +// user.setCounty(""); +// } + + int num = userService.insertUser(user); + //新增用户的场馆 + //20230303更新用户的场馆Ids + if (num > 0) { + if (ObjectUtils.isNotEmpty(user.getVenueIds())) { + if (user.getVenueIds().length > 0) { + for (Long venueId : user.getVenueIds()) { + YwSceneUser ywSceneUser = new YwSceneUser(); + //由于没有返回用户的ID,所有这边需要去查询一次 + SysUser thisUser = userService.selectUserByPhone(user.getPhonenumber()); + List userIds = new ArrayList<>(); + userIds.add(thisUser.getUserId()); + ywSceneUser.setUserIds(userIds); + ywSceneUser.setSceneId(venueId); + //设置默认值,需签到,红区 + ywSceneUser.setNeedSign("1"); + //20230330 jkj 如果用户有设置区域,就用这个区域作为默认值,否则的话就用红区做默认值 + if (StringUtils.isNotEmpty(user.getDistinctArea())) { + ywSceneUser.setBelongArea(user.getDistinctArea()); + } + if (StringUtils.isEmpty(user.getDistinctArea())) { + ywSceneUser.setBelongArea("red"); + } + ywSceneUserService.create(ywSceneUser); + } + } + } + } + return toAjax(num); + } + + /** + * 修改用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping + @Transactional + public AjaxResult edit(@Validated @RequestBody SysUser user) { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + + if (StringUtils.isNotEmpty(user.getPhonenumber()) + && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) { + return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); + } else if (StringUtils.isNotEmpty(user.getEmail()) + && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) { + return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setUpdateBy(getUsername()); + + //20230303更新用户的场馆Ids + //删除之前的场馆,重新绑定新的 + ywSceneUserService.delete(user.getUserId()); + if (ObjectUtils.isNotEmpty(user.getVenueIds())) { + for (Long venueId : user.getVenueIds()) { + YwSceneUser ywSceneUser = new YwSceneUser(); + ywSceneUser.setUserId(user.getUserId()); + ywSceneUser.setSceneId(venueId); + //设置默认值,需签到,红区 + ywSceneUser.setNeedSign("1"); + //20230330 jkj 如果用户有设置区域,就用这个区域作为默认值,否则的话就用红区做默认值 + if (StringUtils.isNotEmpty(user.getDistinctArea())) { + ywSceneUser.setBelongArea(user.getDistinctArea()); + } + if (StringUtils.isEmpty(user.getDistinctArea())) { + ywSceneUser.setBelongArea("red"); + } + ywSceneUserService.save(ywSceneUser); + } + } + int res = userService.updateUser(user); + if (res > 0) { + //删除用户短信验证码错误的次数的缓存 + if (UserStatus.OK.getCode().equals(user.getStatus())) { + String key = CacheConstants.SMS_ERR_CNT_KEY + user.getPhonenumber(); + if (redisCache.hasKey(key)) { + redisCache.deleteObject(key); + } + } + + //删除处理用户登录的缓存 + //客户反映不够人性化 + //更新用户的缓存 + Collection keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); + for (String key : keys) { + LoginUser redisUser = redisCache.getCacheObject(key); + if(ObjectUtils.isNotEmpty(redisUser.getUserId())) { + if (redisUser.getUserId().equals(user.getUserId())) { + + if(!redisUser.getUser().getPhonenumber().equals(user.getPhonenumber())) + { + //说明更换了手机号码,踢掉用户 + redisCache.deleteObject(key); + continue; + } + SysUser updateUser = userService.selectUserByUserName(user.getPhonenumber()); + redisUser.setVenueIds(updateUser.getVenueIds()); + redisUser.setPermissions(permissionService.getMenuPermission(updateUser)); + redisUser.setAppPermissions(permissionService.getAppMenuPermission(updateUser)); + redisUser.setUser(updateUser); + //删除冻结账号的缓存 + if (UserStatus.SLEEP.getCode().equals(updateUser.getStatus())) { + redisCache.deleteObject(key); + } else { + tokenService.refreshToken(redisUser); + } + } + } + } + +// +// for (String key : keys) { +// LoginUser redisUser = redisCache.getCacheObject(key); +// //找到登录用户 +// if (redisUser.getUserId().equals(user.getUserId())) { +// redisCache.deleteObject(key); +// } +// } + + } + return toAjax(res); + } + + /** + * 删除用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:remove')") + @Log(title = "用户管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{userIds}") + public AjaxResult remove(@PathVariable Long[] userIds) { + //判断当前用户有没有进行中的物资审核任务 + List lstCheckUserId = sysUserMapper.selectCheckUserIdList(); + + for (Long checkUserId : lstCheckUserId) { + if (ArrayUtils.contains(userIds, checkUserId)) { +// return error("当前用户存在进行中的物资审核任务,请在任务完结或者驳回后重新选择其它审核人后再删除该用户"); + return error("当前用户存在进行中的物资审核任务"); + } + } + + if (ArrayUtils.contains(userIds, getUserId())) { + return error("当前用户不能删除"); + } + + return toAjax(userService.deleteUserByIds(userIds)); + } + + /** + * 重置密码 + */ + @PreAuthorize("@ss.hasPermi('system:user:resetPwd')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/resetPwd") + public AjaxResult resetPwd(@RequestBody SysUser user) { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + user.setUpdateBy(getUsername()); + return toAjax(userService.resetPwd(user)); + } + + /** + * 状态修改 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysUser user) { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setUpdateBy(getUsername()); + return toAjax(userService.updateUserStatus(user)); + } + + /** + * 根据用户编号获取授权角色 + */ + @PreAuthorize("@ss.hasPermi('system:user:query')") + @GetMapping("/authRole/{userId}") + public AjaxResult authRole(@PathVariable("userId") Long userId) { + AjaxResult ajax = AjaxResult.success(); + SysUser user = userService.selectUserById(userId); + List roles = roleService.selectRolesByUserId(userId); + ajax.put("user", user); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + return ajax; + } + + /** + * 用户授权角色 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.GRANT) + @PutMapping("/authRole") + public AjaxResult insertAuthRole(Long userId, Long[] roleIds) { + userService.checkUserDataScope(userId); + userService.insertUserAuth(userId, roleIds); + return success(); + } + + /** + * 获取部门树列表 + */ + @PreAuthorize("@ss.hasPermi('system:user:list')") + @GetMapping("/deptTree") + public AjaxResult deptTree(SysDept dept) { + return success(deptService.selectDeptTreeList(dept)); + } + + + /** + * 获取当前用户关联的场馆所在区县 + */ + @GetMapping("/getCounty") + public AjaxResult getCounty(String cityId) { + SysUser user = SecurityUtils.getLoginUser().getUser(); + if (SecurityUtils.isAdmin(user.getUserId())) { + List countyList = dictDataService.selectDictLabelByValues("yw_county", null); + countyList = countyList.stream().filter(l -> cityId.equals(l.getDictValue().substring(0, 4))).collect(Collectors.toList()); + return success(countyList); + } + //场馆集合 + List ywScenes = ywSceneService.getVenueByUser(user); + //区县集合 + List countyIds = ywScenes.stream().map(YwScene::getAreaCountyId).filter(Objects::nonNull).distinct().collect(Collectors.toList()); + List countyList = dictDataService.selectDictLabelByValues("yw_county", countyIds); + + if (StrUtil.isNotBlank(cityId)) { + countyList = countyList.stream().filter(l -> cityId.equals(l.getDictValue().substring(0, 4))).collect(Collectors.toList()); + } + return success(countyList); + } + + /** + * 根据专业查询专业下人数 + */ + @GetMapping("/selectUserByUserType") + public TableDataInfo selectUserByUserType() { + return getDataTable(userService.selectUserByUserType()); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java new file mode 100644 index 0000000..b4f6bac --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java @@ -0,0 +1,183 @@ +package com.ruoyi.web.controller.tool; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.utils.StringUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import io.swagger.annotations.ApiOperation; + +/** + * swagger 用户测试方法 + * + * @author ruoyi + */ +@Api("用户信息管理") +@RestController +@RequestMapping("/test/user") +public class TestController extends BaseController +{ + private final static Map users = new LinkedHashMap(); + { + users.put(1, new UserEntity(1, "admin", "admin123", "15888888888")); + users.put(2, new UserEntity(2, "ry", "admin123", "15666666666")); + } + + @ApiOperation("获取用户列表") + @GetMapping("/list") + public R> userList() + { + List userList = new ArrayList(users.values()); + return R.ok(userList); + } + + @ApiOperation("获取用户详细") + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) + @GetMapping("/{userId}") + public R getUser(@PathVariable Integer userId) + { + if (!users.isEmpty() && users.containsKey(userId)) + { + return R.ok(users.get(userId)); + } + else + { + return R.fail("用户不存在"); + } + } + + @ApiOperation("新增用户") + @ApiImplicitParams({ + @ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class), + @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class) + }) + @PostMapping("/save") + public R save(UserEntity user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) + { + return R.fail("用户ID不能为空"); + } + users.put(user.getUserId(), user); + return R.ok(); + } + + @ApiOperation("更新用户") + @PutMapping("/update") + public R update(@RequestBody UserEntity user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) + { + return R.fail("用户ID不能为空"); + } + if (users.isEmpty() || !users.containsKey(user.getUserId())) + { + return R.fail("用户不存在"); + } + users.remove(user.getUserId()); + users.put(user.getUserId(), user); + return R.ok(); + } + + @ApiOperation("删除用户信息") + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) + @DeleteMapping("/{userId}") + public R delete(@PathVariable Integer userId) + { + if (!users.isEmpty() && users.containsKey(userId)) + { + users.remove(userId); + return R.ok(); + } + else + { + return R.fail("用户不存在"); + } + } +} + +@ApiModel(value = "UserEntity", description = "用户实体") +class UserEntity +{ + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("用户名称") + private String username; + + @ApiModelProperty("用户密码") + private String password; + + @ApiModelProperty("用户手机") + private String mobile; + + public UserEntity() + { + + } + + public UserEntity(Integer userId, String username, String password, String mobile) + { + this.userId = userId; + this.username = username; + this.password = password; + this.mobile = mobile; + } + + public Integer getUserId() + { + return userId; + } + + public void setUserId(Integer userId) + { + this.userId = userId; + } + + public String getUsername() + { + return username; + } + + public void setUsername(String username) + { + this.username = username; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public String getMobile() + { + return mobile; + } + + public void setMobile(String mobile) + { + this.mobile = mobile; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java new file mode 100644 index 0000000..c93a378 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java @@ -0,0 +1,127 @@ +package com.ruoyi.web.core.config; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.ruoyi.common.config.RuoYiConfig; +import io.swagger.annotations.ApiOperation; +import io.swagger.models.auth.In; +import org.springframework.context.annotation.Profile; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.ApiKey; +import springfox.documentation.service.AuthorizationScope; +import springfox.documentation.service.Contact; +import springfox.documentation.service.SecurityReference; +import springfox.documentation.service.SecurityScheme; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; + +/** + * Swagger2的接口配置 + * + * @author ruoyi + */ +@Configuration +@Profile("test") +public class SwaggerConfig +{ + /** 系统基础配置 */ + @Autowired + private RuoYiConfig ruoyiConfig; + + /** 是否开启swagger */ + @Value("${swagger.enabled}") + private boolean enabled; + + /** 设置请求的统一前缀 */ + @Value("${swagger.pathMapping}") + private String pathMapping; + + /** + * 创建API + */ + @Bean + public Docket createRestApi() + { + return new Docket(DocumentationType.OAS_30) + // 是否启用Swagger + .enable(enabled) + // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息) + .apiInfo(apiInfo()) + // 设置哪些接口暴露给Swagger展示 + .select() + // 扫描所有有注解的api,用这种方式更灵活 + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + // 扫描指定包中的swagger注解 + // .apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger")) + // 扫描所有 .apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()) + .build() + /* 设置安全模式,swagger可以设置访问token */ + .securitySchemes(securitySchemes()) + .securityContexts(securityContexts()) + .pathMapping(pathMapping); + } + + /** + * 安全模式,这里指定token通过Authorization头请求头传递 + */ + private List securitySchemes() + { + List apiKeyList = new ArrayList(); + apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue())); + return apiKeyList; + } + + /** + * 安全上下文 + */ + private List securityContexts() + { + List securityContexts = new ArrayList<>(); + securityContexts.add( + SecurityContext.builder() + .securityReferences(defaultAuth()) + .operationSelector(o -> o.requestMappingPattern().matches("/.*")) + .build()); + return securityContexts; + } + + /** + * 默认的安全上引用 + */ + private List defaultAuth() + { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + List securityReferences = new ArrayList<>(); + securityReferences.add(new SecurityReference("Authorization", authorizationScopes)); + return securityReferences; + } + + /** + * 添加摘要信息 + */ + private ApiInfo apiInfo() + { + // 用ApiInfoBuilder进行定制 + return new ApiInfoBuilder() + // 设置标题 + .title("亚运中小屏幕_接口文档") + // 描述 + .description("亚运中小屏幕的接口文档") + // 作者信息 + .contact(new Contact(ruoyiConfig.getName(), null, null)) + // 版本 + .version("版本号:" + ruoyiConfig.getVersion()) + .build(); + } +} diff --git a/ruoyi-admin/src/main/resources/META-INF/spring-devtools.properties b/ruoyi-admin/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..2b23f85 --- /dev/null +++ b/ruoyi-admin/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.json=/com.alibaba.fastjson.*.jar \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application-bak1.yml b/ruoyi-admin/src/main/resources/application-bak1.yml new file mode 100644 index 0000000..8ceae45 --- /dev/null +++ b/ruoyi-admin/src/main/resources/application-bak1.yml @@ -0,0 +1,154 @@ +# 项目相关配置 +ruoyi: + # 名称 + name: RuoYi + # 版本 + version: 3.8.4 + # 版权年份 + copyrightYear: 2022 + # 实例演示开关 + demoEnabled: true + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: /home/hzdx/data/java/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数组计算 char 字符验证 + captchaType: math + +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + # driverClassName: com.mysql.cj.jdbc.Driver + driverClassName: org.postgresql.Driver + druid: + # 主库数据源 + master: + # url: jdbc:mysql://183.247.163.49:7940/ry_v3?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + url: jdbc:postgresql://10.71.80.241:5432/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true +# url: jdbc:postgresql://127.0.0.1:5432/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true + # url: jdbc:postgresql://183.247.163.49:8099/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true + username: pms + password: Ea$tcyd2023 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # redis 配置 + redis: + # 地址 + host: 10.71.80.241 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 0 + # 密码 + password: YyunRedis@Zxp01 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms +#简报配置 +file: + #文件访问地址前缀 + visitpath: http://183.247.163.49:8093/profile/upload/ + #json本地保存路径 + briefingJsonPath: /home/hzdx/data/java/uploadPath/briefingJson + #json上传路径 + briefingShortUrl: http://10.71.80.185:31994/uploadfile/asiagame + #场馆配置中ppru拓扑图存放路径 + sceneJsonPath: /home/hzdx/data/java/uploadPath/shorturl + + +# 短信发送配置 +system: + msg: + url: http://10.71.80.246/api/PublicHandler.ashx + sms_comm: send_sms + ivr_comm: send_ivr_call + mobileoffice_comm: send_mobileoffice_zmcc + #企业编号 + applicationid: 1087 + #企业名 + platform_code: 东信亚运重保 + publickey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhBtwcgGVE1ILMDoxU4Og77PugS2JlHDnfkmHO3Ek0s+L4ukWDbh6XvRNxUIBM9GvhvrdT7JGE7/Xq6oIYRk6QqfvYp/aHzw1DkhoEz7Bx9O0fdQKWMCHd4kl6hmyLeurmr11/h6nwtu1U/R2BqJ/blRCebUuYvMaCxVO1rr8irQIDAQAB + +#工作流的地址 +workFlowUrl: http://10.71.80.231:8080 + +# minio 文件存储配置信息 +minio: + url: http://192.168.97.212:9000/ + endpoint: + accesskey: minioadmin + secretKey: minioadmin + bucketName: yyzxp + prefix: + + +#大屏数据环境 +daping: WORK + + +#quartz定时器开关 +job: + enabled: false + +token: + # 是否允许同类型端同时登录(true允许 false不允许) + soloLogin: false + +logging: + level: + com.ruoyi: info + org.springframework: warn \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application-bak2.yml b/ruoyi-admin/src/main/resources/application-bak2.yml new file mode 100644 index 0000000..437c18d --- /dev/null +++ b/ruoyi-admin/src/main/resources/application-bak2.yml @@ -0,0 +1,151 @@ +# 项目相关配置 +ruoyi: + # 名称 + name: RuoYi + # 版本 + version: 3.8.4 + # 版权年份 + copyrightYear: 2022 + # 实例演示开关 + demoEnabled: true + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: /home/hzdx/data/java/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数组计算 char 字符验证 + captchaType: math + +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + # driverClassName: com.mysql.cj.jdbc.Driver + driverClassName: org.postgresql.Driver + druid: + # 主库数据源 + master: + url: jdbc:postgresql://10.71.80.231:5432/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true + username: pms + password: Ea$tcyd2023 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # redis 配置 + redis: + # 地址 + host: 10.71.80.231 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 0 + # 密码 + password: YyunRedis@Zxp01 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms +#简报配置 +file: + #文件访问地址前缀 + visitpath: http://183.247.163.49:8093/profile/upload/ + #json本地保存路径 + briefingJsonPath: /home/hzdx/data/java/uploadPath/briefingJson + #json上传路径 + briefingShortUrl: http://10.71.80.185:31994/uploadfile/asiagame + #场馆配置中ppru拓扑图存放路径 + sceneJsonPath: /home/hzdx/data/java/uploadPath/shorturl + + +# 短信发送配置 +system: + msg: + url: http://10.71.80.246/api/PublicHandler.ashx + sms_comm: send_sms + ivr_comm: send_ivr_call + mobileoffice_comm: send_mobileoffice_zmcc + #企业编号 + applicationid: 1087 + #企业名 + platform_code: 东信亚运重保 + publickey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhBtwcgGVE1ILMDoxU4Og77PugS2JlHDnfkmHO3Ek0s+L4ukWDbh6XvRNxUIBM9GvhvrdT7JGE7/Xq6oIYRk6QqfvYp/aHzw1DkhoEz7Bx9O0fdQKWMCHd4kl6hmyLeurmr11/h6nwtu1U/R2BqJ/blRCebUuYvMaCxVO1rr8irQIDAQAB + +#工作流的地址 +workFlowUrl: http://10.71.80.231:8080 + +# minio 文件存储配置信息 +minio: + url: http://192.168.97.212:9000/ + endpoint: + accesskey: minioadmin + secretKey: minioadmin + bucketName: yyzxp + prefix: + + +#大屏数据环境 +daping: WORK + + +#quartz定时器开关 +job: + enabled: true + +token: + # 是否允许同类型端同时登录(true允许 false不允许) + soloLogin: false + +logging: + level: + com.ruoyi: info + org.springframework: warn \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-admin/src/main/resources/application-druid.yml new file mode 100644 index 0000000..c2c74fa --- /dev/null +++ b/ruoyi-admin/src/main/resources/application-druid.yml @@ -0,0 +1,152 @@ +# 项目相关配置 +ruoyi: + # 名称 + name: RuoYi + # 版本 + version: 3.8.4 + # 版权年份 + copyrightYear: 2022 + # 实例演示开关 + demoEnabled: true + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: C:/ruoyi/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数组计算 char 字符验证 + captchaType: math + +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + # driverClassName: com.mysql.cj.jdbc.Driver + driverClassName: org.postgresql.Driver + druid: + # 主库数据源 + master: + # url: jdbc:mysql://183.247.163.49:7940/ry_v3?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&stringtype=unspecified + url: jdbc:postgresql://192.168.97.156:5432/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true +# url: jdbc:postgresql://183.247.163.49:8099/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true + username: postgres + password: eastcom + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # redis 配置 + redis: + # 地址 + host: 192.168.97.212 +# host: 127.0.0.1 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 0 + # 密码 + password: YyunRedis@Zxp01 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + +redisson: + addr: + singleAddr: + host: redis://192.168.97.212:6379 + password: YyunRedis@Zxp01 + database: 0 + + + +# 短信发送配置 +system: + msg: + url: http://10.71.80.246/api/PublicHandler.ashx + sms_comm: send_sms + ivr_comm: send_ivr_call + mobileoffice_comm: send_mobileoffice_zmcc + applicationid: 1087 + platform_code: 东信亚运重保 + publickey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhBtwcgGVE1ILMDoxU4Og77PugS2JlHDnfkmHO3Ek0s+L4ukWDbh6XvRNxUIBM9GvhvrdT7JGE7/Xq6oIYRk6QqfvYp/aHzw1DkhoEz7Bx9O0fdQKWMCHd4kl6hmyLeurmr11/h6nwtu1U/R2BqJ/blRCebUuYvMaCxVO1rr8irQIDAQAB + +#工作流地址 +workFlowUrl: http://192.168.97.212:8080 + +#简报配置 +file: + #文件访问地址前缀 + visitpath: http://183.247.163.49:8093/profile/upload/ + #json本地保存路径 + briefingJsonPath: C:\json\ + #json上传路径 + briefingShortUrl: http://192.168.97.142:80/uploadfile/test + #场馆配置中ppru拓扑图存放路径 + sceneJsonPath: C:\home\data\java\uploadPath\upload\json\ + +# minio 文件存储配置信息 +minio: + url: http://127.0.0.1:9090/ + endpoint: + accesskey: Q8QW6SKTKXIQT631ES3K + secretKey: 55Keq+9CM7elYjINdN3qqW7QBH5cvn8LHoaP5LnT + bucketName: upload + prefix: + +daping: DEBUG + +job: + enabled: false + +token: + # 是否允许同类型端同时登录(true允许 false不允许) + soloLogin: true \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application-local.yml b/ruoyi-admin/src/main/resources/application-local.yml new file mode 100644 index 0000000..9129658 --- /dev/null +++ b/ruoyi-admin/src/main/resources/application-local.yml @@ -0,0 +1,156 @@ +# 项目相关配置 +ruoyi: + # 名称 + name: RuoYi + # 版本 + version: 3.8.4 + # 版权年份 + copyrightYear: 2022 + # 实例演示开关 + demoEnabled: true + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: C:/ruoyi/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数组计算 char 字符验证 + captchaType: math + +server: + # 服务器的HTTP端口,默认为8080 + port: 9080 + +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + # driverClassName: com.mysql.cj.jdbc.Driver + driverClassName: org.postgresql.Driver + druid: + # 主库数据源 + master: + # url: jdbc:mysql://183.247.163.49:7940/ry_v3?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&stringtype=unspecified +# url: jdbc:postgresql://192.168.97.156:5432/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true +# username: postgres +# password: eastcom + url: jdbc:postgresql://127.0.0.1:5433/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true + username: pms + password: Ea$tcyd2023 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # redis 配置 + redis: + # 地址 +# host: 192.168.97.212 + host: 127.0.0.1 + # 端口,默认为6379 +# port: 6379 + port: 6380 + # 数据库索引 + database: 0 + # 密码 + password: YyunRedis@Zxp01 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + +redisson: + addr: + singleAddr: + host: redis://127.0.0.1:6380 + password: YyunRedis@Zxp01 + database: 0 + + +system: + msg: + url: http://10.71.80.246/api/PublicHandler.ashx + sms_comm: send_sms + ivr_comm: send_ivr_call + mobileoffice_comm: send_mobileoffice_zmcc + applicationid: 1087 + platform_code: 东信亚运重保 + publickey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhBtwcgGVE1ILMDoxU4Og77PugS2JlHDnfkmHO3Ek0s+L4ukWDbh6XvRNxUIBM9GvhvrdT7JGE7/Xq6oIYRk6QqfvYp/aHzw1DkhoEz7Bx9O0fdQKWMCHd4kl6hmyLeurmr11/h6nwtu1U/R2BqJ/blRCebUuYvMaCxVO1rr8irQIDAQAB + +workFlowUrl: http://127.0.0.1:8080 + +file: + visitpath: http://183.247.163.49:8093/profile/upload/ + briefingJsonPath: C:\json\ + briefingShortUrl: http://192.168.97.142:80/uploadfile/test + sceneJsonPath: C:\home\data\java\uploadPath\upload\json\ + +# minio 文件存储配置信息 +minio: + url: http://127.0.0.1:9090/ + endpoint: + accesskey: Q8QW6SKTKXIQT631ES3K + secretKey: 55Keq+9CM7elYjINdN3qqW7QBH5cvn8LHoaP5LnT + bucketName: upload + prefix: + +daping: DEBUG + +job: + enabled: false + +token: + # 是否允许同类型端同时登录(true允许 false不允许) + soloLogin: false + +logging: + level: + com.ruoyi: debug + org.springframework: warn \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application-ser.yml b/ruoyi-admin/src/main/resources/application-ser.yml new file mode 100644 index 0000000..a0e60a8 --- /dev/null +++ b/ruoyi-admin/src/main/resources/application-ser.yml @@ -0,0 +1,137 @@ +# 项目相关配置 +ruoyi: + # 名称 + name: RuoYi + # 版本 + version: 3.8.4 + # 版权年份 + copyrightYear: 2022 + # 实例演示开关 + demoEnabled: true + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: /home/data/java/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数组计算 char 字符验证 + captchaType: math + +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + # driverClassName: com.mysql.cj.jdbc.Driver + driverClassName: org.postgresql.Driver + druid: + # 主库数据源 + master: + # url: jdbc:mysql://183.247.163.49:7940/ry_v3?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&stringtype=unspecified + url: jdbc:postgresql://127.0.0.1:5433/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true + # url: jdbc:postgresql://183.247.163.49:8099/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true&stringtype=unspecified + username: pms + password: Ea$tcyd2023 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # redis 配置 + redis: + # 地址 +# host: 192.168.97.212 + host: 127.0.0.1 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 0 + # 密码 + password: + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + +system: + msg: + url: http://10.71.80.246/api/PublicHandler.ashx + sms_comm: send_sms + ivr_comm: send_ivr_call + mobileoffice_comm: send_mobileoffice_zmcc + applicationid: 1087 + platform_code: 东信亚运重保 + publickey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhBtwcgGVE1ILMDoxU4Og77PugS2JlHDnfkmHO3Ek0s+L4ukWDbh6XvRNxUIBM9GvhvrdT7JGE7/Xq6oIYRk6QqfvYp/aHzw1DkhoEz7Bx9O0fdQKWMCHd4kl6hmyLeurmr11/h6nwtu1U/R2BqJ/blRCebUuYvMaCxVO1rr8irQIDAQAB + + +workFlowUrl: http://192.168.97.212:8080 + +file: + visitpath: http://183.247.163.49:8093/profile/upload/ + briefingJsonPath: C:\json\ + briefingShortUrl: http://192.168.97.142:80/uploadfile/test + sceneJsonPath: C:\home\data\java\uploadPath\upload\json\ + +# minio 文件存储配置信息 +minio: + url: http://192.168.97.212:9000/ + endpoint: + accesskey: minioadmin + secretKey: minioadmin + bucketName: yyzxp + prefix: + +daping: WORK + +job: + enabled: false + +token: + # 是否允许同类型端同时登录(true允许 false不允许) + soloLogin: false \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application-test.yml b/ruoyi-admin/src/main/resources/application-test.yml new file mode 100644 index 0000000..cf67ec2 --- /dev/null +++ b/ruoyi-admin/src/main/resources/application-test.yml @@ -0,0 +1,154 @@ +# 项目相关配置 +ruoyi: + # 名称 + name: RuoYi + # 版本 + version: 3.8.4 + # 版权年份 + copyrightYear: 2022 + # 实例演示开关 + demoEnabled: true + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: /home/data/java/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数组计算 char 字符验证 + captchaType: math + +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + # driverClassName: com.mysql.cj.jdbc.Driver + driverClassName: org.postgresql.Driver + druid: + # 主库数据源 + master: + # url: jdbc:mysql://183.247.163.49:7940/ry_v3?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 +# url: jdbc:postgresql://10.71.80.241:5432/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true + url: jdbc:postgresql://127.0.0.1:5432/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true + # url: jdbc:postgresql://183.247.163.49:8099/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true + username: pms + password: Ea$tcyd2023 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # redis 配置 + redis: + # 地址 + host: localhost + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 0 + # 密码 + password: YyunRedis@Zxp01 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms +#简报配置 +file: + #文件访问地址前缀 + visitpath: http://183.247.163.49:8093/profile/upload/ + #json本地保存路径 + briefingJsonPath: /home/data/java/uploadPath/briefingJson + #json上传路径 + briefingShortUrl: http://10.71.80.185:31994/uploadfile/asiagame + #场馆配置中ppru拓扑图存放路径 + sceneJsonPath: /home/data/java/uploadPath/shorturl + + +# 短信发送配置 +system: + msg: + url: http://10.71.80.246/api/PublicHandler.ashx + sms_comm: send_sms + ivr_comm: send_ivr_call + mobileoffice_comm: send_mobileoffice_zmcc + #企业编号 + applicationid: 1087 + #企业名 + platform_code: 东信亚运重保 + publickey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhBtwcgGVE1ILMDoxU4Og77PugS2JlHDnfkmHO3Ek0s+L4ukWDbh6XvRNxUIBM9GvhvrdT7JGE7/Xq6oIYRk6QqfvYp/aHzw1DkhoEz7Bx9O0fdQKWMCHd4kl6hmyLeurmr11/h6nwtu1U/R2BqJ/blRCebUuYvMaCxVO1rr8irQIDAQAB + +#工作流的地址 +workFlowUrl: http://10.71.80.241:8080 + +# minio 文件存储配置信息 +minio: + url: http://192.168.97.212:9000/ + endpoint: + accesskey: minioadmin + secretKey: minioadmin + bucketName: yyzxp + prefix: + + +#大屏数据环境 +daping: WORK + + +#quartz定时器开关 +job: + enabled: true + +token: + # 是否允许同类型端同时登录(true允许 false不允许) + soloLogin: false + +logging: + level: + com.ruoyi: info + org.springframework: warn \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application.properties b/ruoyi-admin/src/main/resources/application.properties new file mode 100644 index 0000000..1604649 --- /dev/null +++ b/ruoyi-admin/src/main/resources/application.properties @@ -0,0 +1,5 @@ +pagehelper.reasonable=false +pagehelper.supportMethodsArguments=true +pagehelper.params.count=countSql +pagehelper.auto-dialect=true +pagehelper.auto-runtime-dialect=true \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml new file mode 100644 index 0000000..e539acb --- /dev/null +++ b/ruoyi-admin/src/main/resources/application.yml @@ -0,0 +1,151 @@ +# 滑块验证码 +aj: + captcha: + # blockPuzzle滑块 clickWord文字点选 default默认两者都实例化 + type: blockPuzzle + # 右下角显示字 + water-mark: ruoyi.vip + # 校验滑动拼图允许误差偏移量(默认5像素) + slip-offset: 5 + # aes加密坐标开启或者禁用(true|false) + aes-status: true + # 滑动干扰项(0/1/2) + interference-options: 2 +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 9010 + servlet: + # 应用的访问路径 + context-path: / + tomcat: + # tomcat的URI编码 + uri-encoding: UTF-8 + # 连接数满后的排队数,默认为100 + accept-count: 1000 + threads: + # tomcat最大线程数,默认为200 + max: 800 + # Tomcat启动初始化的线程数,默认值10 + min-spare: 100 + +# 安全停机 调用curl -X POST http://localhost:9010/monitor/shutdown +management: + endpoint: + shutdown: + enabled: false + endpoints: + web: + exposure: + include: "shutdown" + base-path: /monitor + +# 日志配置 +logging: + level: + com.ruoyi: debug + org.springframework: warn + +# 用户配置 +user: + password: + # 密码最大错误次数 + maxRetryCount: 5 + # 密码锁定时间(默认10分钟) + lockTime: 10 + sms: + # 密码最大错误次数 + maxRetryCount: 3 + # 密码锁定时间(默认10分钟) + lockTime: 15 + defaultCode: false +# Spring配置 +spring: + # 资源信息 + messages: + # 国际化资源文件路径 + basename: i18n/messages + profiles: + active: druid + # 文件上传 + servlet: + multipart: + # 单个文件大小 + max-file-size: 10MB + # 设置总上传的文件大小 + max-request-size: 20MB + # 服务模块 + devtools: + restart: + # 热部署开关 + enabled: false + jackson: + #日期格式化 + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + # redis 配置 +# redis: +# # 地址 +# host: localhost +# # 端口,默认为6379 +# port: 6379 +# # 数据库索引 +# database: 0 +# # 密码 +# password: +# # 连接超时时间 +# timeout: 10s +# lettuce: +# pool: +# # 连接池中的最小空闲连接 +# min-idle: 0 +# # 连接池中的最大空闲连接 +# max-idle: 8 +# # 连接池的最大数据库连接数 +# max-active: 8 +# # #连接池最大阻塞等待时间(使用负值表示没有限制) +# max-wait: -1ms + +# token配置 +token: + # 令牌自定义标识 + header: Authorization + # 令牌密钥 + secret: abcdefghijklmnopqrstuvwxyz + # 令牌有效期(默认30分钟) + expireTime: 4320 + +# MyBatis配置 +mybatis-plus: + type-aliases-package: com.ruoyi.**.domain + mapper-locations: classpath*:mapper/**/*Mapper.xml + config-location: classpath:mybatis/mybatis-config.xml + + +# PageHelper分页插件 +pagehelper: + helperDialect: postgresql + supportMethodsArguments: true + params: count=countSql + page-size-zero: true + +# Swagger配置 +swagger: + # 是否开启swagger + enabled: true + # 请求前缀 + pathMapping: /dev-api + +# 防止XSS攻击 +xss: + # 过滤开关 + enabled: true + # 排除链接(多个用逗号分隔) + excludes: /system/notice + # 匹配链接 + urlPatterns: /system/*,/monitor/*,/tool/* + +# 登录文本加密公私钥 +login: + publicKey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCqjPHyVJ5u9E+d0CMYyc3mMdQ/ac9UZdF9oz2Bxr6UDKNax+Zhn/OARKozMAzH2cpYsb4kGPYTHPzmrbgegbACC7bTFSFFBSkotvvfDHd+YbfgxfNf/VbwczMl/E3OMHzRFbrLO8v3ozA+2w2Gyg0UAV6AGliVrQHCuKIDYV0EwIDAQAB + privateKey: MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMKqM8fJUnm70T53QIxjJzeYx1D9pz1Rl0X2jPYHGvpQMo1rH5mGf84BEqjMwDMfZylixviQY9hMc/OatuB6BsAILttMVIUUFKSi2+98Md35ht+DF81/9VvBzMyX8Tc4wfNEVuss7y/ejMD7bDYbKDRQBXoAaWJWtAcK4ogNhXQTAgMBAAECgYBAzlzytClK8aYVf6nzksbpkWk5o1hb55/O4OfIuFDY6H4L6o/YkphVwrGtlIyf+GJlusa21YsH5Vvsy6L6VGWOT/T1Q924zxwhPHFP8fzWrWJ60IT5jGDChJ1jls8GRWHgCnriQRMHU36eqENC5VZiYdfuulGN2bUNgMzUgmv9UQJBAOZio3CAQ+mwOsdRWixaput636qXoryleXiYrzGOulTzdYrRnJCIF3fE6H9uX5i2MwA3HtgTkN3qS4mtyBHvWP0CQQDYTt4KlkVJN3hsfV3qMk48zYE68lUg0umRaYXlQ0moLPO2P3wLFLLOq0jhWIwWz7ApIQXsR7x0RZOK2NadFFZPAkEA30Nh7klvBw2wuK3+/BLRxkxqavDOVZDq+dLFnPobWu4gz+m4l1w7mebqBWxaGi0fmarRKkcz0csXbxJJXBAepQJAKJtNpbEmGqOWMM+sJL4C3/k4TGeXwYy2mjy0DSD/n9moessaLz5YfuG60cr8qX+ds2rmoL+qyi0RkJw6VcyukwJAS5sxmn0YKbXw7GxDm7HmMcGuRYTo6ai+Olzk1GLwddTj56pfOgex+FF4FFyO33zzpEPeZbEzkbxkLC7Z8m0lWg== diff --git a/ruoyi-admin/src/main/resources/banner.txt b/ruoyi-admin/src/main/resources/banner.txt new file mode 100644 index 0000000..0931cb8 --- /dev/null +++ b/ruoyi-admin/src/main/resources/banner.txt @@ -0,0 +1,24 @@ +Application Version: ${ruoyi.version} +Spring Boot Version: ${spring-boot.version} +//////////////////////////////////////////////////////////////////// +// _ooOoo_ // +// o8888888o // +// 88" . "88 // +// (| ^_^ |) // +// O\ = /O // +// ____/`---'\____ // +// .' \\| |// `. // +// / \\||| : |||// \ // +// / _||||| -:- |||||- \ // +// | | \\\ - /// | | // +// | \_| ''\---/'' | | // +// \ .-\__ `-` ___/-. / // +// ___`. .' /--.--\ `. . ___ // +// ."" '< `.___\_<|>_/___.' >'"". // +// | | : `- \`.;`\ _ /`;.`/ - ` : | | // +// \ \ `-. \_ __\ /__ _/ .-` / / // +// ========`-.____`-.___\_____/___.-`____.-'======== // +// `=---=' // +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // +// 佛祖保佑 永不宕机 永无BUG // +//////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/i18n/messages.properties b/ruoyi-admin/src/main/resources/i18n/messages.properties new file mode 100644 index 0000000..4cbdadc --- /dev/null +++ b/ruoyi-admin/src/main/resources/i18n/messages.properties @@ -0,0 +1,41 @@ +#错误消息 +not.null=* 必须填写 +user.jcaptcha.error=验证码错误 +user.jcaptcha.expire=验证码已失效 +user.sms.expire=短信验证码已失效 +user.not.exists=用户不存在/密码错误 +user.password.not.match=用户不存在/密码错误 +user.password.retry.limit.count=密码输入错误{0}次 +user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟 +user.sms.not.match=短信验证码输入错误,还剩{0}次 +user.sms.retry.limit.count=短信验证码输入错误{0}次 +user.sms.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟 +user.password.delete=对不起,您的账号已被删除 +user.blocked=用户已封禁,请联系管理员 +role.blocked=角色已封禁,请联系管理员 +user.logout.success=退出成功 + +length.not.valid=长度必须在{min}到{max}个字符之间 + +user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头 +user.password.not.valid=* 5-50个字符 + +user.email.not.valid=邮箱格式错误 +user.mobile.phone.number.not.valid=手机号格式错误 +user.login.success=登录成功 +user.register.success=注册成功 +user.notfound=请重新登录 +user.forcelogout=管理员强制退出,请重新登录 +user.unknown.error=未知错误,请重新登录 + +##文件上传消息 +upload.exceed.maxSize=上传的文件大小超出限制的文件大小!
允许的文件最大大小是:{0}MB! +upload.filename.exceed.length=上传的文件名最长{0}个字符 + +##权限 +no.permission=您没有数据的权限,请联系管理员添加权限 [{0}] +no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}] +no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}] +no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}] +no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}] +no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}] diff --git a/ruoyi-admin/src/main/resources/logback.xml b/ruoyi-admin/src/main/resources/logback.xml new file mode 100644 index 0000000..a360583 --- /dev/null +++ b/ruoyi-admin/src/main/resources/logback.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/sys-info.log + + + + ${log.path}/sys-info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/sys-error.log + + + + ${log.path}/sys-error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + ${log.path}/sys-user.log + + + ${log.path}/sys-user.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml b/ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml new file mode 100644 index 0000000..10cf6b0 --- /dev/null +++ b/ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-admin/src/main/resources/rebel-remote.xml b/ruoyi-admin/src/main/resources/rebel-remote.xml new file mode 100644 index 0000000..1b662ec --- /dev/null +++ b/ruoyi-admin/src/main/resources/rebel-remote.xml @@ -0,0 +1,4 @@ + + + com.ruoyi.ruoyi-admin + diff --git a/ruoyi-admin/src/main/resources/templates/wireReportTemplate.ftl b/ruoyi-admin/src/main/resources/templates/wireReportTemplate.ftl new file mode 100644 index 0000000..be7dd50 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/wireReportTemplate.ftl @@ -0,0 +1,3 @@ + + +杭州2022年第19届亚运会${name}测试赛通信产品和服务使用证明2023${beginTime}${endTime}杭州2022年第19届亚运会${name}测试赛在${venueName}举行。在该项目比赛中,使用了官方通信服务合作伙伴中国移动提供的${taskSub}通信产品和服务。所提供的产品和服务符合杭州亚运会${type}项目比赛规则要求,设备性能稳定、运行正常,人员保障到位,满足测试赛要求。官方通信服务合作伙伴所提供的通信产品和服务清单详见附件。场馆信息技术主任(VTM):2023年 月 日附件1:AGIS专网临时布线清单(示例)序号设备属性规格单位数量<#list agisList as item>${item.id}${item.materialName}${item.materialSmallClass}${item.materialStand}${item.materialUnit}${item.sum}场馆网络与通信支持主管(VCM):2023年 月 日亚组委通信网络监理单位:2023年 月 日附件2:互联网(WiFi)专网临时布线清单(示例)序号设备属性规格单位数量<#list wifiList as item>${item.id}${item.materialName}${item.materialSmallClass}${item.materialStand}${item.materialUnit}${item.sum}场馆网络与通信支持主管(VCM):2023年 月 日亚组委通信网络监理单位:2023年 月 日附件3固话VOIP)专网临时布线清单(示例)序号设备属性规格单位数量<#list voipList as item>${item.id}${item.materialName}${item.materialSmallClass}${item.materialStand}${item.materialUnit}${item.sum}场馆网络与通信支持主管(VCM):2023年 月 日亚组委通信网络监理单位:2023年 月 日4402815001falsefalse871WPS Office_11.1.0.14309_F1E327BC-269C-435d-A152-05C5408002CA02023-06-01T01:30:00ZAdministratornbjkj2023-09-11T07:07:21Z2052-11.1.0.14309E4C53410A85F4514A9A76E10A50E260A_13 \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/wireReportTemplate1.ftl b/ruoyi-admin/src/main/resources/templates/wireReportTemplate1.ftl new file mode 100644 index 0000000..ccc20c9 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/wireReportTemplate1.ftl @@ -0,0 +1,3 @@ + + +杭州2022年第19届亚运会${name}测试赛通信产品和服务使用证明2023${beginTime}${endTime}杭州2022年第19届亚运会${name}测试赛在${venueName}举行。在该项目比赛中,使用了官方通信服务合作伙伴中国移动提供的${taskSub}通信产品和服务。所提供的产品和服务符合杭州亚运会${type}项目比赛规则要求,设备性能稳定、运行正常,人员保障到位,满足测试赛要求。官方通信服务合作伙伴所提供的通信产品和服务清单详见附件。场馆信息技术主任(VTM):2023年 月 日附件1:AGIS专网临时布线清单(示例)序号设备属性规格单位数量<#list agisList as item>${item.id}${item.materialName}${item.materialSmallClass}${item.materialStand}${item.materialUnit}${item.sum}场馆网络与通信支持主管(VCM):2023年 月 日亚组委通信网络监理单位:2023年 月 日附件2:互联网(WiFi)专网临时布线清单(示例)序号设备属性规格单位数量<#list wifiList as item>${item.id}${item.materialName}${item.materialSmallClass}${item.materialStand}${item.materialUnit}${item.sum}场馆网络与通信支持主管(VCM):2023年 月 日亚组委通信网络监理单位:2023年 月 日33616610034falsefalse701WPS Office_11.1.0.14309_F1E327BC-269C-435d-A152-05C5408002CA02023-06-01T01:30:00ZAdministratorAdministrator2023-06-05T06:31:11Z2052-11.1.0.14309CAEDF833D7D749E38CA1C0FF33A0A3F1_13 \ No newline at end of file diff --git a/ruoyi-admin/src/test/java/com/ruoyi/wl_test.java b/ruoyi-admin/src/test/java/com/ruoyi/wl_test.java new file mode 100644 index 0000000..6837596 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/wl_test.java @@ -0,0 +1,1000 @@ +package com.ruoyi; + +import cn.hutool.core.date.LocalDateTimeUtil; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import com.ruoyi.cmcc_gm.domain.YwMaterialsClasses; +import com.ruoyi.cmcc_gm.domain.YwMaterialsOrderLog; +import com.ruoyi.cmcc_gm.domain.YwMaterialsStock; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsBatchDTO; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsDTO; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsOrderLogDTO; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSearchDTO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsClassesVo; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsInformRedisVo; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsBatchMapper; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsClassesMapper; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsOrderLogMapper; +import com.ruoyi.cmcc_gm.service.*; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.AlarmConstants; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.TaskConstants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.dto.HandleDataDTO; +import com.ruoyi.common.core.domain.dto.StartProcessInstanceDTO; +import com.ruoyi.common.core.domain.dto.json.UserInfo; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.enums.UserStatus; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.*; +import com.ruoyi.common.utils.file.XmlDocToDocxUtil; +import com.ruoyi.common.utils.poi.WordUtil; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.eastcom_yw.domain.*; +import com.ruoyi.eastcom_yw.domain.dto.*; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeModelQO; +import com.ruoyi.eastcom_yw.domain.qo.YwNoticeObjectQO; +import com.ruoyi.eastcom_yw.domain.vo.*; +import com.ruoyi.eastcom_yw.mapper.*; +import com.ruoyi.eastcom_yw.service.*; +import com.ruoyi.eastcom_yw.service.impl.yw_alarm_deal_logServiceImpl; +import com.ruoyi.framework.web.service.SysLoginService; + +import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.sunlm.mapper.dpConfigMapper; +import com.ruoyi.sunlm.service.dpAllMyServices; +import com.ruoyi.system.mapper.SysDictDataMapper; +import com.ruoyi.system.mapper.SysUserMapper; +import com.ruoyi.system.service.ISysRoleService; +import com.ruoyi.system.service.ISysUserService; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.text.StringSubstitutor; +import org.docx4j.Docx4J; +import org.docx4j.openpackaging.packages.WordprocessingMLPackage; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.http.*; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {RuoYiApplication.class }, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)//配置启动类 +public class wl_test { + + @Autowired + private YwAlarmViewService ywAlarmViewService; + + @Autowired + private YwSignLogService ywSignLogService; + + @Autowired + private ISysUserService userService; + + @Autowired + private yw_alarm_deal_logService alarm_deal_logService; + + @Autowired + private SysLoginService loginService; + + @Autowired + private YwSceneService ywSceneService; + + @Autowired + private YwSignPlanService ywSignPlanService; + + @Autowired + private CommonService commonService; + + @Autowired + private RestTemplate restTemplate; + + @Autowired + private YwSignLogViewService ywSignLogViewService; + + @Autowired + private YwWireTaskLogService ywWireTaskLogService; + + @Autowired + private YwNoticeUserService ywNoticeUserService; + + @Autowired + private YwNoticeUserMapper ywNoticeUserMapper; + + @Autowired + private SysLoginService sysLoginService; + + @Autowired + private YwAlarmDHService ywAlarmDHService; + + @Autowired + private YwAlarmCSService ywAlarmCSService; + + @Autowired + private YwAlarmWXService ywAlarmWXService; + + @Test + public void test1() throws Exception { + + String token = commonService.getToken("13100000000","123456"); + + HttpHeaders headers2 = new HttpHeaders(); + headers2.add("Authorization","Bearer "+token); + headers2.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity> formEntity = new HttpEntity>(headers2); + +// url = "http://192.168.97.212:9010/eastcom_yw/alarm/list"; + String url ="http://localhost:8080/eastcom_yw/alarm/list"; + + YwAlarmDTO dto=new YwAlarmDTO(); + dto.setPageSize(10); + dto.setPageNum(1); + dto.setAlarmType("cs"); + dto.setCounty("0571_4"); + dto.setAlarmStatus("0"); + +// String url ="http://localhost:8080/eastcom_yw/alarm/newAlarmNum/7"; +//// +// YwAlarmDTO dto=new YwAlarmDTO(); +//// +// dto.setAlarmStatus("0"); +// +// dto.setUserId(8L); +// ArrayList venues=new ArrayList<>(); +// +//// venues.add(1000L); +//// +// dto.setVenues(venues); +// +// dto.setPageNum(1); +// dto.setPageSize(10); +//// + HttpHeaders headers = new HttpHeaders(); + +//// + HttpEntity request = new HttpEntity(JSONObject.toJSONString(dto),headers); +// + ResponseEntity responseEntity2 = restTemplate.postForEntity(url,request,String.class); + +// List SceneIds=new ArrayList<>(); +// SceneIds.add(1000L); +// + // String url = "http://192.168.5.132:8081/eastcom_yw/config/exportscenecalendarlist?pageSize=10&pageNum=1"; +// +// HashMap map = new HashMap<>(); +// map.put("venues",SceneIds); +// map.put("roles","gz_wx"); +// +// HttpEntity request2 = new HttpEntity(headers2); +// ResponseEntity responseEntity2 = restTemplate.exchange(url,HttpMethod.GET,request2,String.class); +// ResponseEntity responseEntity2 = restTemplate.postForEntity(url,HttpMethod.POST,formEntity,String.class); + + System.out.println(responseEntity2.getBody()); + + } + + @Test + public void test2() throws Exception { + + YwWireTaskLogDTO dto =new YwWireTaskLogDTO(); + dto.setPageNum(1); + dto.setPageSize(10); + dto.setTaskTypes(new Integer[]{1,2}); + + String token = commonService.getToken("admin","123456"); + String url ="http://127.0.0.1:8088/dev-api/eastcom_yw/wireTask/list"; + HttpHeaders headers = new HttpHeaders(); + headers.add("Authorization","Bearer "+token); +//// + HttpEntity request = new HttpEntity(JSONObject.toJSONString(dto),headers); +// + ResponseEntity responseEntity = restTemplate.postForEntity(url,request,String.class); + + System.out.println(responseEntity.getBody()); + } + + @Autowired + private ISysRoleService roleService; + + @Test + public void test6() throws Exception + { + + String token = commonService.getToken("gz_wx1","123456"); + +// LoginBody loginBody=new LoginBody(); +// loginBody.setPhone("15288888999"); +// sysLoginService.getCode(loginBody); +// System.out.println(sysLoginService.loginByPhone("15288888999","123456","")); + +// HttpHeaders headers2 = new HttpHeaders(); +// headers2.add("Authorization","Bearer "+token); +// headers2.setContentType(MediaType.APPLICATION_JSON); +// HttpEntity> formEntity = new HttpEntity>(headers2); + + +// String url ="http://192.168.97.212:9010/autoLogin"; +// String url ="http://localhost:8080/getInfo"; +// YwSignLogDTO ywSignLogDTO=new YwSignLogDTO(); + + // HttpEntity> formEntity2 = new HttpEntity>(headers2); +// HttpEntity request2 = new HttpEntity(JSONObject.toJSONString(ywSignLogDTO),headers2); +// ResponseEntity responseEntity2 = restTemplate.postForEntity(url,request2,String.class); +// ResponseEntity responseEntity2 = restTemplate.exchange(url,HttpMethod.GET,formEntity2,String.class); + +// ResponseEntity responseEntity2 = restTemplate.exchange(url,HttpMethod.GET,formEntity,String.class); +// System.out.println(responseEntity2.getBody()); + } + + @Test + public void test3() throws Exception { + + + String url_detail = "http://localhost:8080/eastcom_yw/notice?flwId=" + "1625014388736045056"; + + ResponseEntity responseEntity = null; + + try { + responseEntity = restTemplate.getForEntity(url_detail, String.class); + System.out.println(responseEntity.getBody()); + } catch (Exception ex) { + System.out.println("ProcessInstanceId:1625021022858293248 通知接口请求错误"); + } + + } + + @Test + public void test4() throws Exception + { + + + } + + + + @Test + public void test5() throws Exception + { + +// String token = loginService.loginByPhone("","123456", null); +// System.out.println(JSONObject.toJSONString(ywAlarmViewService.GetNewAlarmNum(1L))); +// UserInfo user = new UserInfo(); +// user.setId("2"); +// user.setName("系统"); +// user.setType("user"); +// user.setSex("1"); +// user.setSelected(true); +// +// StartProcessInstanceDTO startDTO = new StartProcessInstanceDTO(); +// startDTO.setStartUserInfo(user); +// startDTO.setProcessDefinitionId("Flowable1610829800288088064:28:1630745311905550336"); +// +// JSONObject json = new JSONObject(); +// json.put("input_cg_zy_id", MessageFormat.format("{0}|{1}|gz", 1000, "wx")); +// +// startDTO.setFormData(json); +// +// String res_flwprocessid= commonService.StartProcess(startDTO); + + + +// YwSignLogDTO ywSignLogDTO=new YwSignLogDTO(); +//// ywSignLogDTO.setUserType("wx"); +//// ywSignLogDTO.setCounty("0571_6"); +//// ywSignLogDTO.setCity("0571"); +// ywSignLogDTO.setPageSize(10); +// ywSignLogDTO.setPageNum(1); +//// Long[] venueId=new Long[]{1000L}; +// System.out.println(JSONObject.toJSONString(ywSignLogViewService.getSignLog(ywSignLogDTO))); +// ywSignLogDTO.setVenueIds(venueId); +// ywSignLogDTO.setStartDate("2023-02-08"); +// ywSignLogDTO.setEndDate("2023-02-11"); +// ywSignLogDTO.setPageNum(1); +// ywSignLogDTO.setPageSize(10); +// List list = ywSignLogViewService.getSignLogStatic(ywSignLogDTO); +//// +// System.out.println(JSONObject.toJSONString(list)); +// +// List list_signlogvo=new ArrayList<>(); +// +// page.getRecords().forEach( +// ywSignLogView -> { +// YwSignLogVo ywSignLogVo=new YwSignLogVo(); +// BeanUtils.copyBeanProp(ywSignLogVo,ywSignLogView); +// list_signlogvo.add(ywSignLogVo); +// } +// ); +// YwSignInDTO ywSignInDTO=new YwSignInDTO(); +// ywSignInDTO.setSignTime("2023-03-19 03:36:55"); +// ywSignInDTO.setVenueId(158L); +// ywSignInDTO.setSignType(1); +// ywSignInDTO.setUsers(new Long[]{8L}); +// ywSignInDTO.setUserTypes(new String[]{"dh"}); +// ywSignLogService.SignIn(ywSignInDTO); + + // System.out.println(JSONObject.toJSONString(page)); + +// String temp_id="1610829800288088064"; +//// +// System.out.println( commonService.GetProcessDefinitionId(temp_id)); + +// JSONObject object = JSONObject.parseObject(responseEntity.getBody()); +// JSONObject res = object.getJSONObject("result"); +// System.out.println(res.getString("processDefinitionId")); + +// System.out.println(ywAlarmViewService.getTemplateId()); + YwSignPlanDTO ywSignPlanDTO=new YwSignPlanDTO(); +// ywSignPlanDTO.setId(160L); +// ywSignPlanDTO.setVenueIds(new Long[]{9231L}); + ywSignPlanDTO.setSignDate(""); + ywSignPlanDTO.setStartDate("2023-05-02"); + ywSignPlanDTO.setEndDate("2023-05-25"); + ywSignPlanDTO.setPageSize(10); + ywSignPlanDTO.setPageNum(1); +// ywSignPlanDTO.setSignDates(new String[]{"2023-03-03"}); +// ywSignPlanDTO.setRepWarnInterval("5"); +// ywSignPlanDTO.setSignScope(111); +//// ywSignPlanDTO.setNoticeType("3"); +// ywSignPlanDTO.setBeginTime("13:41:00"); +// ywSignPlanDTO.setEndTime("19:00:00"); +// ywSignPlanDTO.setIsOpen("1"); +// ywSignPlanService.updateSignPlan(ywSignPlanDTO); + + System.out.println(JSONObject.toJSONString(ywSignPlanService.getSignPlan(ywSignPlanDTO))); + + } + + + @Autowired + private YwAlarmHangupLogService ywAlarmHangupLogService; + + @Autowired + private YwAlarmHangupLogMapper ywAlarmHangupLogMapper; + + @Autowired + private SysUserMapper userMapper; + + @Autowired + private SysDictDataMapper dictData; + + @Autowired + private YwWireTaskLogMapper ywWireTaskLogMapper; + + @Autowired + private YwSignPlanMapper ywSignPlanMapper; + + @Autowired + private YwAlarmService ywAlarmService; + + + @Autowired + private YwSceneUserService ywSceneUserService; + + @Autowired + private YwAlarmOprateLogService ywAlarmOprateLogService; + + @Autowired + private YwAlarmMapper ywAlarmMapper; + + @Autowired + private YwRoutInspectPlanMapper ywRoutInspectPlanMapper; + + @Autowired + private RedisCache redisCache; + + + @Autowired + private YwAlarmViewMapper ywAlarmViewMapper; + + @Autowired + private yw_alarm_deal_logMapper alarm_deal_logMapper; + + @Autowired + private dpConfigMapper dpConfigMapper; + + @Autowired + private yw_alarm_deal_logMapper yw_alarm_deal_logMapper; + + @Autowired + private YwMaterialsOrderLogService ywMaterialsOrderLogService; + + @Autowired + private YwMaterialsOrderLogMapper ywMaterialsOrderLogMapper; + + @Autowired + private YwMaterialsStockService ywMaterialsStockService; + + @Autowired + private YwMaterialsClassesService ywMaterialsClassesService; + + @Autowired + private YwMaterialsInformService ywMaterialsInformService; + + @Autowired + private YwMaterialsBatchMapper ywMaterialsBatchMapper; + + @Autowired + private YwMaterialsBatchService ywMaterialsBatchService; + + @Autowired + private YwNoticeObjectService ywNoticeObjectService; + + @Autowired + private SysNoticeService sysNoticeService; + + @Autowired + private YwRoutInspectPlanService ywRoutInspectPlanService; + + @Autowired + private YwNoticeModelService ywNoticeModelService; + @Autowired + private YwRoutInspectLogMapper ywRoutInspectLogMapper; + + @Autowired + private dpAllMyServices DpAllMyServices; + + @Autowired + private TokenService tokenService; + + @Autowired + private YwSignLogViewMapper ywSignLogViewMapper; + + @Autowired + private YwScenePictureService ywScenePictureService; + + @Autowired + private YwSceneNoticeinfoService ywSceneNoticeinfoService; + + @Autowired + private YwSceneNetelementMapper ywSceneNetelementMapper; + + @Test + public void test7() throws Exception { + + ywSceneNetelementMapper.dp_2_refresh_materialized_view(); + +// ywSceneNoticeinfoService.statisticsNetNum(); + +// List lst = ywAlarmMapper.revokeAlarm(); +// int cnt = lst.size(); +// int i = 1; +// for (String revoke : lst ) +// { +// HandleDataDTO dto = new HandleDataDTO(); +// UserInfo user = new UserInfo(); +// user.setId("2"); +// user.setName("系统"); +// dto.setTaskName("alarm"); +// dto.setCurrentUserInfo(user); +// dto.setProcessInstanceId(revoke); +// try { +// System.out.println("当前已处理第"+cnt+"/"+i+"条,流程号:"+revoke); +// commonService.revokeTask(dto); +// i++; +// } +// catch(Exception ex) +// { +// continue; +// } +// } + + + +// QueryWrapper queryUserWrapper=new QueryWrapper<>(); +// queryUserWrapper.eq("scene_id",8599L); +// +// List lstSceneUser = ywSceneUserService.list(queryUserWrapper); +// +// List lstUserId = lstSceneUser.stream().map(x->x.getUserId()).collect(Collectors.toList()); +// +// System.out.println(StringUtils.join(lstUserId,",")); + +// Map dataMap = new HashMap<>(16); +// dataMap.put("name", "跑步比赛"); +// dataMap.put("beginTime", "07月27日"); +// dataMap.put("endTime", "07月29日"); +// dataMap.put("taskSub", "AGIS专网"); +// dataMap.put("type", "跑步"); +// dataMap.put("venueName", "奥体中心体育馆"); +// +// List> noList = new ArrayList<>(); +// int size = 7; +// for (int i = 0; i < size; i++) { +// Map map = new HashMap<>(16); +// map.put("id", ""); +// map.put("materialName", ""); +// map.put("materialSmallClass", ""); +// map.put("materialStand", ""); +// map.put("materialUnit", ""); +// map.put("sum", ""); +// noList.add(map); +// } +// +// List> taskList = new ArrayList<>(); +// size = 200; +// for (int i = 0; i < size; i++) { +// Map map = new HashMap<>(16); +// map.put("id", ""); +// map.put("materialName", ""); +// map.put("materialSmallClass", ""); +// map.put("materialStand", ""); +// map.put("materialUnit", ""); +// map.put("sum", ""); +// taskList.add(map); +// } +// +// dataMap.put("agisList", taskList); +// dataMap.put("wifiList", noList); +// dataMap.put("intercomList", noList); +// dataMap.put("vedioList", noList); +// dataMap.put("transList", noList); +// +// WordUtil word = new WordUtil(); +// +// String fileName = "报告模板_"+DateUtils.dateTime() + ".doc"; +// String filePath = RuoYiConfig.getDownloadPath()+fileName; +// try { +// word.createWord(dataMap, "word.xml", filePath); +// System.out.println(filePath); +// } +// catch (Exception ex){ +// System.out.println(ex.getMessage()); +// } + +// String template_id = ""; +// try { +// template_id = ywAlarmViewMapper.getTemplateId(TaskConstants.ALARM); +// } catch (Exception e) { +// // log.error(e.getMessage()); +// return; +// } +// +// if (StringUtils.isEmpty(template_id)) +// { +// //todo:有空需要让异常入数据库,方便查询 +// // log.error("没有找到告警工作流template_id"); +// return; +// } +// +// +// String processDefinitionId = ""; +// try { +// processDefinitionId = commonService.GetProcessDefinitionId(template_id); +// } catch (Exception e) { +// // log.error(e.getMessage()); +// return; +// } +// +// if (StringUtils.isEmpty(processDefinitionId)) +// { +// // log.error("没有正确的工作流processDefinitionId"); +// return; +// } +// +// +// UserInfo user = new UserInfo(); +// user.setId("2"); +// user.setName("系统"); +// user.setType("user"); +// user.setSex("1"); +// user.setSelected(true); +// +// Long sceneId = 2L; +// String code = "26324"; +// String groupColnum = "5329"; +// +// for (int i=0;i<10;i++) { +// +// //保存数据到yw_alarm_deal_log +// yw_alarm_deal_log alarm_deal = new yw_alarm_deal_log(); +// alarm_deal.setAlarmCode(code); +// alarm_deal.setAlarmType("wx"); +// alarm_deal.setGroupColnum(groupColnum); +// alarm_deal.setBeginTime(DateUtils.getNowDate()); +// alarm_deal.setPrimaryId(groupColnum); +// alarm_deal.setIsRed("Y"); +// alarm_deal.setSceneId(sceneId); +// alarm_deal.setAlarmTime(DateUtils.getNowDate()); +// +// +// //20230303只有在红线内的告警才需要生成工作流 +// +// YwSearchDTO ywSearchDTO = new YwSearchDTO(); +// ywSearchDTO.setArea_county_id("0571_4"); +// ywSearchDTO.setVenue_id("2"); +// ywSearchDTO.setVenue_name("杭州奥体中心主体育场"); +// ywSearchDTO.setCity("杭州"); +// ywSearchDTO.setCounty("滨江"); +// ywSearchDTO.setTask_type(TaskConstants.ALARM); +// ywSearchDTO.setAlarm_name("测试告警"); +// ywSearchDTO.setNet_name("测试网元"); +// ywSearchDTO.setSite_name("测试站名"); +// +// //20230303工作流增加任务名称 +// ywSearchDTO.setTask_name("测试123 测试告警"); +// //20230307工作流增加专业 +// ywSearchDTO.setSpecialty("无线"); +// +// StartProcessInstanceDTO startDTO = new StartProcessInstanceDTO(); +// startDTO.setStartUserInfo(user); +// startDTO.setProcessDefinitionId(processDefinitionId); +// +// JSONObject json = new JSONObject(); +// +// String groupId = MessageFormat.format("{0}|{1}|gz", "2", "wx"); +// +// json.put("input_cg_zy_id", groupId); +// json.put("input_gjbh", "test1"); +// json.put("input_zyfl", TaskConstants.ALARM); +// json.put("textarea_gjxx", MessageFormat.format("告警网元:{0},告警名称:{1},告警时间:{2}", "测试网元", "测试告警", DateUtils.getNowDate())); +// json.put("textarea_gzyy", ""); +// json.put("pictureupload_sczp", null); +// //20230217 增加查询条件 +// json.put("input_search", JSONObject.toJSONString(ywSearchDTO)); +// +// startDTO.setFormData(json); +// try { +// String res_flwprocessid = commonService.StartProcess(startDTO); +// if (StringUtils.isNotEmpty(res_flwprocessid)) { +// alarm_deal.setFlwProcessid(res_flwprocessid); +// //非红线内的直接进入记录表,用于查看 +// try { +// alarm_deal_logMapper.insert(alarm_deal); +// } catch (Exception e) { +// break; +// } +// } +// } catch (Exception e) { +// break; +// } +// } +// + + +// ywNoticeUserService.noticeYW("1648881170252963840","9169|wx|gz",TaskConstants.ALARM); + +// List alarms = ywAlarmViewService.GetAlarmInfoList("1641774928401481728",false); +// +// System.out.println(JSONObject.toJSONString(alarms.get(0))); +// System.out.println(JSONObject.toJSONString(ywMaterialsBatchMapper.selectBatch("ZXK-20230413-23"))); +// +// +// YwMaterialsSearchDTO searchDTO =new YwMaterialsSearchDTO(); +// searchDTO.setStoreId(0L); +// searchDTO.setTaskStatus("1"); +// searchDTO.setOrderType(1); +// searchDTO.setSearchDate("2023-04-12"); +// System.out.println(JSONObject.toJSONString(ywMaterialsStockService.getMaterialsStock(searchDTO))); + + +// List list = ywMaterialsInformService.getMaterials(); +// +// System.out.println(JSONObject.toJSONString(list)); + + YwMaterialsOrderLogDTO dto=new YwMaterialsOrderLogDTO(); +// dto.setOrderId("ZXK-20230413-23"); + dto.setOrderType(2); +// dto.setTaskStatus("1"); + dto.setInStoreVenue(9231L); + dto.setOutStoreVenue(0L); + dto.setApplyName("jkj"); + dto.setCheckName("jkj"); +// dto.setInStoreName(""); + + + +// String orderId = ywMaterialsOrderLogService.insertMaterialsOrderLog(dto); + + YwMaterialsDTO ywMaterialsDTO=new YwMaterialsDTO(); + ywMaterialsDTO.setAuditor("wm"); + ywMaterialsDTO.setOrderType(2); + ywMaterialsDTO.setOpType("提交申请"); + ywMaterialsDTO.setOrderId("SL-20230506-0008"); + + + YwMaterialsBatch batch =new YwMaterialsBatch(); + batch.setMaterialCode("1101011002"); + batch.setOutSum(3); + batch.setInSum(4); + + YwMaterialsBatch batch2 =new YwMaterialsBatch(); + batch2.setMaterialCode("1101011003"); + batch2.setOutSum(5); + batch2.setInSum(6); + + List listBath =new ArrayList<>(); + listBath.add(batch); + listBath.add(batch2); + YwMaterialsBatchDTO ywMaterialsBatchDTO = new YwMaterialsBatchDTO(); + ywMaterialsBatchDTO.setOrderId("SL-20230421-0002"); + ywMaterialsBatchDTO.setData(listBath); + + +// ywMaterialsOrderLogService.updateMaterialsOrderLogInner(dto); +// +// ywMaterialsStockService.updateMaterialsStock(ywMaterialsDTO); +// ywMaterialsStockService.updateInWayMaterialsStock(ywMaterialsDTO); +// YwMaterialsOrderLog ywMaterialsOrderLog = ywMaterialsStockService.Validate(ywMaterialsDTO); +// ywMaterialsStockService.freezeOutWayMaterialsStockBack(ywMaterialsBatchDTO); +// QueryWrapper queryWrapper=new QueryWrapper<>(); +// queryWrapper.eq("hangup_status","2"); +// queryWrapper.eq("flw_processid","1637101556262428672"); +// queryWrapper.orderByDesc("hangup_time"); +// YwAlarmHangupLog hangupLog = ywAlarmHangupLogMapper.selectList(queryWrapper).get(0); +// Date hangupBegin =hangupLog.getHangupTime(); +// +// double durSecond = Math.ceil((double) ((DateUtils.getNowDate().getTime() - hangupBegin.getTime()) / (1000*60))); +// +// yw_alarm_deal_logMapper.updateHangupSpantime(durSecond,"1637101556262428672"); +// +// throw new ServiceException("取消挂起失败,请联系管理员"); + + +// System.out.println(JSONObject.toJSONString(ywAlarmViewMapper.getYwAlarmInfoList("1638716980505591808"))); + +// YwAlarmDTO ywAlarmDto=new YwAlarmDTO(); +//// ywAlarmDto.setStartTime("2023-03-15"); +//// ywAlarmDto.setEndTime("2023-03-17 23:59:59"); +//// ywAlarmDto.setCounty("0571_3"); +// ywAlarmDto.setUserId(270L); +// ywAlarmDto.setPageNum(1); +// ywAlarmDto.setPageSize(10); +// ywAlarmDto.setIsAll(false); +// ywAlarmDto.setInRedLine("N"); +// ywAlarmDto.setAlarmStatus("1"); +//// ywAlarmDto.setDealStatus("2"); +//// List lstVenue=new ArrayList<>(); +//// lstVenue.add(42L); +//// ywAlarmDto.setVenues(lstVenue); +// ywAlarmDto.setAlarmType("cs"); +// ywAlarmDto.setIsAPP(true); +//// ywAlarmDto.setSearchBox("网元连接中断"); +// ywAlarmDto.setIsAPP(true); +//// System.out.println(JSONObject.toJSONString(ywAlarmWXService.GetAlarmList(ywAlarmDto))); +//// yw_alarm_deal_log alarm_deal = new yw_alarm_deal_log(); +//// alarm_deal.setAlarmCode("test"); +//// alarm_deal.setAlarmType("cs"); +//// alarm_deal.setGroupColnum("100000"); +//// alarm_deal.setBeginTime(DateUtils.getNowDate()); +//// alarm_deal.setPrimaryId("100000"); +//// alarm_deal.setIsRed("Y"); +//// alarm_deal.setSceneId(1L); +//// alarm_deal_logMapper.insert(alarm_deal); +// System.out.println(JSONObject.toJSONString(ywAlarmCSService.GetAlarmList(ywAlarmDto))); +// System.out.println(JSONObject.toJSONString(ywAlarmViewMapper.getYwAlarmNewNumByDto(ywAlarmDto))); +// System.out.println(JSONObject.toJSONString(ywAlarmViewService.getYwAlarmByDto(ywAlarmDto))); +// System.out.println(JSONObject.toJSONString(ywAlarmViewService.GetAlarmInfoList("1638716989053583360"))); +// System.out.println(JSONObject.toJSONString(ywAlarmViewService.getYwAlarmNewNumByDto(ywAlarmDto))); +// System.out.println(JSONObject.toJSONString(ywAlarmViewMapper.getYwAlarmWxNewNumByDto(ywAlarmDto))); +// System.out.println(JSONObject.toJSONString(ywAlarmViewService.GetAlarmInfoList("1637101547278229504"))); +// System.out.println(JSONObject.toJSONString(ywAlarmViewMapper.getYwAlarmByGroupId("")); +// ywAlarmViewMapper.getYwAlarmByGroupId("cs","1015"); +// YwSignPlanDTO ywSignPlanDTO=new YwSignPlanDTO(); +// ywSignPlanDTO.setNoticeType("短信"); +// ywSignPlanDTO.setVenueName("滨江体育馆"); +// ywSignPlanDTO.setSignDate("'2023-03-19'"); +// ywSignPlanDTO.setBeginTime("'8:00:00'"); +// ywSignPlanDTO.setEndTime("'17:00:00'"); +// ywSignPlanDTO.setRepWarnInterval("5,10"); +// ywSignPlanDTO.setNoticeType("短信"); +// List signPlanList =new ArrayList<>(); +// signPlanList.add(ywSignPlanDTO); +//// getLocalDateTime(double date, boolean use1904windowing, boolean roundSeconds) +// +// ywSignPlanService.importSignPlan(signPlanList,false,1L); + +// System.out.println(JSONObject.toJSONString(ywAlarmViewService.GetAlarmInfoList("1635898164437508096"))); + +//SysUser user =new SysUser(); +// List list = userService.selectUserList(user); +// System.out.println(JSONObject.toJSONString(list)); + +// String phone = "18367407691"; +// String code="123456"; +// redisCache.setCacheObject(CacheConstants.CAPTCHA_CODE_KEY + phone, code, 300, TimeUnit.SECONDS); +// + +// +// System.out.println(token); + +// System.out.println(JSONObject.toJSONString( ywRoutInspectPlanMapper.getExecutablePlanList(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(DateUtils.getNowDate())))); + +// YwAlarmOprateLog ywAlarmOprateLog=new YwAlarmOprateLog(); +// ywAlarmOprateLog.setAlarmGroup("109"); +// ywAlarmOprateLog.setUserId(8L); +// ywAlarmOprateLog.setId(0L); +// String aa=DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD_HH_MM_SS); +// ywAlarmOprateLog.setOprateTime(aa); +// ywAlarmOprateLogService.saveOrUpdate(ywAlarmOprateLog); + +// ywSignPlanService.deleteSignPlan(2L); + +// List listScene = ywSceneUserService.getVenuesByUserId(29L); +// System.out.println(JSONObject.toJSONString(listScene)); +// List venueIds=new ArrayList<>(); +// listScene.forEach( +// ywSceneUser -> { +// venueIds.add(ywSceneUser.getSceneId()); +// } +// ); +// Long [] arr_ids = venueIds.toArray(new Long[venueIds.size()]); +// System.out.println(JSONObject.toJSONString(arr_ids)); + + + +// System.out.println(JSONObject.toJSONString(map_YwAlarmLastVo)); +// HashMap> map_YwAlarmLastVo=new HashMap>(); +// +// dictData.selectDictDataByType("yw_specialty").forEach(dictData -> { +// +// if(!map_YwAlarmLastVo.containsKey(dictData.getDictValue())) +// { +// map_YwAlarmLastVo.put(dictData.getDictValue(),new ArrayList()); +// } +// +// SysUser user=new SysUser(); +// user.setUserType(dictData.getDictValue()); +// +// userMapper.selectUserList(user).forEach(sysUser -> { +// +// map_YwAlarmLastVo.get(dictData.getDictValue()).add(sysUser); +// +// }); +// +// +// } ); +// System.out.println(ywSignPlanMapper.getSignRemindList()); +// System.out.println(JSONObject.toJSONString(map_YwAlarmLastVo)); +// ywAlarmViewService.insert_alarm_schedule(); + // ywAlarmHangupLogService.updateAlarmHangupSchedule(); +// YwSearchDTO ywSearchDTO=new YwSearchDTO(); +// ywSearchDTO.setAreaCounty("0571_4"); +// ywSearchDTO.setVenue("1000"); +// System.out.println(JSONObject.toJSONString(ywSearchDTO)); + // System.out.println(JSONObject.toJSONString( ywAlarmViewService.GetAlarmInfoList("1630761578490204160"))); +// YwAlarmHangupLog ywAlarmHangupLog=new YwAlarmHangupLog(); +// ywAlarmHangupLog.setId(2L); +// ywAlarmHangupLog.setRecoveryResult("0"); +// ywAlarmHangupLogMapper.updateById(ywAlarmHangupLog); +// HandleDataDTO handleDataDTO=new HandleDataDTO(); +// +// UserInfo user=new UserInfo(); +// user.setId("8"); +// handleDataDTO.setProcessInstanceId("1622422643670167552"); +// handleDataDTO.setTaskId("1622422643737276427"); +// handleDataDTO.setCurrentUserInfo(user); +// handleDataDTO.setTransferUserInfo(user); +// handleDataDTO.setTransferType(1); +// try { +// commonService.UpdateProcessStatus(handleDataDTO); +// } +// catch (Exception ex) +// { +// System.out.println(ex.getMessage()); +// } + +// YwAlarmHangupLogDTO ywAlarmHangupLog=new YwAlarmHangupLogDTO(); +// ywAlarmHangupLog.setHangupReason("123"); +// ywAlarmHangupLog.setHangupTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,DateUtils.getNowDate())); +// ywAlarmHangupLog.setHangupUserId(10L); +// ywAlarmHangupLog.setRecoveryTime("2023-02-15 23:00:00"); +// ywAlarmHangupLog.setFlwProcessid("123"); +// ywAlarmHangupLog.setFlwTaskid("123"); +// ywAlarmHangupLogService.insertYwAlarmHangupLog(ywAlarmHangupLog); +// +// YwWireTaskLogDTO ywWireTaskLogDTO=new YwWireTaskLogDTO(); +// ywWireTaskLogDTO.setWireTaskName("test123(拆除)"); +// ywWireTaskLogDTO.setVenueId(155L); +// ywWireTaskLogDTO.setWireTaskId("BX-20230329-0001"); +// ywWireTaskLogDTO.setPageSize(10); +// ywWireTaskLogDTO.setPageNum(1); +// ywWireTaskLogDTO.setFlwProcessid("1635928391033245696"); +// ywWireTaskLogDTO.setWireTaskId("BX-20230315-0007"); +// ywWireTaskLogDTO.setCreateTime("2023-02-07 11:00:00"); +// ywWireTaskLogDTO.setTaskType(2); +// ywWireTaskLogDTO.setWireTaskId("123123123"); +// ywWireTaskLogDTO.setVenueId(1000L); +//// System.out.println(JSONObject.toJSONString(ywWireTaskLogService.getWireTaskLog(ywWireTaskLogDTO))); +// ywWireTaskLogService.insertWireTaskLogReWireTaskId(ywWireTaskLogDTO); +// List list = ywNoticeUserService.getYwNoticeUserList("1625355629520695296","1625355631231971328","1000|venuemanager","公网告警"); +// System.out.println(JSONObject.toJSONString(list)) +// String groupId = "0|centerstoragemaster"; +// if(groupId.contains("centerstorage")) +// { +// groupId = groupId.split("\\|")[1]; +// } +// System.out.println(JSONObject.toJSONString(ywNoticeUserMapper.getPhoneByGroupId(groupId))); +// String content = "您的验证码为123456,五分钟有效,请勿向他人泄露。"; +// SysNotice notice=new SysNotice(); +// notice.setNoticeType("3"); +// notice.setNoticeTitle("短信验证码"); +// notice.setStatus("0"); +// notice.setCreateBy("sys"); +// notice.setNoticeContent(content); +// notice.setReciveUser(8L); +// notice.setSendTime(DateUtils.getNowDate()); +// try +// { +// sysNoticeService.insertNotice(notice); +// } +// catch (Exception e) +// { +// e.printStackTrace(); +// } + +// ywAlarmViewService.insert_alarm_schedule(); + +// YwDataDTO ywDataDTO =new YwDataDTO(); +// ywDataDTO.setVenueIds(new Long[]{158L}); +// ywDataDTO.setUserTypes(new String[]{"wx"}); +// ywDataDTO.setRole(""); +// ywDataDTO.setSignDate("2023-03-14"); +// ywDataDTO.setSignType(0); +// List tdi = ywSceneService.getSysUserByVenueAndOther(ywDataDTO); +// System.out.println(JSONObject.toJSONString(tdi)); + +// System.out.println(JSONObject.toJSONString(ywDataDTO)); +// String url="http://localhost:8080/eastcom_yw/alarm/info/1622422643670167552"; +// String token = commonService.getToken("admin","123456"); +// +// HttpHeaders headers = new HttpHeaders(); +// headers.add("Authorization","Bearer "+token); +// headers.setContentType(MediaType.APPLICATION_JSON); +// HttpEntity> formEntity = new HttpEntity>(headers); +// +//// HttpEntity request2 = new HttpEntity(JSONObject.toJSONString(ywDataDTO),headers); +//// ResponseEntity responseEntity = restTemplate.postForEntity(url,request2,String.class); +// ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.GET,formEntity,String.class); +// System.out.println(responseEntity.getBody()); + +// SysNotice notice = new SysNotice(); +//// notice.setReciveUser(13L); +// +// List list = noticeService.selectNoticeListByUser(notice); +// +// System.out.println(JSONObject.toJSONString(list)); + +// List list= new ArrayList<>(); +//// +// list = ywSceneService.getSysUserByVenueAndOther(ywDataDTO); +////// +// TableDataInfo rspData = new TableDataInfo(); +// rspData.setCode(HttpStatus.SUCCESS); +// rspData.setMsg("查询成功"); +// rspData.setRows(list); +// rspData.setTotal(new PageInfo(list).getTotal()); +//// +//// +// System.out.println(JSONObject.toJSONString(rspData)); + } + + +} diff --git a/ruoyi-app/pom.xml b/ruoyi-app/pom.xml new file mode 100644 index 0000000..e10b3c8 --- /dev/null +++ b/ruoyi-app/pom.xml @@ -0,0 +1,134 @@ + + + + ruoyi + com.ruoyi + 3.8.4 + + 4.0.0 + jar + ruoyi-app + + + app服务入口 + + + + + + + org.springframework.boot + spring-boot-devtools + true + + + + + io.springfox + springfox-boot-starter + + + + + io.swagger + swagger-models + 1.6.2 + + + + + + + + + + org.postgresql + postgresql + + + + com.ruoyi + ruoyi-framework + + + + + com.ruoyi + ruoyi-generator + + + + com.ruoyi + eastcom_yw + + + + com.ruoyi + cmcc_gm + + + + junit + junit + 4.13.2 + test + + + org.springframework + spring-test + 5.3.23 + test + + + org.springframework.boot + spring-boot-test + 2.7.5 + test + + + + com.ruoyi + ruoyi-sunlm + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.1.1.RELEASE + + true + + + + + repackage + + + + + + org.apache.maven.plugins + maven-war-plugin + 3.1.0 + + false + ${project.artifactId} + + + + ${project.artifactId} + + + \ No newline at end of file diff --git a/ruoyi-app/src/main/java/com/ruoyi/RuoYiAPPApplication.java b/ruoyi-app/src/main/java/com/ruoyi/RuoYiAPPApplication.java new file mode 100644 index 0000000..dcf0eee --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/RuoYiAPPApplication.java @@ -0,0 +1,39 @@ +package com.ruoyi; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.web.client.RestTemplate; + +/** + * 启动程序 + * + * @author ruoyi + */ +@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) +public class RuoYiAPPApplication +{ + + @Bean + public RestTemplate restTemplate(RestTemplateBuilder builder) { + return builder.build(); + } + + public static void main(String[] args) + { + // System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(RuoYiAPPApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/RuoYiServletInitializer.java b/ruoyi-app/src/main/java/com/ruoyi/RuoYiServletInitializer.java new file mode 100644 index 0000000..b51948b --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/RuoYiServletInitializer.java @@ -0,0 +1,16 @@ +package com.ruoyi; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * web容器中进行部署 + * + * @author ruoyi + */ +public class RuoYiServletInitializer extends SpringBootServletInitializer { + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(RuoYiAPPApplication.class); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsClassesController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsClassesController.java new file mode 100644 index 0000000..f44bb08 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsClassesController.java @@ -0,0 +1,113 @@ +package com.ruoyi.app.controller.cmcc_gm; + + +import com.ruoyi.cmcc_gm.domain.YwMaterialsClasses; +import com.ruoyi.cmcc_gm.domain.dto.YmMaterialsClassesParam; +import com.ruoyi.cmcc_gm.service.YwMaterialsClassesService; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.PageUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.util.List; + +/** + * (YwMaterialsClasses)表控制层 + * + * @author lee + * @since 2023-04-19 10:15:59 + */ +@Api(tags = "物资类别") +@RestController +@RequestMapping("/app/ywMaterialsClasses") +public class YwMaterialsClassesController extends BaseController { + + /** + * 服务对象 + */ + @Resource + private YwMaterialsClassesService ywMaterialsClassesService; + + /** + * 分页查询所有数据 + * + * @param ywMaterialsClasses 查询实体 + * @return 所有数据 + */ + @ApiOperation(value = "分页查询", notes = "分页查询") + @PostMapping("/list") + public TableDataInfo selectAll(@RequestBody YmMaterialsClassesParam ywMaterialsClasses) { + PageUtils.startPage(ywMaterialsClasses, YmMaterialsClassesParam.class); + return getDataTable(ywMaterialsClassesService.getMaterialsBySearch(ywMaterialsClasses)); + } + + /** + * 通过主键查询单条数据 + * + * @param id 主键 + * @return 单条数据 + */ + @ApiOperation(value = "根据id查询", notes = "根据id查询") + @GetMapping("{id}") + public AjaxResult selectOne(@PathVariable Serializable id) { + return AjaxResult.success(this.ywMaterialsClassesService.getById(id)); + } + + /** + * 新增数据 + * + * @param ywMaterialsClasses 实体对象 + * @return 新增结果 + */ + @ApiOperation(value = "新增", notes = "新增") + @PostMapping + public AjaxResult insert(@RequestBody YwMaterialsClasses ywMaterialsClasses) { + boolean res = this.ywMaterialsClassesService.save(ywMaterialsClasses); + if(res) + { + ywMaterialsClassesService.loadingMaterialsClassesCache(); + } + return AjaxResult.success(res); + } + + /** + * 修改数据 + * + * @param ywMaterialsClasses 实体对象 + * @return 修改结果 + */ + @ApiOperation(value = "修改", notes = "修改") + @PutMapping + public AjaxResult update(@RequestBody YwMaterialsClasses ywMaterialsClasses) { + boolean res = this.ywMaterialsClassesService.updateById(ywMaterialsClasses); + if(res) + { + ywMaterialsClassesService.loadingMaterialsClassesCache(); + } + return AjaxResult.success(res); + } + + /** + * 删除数据 + * + * @param idList 主键结合 + * @return 删除结果 + */ + @ApiOperation(value = "删除", notes = "删除") + @DeleteMapping + public AjaxResult delete(@RequestParam("idList") List idList) { + boolean res = this.ywMaterialsClassesService.removeByIds(idList); + if(res) + { + ywMaterialsClassesService.loadingMaterialsClassesCache(); + } + return AjaxResult.success(this.ywMaterialsClassesService.removeByIds(idList)); + } + +} + diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsController.java new file mode 100644 index 0000000..33c58a9 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsController.java @@ -0,0 +1,611 @@ +package com.ruoyi.app.controller.cmcc_gm; + + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.cmcc_gm.common.enums.OrderStatus; +import com.ruoyi.cmcc_gm.common.enums.OrderType; +import com.ruoyi.cmcc_gm.domain.YwMaterialsBatch; +import com.ruoyi.cmcc_gm.domain.YwMaterialsOrderLog; +import com.ruoyi.cmcc_gm.domain.YwMaterialsStock; +import com.ruoyi.cmcc_gm.domain.dto.*; +import com.ruoyi.cmcc_gm.domain.qo.YwMaterialsSnListQO; +import com.ruoyi.cmcc_gm.domain.vo.YwMaterialsInformRedisVo; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsBatchMapper; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsOrderLogMapper; +import com.ruoyi.cmcc_gm.mapper.YwMaterialsSnListMapper; +import com.ruoyi.cmcc_gm.service.*; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.page.PageDomain; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.page.TableSupport; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.domain.dto.YwSearchDTO; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + *

+ * 物资工单日志表 前端控制器 + *

+ * + * @author jkj + * @since 2023-04-07 + */ +@RestController +@RequestMapping("/app/ywMaterials") +public class YwMaterialsController extends BaseController { + + @Autowired + private YwMaterialsStockService ywMaterialsStockService; + + @Autowired + private YwMaterialsInformService ywMaterialsInformService; + + @Autowired + private YwMaterialsOrderLogService ywMaterialsOrderLogService; + + @Autowired + private YwMaterialsClassesService ywMaterialsClassesService; + + @Autowired + private YwMaterialsBatchService ywMaterialsBatchService; + + @Autowired + private YwMaterialsBatchMapper ywMaterialsBatchMapper; + + @Autowired + private YwMaterialsSnListService ywMaterialsSnListService; + + + @ApiOperation("根据条件查询仓库的物资库存数据") + @PostMapping("/stock/list") + @RepeatSubmit(enable = false,interval = 1000) + public TableDataInfo list(@RequestBody YwMaterialsSearchDTO ywMaterialsSearchDTO) throws Exception { + + //APP默认显示所有场馆的物资 +// if(ObjectUtils.isNotEmpty(ywMaterialsSearchDTO.getStoreIds())) +// { +// if(ywMaterialsSearchDTO.getStoreIds().length==0) { +// throw new ServiceException("仓库ID不能为空"); +// } +// } + + String pageNum = ServletUtils.getParameter("pageNum"); + String pageSize = ServletUtils.getParameter("pageSize"); + if(!StringUtils.isEmpty(pageNum) && !StringUtils.isEmpty(pageSize)) { + startPage(); + } + return getDataTable(ywMaterialsStockService.getMaterialsStock(ywMaterialsSearchDTO)); + + } + + + @Log(title = "更新物资库存信息数据", businessType = BusinessType.UPDATE) + @ApiOperation("更新物资库存信息数据") + @PostMapping("/stock/update") + @Transactional + public AjaxResult updateStock(@RequestBody YwMaterialsDTO ywMaterialsDTO) throws Exception { + + + Boolean res = true; + + if (ObjectUtils.isEmpty(ywMaterialsDTO.getOpType())) { + throw new ServiceException("操作类型不能为空"); + } + + if (ObjectUtils.isEmpty(ywMaterialsDTO.getOrderType())) { + throw new ServiceException("物资工单类型不能为空"); + } + +// 验证当前用户的角色是否具有操作权限 + List roles = SecurityUtils.getLoginUser().getUser().getRoles(); + + List filterRoles = null; + + boolean needCheck = false; + + if (ywMaterialsDTO.getOpType().equals("提交申请")) { + + if (ywMaterialsDTO.getOrderType().equals(OrderType.ZXK.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("centerstoragechecker")).collect(Collectors.toList()); + } + + if (ywMaterialsDTO.getOrderType().equals(OrderType.SL.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.TK.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("venuestoragechecker") || e.getRoleKey().equals("venuemanager")).collect(Collectors.toList()); + } + + //20230815 出入库不需要验证角色 +// if (ywMaterialsDTO.getOrderType().equals(OrderType.CK.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.RK.getCode())) { +// filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("builder")).collect(Collectors.toList()); +// } + + if (ywMaterialsDTO.getOrderType().equals(OrderType.DB.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("centerstoragemaster")).collect(Collectors.toList()); + } + + + if (ywMaterialsDTO.getOrderType().equals(OrderType.CK.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.RK.getCode())) { + + } + else + { + needCheck = true; + } + + } + + if (ywMaterialsDTO.getOpType().equals("审核任务")) { + + if (ywMaterialsDTO.getOrderType().equals(OrderType.ZXK.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.SL.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.TK.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("centerstoragemaster")).collect(Collectors.toList()); + } + + + if (ywMaterialsDTO.getOrderType().equals(OrderType.CK.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.RK.getCode()) || ywMaterialsDTO.getOrderType().equals(OrderType.DB.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("venuestoragemaster")).collect(Collectors.toList()); + } + needCheck = true; + } + + if (ywMaterialsDTO.getOpType().equals("出库确认") || ywMaterialsDTO.getOpType().equals("入库确认")) { + + if (!ywMaterialsDTO.getOrderType().equals(OrderType.ZXK.getCode())) { +// 默认都是场馆物资仓库管理员出入库确认 + //物资退库,是中心库物资维护员角色提交入库 + if (ywMaterialsDTO.getOpType().equals("入库确认")) { + if (ywMaterialsDTO.getOrderType().equals(OrderType.TK.getCode())) { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("centerstoragechecker")).collect(Collectors.toList()); + } else { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("venuestoragekeeper")).collect(Collectors.toList()); + } + } else { + filterRoles = roles.stream().filter(e -> e.getRoleKey().equals("venuestoragekeeper")).collect(Collectors.toList()); + } + } + needCheck = true; + } + + if (needCheck) { + if(filterRoles!=null) { + if (filterRoles.isEmpty()) { + throw new ServiceException("当前用户没有操作的权限"); + } + } + } + + //创建时如果不是中心库,折旧入库 的需要冻结库存 + if (ywMaterialsDTO.getOpType().equals("创建")) { + + + YwMaterialsOrderLog ywMaterialsOrderLog = ywMaterialsStockService.Validate(ywMaterialsDTO); + + //待申请的才可以创建 + if (!ywMaterialsOrderLog.getTaskStatus().equals(OrderStatus.DSQ.getCode())) { + throw new ServiceException("当前物资订单状态不允许该操作"); + } + + if (!(ywMaterialsDTO.getOrderType() == OrderType.ZXK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.RK.getCode())) { + +// //正向,冻结操作放在了批量表的插入 +// if(StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) +// { +// res = ywMaterialsStockService.freezeOutWayMaterialsStock(ywMaterialsDTO, ywMaterialsOrderLog); +// } + + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + if (ywMaterialsDTO.getIsBack().equals("是")) { + res = ywMaterialsStockService.freezeOutWayMaterialsStockBack(ywMaterialsDTO, ywMaterialsOrderLog); + } + } + } + + } + + if (ywMaterialsDTO.getOpType().equals("撤销")) { + + YwMaterialsOrderLog ywMaterialsOrderLog = ywMaterialsStockService.Validate(ywMaterialsDTO); + + if (!ywMaterialsOrderLog.getTaskStatus().equals(OrderStatus.DSQ.getCode())) { + throw new ServiceException("当前物资订单状态不允许该操作"); + } + + res = ywMaterialsStockService.freezeOutWayMaterialsStockBack(ywMaterialsDTO, ywMaterialsOrderLog); + + if (res) { + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + orderDto.setOrderId(ywMaterialsOrderLog.getOrderId()); + orderDto.setOrderType(ywMaterialsOrderLog.getOrderType()); + orderDto.setTaskStatus(OrderStatus.CX.getCode()); + res = ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); + + } + + if (res) { + return AjaxResult.success("撤销物资订单成功"); + } + + return AjaxResult.error("撤销物资订单失败"); + + } + + if (ywMaterialsDTO.getOpType().equals("驳回") || ywMaterialsDTO.getOpType().equals("提交申请")) { + + YwMaterialsOrderLog ywMaterialsOrderLog = ywMaterialsStockService.Validate(ywMaterialsDTO); + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + + orderDto.setOrderId(ywMaterialsOrderLog.getOrderId()); + orderDto.setOrderType(ywMaterialsOrderLog.getOrderType()); + + //正向 + if (StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) { + + if (ywMaterialsDTO.getOpType().equals("驳回")) { + + if (!ywMaterialsOrderLog.getTaskStatus().equals(OrderStatus.DSH.getCode())) { + throw new ServiceException("当前物资订单不是待审核状态,无法驳回"); + } + + //驳回后释放库存 + boolean resBack = ywMaterialsStockService.freezeOutWayMaterialsStockBack(ywMaterialsDTO, ywMaterialsOrderLog); + + if (!resBack) { + throw new ServiceException("释放库存异常,驳回失败了,不用走工作流"); + } + + orderDto.setTaskStatus(OrderStatus.DSQ.getCode()); + } + + if (ywMaterialsDTO.getOpType().equals("提交申请")) { + + if (!ywMaterialsOrderLog.getTaskStatus().equals(OrderStatus.DSQ.getCode())) { + throw new ServiceException("当前物资订单不是待申请状态,无法提交申请"); + } + + orderDto.setTaskStatus(OrderStatus.DSH.getCode()); + } + + } + + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + + if (ywMaterialsDTO.getIsBack().equals("是")) { + if (ywMaterialsDTO.getOpType().equals("驳回")) { + + if (!ywMaterialsOrderLog.getTaskStatus().equals(OrderStatus.DSQ.getCode())) { + throw new ServiceException("当前物资订单不是待申请状态,无法回滚到待审核"); + } + + //工作流驳回失败了,重新冻结上去 + boolean resBack = ywMaterialsStockService.freezeOutWayMaterialsStock(ywMaterialsDTO, ywMaterialsOrderLog); + + if (!resBack) { + throw new ServiceException("回滚驳回库存异常,需要人工处理"); + } + + if (ywMaterialsDTO.getIsBack().equals("是")) { + orderDto.setTaskStatus(OrderStatus.DSH.getCode()); + } + } + } + + if (ywMaterialsDTO.getOpType().equals("提交申请")) { + + if (!ywMaterialsOrderLog.getTaskStatus().equals(OrderStatus.DSH.getCode())) { + throw new ServiceException("当前物资订单不是待审核状态,无法回滚到待申请"); + } + + if (ywMaterialsDTO.getIsBack().equals("是")) { + orderDto.setTaskStatus(OrderStatus.DSQ.getCode()); + } + + } + + } + + res = ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); + +// if(!res) +// { +// //回滚释放库存的操作 +// throw new ServiceException("修改为待审核异常,驳回失败了"); +// } + + } + + //中心库审核任务通过就入库确认 + if (ywMaterialsDTO.getOpType().equals("审核任务")) { + if (ywMaterialsDTO.getOrderType() == OrderType.ZXK.getCode()) { + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + if (ywMaterialsDTO.getIsBack().equals("是")) { + res = ywMaterialsStockService.updateMaterialsStockBack(ywMaterialsDTO); + } + } + + //正向 + if (StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) { + res = ywMaterialsStockService.updateMaterialsStock(ywMaterialsDTO); + } + } else { + + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + if (ywMaterialsDTO.getIsBack().equals("是")) { + if(ywMaterialsDTO.getOrderType() == OrderType.SL.getCode() || ywMaterialsDTO.getOrderType() == OrderType.RK.getCode()) { + res = ywMaterialsStockService.updateFreezeOutWayMaterialsStockBack(ywMaterialsDTO); + } + + if(ywMaterialsDTO.getOrderType() == OrderType.TK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.CK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.DB.getCode()) { + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + orderDto.setOrderId(ywMaterialsDTO.getOrderId()); + orderDto.setOrderType(ywMaterialsDTO.getOrderType()); + orderDto.setTaskStatus(OrderStatus.DSH.getCode()); + res = ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); + } + + } + } + + //正向 + if (StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) { +// 申领和入库在审核环节释放库存 + if(ywMaterialsDTO.getOrderType() == OrderType.SL.getCode() || ywMaterialsDTO.getOrderType() == OrderType.RK.getCode()) { + res = ywMaterialsStockService.updateFreezeOutWayMaterialsStock(ywMaterialsDTO); + } +// 退库,出库,调拨存在出库环节,只需要更新下状态为ysh就可以 + if(ywMaterialsDTO.getOrderType() == OrderType.TK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.CK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.DB.getCode()) { + + YwMaterialsOrderLogDTO orderDto = new YwMaterialsOrderLogDTO(); + orderDto.setOrderId(ywMaterialsDTO.getOrderId()); + orderDto.setOrderType(ywMaterialsDTO.getOrderType()); + orderDto.setTaskStatus(OrderStatus.YSH.getCode()); + res = ywMaterialsOrderLogService.updateMaterialsOrderLogInner(orderDto); + } + + + + + } + + } + } + + if (ywMaterialsDTO.getOpType().equals("出库确认")) { + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + if (ywMaterialsDTO.getIsBack().equals("是")) { + if(ywMaterialsDTO.getOrderType() == OrderType.TK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.CK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.DB.getCode()) { + res = ywMaterialsStockService.updateFreezeOutWayMaterialsStock(ywMaterialsDTO); + } + else + { + return AjaxResult.error("当前步骤和任务状态不同步"); + } + } + } + + //正向 + if (StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) { + // 退库,出库和调拨在出库确认环节释放库存 + if(ywMaterialsDTO.getOrderType() == OrderType.TK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.CK.getCode() || ywMaterialsDTO.getOrderType() == OrderType.DB.getCode()) { + res = ywMaterialsStockService.updateFreezeOutWayMaterialsStock(ywMaterialsDTO); + } + else + { + return AjaxResult.error("当前步骤和任务状态不同步"); + } + } + + } + + if (ywMaterialsDTO.getOpType().equals("入库确认")) { + //回滚 + if (StringUtils.isNotEmpty(ywMaterialsDTO.getIsBack())) { + if (ywMaterialsDTO.getIsBack().equals("是")) { + res = ywMaterialsStockService.updateMaterialsStockBack(ywMaterialsDTO); + } + } + + //正向 + if (StringUtils.isEmpty(ywMaterialsDTO.getIsBack())) { + res = ywMaterialsStockService.updateMaterialsStock(ywMaterialsDTO); + } + } + + if (res) { + return AjaxResult.success("更新物资库存成功"); + } + + return AjaxResult.error("更新物资库存失败"); + + } + + + @ApiOperation("根据条件查询仓库的物资信息数据") + @PostMapping("/info/list") + public TableDataInfo info(@RequestBody YwMaterialsSearchDTO ywMaterialsSearchDTO) throws Exception { + String pageNum = ServletUtils.getParameter("pageNum"); + String pageSize = ServletUtils.getParameter("pageSize"); + if(!StringUtils.isEmpty(pageNum) && !StringUtils.isEmpty(pageSize)) { + startPage(); + } + return getDataTable(ywMaterialsInformService.selectMaterials(ywMaterialsSearchDTO)); + } + + @ApiOperation("获取所有物资信息数据") + @GetMapping("/info/list") + public AjaxResult InfoAll() throws Exception { + List list = ywMaterialsInformService.getMaterials(); + if(ObjectUtils.isNotEmpty(list)) { + return AjaxResult.success("获取物资信息数据成功", list); + } + return AjaxResult.error("获取物资信息数据失败"); + } + + + @Log(title = "新增物资信息数据", businessType = BusinessType.INSERT) + @ApiOperation("新增物资信息数据") + @PostMapping("/info/insert") + public AjaxResult insertInfo(@RequestBody YwMaterialsInformDTO ywMaterialsInformDTO) + { + + Boolean res = ywMaterialsInformService.insertMaterials(ywMaterialsInformDTO); + if(res) + { + return AjaxResult.success("新增物资信息数据成功"); + } + return AjaxResult.error("新增物资信息数据失败"); + + } + + @Log(title = "修改物资信息数据", businessType = BusinessType.UPDATE) + @ApiOperation("修改物资信息数据") + @PostMapping("/info/update") + public AjaxResult updateInfo(@RequestBody YwMaterialsInformDTO ywMaterialsInformDTO) + { + Boolean res = ywMaterialsInformService.updateMaterials(ywMaterialsInformDTO); + if(res) + { + return AjaxResult.success("修改物资信息数据成功"); + } + return AjaxResult.error("修改物资信息数据失败"); + + } + + + @ApiOperation("查询所有大小类") + @GetMapping("/classes/list") + public AjaxResult list() throws Exception { + + Map map = ywMaterialsClassesService.GetMaterialsClasses(); + if(ObjectUtils.isNotEmpty(map)) { + return AjaxResult.success("获取大小类数据成功", map); + } + + return AjaxResult.error("获取大小类数据失败"); + } + + @Log(title = "新增申领数据", businessType = BusinessType.INSERT) + @ApiOperation("新增申领数据") + @PostMapping("/batch/insert") + public AjaxResult insertBatch(@RequestBody YwMaterialsBatchDTO ywMaterialsBatchDTO) { + + boolean res = ywMaterialsBatchService.insertBatch(ywMaterialsBatchDTO); + + if(res) + { + return AjaxResult.success("新增申领数据成功"); + } + + return AjaxResult.error("新增申领数据失败"); + + } + + @Log(title = "修改申领数据", businessType = BusinessType.UPDATE) + @ApiOperation("修改申领数据") + @PostMapping("/batch/update") + public AjaxResult updateBatch(@RequestBody YwMaterialsBatch ywMaterialsBatch) { + + boolean res = ywMaterialsBatchService.updateBatch(ywMaterialsBatch); + + if(res) + { + return AjaxResult.success("修改申领数据成功"); + } + + return AjaxResult.error("修改申领数据失败"); + + } + + @Log(title = "删除申领数据", businessType = BusinessType.DELETE) + @ApiOperation("删除申领数据") + @PostMapping("/batch/delete") + public AjaxResult deleteBatch(@RequestBody YwMaterialsBatchDTO ywMaterialsBatchDTO) + { + + boolean res = ywMaterialsBatchService.deleteBatch(ywMaterialsBatchDTO); + + if(res) + { + return AjaxResult.success("删除申领数据成功"); + } + return AjaxResult.error("删除申领数据失败"); + } + + @ApiOperation("查询物资申领数据") + @PostMapping("/batch/list") + public TableDataInfo getBatch(@RequestBody YwMaterialsBatchDTO ywMaterialsBatchDTO) + { + if(StringUtils.isEmpty(ywMaterialsBatchDTO.getOrderId())) + { + throw new ServiceException("订单编号不允许为空"); + } + String pageNum = ServletUtils.getParameter("pageNum"); + String pageSize = ServletUtils.getParameter("pageSize"); + if(!StringUtils.isEmpty(pageNum) && !StringUtils.isEmpty(pageSize)) { + startPage(); + } + return getDataTable(ywMaterialsBatchMapper.selectBatch(ywMaterialsBatchDTO.getOrderId())); + } + + @Log(title = "新增物资串码数据", businessType = BusinessType.INSERT) + @ApiOperation("新增物资串码数据") + @PostMapping("/snList/insert") + public AjaxResult insertBatch(@RequestBody YwMaterialsSnListDTO ywMaterialsSnListDTO) { + + List roles = SecurityUtils.getLoginUser().getUser().getRoles(); + + List filterRoles = roles.stream().filter(e -> "venuestoragekeeper".equals(e.getRoleKey()) || "centerstoragechecker".equals(e.getRoleKey())).collect(Collectors.toList()); + + if(filterRoles!=null) { + if (filterRoles.isEmpty()) { + return AjaxResult.error("当前用户没有操作的权限"); + } + } + + boolean res = ywMaterialsSnListService.insertSnList(ywMaterialsSnListDTO); + + if(res) + { + return AjaxResult.success("新增串码数据成功"); + } + + return AjaxResult.error("新增串码数据失败"); + + } + + @ApiOperation("查询物资串码数据") + @PostMapping("/snList/list") + public TableDataInfo getSnList(@RequestBody YwMaterialsSnListQO ywMaterialsSnListQO) + { + String pageNum = ServletUtils.getParameter("pageNum"); + String pageSize = ServletUtils.getParameter("pageSize"); + if(!StringUtils.isEmpty(pageNum) && !StringUtils.isEmpty(pageSize)) { + startPage(); + } + return getDataTable(ywMaterialsSnListService.selectSnList(ywMaterialsSnListQO)); + } + +} + diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsInformController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsInformController.java new file mode 100644 index 0000000..c6b2b68 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsInformController.java @@ -0,0 +1,164 @@ +package com.ruoyi.app.controller.cmcc_gm; + + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.cmcc_gm.domain.YwMaterialsInform; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSearchDTO; +import com.ruoyi.cmcc_gm.service.YwMaterialsInformService; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.util.List; + +/** + * 物资信息表(YwMaterialsInform)表控制层 + * + * @author lee + * @since 2023-04-14 16:35:17 + */ +@Api("物料信息") +@RestController +@RequestMapping("/app/ywMaterialsInform") +public class YwMaterialsInformController extends BaseController { + + /** + * 服务对象 + */ + @Resource + private YwMaterialsInformService ywMaterialsInformService; + + /** + * 分页查询所有数据 + * + * @param ywMaterialsInform 查询实体 + * @return 所有数据 + */ + @ApiOperation("分页查询") + @PostMapping("/list") + public TableDataInfo selectAll(@RequestBody YwMaterialsSearchDTO ywMaterialsInform) { + PageUtils.startPage(ywMaterialsInform, YwMaterialsSearchDTO.class); + return getDataTable(ywMaterialsInformService.getMaterialsBySearch(ywMaterialsInform)); + } + + /** + * 导出 + * @param ywMaterialsInform + */ + @ApiOperation("导出") + @PostMapping("/export") + public void exportRd(@RequestBody YwMaterialsSearchDTO ywMaterialsInform) { + PageUtils.startPage(ywMaterialsInform, YwMaterialsSearchDTO.class); + List list = ywMaterialsInformService.getMaterialsBySearch(ywMaterialsInform); + ExcelUtil util = new ExcelUtil<>(YwMaterialsInform.class); + util.hideColumn("sum", "reason"); + util.exportExcel(list, "物资信息导出"); + } + + /** + * 通过主键查询单条数据 + * + * @param id 主键 + * @return 单条数据 + */ + @ApiOperation("根据id查询") + @GetMapping("{id}") + public AjaxResult selectOne(@PathVariable Serializable id) { + return AjaxResult.success(this.ywMaterialsInformService.getById(id)); + } + + /** + * 新增数据 + * + * @param ywMaterialsInform 实体对象 + * @return 新增结果 + */ + @ApiOperation("插入") + @PostMapping + public AjaxResult insert(@RequestBody YwMaterialsInform ywMaterialsInform) { + + //检查物资编号是否已经存在 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(YwMaterialsInform::getMaterialCode, ywMaterialsInform.getMaterialCode()); + + YwMaterialsInform inform = ywMaterialsInformService.getOne(query); + + if (ObjectUtils.isNotEmpty(inform)) { + throw new ServiceException("物资编号已存在"); + } + + boolean res = this.ywMaterialsInformService.save(ywMaterialsInform); + if(res) + { + ywMaterialsInformService.loadingMaterialsInfoCache(); + } + return AjaxResult.success(res); + } + + /** + * 修改数据 + * + * @param ywMaterialsInform 实体对象 + * @return 修改结果 + */ + @ApiOperation("更新") + @PutMapping + public AjaxResult update(@RequestBody YwMaterialsInform ywMaterialsInform) { + + if (ObjectUtils.isEmpty(ywMaterialsInform.getMaterialCode())) { + throw new ServiceException("物资编号不为空"); + } + + boolean res = this.ywMaterialsInformService.updateById(ywMaterialsInform); + if(res) + { + ywMaterialsInformService.loadingMaterialsInfoCache(); + } + return AjaxResult.success(); + } + + /** + * 删除数据 + * + * @param idList 主键结合 + * @return 删除结果 + */ + @ApiOperation("删除") + @DeleteMapping + public AjaxResult delete(@RequestParam("idList") List idList) { + boolean res = this.ywMaterialsInformService.removeByIds(idList); + if(res) + { + ywMaterialsInformService.loadingMaterialsInfoCache(); + } + return AjaxResult.success(); + } + + /** + * 导入 + * + * @param file excel + * @return + * @throws Exception + */ + @ApiOperation("导入") + @PostMapping("/import") + public AjaxResult doImport(@RequestPart(name = "file") MultipartFile file) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwMaterialsInform.class); + util.hideColumn("sum"); + List informs = util.importExcel(file.getInputStream()); + return ywMaterialsInformService.doImport(informs); + } + +} + diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsOrderLogController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsOrderLogController.java new file mode 100644 index 0000000..5e4b052 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/cmcc_gm/YwMaterialsOrderLogController.java @@ -0,0 +1,176 @@ +package com.ruoyi.app.controller.cmcc_gm; + + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.cmcc_gm.common.enums.OrderType; +import com.ruoyi.cmcc_gm.domain.YwMaterialsStock; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsOrderLogDTO; +import com.ruoyi.cmcc_gm.domain.dto.YwMaterialsSearchDTO; +import com.ruoyi.cmcc_gm.service.YwMaterialsOrderLogService; +import com.ruoyi.cmcc_gm.service.YwMaterialsStockService; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.mapper.YwSceneMapper; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; + +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 物资工单日志表 前端控制器 + *

+ * + * @author jkj + * @since 2023-04-07 + */ +@RestController +@RequestMapping("/app/ywMaterialsOrderLog") +public class YwMaterialsOrderLogController extends BaseController { + + @Autowired + private YwMaterialsOrderLogService ywMaterialsOrderLogService; + + @Autowired + private YwSceneMapper ywSceneMapper; + + + @Log(title = "新增物资日志记录", businessType = BusinessType.INSERT) + @ApiOperation("新增物资日志记录") + @PostMapping("/insert") + public AjaxResult insert(@RequestBody YwMaterialsOrderLogDTO ywMaterialsOrderLogDTO) + { + try + { + String res = ywMaterialsOrderLogService.insertMaterialsOrderLog(ywMaterialsOrderLogDTO); + + if(StringUtils.isNotEmpty(res)) + { + return AjaxResult.success("新增物资工单日志成功",res); + } + + return AjaxResult.error("新增物资工单日志失败"); + + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + + } + + @Log(title = "修改物资日志记录", businessType = BusinessType.UPDATE) + @ApiOperation("修改物资日志记录") + @PostMapping("/update") + public AjaxResult update(@RequestBody YwMaterialsOrderLogDTO ywMaterialsOrderLogDTO) + { + try + { + boolean res = ywMaterialsOrderLogService.updateMaterialsOrderLog(ywMaterialsOrderLogDTO); + if(res) + { + return AjaxResult.success("修改物资日志记录成功"); + } + + return AjaxResult.error("修改物资日志记录失败"); + + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + + } + + @Log(title = "删除物资日志记录", businessType = BusinessType.DELETE) + @ApiOperation("删除物资日志记录") + @PostMapping("/delete") + public AjaxResult remove(@RequestBody YwMaterialsOrderLogDTO ywMaterialsOrderLogDTO) + { + try + { + boolean res = ywMaterialsOrderLogService.deleteMaterialsOrderLog(ywMaterialsOrderLogDTO); + if(res) + { + return AjaxResult.success("删除物资日志记录成功"); + } + + return AjaxResult.error("删除物资日志记录失败"); + + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + } + + + @ApiOperation("获取物资日志记录") + @PostMapping("/list") + @RepeatSubmit(enable = false,interval = 1000) + public TableDataInfo list(@RequestBody YwMaterialsSearchDTO ywMaterialsSearchDTO) throws Exception { +// TableDataInfo resData = ywMaterialsOrderLogService.getMaterialsOrderLog(ywMaterialsSearchDTO); +// return getDataTable(resData.getRows(), resData.getTotal()); + + if(ObjectUtils.isEmpty(ywMaterialsSearchDTO.getOrderType())) + { + throw new ServiceException("工单类型不能为空"); + } + +// if(ObjectUtils.isEmpty(ywMaterialsSearchDTO.getInStoreId()) || ObjectUtils.isEmpty(ywMaterialsSearchDTO.getOutStoreId())) +// { +// throw new ServiceException("入库ID和出库ID不允许为空"); +// } + + //中心库和调拨不需要当前用户的所属场馆 + if(!(ywMaterialsSearchDTO.getOrderType() == OrderType.ZXK.getCode() || ywMaterialsSearchDTO.getOrderType() == OrderType.DB.getCode())) { + if (ObjectUtils.isNotEmpty(ywMaterialsSearchDTO.getInStoreId()) && ObjectUtils.isNotEmpty(ywMaterialsSearchDTO.getOutStoreId())) { + if (ywMaterialsSearchDTO.getInStoreId() == -2 || ywMaterialsSearchDTO.getOutStoreId() == -2) { + SysUser user = getLoginUser().getUser(); + if (!(user.isAdmin(user) || user.isCenter(user))) { + List list = ywSceneMapper.getVenueByUserId(user.getUserId()); + if(list.size()>0) { + List lstIds = list.stream().map(x -> x.getId()).collect(Collectors.toList()); + Long[] arr_ids = lstIds.toArray(new Long[lstIds.size()]); + if (ywMaterialsSearchDTO.getInStoreId() == -2) { + ywMaterialsSearchDTO.setInStoreIds(arr_ids); + ywMaterialsSearchDTO.setInStoreId(null); + } + if (ywMaterialsSearchDTO.getOutStoreId() == -2) { + ywMaterialsSearchDTO.setOutStoreIds(arr_ids); + ywMaterialsSearchDTO.setOutStoreId(null); + } + } + } + else + { + if (ywMaterialsSearchDTO.getInStoreId() == -2) { + ywMaterialsSearchDTO.setInStoreId(null); + } + if (ywMaterialsSearchDTO.getOutStoreId() == -2) { + ywMaterialsSearchDTO.setOutStoreId(null); + } + } + } + } + } + startPage(); + return getDataTable(ywMaterialsOrderLogService.selectMaterialsOrderLog(ywMaterialsSearchDTO)); + } + +} + diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/common/CaptchaController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/common/CaptchaController.java new file mode 100644 index 0000000..551a429 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/common/CaptchaController.java @@ -0,0 +1,94 @@ +package com.ruoyi.app.controller.common; + +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import javax.annotation.Resource; +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.FastByteArrayOutputStream; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import com.google.code.kaptcha.Producer; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.utils.sign.Base64; +import com.ruoyi.common.utils.uuid.IdUtils; +import com.ruoyi.system.service.ISysConfigService; + +/** + * 验证码操作处理 + * + * @author ruoyi + */ +@RestController +public class CaptchaController +{ + @Resource(name = "captchaProducer") + private Producer captchaProducer; + + @Resource(name = "captchaProducerMath") + private Producer captchaProducerMath; + + @Autowired + private RedisCache redisCache; + + @Autowired + private ISysConfigService configService; + /** + * 生成验证码 + */ + @GetMapping("/captchaImage") + public AjaxResult getCode(HttpServletResponse response) throws IOException + { + AjaxResult ajax = AjaxResult.success(); + boolean captchaEnabled = configService.selectCaptchaEnabled(); + ajax.put("captchaEnabled", captchaEnabled); + if (!captchaEnabled) + { + return ajax; + } + + // 保存验证码信息 + String uuid = IdUtils.simpleUUID(); + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; + + String capStr = null, code = null; + BufferedImage image = null; + + // 生成验证码 + String captchaType = RuoYiConfig.getCaptchaType(); + if ("math".equals(captchaType)) + { + String capText = captchaProducerMath.createText(); + capStr = capText.substring(0, capText.lastIndexOf("@")); + code = capText.substring(capText.lastIndexOf("@") + 1); + image = captchaProducerMath.createImage(capStr); + } + else if ("char".equals(captchaType)) + { + capStr = code = captchaProducer.createText(); + image = captchaProducer.createImage(capStr); + } + + redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + // 转换流信息写出 + FastByteArrayOutputStream os = new FastByteArrayOutputStream(); + try + { + ImageIO.write(image, "jpg", os); + } + catch (IOException e) + { + return AjaxResult.error(e.getMessage()); + } + + ajax.put("uuid", uuid); + ajax.put("img", Base64.encode(os.toByteArray())); + return ajax; + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/common/CommonController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/common/CommonController.java new file mode 100644 index 0000000..b4ac436 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/common/CommonController.java @@ -0,0 +1,229 @@ +package com.ruoyi.app.controller.common; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.common.core.domain.dto.HandleDataDTO; +import com.ruoyi.common.core.domain.dto.TaskDTO; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.dto.WorkFlowDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwWireTaskLogDTO; +import com.ruoyi.eastcom_yw.domain.enums.TaskNameWithRoleEnum; +import com.ruoyi.eastcom_yw.service.CommonService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.system.service.ISysRoleService; +import com.ruoyi.system.service.ISysUserService; +import io.swagger.annotations.ApiOperation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.FileUploadUtils; +import com.ruoyi.common.utils.file.FileUtils; +import com.ruoyi.framework.config.ServerConfig; + +/** + * 通用请求处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/app/common") +public class CommonController { + private static final Logger log = LoggerFactory.getLogger(CommonController.class); + + @Autowired + private ServerConfig serverConfig; + + @Autowired + private CommonService commonService; + + @Autowired + private ISysUserService sysUserService; + + @Autowired + private ISysRoleService sysRoleService; + + @Autowired + private YwSceneService yw_sceneService; + + private static final String FILE_DELIMETER = ","; + + /** + * 通用下载请求 + * + * @param fileName 文件名称 + * @param delete 是否删除 + */ + @GetMapping("/download") + public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) { + try { + if (!FileUtils.checkAllowDownload(fileName)) { + throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName)); + } + String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1); + String filePath = RuoYiConfig.getDownloadPath() + fileName; + + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, realFileName); + FileUtils.writeBytes(filePath, response.getOutputStream()); + if (delete) { + FileUtils.deleteFile(filePath); + } + } catch (Exception e) { + log.error("下载文件失败", e); + } + } + + /** + * 自定义 Minio 服务器上传请求 + */ + @PostMapping("/uploadMinio") + public AjaxResult uploadFileMinio(MultipartFile file) throws Exception { + try { + // 上传并返回新文件名称 + String fileName = FileUploadUtils.uploadMinio(file); + AjaxResult ajax = AjaxResult.success(); + ajax.put("url", fileName); + ajax.put("fileName", fileName); + ajax.put("newFileName", FileUtils.getName(fileName)); + ajax.put("originalFilename", file.getOriginalFilename()); + return ajax; + } catch (Exception e) { + return AjaxResult.error(e.getMessage()); + } + } + + /** + * 通用上传请求(单个) + */ + @PostMapping("/upload") + public AjaxResult uploadFile(MultipartFile file) throws Exception { + try { + // 上传文件路径 + String filePath = RuoYiConfig.getUploadPath(); + // 上传并返回新文件名称 + String fileName = FileUploadUtils.upload(filePath, file); + String url = serverConfig.getUrl() + fileName; + AjaxResult ajax = AjaxResult.success(); + ajax.put("url", url); + ajax.put("fileName", fileName); + ajax.put("newFileName", FileUtils.getName(fileName)); + ajax.put("originalFilename", file.getOriginalFilename()); + return ajax; + } catch (Exception e) { + return AjaxResult.error(e.getMessage()); + } + } + + /** + * 通用上传请求(多个) + */ + @PostMapping("/uploads") + public AjaxResult uploadFiles(List files) throws Exception { + try { + // 上传文件路径 + String filePath = RuoYiConfig.getUploadPath(); + List urls = new ArrayList(); + List fileNames = new ArrayList(); + List newFileNames = new ArrayList(); + List originalFilenames = new ArrayList(); + for (MultipartFile file : files) { + // 上传并返回新文件名称 + String fileName = FileUploadUtils.upload(filePath, file); + String url = serverConfig.getUrl() + fileName; + urls.add(url); + fileNames.add(fileName); + newFileNames.add(FileUtils.getName(fileName)); + originalFilenames.add(file.getOriginalFilename()); + } + AjaxResult ajax = AjaxResult.success(); + ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER)); + ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER)); + ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER)); + ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER)); + return ajax; + } catch (Exception e) { + return AjaxResult.error(e.getMessage()); + } + } + + /** + * 本地资源通用下载 + */ + @GetMapping("/download/resource") + public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) + throws Exception { + try { + if (!FileUtils.checkAllowDownload(resource)) { + throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource)); + } + // 本地资源路径 + String localPath = RuoYiConfig.getProfile(); + // 数据库资源地址 + String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX); + // 下载名称 + String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, downloadName); + FileUtils.writeBytes(downloadPath, response.getOutputStream()); + } catch (Exception e) { + log.error("下载文件失败", e); + } + } + + @ApiOperation("查看节点详情") + @PostMapping("/taskInfo") + public AjaxResult getTaskInfo(@RequestBody WorkFlowDTO workFlowDTO) throws Exception { + HandleDataDTO handleDataDTO = new HandleDataDTO(); + handleDataDTO.setProcessInstanceId(workFlowDTO.getProcessInstanceId()); + handleDataDTO.setTaskName(workFlowDTO.getTaskName()); + JSONObject taskInfo = commonService.getTaskInfo(handleDataDTO); + String taskId = taskInfo.getString("taskId"); + String venueId = taskInfo.getString("venueId"); + String assignee = taskInfo.getString("assignee"); + String createTime = taskInfo.getString("createTime"); + String endTime = taskInfo.getString("endTime"); + String nickName = ""; + if (StrUtil.isNotBlank(assignee)) { + SysUser user = sysUserService.selectAllUserById(Long.valueOf(assignee)); + if(ObjectUtils.isNotEmpty(user)) + { + nickName = user.getNickName(); + } + } + String taskName = workFlowDTO.getTaskName(); + Long[] roleIds = TaskNameWithRoleEnum.getRoleId(taskName); + List sysUsers=new ArrayList<>(); + if (StrUtil.isNotBlank(venueId)) { + sysUsers = sysUserService.selectUserByRoleIdsAndSceneId(roleIds, Long.valueOf(venueId)); + } + AjaxResult ajax = AjaxResult.success(); + ajax.put("taskId", taskId); + ajax.put("assignee", assignee); + ajax.put("nickName", nickName); + ajax.put("createTime", createTime); + ajax.put("endTime", endTime); + ajax.put("role", TaskNameWithRoleEnum.getRoleName(taskName)); + ajax.put("sysUserList", sysUsers); + + return ajax; + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/AppBaseStationController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/AppBaseStationController.java new file mode 100644 index 0000000..84a43ae --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/AppBaseStationController.java @@ -0,0 +1,58 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.domain.dto.MmlObjectDTO; +import com.ruoyi.eastcom_yw.service.OpenApiService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import io.swagger.annotations.Api; +import lombok.RequiredArgsConstructor; +import lombok.Synchronized; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.util.List; + +/** + * @author yqf + * @date 2023/6/5 + */ +@Api("app基站信息接口") +@RestController +@RequestMapping("/app/baseStation") +@Slf4j +@RequiredArgsConstructor +public class AppBaseStationController extends BaseController { + + private final YwSceneService ywSceneService; + private final OpenApiService openApiService; + + + /** + * 获取场馆json数据 + * + * @return + */ + @GetMapping(value = "/getJsonBySceneId") + public void getJsonBySceneId(@RequestParam Long sceneId, HttpServletRequest request, HttpServletResponse response) { + try { + ywSceneService.getJsonBySceneId(sceneId,response); + } catch (Exception ex) { + ex.printStackTrace(); + } + + } + + /** + * 基站MML查询 + * + * @return + */ + @PostMapping(value = "/geMsgByMML") + public AjaxResult geMsgByMML(@RequestBody MmlObjectDTO mmlObjectDTO) { + return openApiService.getMsgByMML(mmlObjectDTO); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/AppKpiController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/AppKpiController.java new file mode 100644 index 0000000..5e8c5c3 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/AppKpiController.java @@ -0,0 +1,200 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.eastcom_yw.common.constant.KpiConstants; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiCellQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiMinQO; +import com.ruoyi.eastcom_yw.domain.qo.PmKpiVenueQO; +import com.ruoyi.eastcom_yw.domain.vo.*; +import com.ruoyi.eastcom_yw.service.*; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author yqf + * @date 2023/4/11 + */ +@Api("app性能指标") +@RestController +@RequestMapping("/app/kpi") +@Slf4j +@RequiredArgsConstructor +public class AppKpiController extends BaseController { + + private final PmKpi4gVenueService pmKpi4gVenueService; + + private final PmKpi5gVenueService pmKpi5gVenueService; + + private final PmKpi5gCellService pmKpi5gCellService; + + private final PmKpi4gCellService pmKpi4gCellService; + + private final PmKpi4gMinService pmKpi4gMinService; + + private final PmKpi5gMinService pmKpi5gMinService; + + private final YwSceneService ywSceneService; + + /** + * 场馆级15分钟指标分页列表 + */ + @ApiOperation(value = "场馆级15分钟指标分页列表", notes = "场馆级15分钟指标分页列表") + @RequestMapping(value = "getVeueList", method = RequestMethod.POST) + public TableDataInfo getVeueList(@Validated @RequestBody PmKpiVenueQO qo) { + if(null == qo.getVenueIds() || null == qo.getVenueId()){ + SysUser user = SecurityUtils.getLoginUser().getUser(); + //场馆集合 + if (!user.isAdmin(user)) { + List ywScenes = ywSceneService.getVenueByUser(user); + Long[] venueIds = ywScenes.stream().map(YwScene::getId).toArray(Long[]::new); + Integer[] sceneIds = new Integer[venueIds.length]; + for (int i = 0; i < venueIds.length; i++) { + sceneIds[i] = venueIds[i].intValue(); + } + qo.setVenueIds(sceneIds); + } + } + if (qo.getNetType().equals(KpiConstants.YW_NETTYPE_4G)) { + IPage page = pmKpi4gVenueService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } else { + IPage page = pmKpi5gVenueService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } + } + + /** + * 场馆小区级15分钟指标分页列表 + */ + @ApiOperation(value = "场馆小区级15分钟指标分页列表", notes = "场馆小区级15分钟指标分页列表") + @RequestMapping(value = "getFifteenList", method = RequestMethod.POST) + public TableDataInfo getFifteenList(@Validated @RequestBody PmKpiCellQO qo) { + if(null == qo.getVenueIds() || null == qo.getVenueid()){ + SysUser user = SecurityUtils.getLoginUser().getUser(); + //场馆集合 +// List ywScenes = ywSceneService.getVenueByUser(user); +// Long[] venueIds = ywScenes.stream().map(YwScene::getId).toArray(Long[]::new); +// Integer[] sceneIds = new Integer[venueIds.length]; +// for (int i = 0; i < venueIds.length; i++) { +// sceneIds[i] = venueIds[i].intValue(); +// } +// qo.setVenueIds(sceneIds); + List lstScene = ywSceneService.getVenueByUserCanNoData(user,false); + if(!lstScene.isEmpty()) + { + Long[] venueIds = lstScene.stream().map(YwScene::getId).toArray(Long[]::new); + Integer[] sceneIds = new Integer[venueIds.length]; + for (int i = 0; i < venueIds.length; i++) { + sceneIds[i] = venueIds[i].intValue(); + } + qo.setVenueIds(sceneIds); + } + } + if (qo.getNetType().equals(KpiConstants.YW_NETTYPE_4G)) { + if(null == qo.getSortcol() || qo.getSortcol().equals("")){ + qo.setSortcol("starttime"); + } + if(null == qo.getSort() || qo.getSort().equals("")){ + qo.setSortcol("desc"); + } + IPage page = pmKpi4gCellService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } else { + if(null == qo.getSortcol() || qo.getSortcol().equals("")){ + qo.setSortcol("starttime"); + } + if(null == qo.getSort() || qo.getSort().equals("")){ + qo.setSortcol("desc"); + } + IPage page = pmKpi5gCellService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } + } + + + /** + * 场馆小区级1分钟指标分页列表 + */ + @ApiOperation(value = "场馆小区级1分钟指标分页列表", notes = "场馆小区级1分钟指标分页列表") + @RequestMapping(value = "getOneMinList", method = RequestMethod.POST) + public TableDataInfo getOneMinList(@Validated @RequestBody PmKpiMinQO qo) { + if(null == qo.getVenueIds() || null == qo.getVenueid()){ + SysUser user = SecurityUtils.getLoginUser().getUser(); + //场馆集合 + if (!user.isAdmin(user)) { + List ywScenes = ywSceneService.getVenueByUser(user); + Long[] venueIds = ywScenes.stream().map(YwScene::getId).toArray(Long[]::new); + Integer[] sceneIds = new Integer[venueIds.length]; + for (int i = 0; i < venueIds.length; i++) { + sceneIds[i] = venueIds[i].intValue(); + } + qo.setVenueIds(sceneIds); + } + } + + if (qo.getNetType().equals(KpiConstants.YW_NETTYPE_4G)) { + if(null == qo.getSortcol() || qo.getSortcol().equals("")){ + qo.setSortcol("时间"); + } + if(null == qo.getSort() || qo.getSort().equals("")){ + qo.setSortcol("desc"); + } + IPage page = pmKpi4gMinService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } else { + if(null == qo.getSortcol() || qo.getSortcol().equals("")){ + qo.setSortcol("时间"); + } + if(null == qo.getSort() || qo.getSort().equals("")){ + qo.setSortcol("desc"); + } + IPage page = pmKpi5gMinService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } + } + + + /** + * 获取4G最新有数据的时间 + * + * @return + */ + @GetMapping(value = "/getLastTime") + public AjaxResult getLastTime(@RequestParam String type){ + Integer[] sceneIds = null; + Map lastTime = new HashMap<>(); + + SysUser user = SecurityUtils.getLoginUser().getUser(); + //场馆集合 + if (!user.isAdmin(user)) { + List ywScenes = ywSceneService.getVenueByUser(user); + Long[] venueIds = ywScenes.stream().map(YwScene::getId).toArray(Long[]::new); + sceneIds = new Integer[venueIds.length]; + for (int i = 0; i < venueIds.length; i++) { + sceneIds[i] = venueIds[i].intValue(); + } + } + if(type.equals("4G")){ + lastTime = pmKpi4gVenueService.get4gVenueLastTime(sceneIds); + }else { + lastTime = pmKpi5gVenueService.get5gVenueLastTime(sceneIds); + } + return success(lastTime); + + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/AppVersionController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/AppVersionController.java new file mode 100644 index 0000000..55b585b --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/AppVersionController.java @@ -0,0 +1,30 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.eastcom_yw.domain.AppVersionConfig; +import com.ruoyi.eastcom_yw.service.AppVersionService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@Api("app版本更新管理") +@RestController +@RequestMapping("/app/version") +public class AppVersionController extends BaseController { + + @Autowired + private AppVersionService appVersionService; + + @ApiOperation("获取更新配置") + @GetMapping("/config") + public TableDataInfo getConfig() { + List list = appVersionService.list(); + return getDataTable(list, (long) list.size()); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/PersonalCenterController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/PersonalCenterController.java new file mode 100644 index 0000000..6245b04 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/PersonalCenterController.java @@ -0,0 +1,142 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import cn.hutool.core.util.StrUtil; +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysAppMenu; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.system.mapper.SysUserMapper; +import com.ruoyi.system.service.ISysAppMenuService; +import com.ruoyi.system.service.ISysDictDataService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@RestController +@RequestMapping("/app/personalCenter") +public class PersonalCenterController extends BaseController { + + @Resource + private ISysAppMenuService appMenuService; + + @Autowired + private YwSceneService yw_sceneService; + + + + @Autowired + private ISysDictDataService dictDataService; + + /** + * 根据当前登录用户拥有权限获取更多中菜单列表(sys_app_menu) + */ + @GetMapping("/list") + public AjaxResult list(SysAppMenu menu) { + menu.setVisible("0"); + List menus = appMenuService.selectMenuList(menu, getUserId()); + //新增用户是否已添加应用标记 + List customMenus = appMenuService.selectCustomList(getUserId()); + for (SysAppMenu sysAppMenu : menus) { + for (SysAppMenu customMenu : customMenus) { + if (customMenu.getMenuId().equals(sysAppMenu.getMenuId())) { + sysAppMenu.setIsAdd(1); + } + } + } + + + List tree = appMenuService.buildMenuTree(menus); + return success(tree); + } + + /** + * 获取个人定制菜单列表(sys_app_user_menu) + */ + @GetMapping("/customList") + @RepeatSubmit(enable = false, interval = 1000) + public AjaxResult customList() { + //获取用户自定义展示菜单 + List menus = appMenuService.selectCustomList(getUserId()); + return success(menus); + } + + /** + * 更改个人定制菜单列表(sys_app_user_menu) + */ + @PostMapping("/updateCustomList") + public AjaxResult updateCustomList(@RequestBody List menuIds) { + appMenuService.updateCustomList(getUserId(), menuIds); + return success(); + } + + /** + * 获取当前登录用户场馆 + */ + @GetMapping("/getYwScene") + @RepeatSubmit(enable = false, interval = 1000) + public AjaxResult getYwScene(@RequestParam(required = false) String cityId, @RequestParam(required = false) String countyId) { + SysUser user = SecurityUtils.getLoginUser().getUser(); + //场馆集合 + List ywScenes = yw_sceneService.getVenueByUser(user); + if (StrUtil.isNotBlank(cityId)) { + ywScenes = ywScenes.stream().filter(l -> cityId.equals(l.getCityId())).collect(Collectors.toList()); + } + if (StrUtil.isNotBlank(countyId)) { + ywScenes = ywScenes.stream().filter(l -> countyId.equals(l.getAreaCountyId())).collect(Collectors.toList()); + } + return success(ywScenes); + } + + /** + * 获取当前登录区县 + */ + @GetMapping("/getCounty") + @RepeatSubmit(enable = false, interval = 1000) + public AjaxResult getCounty(@RequestParam String cityId) { + SysUser user = SecurityUtils.getLoginUser().getUser(); + if (SecurityUtils.isAdmin(user.getUserId())) { + List countyList = dictDataService.selectDictLabelByValues("yw_county", null); + countyList = countyList.stream().filter(l -> cityId.equals(l.getDictValue().substring(0, 4))).collect(Collectors.toList()); + return success(countyList); + } + //场馆集合 + List ywScenes = yw_sceneService.getVenueByUser(user); + //区县集合 + List countyIds = ywScenes.stream().map(YwScene::getAreaCountyId).filter(Objects::nonNull).distinct().collect(Collectors.toList()); + List countyList = dictDataService.selectDictLabelByValues("yw_county", countyIds); + + if (StrUtil.isNotBlank(cityId)) { + countyList = countyList.stream().filter(l -> cityId.equals(l.getDictValue().substring(0, 4))).collect(Collectors.toList()); + } + return success(countyList); + } + + /** + * 获取当前登录用户地市 + */ + @GetMapping("/getCity") + @RepeatSubmit(enable = false, interval = 1000) + public AjaxResult getCity() { + SysUser user = SecurityUtils.getLoginUser().getUser(); + if (SecurityUtils.isAdmin(user.getUserId())) { + return success(dictDataService.selectDictLabelByValues("yw_city", null)); + } + //场馆集合 + List ywScenes = yw_sceneService.getVenueByUser(user); + //区县集合 + List countyIds = ywScenes.stream().map(YwScene::getAreaCountyId).filter(Objects::nonNull).distinct().collect(Collectors.toList()); + //地市集合 + List cityIds = countyIds.stream().map(l -> l.substring(0, 4)).distinct().collect(Collectors.toList()); + List cityList = dictDataService.selectDictLabelByValues("yw_city", cityIds); + return success(cityList); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/SysNoticeController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/SysNoticeController.java new file mode 100644 index 0000000..b3b827e --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/SysNoticeController.java @@ -0,0 +1,124 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.SysNotice; +import com.ruoyi.eastcom_yw.domain.dto.SysNoticeDTO; +import com.ruoyi.eastcom_yw.domain.qo.SysNoticeQO; +import com.ruoyi.eastcom_yw.domain.vo.SysNoticeVO; +import com.ruoyi.eastcom_yw.service.SysNoticeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + *

+ * 通知公告表 前端控制器 + *

+ * + * @author ck + * @since 2023-04-14 + */ +@Api(tags = "通知公告表") +@RestController +@RequestMapping("/app/sysNotice") +@Slf4j +@RequiredArgsConstructor +public class SysNoticeController extends BaseController { + + private final SysNoticeService sysNoticeService; + + /** + * 通知公告表列表 + */ + @ApiOperation(value = "通知公告表列表", notes = "通知公告表列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody SysNoticeQO qo) { + List list = sysNoticeService.getData(qo); + return getDataTable(list); + } + + + /** + * 通知公告表分页列表 + */ + @ApiOperation(value = "通知公告表分页列表", notes = "通知公告表分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody SysNoticeQO qo) { + IPage page = sysNoticeService.getDataByPage(qo); + return getDataTable(page.getRecords(), page.getTotal()); + } + + /** + * 获取通知公告表详情 + */ + @ApiOperation(value = "通知公告表详情", notes = "通知公告表详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(sysNoticeService.fetchById(id)); + } + + /** + * 新增或修改通知公告表 + */ + @Log(title = "新增或修改通知公告表", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改通知公告表", notes = "新增或修改通知公告表") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated SysNoticeDTO dto) { + sysNoticeService.saveOrUpdate(dto); + return AjaxResult.success(); + } + + /** + * 根据id删除通知公告表 + */ + @Log(title = "根据id删除通知公告表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除通知公告表", notes = "根据id删除通知公告表") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + sysNoticeService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除通知公告表 + */ + @Log(title = "根据id批量删除通知公告表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除通知公告表", notes = "根据id批量删除通知公告表") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + sysNoticeService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "通知公告表导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(SysNotice.class); + List list = util.importExcel(file.getInputStream()); + sysNoticeService.importData(list, updateSupport); + return AjaxResult.success(); + } + + + /** + * 通知公告表导出 + */ + @ApiOperation(value = "通知公告表导出") + @PostMapping(value = "/export") + public void export(@RequestBody SysNoticeQO qo) { + sysNoticeService.export(qo); + } + +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/WeatherController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/WeatherController.java new file mode 100644 index 0000000..e8dda43 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/WeatherController.java @@ -0,0 +1,29 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.service.WeatherService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Api("爬取天气数据") +@RestController +@RequestMapping("/app/weather") +public class WeatherController { + + @Autowired + private WeatherService weatherService; + + /** + * 获取场馆天气详情 + */ + @ApiOperation(value = "获取场馆天气详情", notes = "获取场馆天气详情") + @GetMapping(value = "/fetchById/{venueId}") + public AjaxResult fetchById(@PathVariable Long venueId) { + return AjaxResult.success(weatherService.fetchById(venueId)); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwAlarmController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwAlarmController.java new file mode 100644 index 0000000..8cc6957 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwAlarmController.java @@ -0,0 +1,704 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import cn.hutool.core.collection.CollUtil; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.github.pagehelper.PageHelper; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.dto.HandleDataDTO; +import com.ruoyi.common.core.domain.dto.json.UserInfo; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.common.constant.AlarmConstants; +import com.ruoyi.eastcom_yw.domain.*; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmDTONoPage; +import com.ruoyi.eastcom_yw.domain.dto.YwAlarmHangupLogDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmLastVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmNewNumVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmViewVo; +import com.ruoyi.eastcom_yw.domain.vo.YwAlarmVo; +import com.ruoyi.eastcom_yw.mapper.YwAlarmMapper; +import com.ruoyi.eastcom_yw.mapper.yw_alarm_deal_logMapper; +import com.ruoyi.eastcom_yw.service.*; +import com.ruoyi.generator.util.GenUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.http.util.EntityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import com.ruoyi.eastcom_yw.common.constant.CacheConstants; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * + * @author jkj + * @since 2023-01-12 + */ + +@Api("告警信息管理") +@RestController +@RequestMapping("/app/alarm") +public class YwAlarmController extends BaseController { + + @Autowired + private YwAlarmViewService ywAlarmViewService; + + @Autowired + private YwAlarmDHService ywAlarmDHService; + + @Autowired + private YwAlarmCSService ywAlarmCSService; + + @Autowired + private YwAlarmWXService ywAlarmWXService; + + @Autowired + private YwSceneService yw_sceneService; + + @Autowired + private YwAlarmService ywAlarmService; + + @Autowired + private YwAlarmHangupLogService ywAlarmHangupLogService; + + @Autowired + private YwAlarmOprateLogService ywAlarmOprateLogService; + + @Autowired + private RedisCache redisCache; + + @Autowired + private yw_alarm_deal_logMapper alarm_deal_logMapper; + + @Autowired + private HmAlarmDeriveService hmAlarmDeriveService; + + @ApiOperation("根据条件获取告警") + @PostMapping("/appList") + public TableDataInfo newlist2(@RequestBody YwAlarmDTO alarmDTO) + { + alarmDTO.setIsAPP(true); + SysUser user = getLoginUser().getUser(); + alarmDTO.setUserId(user.getUserId()); + if(ObjectUtils.isNotEmpty(alarmDTO.getIsRefresh())) + { + //1自动刷新,0是手动刷新 + if(0==alarmDTO.getIsRefresh()) { + //如果是用户点击的查询,保存当前用户查询的场馆,便于用户重新登录后自动勾选场馆查询 + redisCache.setCacheObject(CacheConstants.YW_ALARM_LAST_VENUES + getUserId(), alarmDTO.getVenues(), 3, TimeUnit.DAYS); + } + } + + //如果没有传入场馆就用当前登录用户的配置的场馆 + if (alarmDTO.getVenues().size()==0) { +// boolean isAll= user.isAdmin(user); +// alarmDTO.setIsAll(isAll); +// if(!isAll) { +// List venueList = new ArrayList(); +// yw_sceneService.getVenueByUser(user).forEach( +// venue -> { +// venueList.add(venue.getId()); +// } +// ); +// alarmDTO.setVenues(venueList); +// } + List lstScene = yw_sceneService.getVenueByUserCanNoData(user,false); + + if(lstScene.isEmpty()) + { + alarmDTO.setIsAll(true); + } + + if(!lstScene.isEmpty()) + { + List venueList = new ArrayList(); + for(YwScene ywScene : lstScene) { + venueList.add(ywScene.getId()); + } + alarmDTO.setVenues(venueList); + } + } + + TableDataInfo resData = null; + if(!alarmDTO.getAlarmType().isEmpty()) + { + if(GenUtils.arraysContains(AlarmConstants.ALARMS,alarmDTO.getAlarmType())) + { + + String siteType = alarmDTO.getSiteType(); + + if(!"wx".equals(alarmDTO.getAlarmType())) + { + alarmDTO.setSiteType(null); + } + + List list = null; + try { + list = ywAlarmViewService.getYwAlarmByDto(alarmDTO); + } + catch (Exception ex) + { + throw new ServiceException(ex.getMessage()); + } + resData = getDataTable(list); + HashMap alarmNewNum =new HashMap<>(); + YwAlarmDTONoPage alarmNoPage = new YwAlarmDTONoPage(); + BeanUtils.copyBeanProp(alarmNoPage, alarmDTO); + + alarmNoPage.setSiteType(siteType); + alarmNoPage.setAlarmType("wx"); + alarmNewNum.put("wx",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + + //其它类型没有网络类型 + alarmNoPage.setSiteType(null); + + alarmNoPage.setAlarmType("cs"); + alarmNewNum.put("cs",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("dh"); + alarmNewNum.put("dh",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("agis"); + alarmNewNum.put("agis",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("wifi"); + alarmNewNum.put("wifi",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("voip"); + alarmNewNum.put("voip",ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + resData.setMaps(alarmNewNum); + return resData; + } + throw new ServiceException("告警类型未接入"); + } + throw new ServiceException("告警类型不允许为空"); + } + + @ApiOperation("根据条件获取告警") + @PostMapping("/newlist") + public TableDataInfo newlist3(@RequestBody YwAlarmDTO alarmDTO) + { + alarmDTO.setIsAPP(true); + SysUser user = getLoginUser().getUser(); + alarmDTO.setUserId(user.getUserId()); + if(ObjectUtils.isNotEmpty(alarmDTO.getIsRefresh())) + { + //1自动刷新,0是手动刷新 + if(0==alarmDTO.getIsRefresh()) { + //如果是用户点击的查询,保存当前用户查询的场馆,便于用户重新登录后自动勾选场馆查询 + redisCache.setCacheObject(CacheConstants.YW_ALARM_LAST_VENUES + getUserId(), alarmDTO.getVenues(), 3, TimeUnit.DAYS); + } + } + //如果没有传入场馆就用当前登录用户的配置的场馆 + if (alarmDTO.getVenues().size()==0) { + List lstScene = yw_sceneService.getVenueByUserCanNoData(user,false); + + if(lstScene.isEmpty()) + { + alarmDTO.setIsAll(true); + } + + if(!lstScene.isEmpty()) + { + List venueList = new ArrayList(); + for(YwScene ywScene : lstScene) { + venueList.add(ywScene.getId()); + } + alarmDTO.setVenues(venueList); + } + } + TableDataInfo resData = null; + + if(!alarmDTO.getAlarmType().isEmpty()) + { + if("tel".equals(alarmDTO.getAlarmType())) + { + alarmDTO.setAlarmType("voip"); + } + if(GenUtils.arraysContains(AlarmConstants.ALARMS,alarmDTO.getAlarmType())) + { + if(alarmDTO.getPageNum()<=0) + { + alarmDTO.setPageNum(1); + } + if(alarmDTO.getPageSize()<=0) + { + alarmDTO.setPageSize(10); + } + String siteType = alarmDTO.getSiteType(); + + if(!"wx".equals(alarmDTO.getAlarmType())) + { + alarmDTO.setSiteType(null); + } + + List list = null; + try { + list = ywAlarmViewService.getYwAlarmByDto(alarmDTO); + } + catch (Exception ex) + { + throw new ServiceException("告警查询异常"); + } + resData = getDataTable(list); + return resData; + } + throw new ServiceException("告警类型未接入"); + } + throw new ServiceException("告警类型不允许为空"); + } + + + @ApiOperation("根据条件未恢复告警数量") + @PostMapping("/num") + public AjaxResult newlistNum(@RequestBody YwAlarmDTO alarmDTO) { + + alarmDTO.setIsAPP(true); + SysUser user = getLoginUser().getUser(); + alarmDTO.setUserId(user.getUserId()); + + //如果没有传入场馆就用当前登录用户的配置的场馆 + if (alarmDTO.getVenues().size() == 0) { + List lstScene = yw_sceneService.getVenueByUserCanNoData(user,false); + + if(lstScene.isEmpty()) + { + alarmDTO.setIsAll(true); + } + + if(!lstScene.isEmpty()) + { + List venueList = new ArrayList(); + for(YwScene ywScene : lstScene) { + venueList.add(ywScene.getId()); + } + alarmDTO.setVenues(venueList); + } + } + if (!alarmDTO.getAlarmType().isEmpty()) { + if ("tel".equals(alarmDTO.getAlarmType())) { + alarmDTO.setAlarmType("voip"); + } + if (GenUtils.arraysContains(AlarmConstants.ALARMS, alarmDTO.getAlarmType())) { + + String siteType = alarmDTO.getSiteType(); + + if(!"wx".equals(alarmDTO.getAlarmType())) + { + alarmDTO.setSiteType(null); + } + + HashMap alarmNewNum = new HashMap<>(); + if ("0".equals(alarmDTO.getAlarmStatus())) { + + YwAlarmDTONoPage alarmNoPage = new YwAlarmDTONoPage(); + BeanUtils.copyBeanProp(alarmNoPage, alarmDTO); + alarmNoPage.setSiteType(siteType); + alarmNoPage.setAlarmType("wx"); + alarmNewNum.put("wx", ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + //其它类型没有网络类型 + alarmNoPage.setSiteType(null); + alarmNoPage.setAlarmType("cs"); + alarmNewNum.put("cs", ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("dh"); + alarmNewNum.put("dh", ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("agis"); + alarmNewNum.put("agis", ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("wifi"); + alarmNewNum.put("wifi", ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage)); + alarmNoPage.setAlarmType("voip"); + Long voipNum = ywAlarmViewService.getYwAlarmNewNumByDto(alarmNoPage); + alarmNewNum.put("voip", voipNum); + //前端用的是tel + alarmNewNum.put("tel", voipNum); + } else { + alarmNewNum.put("cs", 0L); + alarmDTO.setAlarmType("dh"); + alarmNewNum.put("dh", 0L); + alarmDTO.setAlarmType("wx"); + alarmNewNum.put("wx", 0L); + alarmDTO.setAlarmType("agis"); + alarmNewNum.put("agis", 0L); + alarmDTO.setAlarmType("wifi"); + alarmNewNum.put("wifi", 0L); + alarmDTO.setAlarmType("voip"); + alarmNewNum.put("voip", 0L); + } + return AjaxResult.success(alarmNewNum); + } + throw new ServiceException("告警类型未接入"); + } + throw new ServiceException("告警类型不允许为空"); + } + + + + @ApiOperation("根据条件获取告警") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwAlarmDTO alarmDTO) + { + alarmDTO.setIsAPP(true); + SysUser user = getLoginUser().getUser(); +// SysUser user = new SysUser(); +// user.setUserId(10L); + if(ObjectUtils.isNotEmpty(alarmDTO.getIsRefresh())) + { + //1自动刷新,0是手动刷新 + if(0==alarmDTO.getIsRefresh()) { + //如果是用户点击的查询,保存当前用户查询的场馆,便于用户重新登录后自动勾选场馆查询 + redisCache.setCacheObject(CacheConstants.YW_ALARM_LAST_VENUES + getUserId(), alarmDTO.getVenues(), 3, TimeUnit.DAYS); + } + } + + //如果没有传入场馆就用当前登录用户的配置的场馆 + if (CollUtil.isEmpty(alarmDTO.getVenues())) { + boolean isAll= user.isAdmin(user); + alarmDTO.setIsAll(isAll); + if(!isAll) { + List venueList = new ArrayList(); + yw_sceneService.getVenueByUser(user).forEach( + venue -> { + venueList.add(venue.getId()); + } + ); + alarmDTO.setVenues(venueList); + } + } + + TableDataInfo resData = null; + if(!alarmDTO.getAlarmType().isEmpty()) + { + if(GenUtils.arraysContains(AlarmConstants.ALARMS,alarmDTO.getAlarmType())) + { + List list = ywAlarmViewService.getYwAlarmByDto(alarmDTO); + resData = getDataTable(list); + HashMap alarmNewNum =new HashMap<>(); + alarmDTO.setPageNum(1); + alarmDTO.setAlarmType("cs"); + alarmNewNum.put("cs",ywAlarmViewService.getYwAlarmNewNumByDto(alarmDTO)); + alarmDTO.setAlarmType("dh"); + alarmNewNum.put("dh",ywAlarmViewService.getYwAlarmNewNumByDto(alarmDTO)); + alarmDTO.setAlarmType("wx"); + alarmNewNum.put("wx",ywAlarmViewService.getYwAlarmNewNumByDto(alarmDTO)); + alarmDTO.setAlarmType("agis"); + alarmNewNum.put("agis",ywAlarmViewService.getYwAlarmNewNumByDto(alarmDTO)); + resData.setMaps(alarmNewNum); + return resData; + } + throw new ServiceException("告警类型未接入"); + } + throw new ServiceException("告警类型不允许为空"); + } + + + @ApiOperation("根据条件获取告警角标数量") + @PostMapping("/appNumList") + public TableDataInfo numList(@RequestBody YwAlarmDTO alarmDTO) + { + alarmDTO.setIsAPP(true); + SysUser user = getLoginUser().getUser(); +// SysUser user = new SysUser(); +// user.setUserId(10L); + if(ObjectUtils.isNotEmpty(alarmDTO.getIsRefresh())) + { + //1自动刷新,0是手动刷新 + if(0==alarmDTO.getIsRefresh()) { + //如果是用户点击的查询,保存当前用户查询的场馆,便于用户重新登录后自动勾选场馆查询 + redisCache.setCacheObject(CacheConstants.YW_ALARM_LAST_VENUES + getUserId(), alarmDTO.getVenues(), 3, TimeUnit.DAYS); + } + } + + //如果没有传入场馆就用当前登录用户的配置的场馆 + if (CollUtil.isEmpty(alarmDTO.getVenues())) { + boolean isAll= user.isAdmin(user); + alarmDTO.setIsAll(isAll); + if(!isAll) { + List venueList = new ArrayList(); + yw_sceneService.getVenueByUser(user).forEach( + venue -> { + venueList.add(venue.getId()); + } + ); + alarmDTO.setVenues(venueList); + } + } + + alarmDTO.setUserId(user.getUserId()); + //获取告警数据 + alarmDTO.setPageNum(1); + HashMap alarmNewNum =new HashMap<>(); + alarmDTO.setAlarmType("cs"); + alarmNewNum.put("cs",ywAlarmViewService.getYwAlarmNewNumByDto(alarmDTO)); + alarmDTO.setAlarmType("dh"); + alarmNewNum.put("dh",ywAlarmViewService.getYwAlarmNewNumByDto(alarmDTO)); + alarmDTO.setAlarmType("wx"); + alarmNewNum.put("wx",ywAlarmViewService.getYwAlarmNewNumByDto(alarmDTO)); + TableDataInfo tableDataInfo = new TableDataInfo(); + tableDataInfo.setMaps(alarmNewNum); + return tableDataInfo; + } + + @ApiOperation("根据用户ID获取最新的告警数量") + @PostMapping("/newAlarmNum") + public AjaxResult newAlarmNum(@RequestBody YwAlarmDTO alarmDTO) + { + //20230316 jkj 管理员类的不加判断场馆的条件,所有场馆的数据 + SysUser user = getLoginUser().getUser(); + + //获取告警数据 + List ywAlarmNewNumVos= ywAlarmViewService.GetNewAlarmNum(user.getUserId(),user.isAdmin(user)); + + return AjaxResult.success("操作成功",JSONObject.toJSONString(ywAlarmNewNumVos)); + + + } + + @ApiOperation("根据组号获取最新告警数据") + @PostMapping("/alarmGroup") + public TableDataInfo alarmGroup(@RequestBody YwAlarmDTO alarmDTO) + { + return getDataTable(ywAlarmViewService.getYwAlarmLessList(alarmDTO.getAlarmType(),alarmDTO.getAlarmGroup())); + } + + + @ApiOperation("根据用户ID获取最新的告警数量") + @GetMapping("/newAlarmNum/{userId}") + public AjaxResult newAlarmNum(@PathVariable String userId) + { + +// Long longUserId=Long.parseLong(userId); + //20230316 jkj 管理员类的不加判断场馆的条件,所有场馆的数据 + SysUser user = getLoginUser().getUser(); + + //获取告警数据 + List ywAlarmNewNumVos= ywAlarmViewService.GetNewAlarmNum(user.getUserId(),user.isAdmin(user)); + + return AjaxResult.success("操作成功",JSONObject.toJSONString(ywAlarmNewNumVos)); + + + } + + + @ApiOperation("根据processId获取告警详情") + @GetMapping("/info/{processId}") + public TableDataInfo info(@PathVariable String processId) + { + return getDataTable(ywAlarmViewService.GetAlarmInfoList(processId)); + } + + @ApiOperation("根据GroupId获取告警详情") + @GetMapping("/info/group/{groupId}") + public TableDataInfo infoByGroup(@PathVariable String groupId) + { + return getDataTable(ywAlarmViewService.getYwAlarmInfoListByGroup(groupId)); + } + + @Log(title = "告警挂起记录", businessType = BusinessType.INSERT) + @ApiOperation("根据条件新增告警挂起的记录") + @PostMapping("/insert/hanguplog") + public AjaxResult list(@RequestBody YwAlarmHangupLogDTO ywAlarmHangupLogDTO) throws Exception + { + try + { + if(ObjectUtils.isEmpty(ywAlarmHangupLogDTO.getHangupUserId())) + { + SysUser user = getLoginUser().getUser(); + ywAlarmHangupLogDTO.setHangupUserId(user.getUserId()); + } + if(ywAlarmHangupLogService.insertYwAlarmHangupLog(ywAlarmHangupLogDTO)) + { + return AjaxResult.success(); + } + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + return AjaxResult.error(); + } + + @ApiOperation("获取告警问题") + @GetMapping("/question") + public TableDataInfo getAlarmQuestion(String spec) + { + return getDataTable(ywAlarmService.getYwAlarmQuestionList(spec)); + } + + @ApiOperation("告警操作") + @PostMapping("/operate") + public AjaxResult add(@RequestBody YwAlarmOprateLog ywAlarmOprateLog) + { + if(ywAlarmOprateLogService.saveOrUpdate(ywAlarmOprateLog)){ + return success(); + } + return error(); + } + + @ApiOperation("告警回填反馈人和反馈时间") + @PostMapping("/feedback") + public AjaxResult feedback(@RequestBody YwAlarmDTO ywAlarmDTO) + { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + yw_alarm_deal_log yw_alarm_deal_log =new yw_alarm_deal_log(); + yw_alarm_deal_log.setDealUser(ywAlarmDTO.getDealUser()); + yw_alarm_deal_log.setDealStatus(ywAlarmDTO.getDealStatus()); + updateWrapper.eq("flw_processid", ywAlarmDTO.getProcessId()); + if(alarm_deal_logMapper.update(yw_alarm_deal_log,updateWrapper)>0){ + return success(); + } + return error(); + } + + + @ApiOperation("获取告警数据") + @PostMapping("/getYwAlarmAll") + public TableDataInfo getYwAlarmAll(@RequestBody YwAlarmDTO ywAlarmDTO) + { + startPage(); + List list = ywAlarmViewService.getYwAlarmList(ywAlarmDTO.getAlarmType(),ywAlarmDTO.getVenueName(),ywAlarmDTO.getStartTime(),ywAlarmDTO.getEndTime()); + return getDataTable(list); + } + + @Log(title = "用户手工恢复告警", businessType = BusinessType.INSERT) + @ApiOperation("告警恢复时间") + @PostMapping("/alarmClear") + public AjaxResult alarmClear(@RequestBody YwAlarmDTO alarmDTO) + { + boolean res = ywAlarmService.YwAlarmClear(alarmDTO); + if(res) + { + return success(); + } + return error(); + } + + @Log(title = "告警记录", businessType = BusinessType.UPDATE) + @ApiOperation("告警记录") + @PostMapping("/record") + public AjaxResult record(@RequestBody YwAlarmDTO ywAlarmDTO) + { + if(ObjectUtils.isEmpty(ywAlarmDTO.getRecord())) + { + return AjaxResult.error("记录内容不允许为空"); + } + // String text_record = ywAlarmDTO.getRecords().stream().collect(Collectors.joining("##@##")); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + yw_alarm_deal_log yw_alarm_deal_log =new yw_alarm_deal_log(); + yw_alarm_deal_log.setRecord(ywAlarmDTO.getRecord()); + updateWrapper.eq("group_id", ywAlarmDTO.getAlarmId()); + updateWrapper.eq("is_new","0"); + if(alarm_deal_logMapper.update(yw_alarm_deal_log,updateWrapper)>0){ + return success(); + } + return error(); + } + + @ApiOperation("告警阶段处理记录查询") + @GetMapping("/record") + public AjaxResult recordList(YwAlarmDTO ywAlarmDTO) + { + if(ObjectUtils.isEmpty(ywAlarmDTO.getAlarmId())) + { + return AjaxResult.error("告警编号不允许为空"); + } + if(ObjectUtils.isEmpty(ywAlarmDTO.getAlarmType())) + { + return AjaxResult.error("告警类型不允许为空"); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("group_id", ywAlarmDTO.getAlarmId()); + queryWrapper.eq("alarm_type",ywAlarmDTO.getAlarmType()); + List lstDealLog = alarm_deal_logMapper.selectList(queryWrapper); + return AjaxResult.success(lstDealLog); + } + + @Log(title = "批量告警记录阶段处理", businessType = BusinessType.UPDATE) + @ApiOperation("批量告警记录阶段处理") + @PostMapping("/recordBatch") + public AjaxResult recordBatch(@RequestBody YwAlarmDTO ywAlarmDTO) + { + if(ObjectUtils.isEmpty(ywAlarmDTO.getAlarmIds()) || ObjectUtils.isEmpty(ywAlarmDTO.getStepInfo())) + { + return AjaxResult.error("缺少处理的参数"); + } + + if(ywAlarmDTO.getAlarmIds().length == 0) + { + return AjaxResult.error("alarmIds没有值"); + } + + if(StringUtils.isEmpty(ywAlarmDTO.getStepInfo().getTitle())||StringUtils.isEmpty(ywAlarmDTO.getStepInfo().getInfo())) + { + return AjaxResult.error("stepInfo没有值"); + } + + for(Long alarmId : ywAlarmDTO.getAlarmIds()) + { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("group_id", alarmId); + queryWrapper.eq("is_new","0"); + List lstAlarm = alarm_deal_logMapper.selectList(queryWrapper); + if(lstAlarm.isEmpty()) + { + continue; + } + String record = lstAlarm.get(0).getRecord(); + JSONArray arrayRecord = new JSONArray(); + if(StringUtils.isNotEmpty(record)) + { + arrayRecord = JSONArray.parseArray(record); + } + JSONObject jsonRecord = new JSONObject(); + jsonRecord.put("title",ywAlarmDTO.getStepInfo().getTitle()); + jsonRecord.put("info",ywAlarmDTO.getStepInfo().getInfo()); + arrayRecord.add(jsonRecord); + record = JSONArray.toJSONString(arrayRecord); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + yw_alarm_deal_log yw_alarm_deal_log =new yw_alarm_deal_log(); + yw_alarm_deal_log.setRecord(record); + updateWrapper.eq("group_id", alarmId); + updateWrapper.eq("is_new","0"); + alarm_deal_logMapper.update(yw_alarm_deal_log,updateWrapper); + } + return success(); + } + + @ApiOperation("查询亚运衍生告警") + @PostMapping("/hmAlarmDerive/list") + public TableDataInfo derivelist(@RequestBody YwAlarmDTO alarmDTO) { + startPage(); + return getDataTable(hmAlarmDeriveService.getAlarmDerive(alarmDTO)); + } + + + @ApiOperation("查询亚运衍生告警") + @PostMapping("/hmAlarmDerive/export") + public void deriveExport(@RequestBody YwAlarmDTO alarmDTO) throws IllegalAccessException { + alarmDTO.setPageNum(1); + alarmDTO.setPageSize(Integer.MAX_VALUE); + List list = hmAlarmDeriveService.getAlarmDerive(alarmDTO); + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + ExcelUtil util = new ExcelUtil(HmAlarmDerive.class); + util.exportExcel(response, list, "亚运事件告警"); + } + +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwContactBookController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwContactBookController.java new file mode 100644 index 0000000..f5d0f54 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwContactBookController.java @@ -0,0 +1,115 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwSceneUser; +import com.ruoyi.eastcom_yw.mapper.YwSceneBigConfigMapper; +import com.ruoyi.eastcom_yw.mapper.YwSceneMapper; +import com.ruoyi.eastcom_yw.mapper.YwSceneUserMapper; +import com.ruoyi.system.domain.SysUserRole; +import com.ruoyi.system.mapper.SysDictDataMapper; +import com.ruoyi.system.mapper.SysUserMapper; +import com.ruoyi.system.mapper.SysUserRoleMapper; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 通讯录 前端控制器 + *

+ * + * @author ck + * @since 2023-08-28 + */ +@Api(tags = "通讯录") +@RestController +@RequestMapping("/app/ywContactBook") +@Slf4j +@RequiredArgsConstructor +public class YwContactBookController extends BaseController { + + + private final YwSceneMapper ywSceneMapper; + private final YwSceneBigConfigMapper ywSceneBigConfigMapper; + private final YwSceneUserMapper ywSceneUserMapper; + private final SysUserMapper sysUserMapper; + private final SysUserRoleMapper sysUserRoleMapper; + private final SysDictDataMapper sysDictDataMapper; + + /** + * 场馆列表 + */ + @ApiOperation(value = "场馆列表", notes = "场馆列表") + @GetMapping(value = "venueList") + public TableDataInfo venueList(@RequestParam String cityId, @RequestParam String venueType, @RequestParam Long pageNum, @RequestParam Long pageSize) { + + Long sceneBigId = ywSceneBigConfigMapper.selectCurrentBig(); + if(sceneBigId==null){ + throw new ServiceException("当前没有大场景,请在场景配置配置一条当前状态的场景"); + } + + Page page = ywSceneMapper.selectPage(new Page<>(pageNum, pageSize), new LambdaQueryWrapper() + .eq(YwScene::getCityId, cityId) + .eq(YwScene::getVenueType, venueType) + .eq(YwScene::getSceneBigId,sceneBigId) + .orderByAsc(YwScene::getVenueName) + ); + return getDataTable(page.getRecords(), page.getTotal()); + } + + /** + * 人员列表 + */ + @ApiOperation(value = "人员列表", notes = "人员列表") + @GetMapping(value = "userList") + public TableDataInfo userList(@RequestParam(required = false) String keywords, @RequestParam(required = false) Long sceneId, @RequestParam Integer pageNum, @RequestParam Integer pageSize) { + + PageHelper.startPage(pageNum, pageSize); + List sysUsers = sysUserMapper.selectUserByKeywords(keywords, sceneId); + for (SysUser sysUser : sysUsers) { + List sysUserRoles = sysUserRoleMapper.selectRoleByUserId(sysUser.getUserId()); + List roles = sysUserRoles.stream().map(SysUserRole::getRoleName).collect(Collectors.toList()); + String label = sysDictDataMapper.selectDictLabel("yw_specialty", sysUser.getUserType()); + sysUser.setUserTypeStr(label); + sysUser.setRoleNames(roles); + } + PageInfo pageInfo = PageInfo.of(sysUsers); + return getDataTable(pageInfo.getList(), pageInfo.getTotal()); + } + + /** + * 人员详情 + */ + @ApiOperation(value = "人员详情", notes = "人员详情") + @GetMapping(value = "userInfo") + public AjaxResult userInfo(@RequestParam Long userId) { + + SysUser user = sysUserMapper.selectUserById(userId); + List venues = ywSceneUserMapper.getVenuesByUserId(user.getUserId()); + List venueNames = venues.stream().map(YwSceneUser::getVenueName).collect(Collectors.toList()); + user.setVenueNames(venueNames); + String label = sysDictDataMapper.selectDictLabel("yw_specialty", user.getUserType()); + user.setUserTypeStr(label); + List sysUserRoles = sysUserRoleMapper.selectRoleByUserId(user.getUserId()); + List roles = sysUserRoles.stream().map(SysUserRole::getRoleName).collect(Collectors.toList()); + user.setRoleNames(roles); + return AjaxResult.success(user); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwDrsTempTaskController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwDrsTempTaskController.java new file mode 100644 index 0000000..e8b43a7 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwDrsTempTaskController.java @@ -0,0 +1,135 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.dto.YwDrsTempTaskDTO; +import com.ruoyi.eastcom_yw.domain.qo.YwDrsTempTaskQO; +import com.ruoyi.eastcom_yw.domain.vo.YwDrsTempTaskVO; +import com.ruoyi.eastcom_yw.service.YwDrsTempTaskService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDate; +import java.util.List; + +/** + *

+ * DRS临时任务表 前端控制器 + *

+ * + * @author ck + * @since 2023-06-13 + */ +@Api(tags = "DRS临时任务表") +@RestController +@RequestMapping("/app/ywDrsTempTask") +@Slf4j +@RequiredArgsConstructor +public class YwDrsTempTaskController extends BaseController { + + private final YwDrsTempTaskService ywDrsTempTaskService; + + /** + * DRS临时任务表列表 + */ + @ApiOperation(value = "DRS临时任务表列表", notes = "DRS临时任务表列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody YwDrsTempTaskQO qo) { + List list = ywDrsTempTaskService.getData(qo); + return getDataTable(list); + } + + + /** + * DRS临时任务表分页列表 + */ + @ApiOperation(value = "DRS临时任务表分页列表", notes = "DRS临时任务表分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody YwDrsTempTaskQO qo) { + PageInfo page = ywDrsTempTaskService.getDataByPage(qo); + return getDataTable(page.getList(), page.getTotal()); + } + + /** + * 获取DRS临时任务表详情 + */ + @ApiOperation(value = "DRS临时任务表详情", notes = "DRS临时任务表详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(ywDrsTempTaskService.fetchById(id)); + } + + /** + * 新增或修改DRS临时任务表 + */ + @Log(title = "新增或修改DRS临时任务表", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改DRS临时任务表", notes = "新增或修改DRS临时任务表") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated YwDrsTempTaskDTO dto) { + ywDrsTempTaskService.saveOrUpdate(dto); + return AjaxResult.success(); + } + + /** + * 根据id删除DRS临时任务表 + */ + @Log(title = "根据id删除DRS临时任务表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除DRS临时任务表", notes = "根据id删除DRS临时任务表") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + ywDrsTempTaskService.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除DRS临时任务表 + */ + @Log(title = "根据id批量删除DRS临时任务表", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除DRS临时任务表", notes = "根据id批量删除DRS临时任务表") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + ywDrsTempTaskService.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "DRS临时任务表导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil util = new ExcelUtil<>(YwDrsTempTaskVO.class); + List list = util.importExcel(file.getInputStream()); + ywDrsTempTaskService.importData(list, updateSupport); + return AjaxResult.success(); + } + + + /** + * DRS临时任务表导出 + */ + @ApiOperation(value = "DRS临时任务表导出") + @PostMapping(value = "/export") + public void export(@RequestBody YwDrsTempTaskQO qo) { + ywDrsTempTaskService.export(qo); + } + + + /** + * DRS预览 + */ + @ApiOperation(value = "DRS预览", notes = "DRS预览") + @GetMapping(value = "/drsPreview/{venueId}/{date}") + public TableDataInfo drsPreview(@PathVariable("venueId") Long venueId, @PathVariable("date") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date) { + return getDataTable(ywDrsTempTaskService.drsPreview(venueId,date)); + } + +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwRoutInspectLogController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwRoutInspectLogController.java new file mode 100644 index 0000000..d92e080 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwRoutInspectLogController.java @@ -0,0 +1,45 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.enums.OperatorType; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectLog; +import com.ruoyi.eastcom_yw.service.YwRoutInspectLogService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author los + */ +@Api("巡检计划反馈接口") +@RestController +@RequestMapping("/app/routInspectLog") +@RequiredArgsConstructor +public class YwRoutInspectLogController extends BaseController { + + private final YwRoutInspectLogService ywRoutInspectLogService; + + @ApiOperation("修改") + @PutMapping("") +// @PreAuthorize("@app.hasPermi('focus:inspect:update')") + @Log(title = "修改巡检计划", businessType = BusinessType.UPDATE,operatorType = OperatorType.MOBILE ) + public AjaxResult update(@RequestBody YwRoutInspectLog log) { + try { + ywRoutInspectLogService.updateLog(log); + + return AjaxResult.success(); + } catch (Exception e) { + e.printStackTrace(); + return AjaxResult.error(e.getMessage()); + } + } + +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwRoutInspectPlanController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwRoutInspectPlanController.java new file mode 100644 index 0000000..f865d06 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwRoutInspectPlanController.java @@ -0,0 +1,173 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.enums.OperatorType; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectConfig; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectPlan; +import com.ruoyi.eastcom_yw.domain.dto.YwInspectStatDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwInspectTaskDTO; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectConfigParam; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectPlanParam; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectStatParam; +import com.ruoyi.eastcom_yw.domain.vo.YwInspectLogVo; +import com.ruoyi.eastcom_yw.service.YwRoutInspectConfigService; +import com.ruoyi.eastcom_yw.service.YwRoutInspectPlanService; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + +/** + * @author huamile + */ +@Api("巡检计划管理") +@RestController +@RequestMapping("/app/routInspectPlan") +@RequiredArgsConstructor +public class YwRoutInspectPlanController extends BaseController { + + private final YwRoutInspectPlanService ywRoutInspectPlanService; + private final YwRoutInspectConfigService ywRoutInspectConfigService; + + private final YwSceneService yw_sceneService; + + @ApiOperation("获取巡检计划列表") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwRoutInspectConfigParam param) { + param = (YwRoutInspectConfigParam) yw_sceneService.validateUserVenues(param,YwRoutInspectConfigParam.class,"venueIds"); + List list = ywRoutInspectPlanService.getList(param); + return getDataTable(list); + } + + @ApiOperation("获取巡检记录列表") + @PostMapping("/plan/list") + public TableDataInfo planList(@RequestBody YwRoutInspectPlanParam param) { + param = (YwRoutInspectPlanParam) yw_sceneService.validateUserVenues(param,YwRoutInspectPlanParam.class,"venueIds"); + param.setIsApp(true); + return ywRoutInspectPlanService.getPlanList(param); + } + + @ApiOperation("根据条件获取巡检任务统计汇总") + @PostMapping("/stat") + public AjaxResult stat(@RequestBody YwRoutInspectStatParam param) { + param = (YwRoutInspectStatParam) yw_sceneService.validateUserVenues(param,YwRoutInspectStatParam.class,"venueIds"); + Map data = ywRoutInspectPlanService.getStatData(param); + return AjaxResult.success(data); + } + + @ApiOperation("根据条件获取巡检任务统计列表") + @PostMapping("/stat/list") + public AjaxResult statList(@RequestBody YwRoutInspectStatParam param) { + param = (YwRoutInspectStatParam) yw_sceneService.validateUserVenues(param,YwRoutInspectStatParam.class,"venueIds"); + Map map = ywRoutInspectPlanService.getStatListData(param); + return AjaxResult.success(map); + } + + @ApiOperation("根据条件获取巡检结果统计汇总") + @PostMapping("/resultStat") + public AjaxResult resultStat(@RequestBody YwRoutInspectStatParam param) { + param = (YwRoutInspectStatParam) yw_sceneService.validateUserVenues(param,YwRoutInspectStatParam.class,"venueIds"); + Map data = ywRoutInspectPlanService.getResultStatData(param); + return AjaxResult.success(data); + } + + @ApiOperation("根据条件获取巡检结果统计列表") + @PostMapping("/resultStat/list") + public AjaxResult resultStatList(@RequestBody YwRoutInspectStatParam param) { + param = (YwRoutInspectStatParam) yw_sceneService.validateUserVenues(param,YwRoutInspectStatParam.class,"venueIds"); + Map map = ywRoutInspectPlanService.getResultStatListData(param); + return AjaxResult.success(map); + } + + @ApiOperation("场馆任务结果统计列表(app端合并statList与resultStatList两接口结果返回)") + @PostMapping("/mergeResultStat/list") + public TableDataInfo mergeResultStat(@RequestBody YwRoutInspectStatParam param) { + param = (YwRoutInspectStatParam) yw_sceneService.validateUserVenues(param,YwRoutInspectStatParam.class,"venueIds"); + List list = ywRoutInspectPlanService.mergeResultStat(param); + return getDataTable(list); + } + + @ApiOperation("根据processId获取巡检详情") + @GetMapping("/info/{processId}") + public TableDataInfo info(@PathVariable String processId) + { + return getDataTable(ywRoutInspectPlanService.getRoutInspectInfoList(processId)); + } + + @ApiOperation("查巡检配置参数") + @PostMapping("/inspectConfigList") + public TableDataInfo inspectConfigList(@RequestBody YwRoutInspectConfigParam param) { + List list = ywRoutInspectConfigService.getInspectConfigList(param); + return getDataTable(list); + } + + @ApiOperation("新增巡检计划") + @PostMapping + @PreAuthorize("@app.hasPermi('focus:inspect:add')") + @Log(title = "新增巡检计划", businessType = BusinessType.INSERT,operatorType = OperatorType.MOBILE ) + public AjaxResult create(@RequestBody YwInspectTaskDTO dto) { + try { + return ywRoutInspectPlanService.create(dto); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("编辑巡检计划") + @PutMapping + @PreAuthorize("@app.hasPermi('focus:inspect:update')") + public AjaxResult update(@RequestBody YwInspectTaskDTO dto) { + try { + if (ywRoutInspectPlanService.checkPlanStatus(dto.getYwRoutInspectPlan().getJobNo())) { + return AjaxResult.error("巡检记录已生成,无法修改。"); + } + ywRoutInspectPlanService.updatePlan(dto); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @Log(title = "巡检计划", businessType = BusinessType.DELETE) + @ApiOperation("删除巡检计划") + @DeleteMapping("/{ids}") + @PreAuthorize("@app.hasPermi('focus:inspect:del')") + public AjaxResult delete(@PathVariable String[] ids) { + try { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.in(YwRoutInspectPlan::getJobNo,ids); + ywRoutInspectPlanService.remove(wrapper); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("导出巡检任务列表") + @PostMapping("/export") + public void export(YwRoutInspectConfigParam param, HttpServletRequest request, HttpServletResponse response) { + ywRoutInspectPlanService.export(param,request,response); + } + + @ApiOperation("导出巡检计划列表") + @PostMapping("/plan/export") + public void planExport(YwRoutInspectPlanParam param, HttpServletRequest request, HttpServletResponse response) { + ywRoutInspectPlanService.planExport(param,request,response); + } + +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwRoutInspectQuestionConfigController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwRoutInspectQuestionConfigController.java new file mode 100644 index 0000000..637561c --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwRoutInspectQuestionConfigController.java @@ -0,0 +1,93 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.eastcom_yw.domain.YwRoutInspectQuestionConfig; +import com.ruoyi.eastcom_yw.domain.param.YwInspectQuestionConfigParam; +import com.ruoyi.eastcom_yw.service.YwRoutInspectQuestionConfigService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; +import java.util.List; + +/** + * @author huamile + */ +@Api("巡检问题类型管理") +@RestController +@RequestMapping("/app/routInspectQuestionConfig") +@RequiredArgsConstructor +public class YwRoutInspectQuestionConfigController extends BaseController { + + private final YwRoutInspectQuestionConfigService ywRoutInspectQuestionConfigService; + + @ApiOperation("获取巡检问题类型列表") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwInspectQuestionConfigParam param) { + List list = ywRoutInspectQuestionConfigService.getlist(param); + return getDataTable(list); + } + + @ApiOperation("获取巡检问题列表") + @PostMapping("/appList") + public TableDataInfo bigList(@RequestBody YwInspectQuestionConfigParam param) { + List list = ywRoutInspectQuestionConfigService.appList(param); + return getDataTable(list); + } + + + @Log(title = "巡检问题类型", businessType = BusinessType.INSERT) + @ApiOperation("新增巡检问题类型") + @PostMapping + public AjaxResult create(@RequestBody YwRoutInspectQuestionConfig ywRoutInspectQuestionConfig) { + try { + ywRoutInspectQuestionConfigService.create(ywRoutInspectQuestionConfig); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @Log(title = "巡检问题类型", businessType = BusinessType.UPDATE) + @ApiOperation("编辑巡检问题类型") + @PutMapping + public AjaxResult update(@RequestBody YwRoutInspectQuestionConfig ywRoutInspectQuestionConfig) { + try { + ywRoutInspectQuestionConfigService.updateByPrimaryKeySelective(ywRoutInspectQuestionConfig); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @Log(title = "巡检问题类型", businessType = BusinessType.DELETE) + @ApiOperation("删除巡检问题类型") + @DeleteMapping("/{ids}") + public AjaxResult delete(@PathVariable Long[] ids) { + try { + ywRoutInspectQuestionConfigService.removeByIds(Arrays.asList(ids)); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @Log(title = "巡检问题类型", businessType = BusinessType.EXPORT) + @ApiOperation("导出巡检问题类型列表") + @PostMapping("/export") + public void export(YwInspectQuestionConfigParam param, HttpServletRequest request, HttpServletResponse response) { + ywRoutInspectQuestionConfigService.export(param,request,response); + } + +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwSceneController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwSceneController.java new file mode 100644 index 0000000..691bbb8 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwSceneController.java @@ -0,0 +1,133 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.dto.YwDataDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSceneDTO; +import com.ruoyi.eastcom_yw.domain.param.YwSceneParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSceneVo; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.system.service.ISysUserService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * + * @author jkj + * @since 2023-01-12 + */ +@Api("场馆信息管理") +@RestController +@RequestMapping("/app/venue") +public class YwSceneController extends BaseController { + + @Autowired + private YwSceneService yw_sceneService; + + @Autowired + private ISysUserService userService; + + @ApiOperation("获取场馆数据") + @GetMapping("/list/redis") + public AjaxResult listAll() throws Exception { + return AjaxResult.success(yw_sceneService.selectVenues()); + } + + + @ApiOperation("获取当前登录用户关联的场馆数据") + @GetMapping("/list") + public TableDataInfo list() + { + startPage(); + + SysUser user = SecurityUtils.getLoginUser().getUser(); + + List list= yw_sceneService.getVenueByUser(user); + + return getDataTable(list); + } + + @ApiOperation("根据场馆和角色获取相关的用户") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwDataDTO ywDataDTO) + { + List list = yw_sceneService.getSysUserByVenueAndOther(ywDataDTO); + return getDataTable(list); + } + + @ApiOperation("根据场馆ID获取场馆") + @GetMapping(value = { "/", "/{venueId}" }) + public TableDataInfo list(@PathVariable(value = "venueId", required = false) Long venueId) + { + LambdaQueryWrapper lambdaQueryWrapper=new LambdaQueryWrapper<>(); + lambdaQueryWrapper.eq(YwScene::getId,venueId); + List list = yw_sceneService.list(lambdaQueryWrapper); + + return getDataTable(list); + } + + @ApiOperation("获取场馆信息列表") + @PostMapping("/msgList") + public TableDataInfo msgList(@RequestBody YwSceneParam param) { + List list = yw_sceneService.msgList(param); + return getDataTable(list); + } + + @ApiOperation("新增场馆") + @PostMapping + public AjaxResult create(@RequestBody YwSceneDTO dto) { + try { + yw_sceneService.create(dto); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("编辑场馆信息") + @PutMapping + public AjaxResult update(@RequestBody YwSceneDTO dto) { + try { + yw_sceneService.updateByPrimaryKeySelective(dto); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("删除场馆") + @DeleteMapping("/{ids}") + public AjaxResult delete(@PathVariable Long[] ids) { + try { + yw_sceneService.delByIds(Arrays.asList(ids)); + return AjaxResult.success(); + } catch (Exception ex) { + ex.printStackTrace(); + return AjaxResult.error(ex.getMessage()); + } + } + + @ApiOperation("导出场馆") + @PostMapping("/export") + public void export(YwSceneParam param, HttpServletRequest request, HttpServletResponse response) { + yw_sceneService.export(param,request,response); + } + +} + diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwScenePictureController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwScenePictureController.java new file mode 100644 index 0000000..cd9a20d --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwScenePictureController.java @@ -0,0 +1,108 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.eastcom_yw.service.YwScenePictureService; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author los + */ +@RestController +@RequestMapping("/app/scenePicture") +@RequiredArgsConstructor +public class YwScenePictureController extends BaseController { + + private final YwScenePictureService service; + + /** + * 任务管理统计 + * + * @param id 场馆id + * @return 返回数据 + */ + @ApiOperation(value = "任务管理统计", notes = "任务管理统计") + @PostMapping("/listTaskManage") + public AjaxResult listTaskManage(@RequestParam("sceneId") Long id) { + return AjaxResult.success(service.listTaskManage2(id,false)); + } + + /** + * 人员签到统计 + * + * @param id 场馆id + * @return 返回数据 + */ + @ApiOperation(value = "人员签到统计", tags = "人员签到统计") + @PostMapping("/listSign") + public AjaxResult listSign(@RequestParam("sceneId") Long id) { + return AjaxResult.success(service.listSign(id)); + } + + /** + * 场馆基本信息 + * + * @param id 场馆id + * @return 返回数据 + */ + @ApiOperation(value = "场馆基本信息", tags = "场馆基本信息") + @PostMapping("/baseInfo") + public AjaxResult listMatchTop3(@RequestParam("sceneId") Long id) { + return AjaxResult.success(service.listMatchTop3(id)); + } + + /** + * 场馆告警 + * + * @param id 场馆id + * @return 返回数据 + */ + @ApiOperation(value = "场馆告警", tags = "场馆告警") + @PostMapping("/alarm") + public AjaxResult listAlarm(@RequestParam("sceneId") Long id) { + return AjaxResult.success(service.listAlarm(id)); + } + + /** + * 场馆Kpi指标 + * + * @param id 场馆id + * @param typeId 网络类型 1 --> 4g 2 --> 5g + * @return 数据 + */ + @ApiOperation(value = "场馆性能(15分粒度)", tags = "场馆性能(15分粒度)") + @PostMapping("/kpi") + public AjaxResult listKPI(@RequestParam("sceneId") Long id, @RequestParam("typeId") String typeId) { + return AjaxResult.success(service.listKPI(id, typeId)); + } + + /** + * + * @param id 场馆id + * @param type 1-AGIS 2-互联网 3-固话 + * @return + */ + @ApiOperation(value = "场馆性能-专网", tags = "场馆性能-专网") + @PostMapping("/listNetKpi") + public AjaxResult listNetKpi(@RequestParam("sceneId") Long id,@RequestParam("type") Integer type) { + return service.listNetKpi(id,type); + } + + /** + * + * @param id 场馆id + * @param type 1-环路浏量 2-光功率 + * @return + */ + @ApiOperation(value = "场馆性能-传输", tags = "场馆性能-传输") + @PostMapping("/listTransKpi") + public AjaxResult listTransKpi(@RequestParam("sceneId") Long id,@RequestParam("type") Integer type) { + return service.listTransKpi(id,type); + } + +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwSignController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwSignController.java new file mode 100644 index 0000000..eb5785a --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwSignController.java @@ -0,0 +1,368 @@ +package com.ruoyi.app.controller.eastcom_yw; + + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.enums.OperatorType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.utils.reflect.ReflectUtils; +import com.ruoyi.eastcom_yw.domain.YwSignLog; +import com.ruoyi.eastcom_yw.domain.YwSignPlanView; +import com.ruoyi.eastcom_yw.domain.dto.*; +import com.ruoyi.eastcom_yw.domain.param.YwSignPlanParam; +import com.ruoyi.eastcom_yw.domain.vo.YwSignLogStaticVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSignLogVo; +import com.ruoyi.eastcom_yw.domain.vo.YwSignPlanVo; +import com.ruoyi.eastcom_yw.mapper.YwSceneUserMapper; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.eastcom_yw.service.YwSignLogService; +import com.ruoyi.eastcom_yw.service.YwSignLogViewService; +import com.ruoyi.eastcom_yw.service.YwSignPlanService; +import com.ruoyi.system.mapper.SysUserMapper; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + + +/** + * + * @author jkj + * @since 2023-01-14 + */ +@Api("签到信息管理") +@RestController +@RequestMapping("/app/sign") +public class YwSignController extends BaseController { + + @Autowired + private YwSignLogService ywSignLogService; + + @Autowired + private YwSignPlanService ywSignPlanService; + + + @Autowired + private YwSignLogViewService ywSignLogViewService; + + @Autowired + private YwSceneUserMapper ywSceneUserMapper; + + @Autowired + private SysUserMapper sysUserMapper; + + @Autowired + private YwSceneService yw_sceneService; + + + @ApiOperation("是否可签到") + @PostMapping("/couldSign") + public AjaxResult couldSign(@RequestBody YwSignDTO ywSignDTO) + { + return AjaxResult.success( ywSignLogService.couldSign(ywSignDTO)); + } + + @ApiOperation("签到") + @PostMapping("/sign") + @Log(title = "APP", businessType = BusinessType.UPDATE,operatorType= OperatorType.MOBILE) + public AjaxResult sign(@RequestBody YwSignDTO ywSignDTO) + { + return AjaxResult.success( ywSignLogService.sign(ywSignDTO)); + } + + @ApiOperation("签到") + @PostMapping("/signTest") + @Log(title = "APP", businessType = BusinessType.UPDATE,operatorType= OperatorType.MOBILE) + public AjaxResult signTest(@RequestBody YwSignDTO ywSignDTO) + { + return AjaxResult.success( ywSignLogService.signTest(ywSignDTO)); + } + + @ApiOperation("根据场馆ID获取当前登录用户的签到记录") + @GetMapping("/getSignLogAndPlan/{venueId}") + public AjaxResult getSignLogAndPlan(@PathVariable("venueId") Long venueId) + { + return AjaxResult.success(ywSignLogViewService.getSignLogAndPlan(venueId)); + } + + @ApiOperation("根据签到计划ID获取当前登录用户的签到记录") + @GetMapping("/getSignLog/{signPlanId}") + public AjaxResult getSignLog(@PathVariable("signPlanId") Long signPlanId) + { + return AjaxResult.success(ywSignLogViewService.getSignLogByPlanId(signPlanId)); + } + + @ApiOperation("获取签到") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwSignLogDTO ywSignLogDTO) + { + ywSignLogDTO = (YwSignLogDTO) yw_sceneService.validateUserVenues(ywSignLogDTO,YwSignLogDTO.class,"venueIds"); + TableDataInfo resData=ywSignLogViewService.getSignLog(ywSignLogDTO); + return getDataTable(resData.getRows(),resData.getTotal()); + } + + /** + * 获取签到计划详情 + */ + @ApiOperation(value = "获取签到计划详情", notes = "获取签到计划详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + + YwSignPlanView ywSignPlanView = ywSignPlanService.getById(id); + + YwSignPlanVo ywSignPlanVo = ywSignPlanService.handleYwSignPlan(ywSignPlanView); + + return AjaxResult.success(ywSignPlanVo); + } + + @ApiOperation("获取签到统计") + @PostMapping("/static/list") +// @PreAuthorize("@app.hasPermi('focus:sign:static')") + public TableDataInfo static_list(@RequestBody YwSignLogDTO ywSignLogDTO) + { + ywSignLogDTO.setIsExport(false); + ywSignLogDTO.setGenTime(true); + ywSignLogDTO = (YwSignLogDTO) yw_sceneService.validateUserVenues(ywSignLogDTO,YwSignLogDTO.class,"venueIds"); + List list=ywSignLogViewService.getSignLogStatic(ywSignLogDTO); + return getDataTable(list); + } + + @ApiOperation("获取签到计划") + @PostMapping("/plan/list") +// @PreAuthorize("@app.hasPermi('focus:signPlan:list')") + public TableDataInfo plan_list(@RequestBody YwSignPlanDTO ywSignPlanDTO) + { + ywSignPlanDTO.setIsExport(false); + ywSignPlanDTO = (YwSignPlanDTO) yw_sceneService.validateUserVenues(ywSignPlanDTO,YwSignPlanDTO.class,"venueIds"); + TableDataInfo resData= ywSignPlanService.getSignPlan(ywSignPlanDTO); + return getDataTable(resData.getRows(),resData.getTotal()); + } + + @ApiOperation("获取登录用户的签到计划") + @PostMapping("/plan/listByUser") + public TableDataInfo plan_list2(@RequestBody YwSignPlanDTO ywSignPlanDTO) + { + startPage(); + return getDataTable(ywSignPlanService.getSignPlan(ywSignPlanDTO.getVenueId(),ywSignPlanDTO.getSignDate())); + } + + @Log(title = "签到计划", businessType = BusinessType.INSERT) + @ApiOperation("新增签到计划") + @PostMapping("/plan/insert") + @PreAuthorize("@app.hasPermi('focus:sign:add')") + public AjaxResult palnInsert(@RequestBody YwSignPlanParam ywSignPlanParam) + { + + Boolean res = false; + + String strError = ""; + + try + { + if(ObjectUtils.isEmpty(ywSignPlanParam.getTimePeriods())) + { + YwSignPlanDTO ywSignPlanDTO =new YwSignPlanDTO(); + + BeanUtils.copyBeanProp(ywSignPlanDTO,ywSignPlanParam); + + res = ywSignPlanService.insertSignPlan(ywSignPlanDTO); + + if(!res) + { + strError = ywSignPlanDTO.getSignDates()[0]+" "+ywSignPlanDTO.getBeginTime()+" "+ywSignPlanDTO.getEndTime()+"相同场馆存在时间重叠"; + } + } + + + if(ObjectUtils.isNotEmpty(ywSignPlanParam.getTimePeriods())) + { + + for(YwSignPlanUserDTO ywSignPlanUserDTO : ywSignPlanParam.getTimePeriods()) + { + YwSignPlanDTO ywSignPlanDTO =new YwSignPlanDTO(); + + BeanUtils.copyBeanProp(ywSignPlanDTO,ywSignPlanParam); + + ywSignPlanDTO.setBeginTime(ywSignPlanUserDTO.getBeginTime()); + + ywSignPlanDTO.setEndTime(ywSignPlanUserDTO.getEndTime()); + + ywSignPlanDTO.setSignUsers(StringUtils.join(ywSignPlanUserDTO.getSignUsers(),",")); + + res = ywSignPlanService.insertSignPlan(ywSignPlanDTO); + + if(!res) + { + strError = ywSignPlanDTO.getSignDates()[0]+" "+ywSignPlanDTO.getBeginTime()+" "+ywSignPlanDTO.getEndTime()+"相同场馆存在时间重叠"; + break; + } + } + } + + if(res) + { + return AjaxResult.success(); + } + else + { + return AjaxResult.error(strError); + } + + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + + } + + @Log(title = "签到计划", businessType = BusinessType.UPDATE) + @ApiOperation("修改签到计划") + @PostMapping("/plan/update") + @PreAuthorize("@app.hasPermi('focus:signPlan:update')") + public AjaxResult palnUpdate(@RequestBody YwSignPlanParam ywSignPlanParam) + { + try + { + if(ObjectUtils.isEmpty(ywSignPlanParam.getTimePeriods())) + { + YwSignPlanDTO ywSignPlanDTO =new YwSignPlanDTO(); + BeanUtils.copyBeanProp(ywSignPlanDTO,ywSignPlanParam); + ywSignPlanService.updateSignPlan(ywSignPlanDTO); + return AjaxResult.success(); + } + + if(ObjectUtils.isNotEmpty(ywSignPlanParam.getTimePeriods())) + { + + for(YwSignPlanUserDTO ywSignPlanUserDTO : ywSignPlanParam.getTimePeriods()) + { + + YwSignPlanDTO ywSignPlanDTO =new YwSignPlanDTO(); + + BeanUtils.copyBeanProp(ywSignPlanDTO,ywSignPlanParam); + + ywSignPlanDTO.setBeginTime(ywSignPlanUserDTO.getBeginTime()); + + ywSignPlanDTO.setEndTime(ywSignPlanUserDTO.getEndTime()); + + ywSignPlanDTO.setSignUsers(StringUtils.join(ywSignPlanUserDTO.getSignUsers(),",")); + + ywSignPlanService.updateSignPlan(ywSignPlanDTO); + + } + } + + return AjaxResult.success(); + + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + + } + + @Log(title = "签到计划", businessType = BusinessType.DELETE) + @ApiOperation("删除签到计划") + @DeleteMapping("/plan/{id}") + @PreAuthorize("@app.hasPermi('focus:signPlan:del')") + public AjaxResult palnDelete(@PathVariable Long id) + { + try + { + ywSignPlanService.deleteSignPlan(id); + return AjaxResult.success(); + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + + } + + @ApiOperation("根据用户ID获取该用户的签到") + @GetMapping(value = { "/", "/{userId}" }) + public TableDataInfo list(@PathVariable(value = "userId", required = false) Long userId) + { + LambdaQueryWrapper lambdaQueryWrapper=new LambdaQueryWrapper<>(); + lambdaQueryWrapper.eq(YwSignLog::getUserId,userId); + List list = ywSignLogService.list(lambdaQueryWrapper); + return getDataTable(list); + } + + @Log(title = "批量签到", businessType = BusinessType.UPDATE) + @ApiOperation("后端批量签到") + @PostMapping("/signIn") + public AjaxResult signIn(@RequestBody YwSignInDTO ywSignInDTO) + { + try + { +// SysUser user = getLoginUser().getUser(); +// ywSignInDTO.setUserId(user.getUserId()); + ywSignLogService.SignIn(ywSignInDTO); + return AjaxResult.success(); + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + + } + + @Log(title = "签到计划导入", businessType = BusinessType.IMPORT) + @PostMapping("/plan/import") + public AjaxResult importData(MultipartFile file, Boolean updateSupport,Long sceneBigId) throws Exception + { + ExcelUtil util = new ExcelUtil(YwSignPlanDTO.class); + List signPlanList = util.importExcel(file.getInputStream()); + return ywSignPlanService.importSignPlan(signPlanList,updateSupport,sceneBigId); +// return success(message); + } + + @Log(title = "签到记录导出", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response,YwSignLogDTO ywSignLogDTO) throws IllegalAccessException { + ywSignLogDTO.setIsExport(true); + ywSignLogDTO = (YwSignLogDTO) yw_sceneService.validateUserVenues(ywSignLogDTO,YwSignLogDTO.class,"venueIds"); + TableDataInfo resData=ywSignLogViewService.getSignLog(ywSignLogDTO); + List list = ReflectUtils.toList(resData.getRows(),YwSignLogVo.class); + ExcelUtil util = new ExcelUtil(YwSignLogVo.class); + util.exportExcel(response, list, "签到数据"); + } + + @Log(title = "签到计划导出", businessType = BusinessType.EXPORT) + @PostMapping("/plan/export") + public void exportPlan(HttpServletResponse response,YwSignPlanDTO ywSignPlanDTO) throws IllegalAccessException { + ywSignPlanDTO.setIsExport(true); + ywSignPlanDTO = (YwSignPlanDTO) yw_sceneService.validateUserVenues(ywSignPlanDTO,YwSignPlanDTO.class,"venueIds"); + TableDataInfo resData=ywSignPlanService.getSignPlan(ywSignPlanDTO); + List list = ReflectUtils.toList(resData.getRows(), YwSignPlanVo.class); + ExcelUtil util = new ExcelUtil(YwSignPlanVo.class); + util.exportExcel(response, list, "签到计划数据"); + } + + @Log(title = "签到统计导出", businessType = BusinessType.EXPORT) + @PostMapping("/static/export") + public void exportStatic(HttpServletResponse response,YwSignLogDTO ywSignLogDTO) throws IllegalAccessException { + ywSignLogDTO.setIsExport(true); + ywSignLogDTO = (YwSignLogDTO) yw_sceneService.validateUserVenues(ywSignLogDTO,YwSignLogDTO.class,"venueIds"); + List list=ywSignLogViewService.getSignLogStatic(ywSignLogDTO); + ExcelUtil util = new ExcelUtil(YwSignLogStaticVo.class); + util.exportExcel(response, list, "签到统计数据"); + } + + +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwWireTaskLogController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwWireTaskLogController.java new file mode 100644 index 0000000..db5cab0 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/YwWireTaskLogController.java @@ -0,0 +1,167 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwWireTaskLog; +import com.ruoyi.eastcom_yw.domain.dto.YwWireTaskLogDTO; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.eastcom_yw.service.YwWireTaskLogService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +/** + * + * @author jkj + * @since 2023-01-12 + */ + +@Api("综合布线") +@RestController +@RequestMapping("/app/wireTask") +public class YwWireTaskLogController extends BaseController { + + @Autowired + private YwWireTaskLogService ywWireTaskLogService; + + @Autowired + private YwSceneService yw_sceneService; + + @Log(title = "布线记录", businessType = BusinessType.INSERT) + @ApiOperation("布线记录") + @PostMapping("/insert") + @PreAuthorize("@app.hasPermi('focus:wireTask:add')") + public AjaxResult insert(@RequestBody YwWireTaskLogDTO ywWireTaskLogDTO) + { + try + { + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + lambdaQueryWrapper.eq(StringUtils.isNotEmpty(ywWireTaskLogDTO.getWireTaskName()), YwWireTaskLog::getWireTaskName, ywWireTaskLogDTO.getWireTaskName()); + + if(ywWireTaskLogService.list(lambdaQueryWrapper).size()>0) + { + return AjaxResult.error("该场馆的任务名称已存在"); + } + + String res = ywWireTaskLogService.insertWireTaskLogReWireTaskId(ywWireTaskLogDTO); + if(StringUtils.isNotEmpty(res)) + { + return AjaxResult.success("新增布线日志成功",res); + } + else + { + return AjaxResult.error("新增布线日志失败"); + } + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + + } + + @Log(title = "布线记录", businessType = BusinessType.UPDATE) + @ApiOperation("布线记录") + @PostMapping("/update") +// @PreAuthorize("@app.hasPermi('focus:wireTask:update')") + public AjaxResult update(@RequestBody YwWireTaskLogDTO ywWireTaskLogDTO) + { + try + { + boolean res = ywWireTaskLogService.updateWireTaskLog(ywWireTaskLogDTO); + if(res) + { + return AjaxResult.success(); + } + else + { + return AjaxResult.error("修改布线日志失败"); + } + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + + } + + @Log(title = "布线记录", businessType = BusinessType.DELETE) + @PostMapping("/delete") + public AjaxResult remove(@RequestBody YwWireTaskLogDTO ywWireTaskLogDTO) + { + try + { + boolean res = ywWireTaskLogService.deleteWireTaskLog(ywWireTaskLogDTO); + if(res) + { + return AjaxResult.success(); + } + else + { + return AjaxResult.error("删除布线日志失败"); + } + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + } + @Log(title = "布线记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{wireTaskId}") + public AjaxResult remove(@PathVariable String wireTaskId) + { + try + { + YwWireTaskLogDTO ywWireTaskLogDTO=new YwWireTaskLogDTO(); + ywWireTaskLogDTO.setWireTaskId(wireTaskId); + + boolean res = ywWireTaskLogService.deleteWireTaskLog(ywWireTaskLogDTO); + if(res) + { + return AjaxResult.success(); + } + else + { + return AjaxResult.error("修改布线日志失败"); + } + } + catch (Exception ex) + { + return AjaxResult.error(ex.getMessage()); + } + } + + + @ApiOperation("获取场馆布线记录") + @PostMapping("/list") + public TableDataInfo list(@RequestBody YwWireTaskLogDTO ywWireTaskLogDTO) throws Exception { + ywWireTaskLogDTO.setIsApp(true); + if(ywWireTaskLogDTO.getVenueIds()!=null&&ywWireTaskLogDTO.getVenueIds().length==0){ + SysUser user = SecurityUtils.getLoginUser().getUser(); + //场馆集合 + List ywScenes = yw_sceneService.getVenueByUser(user); + Long[] venueIds = ywScenes.stream().map(YwScene::getId).toArray(Long[]::new); + ywWireTaskLogDTO.setVenueIds(venueIds); + } + TableDataInfo resData = ywWireTaskLogService.getWireTaskLog(ywWireTaskLogDTO); + return getDataTable(resData.getRows(), resData.getTotal()); + } + + + +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/dpConfigController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/dpConfigController.java new file mode 100644 index 0000000..1268d9e --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/eastcom_yw/dpConfigController.java @@ -0,0 +1,102 @@ +package com.ruoyi.app.controller.eastcom_yw; + +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.sunlm.domain.class_scene_match; +import com.ruoyi.sunlm.entity.scene_match_entity_list; +import com.ruoyi.sunlm.mapper.dpConfigMapper; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.List; + + +/** + * 参数配置 信息操作处理 + * + * @author ruoyi + * Spring Security提供了Spring EL表达式,允许我们在定义接口访问的方法上面添加注解,来控制访问权限 + * + * 方法 参数 描述 + * hasPermi String 验证用户是否具备某权限 + * lacksPermi String 验证用户是否不具备某权限,与hasPermi逻辑相反 + * hasAnyPermi String 验证用户是否具有以下任意一个权限 + * hasRole String 判断用户是否拥有某个权限 + * lacksRole String 验证用户是否不具备某个权限,与hasRole逻辑相反 + * hasAnyRoles String 验证用户是否具有以下任意一个角色,多个逗号分隔 + + */ + +@RestController +@CrossOrigin +@RequestMapping("/eastcom_yw/config") + +public class dpConfigController extends BaseController +{ + @Resource + dpConfigMapper MydpConfigMapper; //直接在这里引用数据库操作层(MAPPER),就不用写Service层了! + + @Resource + YwSceneService ywSceneService; + + + + //region------------------------------------------------------------------------------------赛程增删改查接口 + //--------------------------------------------获取赛程列表 + @ApiOperation("根据ID获取赛程") + @GetMapping(value = "/getscenematch/{matchid}") + public AjaxResult getscenematch(@PathVariable int matchid, HttpServletRequest request) + { + class_scene_match scenematch=new class_scene_match(); + scenematch = MydpConfigMapper.getscenematch(matchid); + return success(scenematch); + } + + @ApiOperation("根据查询条件获取赛程") + @PostMapping(value = "/getscenematchlist") + @RepeatSubmit(enable = false,interval = 1000) + public TableDataInfo getscenematchlists(@RequestBody scene_match_entity_list jsonObject, HttpServletRequest request) + { + List scenematch=new ArrayList(); + + String scenebigid=jsonObject.sceneBigId==null?getSceneStatusIs2():jsonObject.sceneBigId; + List sceneid=jsonObject.sceneIds==null?new ArrayList():jsonObject.sceneIds; + String taskName=jsonObject.taskName==null?"":jsonObject.taskName; + String taskStatus=jsonObject.taskStatus==null?"":jsonObject.taskStatus; + String taskdate=jsonObject.taskDate==null?"":jsonObject.taskDate; + + String tasktype=jsonObject.taskType==null?"":jsonObject.taskType; + + int pagenumber=jsonObject.pageNum; + int pagesize=jsonObject.pageSize; + scenematch= MydpConfigMapper.getscenematchlists(scenebigid,sceneid,taskName,taskStatus,taskdate,tasktype,pagenumber,pagesize); + + Long total=MydpConfigMapper.getscenematchlistscnt(scenebigid,sceneid,taskName,taskStatus,taskdate,tasktype); + return getDataTable(scenematch,total); + } + + //----------------------------获取当前场景ID + public String getSceneStatusIs2() + { + return MydpConfigMapper.getSceneBigIs2(); + } + + //----------------------------------------------新增 + public int getscenematchbyName(int sceneId,String name) + { + int counts= MydpConfigMapper.getscenematchbyName(sceneId,name); + return counts; + } + + + //endregion +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/CacheController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/CacheController.java new file mode 100644 index 0000000..4be98ff --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/CacheController.java @@ -0,0 +1,120 @@ +package com.ruoyi.app.controller.monitor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisCallback; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.domain.SysCache; + +/** + * 缓存监控 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/cache") +public class CacheController +{ + @Autowired + private RedisTemplate redisTemplate; + + private final static List caches = new ArrayList(); + { + caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息")); + caches.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "配置信息")); + caches.add(new SysCache(CacheConstants.SYS_DICT_KEY, "数据字典")); + caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码")); + caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交")); + caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理")); + caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数")); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping() + public AjaxResult getInfo() throws Exception + { + Properties info = (Properties) redisTemplate.execute((RedisCallback) connection -> connection.info()); + Properties commandStats = (Properties) redisTemplate.execute((RedisCallback) connection -> connection.info("commandstats")); + Object dbSize = redisTemplate.execute((RedisCallback) connection -> connection.dbSize()); + + Map result = new HashMap<>(3); + result.put("info", info); + result.put("dbSize", dbSize); + + List> pieList = new ArrayList<>(); + commandStats.stringPropertyNames().forEach(key -> { + Map data = new HashMap<>(2); + String property = commandStats.getProperty(key); + data.put("name", StringUtils.removeStart(key, "cmdstat_")); + data.put("value", StringUtils.substringBetween(property, "calls=", ",usec")); + pieList.add(data); + }); + result.put("commandStats", pieList); + return AjaxResult.success(result); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping("/getNames") + public AjaxResult cache() + { + return AjaxResult.success(caches); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping("/getKeys/{cacheName}") + public AjaxResult getCacheKeys(@PathVariable String cacheName) + { + Set cacheKeys = redisTemplate.keys(cacheName + "*"); + return AjaxResult.success(cacheKeys); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping("/getValue/{cacheName}/{cacheKey}") + public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey) + { + String cacheValue = redisTemplate.opsForValue().get(cacheKey); + SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue); + return AjaxResult.success(sysCache); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @DeleteMapping("/clearCacheName/{cacheName}") + public AjaxResult clearCacheName(@PathVariable String cacheName) + { + Collection cacheKeys = redisTemplate.keys(cacheName + "*"); + redisTemplate.delete(cacheKeys); + return AjaxResult.success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @DeleteMapping("/clearCacheKey/{cacheKey}") + public AjaxResult clearCacheKey(@PathVariable String cacheKey) + { + redisTemplate.delete(cacheKey); + return AjaxResult.success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @DeleteMapping("/clearCacheAll") + public AjaxResult clearCacheAll() + { + Collection cacheKeys = redisTemplate.keys("*"); + redisTemplate.delete(cacheKeys); + return AjaxResult.success(); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/ServerController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/ServerController.java new file mode 100644 index 0000000..3361102 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/ServerController.java @@ -0,0 +1,27 @@ +package com.ruoyi.app.controller.monitor; + +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.framework.web.domain.Server; + +/** + * 服务器监控 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/server") +public class ServerController +{ + @PreAuthorize("@ss.hasPermi('monitor:server:list')") + @GetMapping() + public AjaxResult getInfo() throws Exception + { + Server server = new Server(); + server.copyTo(); + return AjaxResult.success(server); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/SysLogininforController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/SysLogininforController.java new file mode 100644 index 0000000..7344163 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/SysLogininforController.java @@ -0,0 +1,82 @@ +package com.ruoyi.app.controller.monitor; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.framework.web.service.SysPasswordService; +import com.ruoyi.system.domain.SysLogininfor; +import com.ruoyi.system.service.ISysLogininforService; + +/** + * 系统访问记录 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/logininfor") +public class SysLogininforController extends BaseController +{ + @Autowired + private ISysLogininforService logininforService; + + @Autowired + private SysPasswordService passwordService; + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')") + @GetMapping("/list") + public TableDataInfo list(SysLogininfor logininfor) + { + startPage(); + List list = logininforService.selectLogininforList(logininfor); + return getDataTable(list); + } + + @Log(title = "登录日志", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysLogininfor logininfor) + { + List list = logininforService.selectLogininforList(logininfor); + ExcelUtil util = new ExcelUtil(SysLogininfor.class); + util.exportExcel(response, list, "登录日志"); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") + @Log(title = "登录日志", businessType = BusinessType.DELETE) + @DeleteMapping("/{infoIds}") + public AjaxResult remove(@PathVariable Long[] infoIds) + { + return toAjax(logininforService.deleteLogininforByIds(infoIds)); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") + @Log(title = "登录日志", businessType = BusinessType.CLEAN) + @DeleteMapping("/clean") + public AjaxResult clean() + { + logininforService.cleanLogininfor(); + return success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')") + @Log(title = "账户解锁", businessType = BusinessType.OTHER) + @GetMapping("/unlock/{userName}") + public AjaxResult unlock(@PathVariable("userName") String userName) + { + passwordService.clearLoginRecordCache(userName); + return success(); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/SysOperlogController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/SysOperlogController.java new file mode 100644 index 0000000..a1d0f5a --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/SysOperlogController.java @@ -0,0 +1,69 @@ +package com.ruoyi.app.controller.monitor; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.SysOperLog; +import com.ruoyi.system.service.ISysOperLogService; + +/** + * 操作日志记录 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/operlog") +public class SysOperlogController extends BaseController +{ + @Autowired + private ISysOperLogService operLogService; + + @PreAuthorize("@ss.hasPermi('monitor:operlog:list')") + @GetMapping("/list") + public TableDataInfo list(SysOperLog operLog) + { + startPage(); + List list = operLogService.selectOperLogList(operLog); + return getDataTable(list); + } + + @Log(title = "操作日志", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('monitor:operlog:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysOperLog operLog) + { + List list = operLogService.selectOperLogList(operLog); + ExcelUtil util = new ExcelUtil(SysOperLog.class); + util.exportExcel(response, list, "操作日志"); + } + + @Log(title = "操作日志", businessType = BusinessType.DELETE) + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") + @DeleteMapping("/{operIds}") + public AjaxResult remove(@PathVariable Long[] operIds) + { + return toAjax(operLogService.deleteOperLogByIds(operIds)); + } + + @Log(title = "操作日志", businessType = BusinessType.CLEAN) + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") + @DeleteMapping("/clean") + public AjaxResult clean() + { + operLogService.cleanOperLog(); + return success(); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/SysUserOnlineController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/SysUserOnlineController.java new file mode 100644 index 0000000..55b8ec3 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/monitor/SysUserOnlineController.java @@ -0,0 +1,92 @@ +package com.ruoyi.app.controller.monitor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.domain.SysUserOnline; +import com.ruoyi.system.service.ISysUserOnlineService; + +/** + * 在线用户监控 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/online") +public class SysUserOnlineController extends BaseController +{ + @Autowired + private ISysUserOnlineService userOnlineService; + + @Autowired + private RedisCache redisCache; + + @PreAuthorize("@ss.hasPermi('monitor:online:list')") + @GetMapping("/list") + public TableDataInfo list(String ipaddr, String userName) + { + Collection keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); + List userOnlineList = new ArrayList(); + for (String key : keys) + { + LoginUser user = redisCache.getCacheObject(key); + if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) + { + if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) + { + userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user)); + } + } + else if (StringUtils.isNotEmpty(ipaddr)) + { + if (StringUtils.equals(ipaddr, user.getIpaddr())) + { + userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user)); + } + } + else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser())) + { + if (StringUtils.equals(userName, user.getUsername())) + { + userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user)); + } + } + else + { + userOnlineList.add(userOnlineService.loginUserToUserOnline(user)); + } + } + Collections.reverse(userOnlineList); + userOnlineList.removeAll(Collections.singleton(null)); + return getDataTable(userOnlineList); + } + + /** + * 强退用户 + */ + @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')") + @Log(title = "在线用户", businessType = BusinessType.FORCE) + @DeleteMapping("/{tokenId}") + public AjaxResult forceLogout(@PathVariable String tokenId) + { + redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId); + return success(); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysAppMenuController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysAppMenuController.java new file mode 100644 index 0000000..40ec0c7 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysAppMenuController.java @@ -0,0 +1,118 @@ +package com.ruoyi.app.controller.system; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysAppMenu; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.service.ISysAppMenuService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 菜单信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/app/system/appMenu") +public class SysAppMenuController extends BaseController { + @Autowired + private ISysAppMenuService appMenuService; + + /** + * 获取菜单列表 + */ + @PreAuthorize("@ss.hasPermi('system:appMenu:list')") + @GetMapping("/list") + public AjaxResult list(SysAppMenu menu) { + List menus = appMenuService.selectMenuList(menu, getUserId()); + return success(menus); + } + + /** + * 根据菜单编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:appMenu:query')") + @GetMapping(value = "/{menuId}") + public AjaxResult getInfo(@PathVariable Long menuId) { + return success(appMenuService.selectMenuById(menuId)); + } + + /** + * 获取菜单下拉树列表 + */ + @GetMapping("/treeselect") + public AjaxResult treeselect(SysAppMenu menu) { + List menus = appMenuService.selectMenuList(menu, getUserId()); + return success(appMenuService.buildMenuTreeSelect(menus)); + } + + /** + * 加载对应角色菜单列表树 + */ + @GetMapping(value = "/roleMenuTreeselect/{roleId}/{menuCheckStrictly}") + public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId,@PathVariable("menuCheckStrictly") Boolean menuCheckStrictly) { + List menus = appMenuService.selectMenuList(getUserId()); + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", appMenuService.selectMenuListByRoleId(roleId,menuCheckStrictly)); + ajax.put("menus", appMenuService.buildMenuTreeSelect(menus)); + return ajax; + } + + /** + * 新增菜单 + */ + @PreAuthorize("@ss.hasPermi('system:appMenu:add')") + @Log(title = "菜单管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysAppMenu menu) { + if (UserConstants.NOT_UNIQUE.equals(appMenuService.checkMenuNameUnique(menu))) { + return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) { + return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + menu.setCreateBy(getUsername()); + return toAjax(appMenuService.insertMenu(menu)); + } + + /** + * 修改菜单 + */ + @PreAuthorize("@ss.hasPermi('system:appMenu:edit')") + @Log(title = "菜单管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysAppMenu menu) { + if (UserConstants.NOT_UNIQUE.equals(appMenuService.checkMenuNameUnique(menu))) { + return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) { + return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } else if (menu.getMenuId().equals(menu.getParentId())) { + return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己"); + } + menu.setUpdateBy(getUsername()); + return toAjax(appMenuService.updateMenu(menu)); + } + + /** + * 删除菜单 + */ + @PreAuthorize("@ss.hasPermi('system:appMenu:remove')") + @Log(title = "菜单管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{menuId}") + public AjaxResult remove(@PathVariable("menuId") Long menuId) { + if (appMenuService.hasChildByMenuId(menuId)) { + return warn("存在子菜单,不允许删除"); + } + if (appMenuService.checkMenuExistRole(menuId)) { + return warn("菜单已分配,不允许删除"); + } + return toAjax(appMenuService.deleteMenuById(menuId)); + } +} \ No newline at end of file diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysConfigController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysConfigController.java new file mode 100644 index 0000000..305f257 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysConfigController.java @@ -0,0 +1,134 @@ +package com.ruoyi.app.controller.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.SysConfig; +import com.ruoyi.system.service.ISysConfigService; + +/** + * 参数配置 信息操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/app/system/config") +public class SysConfigController extends BaseController +{ + @Autowired + private ISysConfigService configService; + + /** + * 获取参数配置列表 + */ + @PreAuthorize("@ss.hasPermi('system:config:list')") + @GetMapping("/list") + public TableDataInfo list(SysConfig config) + { + startPage(); + List list = configService.selectConfigList(config); + return getDataTable(list); + } + + @Log(title = "参数管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:config:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysConfig config) + { + List list = configService.selectConfigList(config); + ExcelUtil util = new ExcelUtil(SysConfig.class); + util.exportExcel(response, list, "参数数据"); + } + + /** + * 根据参数编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:config:query')") + @GetMapping(value = "/{configId}") + public AjaxResult getInfo(@PathVariable Long configId) + { + return success(configService.selectConfigById(configId)); + } + + /** + * 根据参数键名查询参数值 + */ + @GetMapping(value = "/configKey/{configKey}") + public AjaxResult getConfigKey(@PathVariable String configKey) + { + return success(configService.selectConfigByKey(configKey)); + } + + /** + * 新增参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:add')") + @Log(title = "参数管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysConfig config) + { + if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) + { + return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setCreateBy(getUsername()); + return toAjax(configService.insertConfig(config)); + } + + /** + * 修改参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:edit')") + @Log(title = "参数管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysConfig config) + { + if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) + { + return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setUpdateBy(getUsername()); + return toAjax(configService.updateConfig(config)); + } + + /** + * 删除参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:remove')") + @Log(title = "参数管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{configIds}") + public AjaxResult remove(@PathVariable Long[] configIds) + { + configService.deleteConfigByIds(configIds); + return success(); + } + + /** + * 刷新参数缓存 + */ + @PreAuthorize("@ss.hasPermi('system:config:remove')") + @Log(title = "参数管理", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + configService.resetConfigCache(); + return success(); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysDeptController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysDeptController.java new file mode 100644 index 0000000..fbc4bac --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysDeptController.java @@ -0,0 +1,132 @@ +package com.ruoyi.app.controller.system; + +import java.util.List; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDept; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.service.ISysDeptService; + +/** + * 部门信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/app/system/dept") +public class SysDeptController extends BaseController +{ + @Autowired + private ISysDeptService deptService; + + /** + * 获取部门列表 + */ + @PreAuthorize("@ss.hasPermi('system:dept:list')") + @GetMapping("/list") + public AjaxResult list(SysDept dept) + { + List depts = deptService.selectDeptList(dept); + return success(depts); + } + + /** + * 查询部门列表(排除节点) + */ + @PreAuthorize("@ss.hasPermi('system:dept:list')") + @GetMapping("/list/exclude/{deptId}") + public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) + { + List depts = deptService.selectDeptList(new SysDept()); + depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + "")); + return success(depts); + } + + /** + * 根据部门编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:dept:query')") + @GetMapping(value = "/{deptId}") + public AjaxResult getInfo(@PathVariable Long deptId) + { + deptService.checkDeptDataScope(deptId); + return success(deptService.selectDeptById(deptId)); + } + + /** + * 新增部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:add')") + @Log(title = "部门管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDept dept) + { + if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) + { + return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + dept.setCreateBy(getUsername()); + return toAjax(deptService.insertDept(dept)); + } + + /** + * 修改部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:edit')") + @Log(title = "部门管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDept dept) + { + Long deptId = dept.getDeptId(); + deptService.checkDeptDataScope(deptId); + if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) + { + return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + else if (dept.getParentId().equals(deptId)) + { + return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己"); + } + else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0) + { + return error("该部门包含未停用的子部门!"); + } + dept.setUpdateBy(getUsername()); + return toAjax(deptService.updateDept(dept)); + } + + /** + * 删除部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:remove')") + @Log(title = "部门管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{deptId}") + public AjaxResult remove(@PathVariable Long deptId) + { + if (deptService.hasChildByDeptId(deptId)) + { + return warn("存在下级部门,不允许删除"); + } + if (deptService.checkDeptExistUser(deptId)) + { + return warn("部门存在用户,不允许删除"); + } + deptService.checkDeptDataScope(deptId); + return toAjax(deptService.deleteDeptById(deptId)); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysDictDataController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysDictDataController.java new file mode 100644 index 0000000..42fc152 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysDictDataController.java @@ -0,0 +1,135 @@ +package com.ruoyi.app.controller.system; + +import java.util.ArrayList; +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.service.ISysDictDataService; +import com.ruoyi.system.service.ISysDictTypeService; + +/** + * 数据字典信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/app/system/dict/data") +public class SysDictDataController extends BaseController +{ + @Autowired + private ISysDictDataService dictDataService; + + @Autowired + private ISysDictTypeService dictTypeService; + + @PreAuthorize("@ss.hasPermi('system:dict:list')") + @GetMapping("/list") + public TableDataInfo list(SysDictData dictData) + { + startPage(); + List list = dictDataService.selectDictDataList(dictData); + return getDataTable(list); + } + + @Log(title = "字典数据", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:dict:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictData dictData) + { + List list = dictDataService.selectDictDataList(dictData); + ExcelUtil util = new ExcelUtil(SysDictData.class); + util.exportExcel(response, list, "字典数据"); + } + + /** + * 查询字典数据详细 + */ + @PreAuthorize("@ss.hasPermi('system:dict:query')") + @GetMapping(value = "/{dictCode}") + public AjaxResult getInfo(@PathVariable Long dictCode) + { + return success(dictDataService.selectDictDataById(dictCode)); + } + + /** + * 根据字典类型查询字典数据信息 + */ + @GetMapping(value = "/type/{dictType}") + public AjaxResult dictType(@PathVariable String dictType) + { + List data = dictTypeService.selectDictDataByType(dictType); + if (StringUtils.isNull(data)) + { + data = new ArrayList(); + } + return success(data); + } + + /** + * 新增字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:add')") + @Log(title = "字典数据", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictData dict) + { + dict.setCreateBy(getUsername()); + return toAjax(dictDataService.insertDictData(dict)); + } + + /** + * 修改保存字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:edit')") + @Log(title = "字典数据", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictData dict) + { + dict.setUpdateBy(getUsername()); + return toAjax(dictDataService.updateDictData(dict)); + } + + /** + * 删除字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictCodes}") + public AjaxResult remove(@PathVariable Long[] dictCodes) + { + dictDataService.deleteDictDataByIds(dictCodes); + return success(); + } + + /** + * 根据字典类型城市查询下属区域 + */ + @GetMapping(value = "/county") + public AjaxResult selectCountyByCity(String cityValue) + { + List data = dictTypeService.selectCountyByCity(cityValue); + if (StringUtils.isNull(data)) + { + data = new ArrayList(); + } + return success(data); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysDictTypeController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysDictTypeController.java new file mode 100644 index 0000000..b802e7e --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysDictTypeController.java @@ -0,0 +1,132 @@ +package com.ruoyi.app.controller.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDictType; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.service.ISysDictTypeService; + +/** + * 数据字典信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/app/system/dict/type") +public class SysDictTypeController extends BaseController +{ + @Autowired + private ISysDictTypeService dictTypeService; + + @PreAuthorize("@ss.hasPermi('system:dict:list')") + @GetMapping("/list") + public TableDataInfo list(SysDictType dictType) + { + startPage(); + List list = dictTypeService.selectDictTypeList(dictType); + return getDataTable(list); + } + + @Log(title = "字典类型", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:dict:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictType dictType) + { + List list = dictTypeService.selectDictTypeList(dictType); + ExcelUtil util = new ExcelUtil(SysDictType.class); + util.exportExcel(response, list, "字典类型"); + } + + /** + * 查询字典类型详细 + */ + @PreAuthorize("@ss.hasPermi('system:dict:query')") + @GetMapping(value = "/{dictId}") + public AjaxResult getInfo(@PathVariable Long dictId) + { + return success(dictTypeService.selectDictTypeById(dictId)); + } + + /** + * 新增字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:add')") + @Log(title = "字典类型", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictType dict) + { + if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) + { + return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setCreateBy(getUsername()); + return toAjax(dictTypeService.insertDictType(dict)); + } + + /** + * 修改字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:edit')") + @Log(title = "字典类型", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictType dict) + { + if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) + { + return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setUpdateBy(getUsername()); + return toAjax(dictTypeService.updateDictType(dict)); + } + + /** + * 删除字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictIds}") + public AjaxResult remove(@PathVariable Long[] dictIds) + { + dictTypeService.deleteDictTypeByIds(dictIds); + return success(); + } + + /** + * 刷新字典缓存 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + dictTypeService.resetDictCache(); + return success(); + } + + /** + * 获取字典选择框列表 + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List dictTypes = dictTypeService.selectDictTypeAll(); + return success(dictTypes); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysIndexController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysIndexController.java new file mode 100644 index 0000000..bd6ed8d --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysIndexController.java @@ -0,0 +1,29 @@ +package com.ruoyi.app.controller.system; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.utils.StringUtils; + +/** + * 首页 + * + * @author ruoyi + */ +@RestController +public class SysIndexController +{ + /** 系统基础配置 */ + @Autowired + private RuoYiConfig ruoyiConfig; + + /** + * 访问首页,提示语 + */ + @RequestMapping("/") + public String index() + { + return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion()); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysLoginController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysLoginController.java new file mode 100644 index 0000000..7595eb2 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysLoginController.java @@ -0,0 +1,167 @@ +package com.ruoyi.app.controller.system; + +import cn.hutool.core.util.StrUtil; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.annotation.RateLimiter; +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.domain.entity.SysMenu; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginBody; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.enums.LimitType; +import com.ruoyi.common.enums.OperatorType; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.framework.web.service.SysLoginService; +import com.ruoyi.framework.web.service.SysPermissionService; +import com.ruoyi.system.service.ISysDictDataService; +import com.ruoyi.system.service.ISysMenuService; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 登录验证 + * + * @author ruoyi + */ +@RestController +public class SysLoginController { + @Autowired + private SysLoginService loginService; + + @Autowired + private ISysMenuService menuService; + + @Autowired + private SysPermissionService permissionService; + + @Autowired + private YwSceneService yw_sceneService; + + @Autowired + private ISysDictDataService dictDataService; + + /** + * 发送登录短信验证码 + * + * @param + * @return + */ + @PostMapping("/getLoginCode") + @ApiOperation(value = "发送登录短信验证码") + @Log(title = "发送登录短信验证码日志", businessType = BusinessType.OTHER,operatorType= OperatorType.MOBILE) + @RateLimiter(time = 3,count = 1,limitType= LimitType.IP) + @RepeatSubmit(interval = 60000,message = "1分钟内请勿重复提交") + public AjaxResult getCode(@RequestBody LoginBody loginBody) throws Exception { + return loginService.getCode(loginBody); + } + + /** + * 登录方法 + * + * @param loginBody 登录信息 + * @return 结果 + */ + @PostMapping("/login") + @RateLimiter(time = 3,count = 1,limitType= LimitType.IP) + @Log(title = "发送登录日志", businessType = BusinessType.OTHER,operatorType= OperatorType.MANAGE) + public AjaxResult login(@RequestBody LoginBody loginBody) { + AjaxResult ajax = AjaxResult.success(); + String token = ""; + // 生成令牌 + if ("1".equals(loginBody.getLoginType())) { + token = loginService.loginByPhone(loginBody.getPhone(), loginBody.getCode(), + loginBody.getUuid(), UserConstants.APP); + } else { + token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), + loginBody.getUuid()); + } + ajax.put(Constants.TOKEN, Constants.TOKEN_PREFIX + token); + return ajax; + } + + /** + * app集成登录 + * + * @param mobile 登录信息 + * @return 结果 + */ + @PostMapping("/ydLogin") +// @RateLimiter(time = 3,count = 1,limitType= LimitType.IP) + @Log(title = "移动集成登录日志", businessType = BusinessType.OTHER,operatorType= OperatorType.OTHER) + public AjaxResult ydAppLogin(@RequestParam("mobile") String mobile) + { + if(StrUtil.isBlank(mobile)){ + AjaxResult ajaxResult = new AjaxResult(); + ajaxResult.put("success","false"); + ajaxResult.put("msg","手机号不能为空"); + ajaxResult.put("return_str",""); + return ajaxResult; + } + // 生成令牌 + return loginService.ydLoginByPhone(mobile); + } + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @GetMapping("getInfo") + @RepeatSubmit(enable = false) + public AjaxResult getInfo() { + SysUser user = SecurityUtils.getLoginUser().getUser(); + if (StrUtil.isNotBlank(user.getUserType())) { + String label = DictUtils.getDictLabel("yw_specialty", user.getUserType()); + user.setUserTypeStr(label); + } + // 角色集合 + Set roles = permissionService.getRolePermission(user); + // 权限集合 + Set permissions = permissionService.getAppMenuPermission(user); + //场馆集合 + //20230505APP端需要把用户场馆给绑定到下拉框,对于无法查询的那条场馆不能绑定,需要特殊处理去掉 + List ywScenes = yw_sceneService.getVenueByUserCanNoData(user,true); + //区县集合 + List countyIds = ywScenes.stream().map(YwScene::getAreaCountyId).filter(Objects::nonNull).distinct().collect(Collectors.toList()); + List countyList = dictDataService.selectDictLabelByValues("yw_county", countyIds); + //地市集合 + List cityIds = countyIds.stream().map(l -> l.substring(0, 4)).distinct().collect(Collectors.toList()); + List cityList = dictDataService.selectDictLabelByValues("yw_city", cityIds); + //专业集合 +// List ywScenes = yw_sceneService.getVenueByUser(user); + + AjaxResult ajax = AjaxResult.success(); + ajax.put("user", user); + ajax.put("roles", roles); + ajax.put("permissions", permissions); + ajax.put("ywScenes", ywScenes); + ajax.put("countys", countyList); + ajax.put("cityList", cityList); + return ajax; + } + + /** + * 获取路由信息 + * + * @return 路由信息 + */ + @GetMapping("getRouters") + public AjaxResult getRouters() { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuTreeByUserId(userId); + return AjaxResult.success(menuService.buildMenus(menus)); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysPostController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysPostController.java new file mode 100644 index 0000000..73e50b3 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysPostController.java @@ -0,0 +1,130 @@ +package com.ruoyi.app.controller.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.SysPost; +import com.ruoyi.system.service.ISysPostService; + +/** + * 岗位信息操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/app/system/post") +public class SysPostController extends BaseController +{ + @Autowired + private ISysPostService postService; + + /** + * 获取岗位列表 + */ + @PreAuthorize("@ss.hasPermi('system:post:list')") + @GetMapping("/list") + public TableDataInfo list(SysPost post) + { + startPage(); + List list = postService.selectPostList(post); + return getDataTable(list); + } + + @Log(title = "岗位管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:post:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysPost post) + { + List list = postService.selectPostList(post); + ExcelUtil util = new ExcelUtil(SysPost.class); + util.exportExcel(response, list, "岗位数据"); + } + + /** + * 根据岗位编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:post:query')") + @GetMapping(value = "/{postId}") + public AjaxResult getInfo(@PathVariable Long postId) + { + return success(postService.selectPostById(postId)); + } + + /** + * 新增岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:add')") + @Log(title = "岗位管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysPost post) + { + if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setCreateBy(getUsername()); + return toAjax(postService.insertPost(post)); + } + + /** + * 修改岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:edit')") + @Log(title = "岗位管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysPost post) + { + if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setUpdateBy(getUsername()); + return toAjax(postService.updatePost(post)); + } + + /** + * 删除岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:remove')") + @Log(title = "岗位管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{postIds}") + public AjaxResult remove(@PathVariable Long[] postIds) + { + return toAjax(postService.deletePostByIds(postIds)); + } + + /** + * 获取岗位选择框列表 + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List posts = postService.selectPostAll(); + return success(posts); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysProfileController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysProfileController.java new file mode 100644 index 0000000..2463334 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysProfileController.java @@ -0,0 +1,145 @@ +package com.ruoyi.app.controller.system; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.FileUploadUtils; +import com.ruoyi.common.utils.file.MimeTypeUtils; +import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.service.ISysUserService; + +/** + * 个人信息 业务处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/app/system/user/profile") +public class SysProfileController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private TokenService tokenService; + + /** + * 个人信息 + */ + @GetMapping + public AjaxResult profile() + { + LoginUser loginUser = getLoginUser(); + SysUser user = loginUser.getUser(); + AjaxResult ajax = AjaxResult.success(user); + ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername())); + ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername())); + return ajax; + } + + /** + * 修改用户 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult updateProfile(@RequestBody SysUser user) + { + LoginUser loginUser = getLoginUser(); + SysUser sysUser = loginUser.getUser(); + user.setUserName(sysUser.getUserName()); + if (StringUtils.isNotEmpty(user.getPhonenumber()) + && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) + { + return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + if (StringUtils.isNotEmpty(user.getEmail()) + && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) + { + return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setUserId(sysUser.getUserId()); + user.setPassword(null); + user.setAvatar(null); + user.setDeptId(null); + if (userService.updateUserProfile(user) > 0) + { + // 更新缓存用户信息 + sysUser.setNickName(user.getNickName()); + sysUser.setPhonenumber(user.getPhonenumber()); + sysUser.setEmail(user.getEmail()); + sysUser.setSex(user.getSex()); + sysUser.setFirstPage(user.getFirstPage()); + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改个人信息异常,请联系管理员"); + } + + /** + * 重置密码 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PutMapping("/updatePwd") + public AjaxResult updatePwd(String oldPassword, String newPassword) + { + LoginUser loginUser = getLoginUser(); + String userName = loginUser.getUsername(); + String password = loginUser.getPassword(); + if (!SecurityUtils.matchesPassword(oldPassword, password)) + { + return error("修改密码失败,旧密码错误"); + } + if (SecurityUtils.matchesPassword(newPassword, password)) + { + return error("新密码不能与旧密码相同"); + } + if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0) + { + // 更新缓存用户密码 + loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword)); + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改密码异常,请联系管理员"); + } + + /** + * 头像上传 + */ + @Log(title = "用户头像", businessType = BusinessType.UPDATE) + @PostMapping("/avatar") + public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception + { + if (!file.isEmpty()) + { + LoginUser loginUser = getLoginUser(); + String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION); + if (userService.updateUserAvatar(loginUser.getUsername(), avatar)) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("imgUrl", avatar); + // 更新缓存用户头像 + loginUser.getUser().setAvatar(avatar); + tokenService.setLoginUser(loginUser); + return ajax; + } + } + return error("上传图片异常,请联系管理员"); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysRegisterController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysRegisterController.java new file mode 100644 index 0000000..78331ee --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysRegisterController.java @@ -0,0 +1,38 @@ +package com.ruoyi.app.controller.system; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.model.RegisterBody; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.web.service.SysRegisterService; +import com.ruoyi.system.service.ISysConfigService; + +/** + * 注册验证 + * + * @author ruoyi + */ +@RestController +public class SysRegisterController extends BaseController +{ + @Autowired + private SysRegisterService registerService; + + @Autowired + private ISysConfigService configService; + + @PostMapping("/register") + public AjaxResult register(@RequestBody RegisterBody user) + { + if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) + { + return error("当前系统没有开启注册功能!"); + } + String msg = registerService.register(user); + return StringUtils.isEmpty(msg) ? success() : error(msg); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysRoleController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysRoleController.java new file mode 100644 index 0000000..ae93f78 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysRoleController.java @@ -0,0 +1,264 @@ +package com.ruoyi.app.controller.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDept; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.framework.web.service.SysPermissionService; +import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.domain.SysUserRole; +import com.ruoyi.system.service.ISysDeptService; +import com.ruoyi.system.service.ISysRoleService; +import com.ruoyi.system.service.ISysUserService; + +/** + * 角色信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/app/system/role") +public class SysRoleController extends BaseController +{ + @Autowired + private ISysRoleService roleService; + + @Autowired + private TokenService tokenService; + + @Autowired + private SysPermissionService permissionService; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysDeptService deptService; + + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/list") + public TableDataInfo list(SysRole role) + { + startPage(); + List list = roleService.selectRoleList(role); + return getDataTable(list); + } + + @Log(title = "角色管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:role:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysRole role) + { + List list = roleService.selectRoleList(role); + ExcelUtil util = new ExcelUtil(SysRole.class); + util.exportExcel(response, list, "角色数据"); + } + + /** + * 根据角色编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping(value = "/{roleId}") + public AjaxResult getInfo(@PathVariable Long roleId) + { + roleService.checkRoleDataScope(roleId); + return success(roleService.selectRoleById(roleId)); + } + + /** + * 新增角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:add')") + @Log(title = "角色管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysRole role) + { + if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setCreateBy(getUsername()); + return toAjax(roleService.insertRole(role)); + + } + + /** + * 修改保存角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setUpdateBy(getUsername()); + + if (roleService.updateAppRole(role) > 0) + { + // 更新缓存用户权限 + LoginUser loginUser = getLoginUser(); + if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin()) + { + loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser())); + loginUser.setAppPermissions(permissionService.getAppMenuPermission(loginUser.getUser())); + loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName())); + tokenService.setLoginUser(loginUser); + } + return success(); + } + return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员"); + } + + /** + * 修改保存数据权限 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping("/dataScope") + public AjaxResult dataScope(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + return toAjax(roleService.authDataScope(role)); + } + + /** + * 状态修改 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + role.setUpdateBy(getUsername()); + return toAjax(roleService.updateRoleStatus(role)); + } + + /** + * 删除角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:remove')") + @Log(title = "角色管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{roleIds}") + public AjaxResult remove(@PathVariable Long[] roleIds) + { + return toAjax(roleService.deleteRoleByIds(roleIds)); + } + + /** + * 获取角色选择框列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + return success(roleService.selectRoleAll()); + } + + /** + * 查询已分配用户角色列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/authUser/allocatedList") + public TableDataInfo allocatedList(SysUser user) + { + startPage(); + List list = userService.selectAllocatedList(user); + return getDataTable(list); + } + + /** + * 查询未分配用户角色列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/authUser/unallocatedList") + public TableDataInfo unallocatedList(SysUser user) + { + startPage(); + List list = userService.selectUnallocatedList(user); + return getDataTable(list); + } + + /** + * 取消授权用户 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancel") + public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole) + { + return toAjax(roleService.deleteAuthUser(userRole)); + } + + /** + * 批量取消授权用户 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancelAll") + public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds) + { + return toAjax(roleService.deleteAuthUsers(roleId, userIds)); + } + + /** + * 批量选择用户授权 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/selectAll") + public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds) + { + roleService.checkRoleDataScope(roleId); + return toAjax(roleService.insertAuthUsers(roleId, userIds)); + } + + /** + * 获取对应角色部门树列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping(value = "/deptTree/{roleId}") + public AjaxResult deptTree(@PathVariable("roleId") Long roleId) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId)); + ajax.put("depts", deptService.selectDeptTreeList(new SysDept())); + return ajax; + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysUserController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysUserController.java new file mode 100644 index 0000000..2d0e0e1 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/system/SysUserController.java @@ -0,0 +1,561 @@ +package com.ruoyi.app.controller.system; + +import cn.hutool.core.util.StrUtil; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDept; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.enums.UserStatus; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.eastcom_yw.domain.YwScene; +import com.ruoyi.eastcom_yw.domain.YwSceneUser; +import com.ruoyi.eastcom_yw.service.YwSceneService; +import com.ruoyi.eastcom_yw.service.YwSceneUserService; +import com.ruoyi.framework.web.service.SysPermissionService; +import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.domain.SysUserRole; +import com.ruoyi.system.mapper.SysUserMapper; +import com.ruoyi.system.service.*; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 用户信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/app/system/user") +@Transactional +public class SysUserController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysDeptService deptService; + + @Autowired + private ISysPostService postService; + + @Autowired + private YwSceneUserService ywSceneUserService; + + + @Autowired + private SysPermissionService permissionService; + + @Autowired + private TokenService tokenService; + + @Autowired + private RedisCache redisCache; + + @Autowired + private RedisTemplate redisTemplate; + + @Autowired + private ISysDictDataService dictDataService; + + @Autowired + private YwSceneService ywSceneService; + + @Autowired + private SysUserMapper sysUserMapper; + + + /** + * 获取用户列表 + */ +// @PreAuthorize("@ss.hasPermi('system:user:list')") + @GetMapping("/list") + public TableDataInfo list(SysUser user) + { + startPage(); + List list = userService.selectUserList(user); + + if(list.size()>0) + { + + List lstUserId = list.stream().map(SysUser::getUserId).collect(Collectors.toList()); + + List listScene = ywSceneUserService.getVenuesByUserIds(lstUserId); + + List listRole = roleService.selectRolesByUserIds(lstUserId); + + for(SysUser sysUser:list) { + + List lstSceneId = listScene.stream().filter(r -> r.getUserId().equals(sysUser.getUserId())).map(YwSceneUser::getSceneId).collect(Collectors.toList()); + int userSceneNum = lstSceneId.size(); + if(userSceneNum>0) + { + Long[] arr_ids = new Long[userSceneNum]; + lstSceneId.toArray(arr_ids); + List venueNames = listScene.stream().filter(r -> r.getUserId().equals(sysUser.getUserId())).map(YwSceneUser::getVenueName).collect(Collectors.toList()); +// String[] arrNames = new String[venueNames.size()]; + sysUser.setVenueIds(arr_ids); + sysUser.setVenueNames(venueNames); + } + else + { + sysUser.setVenueIds(new Long[0]); + sysUser.setVenueNames(new ArrayList()); + } + + List roleNames = listRole.stream().filter(r -> r.getUserId().equals(sysUser.getUserId())).map(SysUserRole::getRoleName).collect(Collectors.toList()); + if(roleNames.size()>0) { +// String[] arrRoleNames = new String[roleNames.size()]; + sysUser.setRoleNames(roleNames); + } + else + { + sysUser.setRoleNames(new ArrayList()); + } + if (StringUtils.isNotEmpty(sysUser.getBelongArea())) { + sysUser.setBelongArea(DictUtils.getDictLabel("yw_belong_area", sysUser.getBelongArea())); + } + + + } + } +// list.forEach( +// sysUser -> { +// List listScene = ywSceneUserService.getVenuesByUserId(sysUser.getUserId()); +// Long[] arr_ids = null; +// listScene.stream().map(YwSceneUser::getSceneId).collect(Collectors.toList()).toArray(arr_ids); +// List venueNames = listScene.stream().map(YwSceneUser::getVenueName).collect(Collectors.toList()); +// sysUser.setVenueIds(arr_ids); +// sysUser.setVenueNames(venueNames); +// +// List listRole = roleService.selectRolesByUserId2(sysUser.getUserId()); +// List roleNames = listRole.stream().map(SysRole::getRoleName).collect(Collectors.toList()); +// sysUser.setRoleNames(roleNames); +// +// } +// ); + return getDataTable(list); + } + + + @GetMapping("/specList") + public AjaxResult specList(SysUser user) + { + HashMap> map = userService.selectUserSpecList(user); + return success(map); + } + + + @Log(title = "用户管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:user:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysUser user) + { + List list = userService.selectUserList(user); + + list.forEach( + sysUser -> { + List listScene = ywSceneUserService.getVenuesByUserId(sysUser.getUserId()); + List venueNames=new ArrayList<>(); + List venueBelong=new ArrayList<>(); + listScene.forEach( + ywSceneUserVo -> { + venueNames.add(ywSceneUserVo.getVenueName()); + if(StringUtils.isNotEmpty(ywSceneUserVo.getBelongArea())) + { + String label = DictUtils.getDictLabel("yw_belong_area", ywSceneUserVo.getBelongArea()); + venueBelong.add(label); + } + } + ); + sysUser.setStrVenueNames(StringUtils.join(venueNames,",")); + sysUser.setStrBelongArea(StringUtils.join(venueBelong,",")); + List listRole = roleService.selectRolesByUserId2(sysUser.getUserId()); + List roleNames=new ArrayList<>(); + listRole.forEach( + role -> { + roleNames.add(role.getRoleName()); + } + ); + //设置角色 + sysUser.setStrRoles(StringUtils.join(roleNames,",")); + + if(StringUtils.isNotEmpty(sysUser.getUserType())) + { + //设置用户专业 + String label = DictUtils.getDictLabel("yw_specialty", sysUser.getUserType()); + sysUser.setUserType(label); + } + + //对city和county进行转中文 + if(StringUtils.isNotEmpty(sysUser.getCity())) + { + String label = DictUtils.getDictLabel("yw_city", sysUser.getCity()); + sysUser.setCity(label); + } + if(StringUtils.isNotEmpty(sysUser.getCounty())) + { + String label = DictUtils.getDictLabel("yw_county", sysUser.getCounty()); + sysUser.setCounty(label); + } + //场馆分区转 + if(StringUtils.isNotEmpty(sysUser.getDistinctArea())) + { + String label = DictUtils.getDictLabel("yw_belong_area", sysUser.getDistinctArea()); + sysUser.setDistinctArea(label); + } + + } + ); + + ExcelUtil util = new ExcelUtil(SysUser.class); + util.exportExcel(response, list, "用户数据"); + } + + @Log(title = "用户管理", businessType = BusinessType.IMPORT) + @PreAuthorize("@ss.hasPermi('system:user:import')") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(SysUser.class); + List userList = util.importExcel(file.getInputStream()); + String operName = getUsername(); + String message = userService.importUser(userList, updateSupport, operName); + return success(message); + } + + @PostMapping("/importTemplate") + public void importTemplate(HttpServletResponse response) + { + ExcelUtil util = new ExcelUtil(SysUser.class); + util.importTemplateExcel(response, "用户数据"); + } + + /** + * 根据用户编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:user:query')") + @GetMapping(value = { "/", "/{userId}" }) + public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) + { + userService.checkUserDataScope(userId); + AjaxResult ajax = AjaxResult.success(); + List roles = roleService.selectRoleAll(); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + ajax.put("posts", postService.selectPostAll()); + if (StringUtils.isNotNull(userId)) + { + SysUser sysUser = userService.selectUserById(userId); + ajax.put(AjaxResult.DATA_TAG, sysUser); + ajax.put("postIds", postService.selectPostListByUserId(userId)); + ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList())); + } + return ajax; + } + + /** + * 新增用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:add')") + @Log(title = "用户管理", businessType = BusinessType.INSERT) + @PostMapping + @Transactional + public AjaxResult add(@Validated @RequestBody SysUser user) + { + if (StringUtils.isNotEmpty(user.getPhonenumber()) + && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) + { + return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) + && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) + { + return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setCreateBy(getUsername()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + + //假定是可以看到所有场馆的角色,那么就不需要设置区县 +// if(user.isAdmin()) +// { +// user.setCounty(""); +// } + + int num = userService.insertUser(user); + //新增用户的场馆 + //20230303更新用户的场馆Ids + if(num>0) { + if (ObjectUtils.isNotEmpty(user.getVenueIds())) { + if (user.getVenueIds().length > 0) { + for (Long venueId : user.getVenueIds()) { + YwSceneUser ywSceneUser = new YwSceneUser(); + //由于没有返回用户的ID,所有这边需要去查询一次 + SysUser thisUser = userService.selectUserByPhone(user.getPhonenumber()); + List userIds =new ArrayList<>(); + userIds.add(thisUser.getUserId()); + ywSceneUser.setUserIds(userIds); + ywSceneUser.setSceneId(venueId); + //设置默认值,需签到,红区 + ywSceneUser.setNeedSign("1"); + //20230330 jkj 如果用户有设置区域,就用这个区域作为默认值,否则的话就用红区做默认值 + if(StringUtils.isNotEmpty(user.getDistinctArea())) + { + ywSceneUser.setBelongArea(user.getDistinctArea()); + } + if(StringUtils.isEmpty(user.getDistinctArea())) { + ywSceneUser.setBelongArea("red"); + } + ywSceneUserService.create(ywSceneUser); + } + } + } + } + return toAjax(num); + } + + /** + * 修改用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping + @Transactional + public AjaxResult edit(@Validated @RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + if (StringUtils.isNotEmpty(user.getPhonenumber()) + && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) + { + return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) + && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) + { + return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setUpdateBy(getUsername()); + + //20230303更新用户的场馆Ids + //删除之前的场馆,重新绑定新的 + ywSceneUserService.delete(user.getUserId()); + if(ObjectUtils.isNotEmpty(user.getVenueIds())) + { + for(Long venueId : user.getVenueIds()) { + YwSceneUser ywSceneUser = new YwSceneUser(); + ywSceneUser.setUserId(user.getUserId()); + ywSceneUser.setSceneId(venueId); + //设置默认值,需签到,红区 + ywSceneUser.setNeedSign("1"); + //20230330 jkj 如果用户有设置区域,就用这个区域作为默认值,否则的话就用红区做默认值 + if(StringUtils.isNotEmpty(user.getDistinctArea())) + { + ywSceneUser.setBelongArea(user.getDistinctArea()); + } + if(StringUtils.isEmpty(user.getDistinctArea())) { + ywSceneUser.setBelongArea("red"); + } + ywSceneUserService.save(ywSceneUser); + } + } + int res =userService.updateUser(user); + if(res>0) + { + //删除用户短信验证码错误的次数的缓存 + if(UserStatus.OK.getCode().equals(user.getStatus())) + { + String key = CacheConstants.SMS_ERR_CNT_KEY + user.getPhonenumber(); + if(redisCache.hasKey(key)) + { + redisCache.deleteObject(key); + } + } + + //删除处理用户登录的缓存 + //客户反映不够人性化 + //更新用户的缓存 + Collection keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); + for (String key : keys) { + LoginUser redisUser = redisCache.getCacheObject(key); + if (redisUser.getUserId().equals(user.getUserId())) { + redisUser.setVenueIds(user.getVenueIds()); + redisUser.setPermissions(permissionService.getMenuPermission(user)); + redisUser.setAppPermissions(permissionService.getAppMenuPermission(user)); + redisUser.setUser(userService.selectUserByUserName(user.getPhonenumber())); + //删除冻结账号的缓存 + if(UserStatus.SLEEP.getCode().equals(user.getStatus())) + { + redisCache.deleteObject(key); + } + else { + tokenService.refreshToken(redisUser); + } + } + } + +// +// for (String key : keys) { +// LoginUser redisUser = redisCache.getCacheObject(key); +// //找到登录用户 +// if (redisUser.getUserId().equals(user.getUserId())) { +// redisCache.deleteObject(key); +// } +// } + + } + return toAjax(res); + } + + /** + * 删除用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:remove')") + @Log(title = "用户管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{userIds}") + public AjaxResult remove(@PathVariable Long[] userIds) + { + //判断当前用户有没有进行中的物资审核任务 + List lstCheckUserId = sysUserMapper.selectCheckUserIdList(); + + for (Long checkUserId : lstCheckUserId) + { + if (ArrayUtils.contains(userIds, checkUserId)) + { +// return error("当前用户存在进行中的物资审核任务,请在任务完结或者驳回后重新选择其它审核人后再删除该用户"); + return error("当前用户存在进行中的物资审核任务"); + } + } + + if (ArrayUtils.contains(userIds, getUserId())) + { + return error("当前用户不能删除"); + } + + return toAjax(userService.deleteUserByIds(userIds)); + } + + /** + * 重置密码 + */ + @PreAuthorize("@ss.hasPermi('system:user:resetPwd')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/resetPwd") + public AjaxResult resetPwd(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + user.setUpdateBy(getUsername()); + return toAjax(userService.resetPwd(user)); + } + + /** + * 状态修改 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setUpdateBy(getUsername()); + return toAjax(userService.updateUserStatus(user)); + } + + /** + * 根据用户编号获取授权角色 + */ + @PreAuthorize("@ss.hasPermi('system:user:query')") + @GetMapping("/authRole/{userId}") + public AjaxResult authRole(@PathVariable("userId") Long userId) + { + AjaxResult ajax = AjaxResult.success(); + SysUser user = userService.selectUserById(userId); + List roles = roleService.selectRolesByUserId(userId); + ajax.put("user", user); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + return ajax; + } + + /** + * 用户授权角色 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.GRANT) + @PutMapping("/authRole") + public AjaxResult insertAuthRole(Long userId, Long[] roleIds) + { + userService.checkUserDataScope(userId); + userService.insertUserAuth(userId, roleIds); + return success(); + } + + /** + * 获取部门树列表 + */ + @PreAuthorize("@ss.hasPermi('system:user:list')") + @GetMapping("/deptTree") + public AjaxResult deptTree(SysDept dept) + { + return success(deptService.selectDeptTreeList(dept)); + } + + + /** + * 获取当前用户关联的场馆所在区县 + */ + @GetMapping("/getCounty") + public AjaxResult getCounty(String cityId) { + SysUser user = SecurityUtils.getLoginUser().getUser(); + if(SecurityUtils.isAdmin(user.getUserId())){ + List countyList = dictDataService.selectDictLabelByValues("yw_county", null); + countyList=countyList.stream().filter(l->cityId.equals(l.getDictValue().substring(0,4))).collect(Collectors.toList()); + return success(countyList); + } + //场馆集合 + List ywScenes = ywSceneService.getVenueByUser(user); + //区县集合 + List countyIds = ywScenes.stream().map(YwScene::getAreaCountyId).filter(Objects::nonNull).distinct().collect(Collectors.toList()); + List countyList = dictDataService.selectDictLabelByValues("yw_county", countyIds); + + if(StrUtil.isNotBlank(cityId)){ + countyList=countyList.stream().filter(l->cityId.equals(l.getDictValue().substring(0,4))).collect(Collectors.toList()); + } + return success(countyList); + } + + /** + * 根据专业查询专业下人数 + */ + @GetMapping("/selectUserByUserType") + public TableDataInfo selectUserByUserType() + { + return getDataTable(userService.selectUserByUserType()); + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/controller/tool/TestController.java b/ruoyi-app/src/main/java/com/ruoyi/app/controller/tool/TestController.java new file mode 100644 index 0000000..7fe6bef --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/controller/tool/TestController.java @@ -0,0 +1,183 @@ +package com.ruoyi.app.controller.tool; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.utils.StringUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import io.swagger.annotations.ApiOperation; + +/** + * swagger 用户测试方法 + * + * @author ruoyi + */ +@Api("用户信息管理") +@RestController +@RequestMapping("/test/user") +public class TestController extends BaseController +{ + private final static Map users = new LinkedHashMap(); + { + users.put(1, new UserEntity(1, "admin", "admin123", "15888888888")); + users.put(2, new UserEntity(2, "ry", "admin123", "15666666666")); + } + + @ApiOperation("获取用户列表") + @GetMapping("/list") + public R> userList() + { + List userList = new ArrayList(users.values()); + return R.ok(userList); + } + + @ApiOperation("获取用户详细") + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) + @GetMapping("/{userId}") + public R getUser(@PathVariable Integer userId) + { + if (!users.isEmpty() && users.containsKey(userId)) + { + return R.ok(users.get(userId)); + } + else + { + return R.fail("用户不存在"); + } + } + + @ApiOperation("新增用户") + @ApiImplicitParams({ + @ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class), + @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class) + }) + @PostMapping("/save") + public R save(UserEntity user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) + { + return R.fail("用户ID不能为空"); + } + users.put(user.getUserId(), user); + return R.ok(); + } + + @ApiOperation("更新用户") + @PutMapping("/update") + public R update(@RequestBody UserEntity user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) + { + return R.fail("用户ID不能为空"); + } + if (users.isEmpty() || !users.containsKey(user.getUserId())) + { + return R.fail("用户不存在"); + } + users.remove(user.getUserId()); + users.put(user.getUserId(), user); + return R.ok(); + } + + @ApiOperation("删除用户信息") + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) + @DeleteMapping("/{userId}") + public R delete(@PathVariable Integer userId) + { + if (!users.isEmpty() && users.containsKey(userId)) + { + users.remove(userId); + return R.ok(); + } + else + { + return R.fail("用户不存在"); + } + } +} + +@ApiModel(value = "UserEntity", description = "用户实体") +class UserEntity +{ + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("用户名称") + private String username; + + @ApiModelProperty("用户密码") + private String password; + + @ApiModelProperty("用户手机") + private String mobile; + + public UserEntity() + { + + } + + public UserEntity(Integer userId, String username, String password, String mobile) + { + this.userId = userId; + this.username = username; + this.password = password; + this.mobile = mobile; + } + + public Integer getUserId() + { + return userId; + } + + public void setUserId(Integer userId) + { + this.userId = userId; + } + + public String getUsername() + { + return username; + } + + public void setUsername(String username) + { + this.username = username; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public String getMobile() + { + return mobile; + } + + public void setMobile(String mobile) + { + this.mobile = mobile; + } +} diff --git a/ruoyi-app/src/main/java/com/ruoyi/app/core/config/SwaggerConfig.java b/ruoyi-app/src/main/java/com/ruoyi/app/core/config/SwaggerConfig.java new file mode 100644 index 0000000..be19978 --- /dev/null +++ b/ruoyi-app/src/main/java/com/ruoyi/app/core/config/SwaggerConfig.java @@ -0,0 +1,125 @@ +package com.ruoyi.app.core.config; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.ruoyi.common.config.RuoYiConfig; +import io.swagger.annotations.ApiOperation; +import io.swagger.models.auth.In; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.ApiKey; +import springfox.documentation.service.AuthorizationScope; +import springfox.documentation.service.Contact; +import springfox.documentation.service.SecurityReference; +import springfox.documentation.service.SecurityScheme; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; + +/** + * Swagger2的接口配置 + * + * @author ruoyi + */ +@Configuration +public class SwaggerConfig +{ + /** 系统基础配置 */ + @Autowired + private RuoYiConfig ruoyiConfig; + + /** 是否开启swagger */ + @Value("${swagger.enabled}") + private boolean enabled; + + /** 设置请求的统一前缀 */ + @Value("${swagger.pathMapping}") + private String pathMapping; + + /** + * 创建API + */ + @Bean + public Docket createRestApi() + { + return new Docket(DocumentationType.OAS_30) + // 是否启用Swagger + .enable(enabled) + // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息) + .apiInfo(apiInfo()) + // 设置哪些接口暴露给Swagger展示 + .select() + // 扫描所有有注解的api,用这种方式更灵活 + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + // 扫描指定包中的swagger注解 + // .apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger")) + // 扫描所有 .apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()) + .build() + /* 设置安全模式,swagger可以设置访问token */ + .securitySchemes(securitySchemes()) + .securityContexts(securityContexts()) + .pathMapping(pathMapping); + } + + /** + * 安全模式,这里指定token通过Authorization头请求头传递 + */ + private List securitySchemes() + { + List apiKeyList = new ArrayList(); + apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue())); + return apiKeyList; + } + + /** + * 安全上下文 + */ + private List securityContexts() + { + List securityContexts = new ArrayList<>(); + securityContexts.add( + SecurityContext.builder() + .securityReferences(defaultAuth()) + .operationSelector(o -> o.requestMappingPattern().matches("/.*")) + .build()); + return securityContexts; + } + + /** + * 默认的安全上引用 + */ + private List defaultAuth() + { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + List securityReferences = new ArrayList<>(); + securityReferences.add(new SecurityReference("Authorization", authorizationScopes)); + return securityReferences; + } + + /** + * 添加摘要信息 + */ + private ApiInfo apiInfo() + { + // 用ApiInfoBuilder进行定制 + return new ApiInfoBuilder() + // 设置标题 + .title("标题:若依管理系统_接口文档") + // 描述 + .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...") + // 作者信息 + .contact(new Contact(ruoyiConfig.getName(), null, null)) + // 版本 + .version("版本号:" + ruoyiConfig.getVersion()) + .build(); + } +} diff --git a/ruoyi-app/src/main/resources/META-INF/spring-devtools.properties b/ruoyi-app/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..2b23f85 --- /dev/null +++ b/ruoyi-app/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.json=/com.alibaba.fastjson.*.jar \ No newline at end of file diff --git a/ruoyi-app/src/main/resources/application-bak1.yml b/ruoyi-app/src/main/resources/application-bak1.yml new file mode 100644 index 0000000..dc3166b --- /dev/null +++ b/ruoyi-app/src/main/resources/application-bak1.yml @@ -0,0 +1,145 @@ +# 项目相关配置 +ruoyi: + # 名称 + name: RuoYi_app + # 版本 + version: 3.8.4 + # 版权年份 + copyrightYear: 2022 + # 实例演示开关 + demoEnabled: true + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: /home/hzdx/data/java/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数组计算 char 字符验证 + captchaType: math + +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource +# driverClassName: com.mysql.cj.jdbc.Driver + driverClassName: org.postgresql.Driver + druid: + # 主库数据源 + master: +# url: jdbc:mysql://183.247.163.49:7940/ry_v3?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + url: jdbc:postgresql://10.71.80.241:5432/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true +# url: jdbc:postgresql://127.0.0.1:5432/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true +# url: jdbc:postgresql://183.247.163.49:8099/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true + username: pms + password: Ea$tcyd2023 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # redis 配置 + redis: + # 地址 + host: 10.71.80.241 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 0 + # 密码 + password: YyunRedis@Zxp01 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + +#简报配置 +file: + #文件访问地址前缀 + visitpath: http://183.247.163.49:8093/profile/upload/ + #json本地保存路径 + briefingJsonPath: /home/hzdx/data/java/uploadPath/briefingJson + #json上传路径 + briefingShortUrl: http://10.71.80.185:31994/uploadfile/asiagame + #场馆配置中ppru拓扑图存放路径 + sceneJsonPath: /home/hzdx/data/java/uploadPath/shorturl + +# 短信发送配置 +system: + msg: + url: http://10.71.80.246/api/PublicHandler.ashx + sms_comm: send_sms + ivr_comm: send_ivr_call + mobileoffice_comm: send_mobileoffice_zmcc + #企业编号 + applicationid: 1087 + #企业名 + platform_code: 东信亚运重保 + publickey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhBtwcgGVE1ILMDoxU4Og77PugS2JlHDnfkmHO3Ek0s+L4ukWDbh6XvRNxUIBM9GvhvrdT7JGE7/Xq6oIYRk6QqfvYp/aHzw1DkhoEz7Bx9O0fdQKWMCHd4kl6hmyLeurmr11/h6nwtu1U/R2BqJ/blRCebUuYvMaCxVO1rr8irQIDAQAB + +workFlowUrl: http://10.71.80.231:8080 +#workFlowUrl: http://127.0.0.1:8080 + +# minio 文件存储配置信息 +minio: + url: http://192.168.97.212:9000/ + endpoint: + accesskey: minioadmin + secretKey: minioadmin + bucketName: yyzxp + prefix: + +token: + # 是否允许同类型端同时登录(true允许 false不允许) + soloLogin: false + +logging: + level: + com.ruoyi: info + org.springframework: warn \ No newline at end of file diff --git a/ruoyi-app/src/main/resources/application-bak2.yml b/ruoyi-app/src/main/resources/application-bak2.yml new file mode 100644 index 0000000..2572bc3 --- /dev/null +++ b/ruoyi-app/src/main/resources/application-bak2.yml @@ -0,0 +1,145 @@ +# 项目相关配置 +ruoyi: + # 名称 + name: RuoYi_app + # 版本 + version: 3.8.4 + # 版权年份 + copyrightYear: 2022 + # 实例演示开关 + demoEnabled: true + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: /home/hzdx/data/java/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数组计算 char 字符验证 + captchaType: math + +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource +# driverClassName: com.mysql.cj.jdbc.Driver + driverClassName: org.postgresql.Driver + druid: + # 主库数据源 + master: +# url: jdbc:mysql://183.247.163.49:7940/ry_v3?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + url: jdbc:postgresql://10.71.80.231:5432/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true +# url: jdbc:postgresql://127.0.0.1:5432/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true +# url: jdbc:postgresql://183.247.163.49:8099/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true + username: pms + password: Ea$tcyd2023 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # redis 配置 + redis: + # 地址 + host: 10.71.80.231 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 0 + # 密码 + password: YyunRedis@Zxp01 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + +#简报配置 +file: + #文件访问地址前缀 + visitpath: http://183.247.163.49:8093/profile/upload/ + #json本地保存路径 + briefingJsonPath: /home/hzdx/data/java/uploadPath/briefingJson + #json上传路径 + briefingShortUrl: http://10.71.80.185:31994/uploadfile/asiagame + #场馆配置中ppru拓扑图存放路径 + sceneJsonPath: /home/hzdx/data/java/uploadPath/shorturl + +# 短信发送配置 +system: + msg: + url: http://10.71.80.246/api/PublicHandler.ashx + sms_comm: send_sms + ivr_comm: send_ivr_call + mobileoffice_comm: send_mobileoffice_zmcc + #企业编号 + applicationid: 1087 + #企业名 + platform_code: 东信亚运重保 + publickey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhBtwcgGVE1ILMDoxU4Og77PugS2JlHDnfkmHO3Ek0s+L4ukWDbh6XvRNxUIBM9GvhvrdT7JGE7/Xq6oIYRk6QqfvYp/aHzw1DkhoEz7Bx9O0fdQKWMCHd4kl6hmyLeurmr11/h6nwtu1U/R2BqJ/blRCebUuYvMaCxVO1rr8irQIDAQAB + +workFlowUrl: http://10.71.80.231:8080 +#workFlowUrl: http://127.0.0.1:8080 + +# minio 文件存储配置信息 +minio: + url: http://192.168.97.212:9000/ + endpoint: + accesskey: minioadmin + secretKey: minioadmin + bucketName: yyzxp + prefix: + +token: + # 是否允许同类型端同时登录(true允许 false不允许) + soloLogin: false + +logging: + level: + com.ruoyi: info + org.springframework: warn \ No newline at end of file diff --git a/ruoyi-app/src/main/resources/application-druid.yml b/ruoyi-app/src/main/resources/application-druid.yml new file mode 100644 index 0000000..7748735 --- /dev/null +++ b/ruoyi-app/src/main/resources/application-druid.yml @@ -0,0 +1,138 @@ +# 项目相关配置 +ruoyi: + # 名称 + name: RuoYi_app + # 版本 + version: 3.8.4 + # 版权年份 + copyrightYear: 2022 + # 实例演示开关 + demoEnabled: true + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: C:/ruoyi/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数组计算 char 字符验证 + captchaType: math + +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource +# driverClassName: com.mysql.cj.jdbc.Driver + driverClassName: org.postgresql.Driver + druid: + # 主库数据源 + master: +# url: jdbc:mysql://183.247.163.49:7940/ry_v3?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + url: jdbc:postgresql://192.168.97.156:5432/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true +# url: jdbc:postgresql://183.247.163.49:8099/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true + username: postgres + password: eastcom + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # redis 配置 + redis: + # 地址 + host: 192.168.97.212 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 0 + # 密码 + password: YyunRedis@Zxp01 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + +#简报配置 +file: + #文件访问地址前缀 + visitpath: http://183.247.163.49:8093/profile/upload/ + #json本地保存路径 + briefingJsonPath: C:\json\ + #json上传路径 + briefingShortUrl: http://192.168.97.142:80/uploadfile/test + #场馆配置中ppru拓扑图存放路径 + sceneJsonPath: C:\home\data\java\uploadPath\upload\json\ + +# 短信发送配置 +system: + msg: + url: http://10.71.80.246/api/PublicHandler.ashx + sms_comm: send_sms + ivr_comm: send_ivr_call + mobileoffice_comm: send_mobileoffice_zmcc + #企业编号 + applicationid: 1087 + #企业名 + platform_code: 东信亚运重保 + publickey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhBtwcgGVE1ILMDoxU4Og77PugS2JlHDnfkmHO3Ek0s+L4ukWDbh6XvRNxUIBM9GvhvrdT7JGE7/Xq6oIYRk6QqfvYp/aHzw1DkhoEz7Bx9O0fdQKWMCHd4kl6hmyLeurmr11/h6nwtu1U/R2BqJ/blRCebUuYvMaCxVO1rr8irQIDAQAB + +workFlowUrl: http://192.168.97.212:8080 + +# minio 文件存储配置信息 +minio: + url: http://192.168.97.212:9000/ + endpoint: + accesskey: minioadmin + secretKey: minioadmin + bucketName: yyzxp + prefix: + +token: + # 是否允许同类型端同时登录(true允许 false不允许) + soloLogin: true \ No newline at end of file diff --git a/ruoyi-app/src/main/resources/application-test.yml b/ruoyi-app/src/main/resources/application-test.yml new file mode 100644 index 0000000..af95de9 --- /dev/null +++ b/ruoyi-app/src/main/resources/application-test.yml @@ -0,0 +1,145 @@ +# 项目相关配置 +ruoyi: + # 名称 + name: RuoYi_app + # 版本 + version: 3.8.4 + # 版权年份 + copyrightYear: 2022 + # 实例演示开关 + demoEnabled: true + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: /home/data/java/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数组计算 char 字符验证 + captchaType: math + +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource +# driverClassName: com.mysql.cj.jdbc.Driver + driverClassName: org.postgresql.Driver + druid: + # 主库数据源 + master: +# url: jdbc:mysql://183.247.163.49:7940/ry_v3?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 +# url: jdbc:postgresql://10.71.80.241:5432/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true + url: jdbc:postgresql://127.0.0.1:5432/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true +# url: jdbc:postgresql://183.247.163.49:8099/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true + username: pms + password: Ea$tcyd2023 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # redis 配置 + redis: + # 地址 + host: localhost + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 0 + # 密码 + password: YyunRedis@Zxp01 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + +#简报配置 +file: + #文件访问地址前缀 + visitpath: http://183.247.163.49:8093/profile/upload/ + #json本地保存路径 + briefingJsonPath: /home/data/java/uploadPath/briefingJson + #json上传路径 + briefingShortUrl: http://10.71.80.185:31994/uploadfile/asiagame + #场馆配置中ppru拓扑图存放路径 + sceneJsonPath: /home/data/java/uploadPath/shorturl + +# 短信发送配置 +system: + msg: + url: http://10.71.80.246/api/PublicHandler.ashx + sms_comm: send_sms + ivr_comm: send_ivr_call + mobileoffice_comm: send_mobileoffice_zmcc + #企业编号 + applicationid: 1087 + #企业名 + platform_code: 东信亚运重保 + publickey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhBtwcgGVE1ILMDoxU4Og77PugS2JlHDnfkmHO3Ek0s+L4ukWDbh6XvRNxUIBM9GvhvrdT7JGE7/Xq6oIYRk6QqfvYp/aHzw1DkhoEz7Bx9O0fdQKWMCHd4kl6hmyLeurmr11/h6nwtu1U/R2BqJ/blRCebUuYvMaCxVO1rr8irQIDAQAB + +workFlowUrl: http://10.71.80.241:8080 +#workFlowUrl: http://127.0.0.1:8080 + +# minio 文件存储配置信息 +minio: + url: http://192.168.97.212:9000/ + endpoint: + accesskey: minioadmin + secretKey: minioadmin + bucketName: yyzxp + prefix: + +token: + # 是否允许同类型端同时登录(true允许 false不允许) + soloLogin: false + +logging: + level: + com.ruoyi: info + org.springframework: warn \ No newline at end of file diff --git a/ruoyi-app/src/main/resources/application.properties b/ruoyi-app/src/main/resources/application.properties new file mode 100644 index 0000000..1604649 --- /dev/null +++ b/ruoyi-app/src/main/resources/application.properties @@ -0,0 +1,5 @@ +pagehelper.reasonable=false +pagehelper.supportMethodsArguments=true +pagehelper.params.count=countSql +pagehelper.auto-dialect=true +pagehelper.auto-runtime-dialect=true \ No newline at end of file diff --git a/ruoyi-app/src/main/resources/application.yml b/ruoyi-app/src/main/resources/application.yml new file mode 100644 index 0000000..8e79cd1 --- /dev/null +++ b/ruoyi-app/src/main/resources/application.yml @@ -0,0 +1,124 @@ +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 9000 + servlet: + # 应用的访问路径 + context-path: / + tomcat: + # tomcat的URI编码 + uri-encoding: UTF-8 + # 连接数满后的排队数,默认为100 + accept-count: 1000 + threads: + # tomcat最大线程数,默认为200 + max: 800 + # Tomcat启动初始化的线程数,默认值10 + min-spare: 100 + +# 安全停机 调用curl -X POST http://localhost:9000/monitor/shutdown +management: + endpoint: + shutdown: + enabled: true + endpoints: + web: + exposure: + include: "shutdown" + base-path: /monitor + +# 日志配置 +logging: + level: + com.ruoyi: debug + org.springframework: warn + +# 用户配置 +user: + password: + # 密码最大错误次数 + maxRetryCount: 5 + # 密码锁定时间(默认10分钟) + lockTime: 10 + sms: + # 密码最大错误次数 + maxRetryCount: 3 + # 密码锁定时间(默认10分钟) + lockTime: 15 + defaultCode: false + + +# Spring配置 +spring: + # 资源信息 + messages: + # 国际化资源文件路径 + basename: i18n/messages + profiles: + active: druid + # 文件上传 + servlet: + multipart: + # 单个文件大小 + max-file-size: 10MB + # 设置总上传的文件大小 + max-request-size: 20MB + # 服务模块 + devtools: + restart: + # 热部署开关 + enabled: true + jackson: + #日期格式化 + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 +# token配置 +token: + # 令牌自定义标识 + header: Authorization + # 令牌密钥 + secret: abcdefghijklmnopqrstuvwxyz + # 令牌有效期(默认30分钟) + expireTime: 4320 + +# MyBatis配置 +#mybatis: +# # 搜索指定包别名 +# typeAliasesPackage: com.ruoyi.**.domain +# # 配置mapper的扫描,找到所有的mapper.xml映射文件 +# mapperLocations: classpath*:mapper/**/*Mapper.xml +# # 加载全局的配置文件 +# configLocation: classpath:mybatis/mybatis-config.xml + +mybatis-plus: + type-aliases-package: com.ruoyi.**.domain + mapper-locations: classpath*:mapper/**/*Mapper.xml + config-location: classpath:mybatis/mybatis-config.xml + +# PageHelper分页插件 +pagehelper: + helperDialect: mysql + supportMethodsArguments: true + params: count=countSql + page-size-zero: true + +# Swagger配置 +swagger: + # 是否开启swagger + enabled: true + # 请求前缀 + pathMapping: /dev-api + +# 防止XSS攻击 +xss: + # 过滤开关 + enabled: true + # 排除链接(多个用逗号分隔) + excludes: /system/notice + # 匹配链接 + urlPatterns: /system/*,/monitor/*,/tool/* + +# 登录文本加密公私钥 +login: + publicKey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCqjPHyVJ5u9E+d0CMYyc3mMdQ/ac9UZdF9oz2Bxr6UDKNax+Zhn/OARKozMAzH2cpYsb4kGPYTHPzmrbgegbACC7bTFSFFBSkotvvfDHd+YbfgxfNf/VbwczMl/E3OMHzRFbrLO8v3ozA+2w2Gyg0UAV6AGliVrQHCuKIDYV0EwIDAQAB + privateKey: MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMKqM8fJUnm70T53QIxjJzeYx1D9pz1Rl0X2jPYHGvpQMo1rH5mGf84BEqjMwDMfZylixviQY9hMc/OatuB6BsAILttMVIUUFKSi2+98Md35ht+DF81/9VvBzMyX8Tc4wfNEVuss7y/ejMD7bDYbKDRQBXoAaWJWtAcK4ogNhXQTAgMBAAECgYBAzlzytClK8aYVf6nzksbpkWk5o1hb55/O4OfIuFDY6H4L6o/YkphVwrGtlIyf+GJlusa21YsH5Vvsy6L6VGWOT/T1Q924zxwhPHFP8fzWrWJ60IT5jGDChJ1jls8GRWHgCnriQRMHU36eqENC5VZiYdfuulGN2bUNgMzUgmv9UQJBAOZio3CAQ+mwOsdRWixaput636qXoryleXiYrzGOulTzdYrRnJCIF3fE6H9uX5i2MwA3HtgTkN3qS4mtyBHvWP0CQQDYTt4KlkVJN3hsfV3qMk48zYE68lUg0umRaYXlQ0moLPO2P3wLFLLOq0jhWIwWz7ApIQXsR7x0RZOK2NadFFZPAkEA30Nh7klvBw2wuK3+/BLRxkxqavDOVZDq+dLFnPobWu4gz+m4l1w7mebqBWxaGi0fmarRKkcz0csXbxJJXBAepQJAKJtNpbEmGqOWMM+sJL4C3/k4TGeXwYy2mjy0DSD/n9moessaLz5YfuG60cr8qX+ds2rmoL+qyi0RkJw6VcyukwJAS5sxmn0YKbXw7GxDm7HmMcGuRYTo6ai+Olzk1GLwddTj56pfOgex+FF4FFyO33zzpEPeZbEzkbxkLC7Z8m0lWg== diff --git a/ruoyi-app/src/main/resources/banner.txt b/ruoyi-app/src/main/resources/banner.txt new file mode 100644 index 0000000..0931cb8 --- /dev/null +++ b/ruoyi-app/src/main/resources/banner.txt @@ -0,0 +1,24 @@ +Application Version: ${ruoyi.version} +Spring Boot Version: ${spring-boot.version} +//////////////////////////////////////////////////////////////////// +// _ooOoo_ // +// o8888888o // +// 88" . "88 // +// (| ^_^ |) // +// O\ = /O // +// ____/`---'\____ // +// .' \\| |// `. // +// / \\||| : |||// \ // +// / _||||| -:- |||||- \ // +// | | \\\ - /// | | // +// | \_| ''\---/'' | | // +// \ .-\__ `-` ___/-. / // +// ___`. .' /--.--\ `. . ___ // +// ."" '< `.___\_<|>_/___.' >'"". // +// | | : `- \`.;`\ _ /`;.`/ - ` : | | // +// \ \ `-. \_ __\ /__ _/ .-` / / // +// ========`-.____`-.___\_____/___.-`____.-'======== // +// `=---=' // +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // +// 佛祖保佑 永不宕机 永无BUG // +//////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/ruoyi-app/src/main/resources/i18n/messages.properties b/ruoyi-app/src/main/resources/i18n/messages.properties new file mode 100644 index 0000000..6a9e0ab --- /dev/null +++ b/ruoyi-app/src/main/resources/i18n/messages.properties @@ -0,0 +1,41 @@ +#错误消息 +not.null=* 必须填写 +user.jcaptcha.error=验证码错误 +user.jcaptcha.expire=验证码已失效 +user.sms.expire=短信验证码已失效 +user.not.exists=用户不存在/密码错误 +user.password.not.match=用户不存在/密码错误 +user.password.retry.limit.count=密码输入错误{0}次 +user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟 +user.sms.not.match=短信验证码输入错误,还剩{0}次 +user.sms.retry.limit.count=短信验证码输入错误{0}次 +user.sms.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟 +user.password.delete=对不起,您的账号已被删除 +user.blocked=用户已封禁,请联系管理员 +role.blocked=角色已封禁,请联系管理员 +user.logout.success=退出成功 + +length.not.valid=长度必须在{min}到{max}个字符之间 + +user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头 +user.password.not.valid=* 5-50个字符 + +user.email.not.valid=邮箱格式错误 +user.mobile.phone.number.not.valid=手机号格式错误 +user.login.success=登录成功 +user.register.success=注册成功 +user.notfound=请重新登录 +user.forcelogout=管理员强制退出,请重新登录 +user.unknown.error=未知错误,请重新登录 + +##文件上传消息 +upload.exceed.maxSize=上传的文件大小超出限制的文件大小!
允许的文件最大大小是:{0}MB! +upload.filename.exceed.length=上传的文件名最长{0}个字符 + +##权限 +no.permission=您没有数据的权限,请联系管理员添加权限 [{0}] +no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}] +no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}] +no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}] +no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}] +no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}] diff --git a/ruoyi-app/src/main/resources/logback.xml b/ruoyi-app/src/main/resources/logback.xml new file mode 100644 index 0000000..a360583 --- /dev/null +++ b/ruoyi-app/src/main/resources/logback.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/sys-info.log + + + + ${log.path}/sys-info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/sys-error.log + + + + ${log.path}/sys-error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + ${log.path}/sys-user.log + + + ${log.path}/sys-user.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-app/src/main/resources/mybatis/mybatis-config.xml b/ruoyi-app/src/main/resources/mybatis/mybatis-config.xml new file mode 100644 index 0000000..10cf6b0 --- /dev/null +++ b/ruoyi-app/src/main/resources/mybatis/mybatis-config.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-app/src/main/resources/rebel-remote.xml b/ruoyi-app/src/main/resources/rebel-remote.xml new file mode 100644 index 0000000..3496ea5 --- /dev/null +++ b/ruoyi-app/src/main/resources/rebel-remote.xml @@ -0,0 +1,4 @@ + + + com.ruoyi.ruoyi-app + diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml new file mode 100644 index 0000000..e71a266 --- /dev/null +++ b/ruoyi-common/pom.xml @@ -0,0 +1,230 @@ + + + + ruoyi + com.ruoyi + 3.8.4 + + 4.0.0 + + ruoyi-common + + + common通用工具 + + + + + + + + + org.springframework + spring-context-support + + + + + org.springframework + spring-web + + + + + org.springframework.boot + spring-boot-starter-security + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter-validation + + + + + org.apache.commons + commons-lang3 + + + + + com.fasterxml.jackson.core + jackson-databind + + + + + com.alibaba.fastjson2 + fastjson2 + + + + + commons-io + commons-io + + + + + commons-fileupload + commons-fileupload + + + + org.springframework.boot + spring-boot-starter-freemarker + + + + + org.apache.poi + poi-ooxml + + + cn.afterturn + easypoi-spring-boot-starter + 4.1.3 + + + + + org.yaml + snakeyaml + + + + + io.jsonwebtoken + jjwt + + + + + + + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + org.apache.commons + commons-pool2 + + + + + eu.bitwalker + UserAgentUtils + + + + org.projectlombok + lombok + + + + + javax.servlet + javax.servlet-api + + + + com.baomidou + mybatis-plus-annotation + 3.5.2 + + + + io.swagger + swagger-annotations + 1.6.6 + + + + cn.hutool + hutool-all + + + + + org.gavaghan + geodesy + + + + + io.minio + minio + 8.2.1 + + + + org.apache.commons + commons-text + + + + dom4j + dom4j + 1.6.1 + + + + org.docx4j + docx4j + 6.1.2 + + + slf4j-log4j12 + org.slf4j + + + + + + javax.xml.bind + jaxb-api + 2.3.1 + + + + com.sun.xml.bind + jaxb-impl + 2.3.4 + + + + + commons-httpclient + commons-httpclient + 3.1 + + + org.apache.httpcomponents + httpclient + 4.3.1 + + + org.apache.httpcomponents + httpcore + 4.3.1 + + + + + + \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Anonymous.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Anonymous.java new file mode 100644 index 0000000..1d6d4f4 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Anonymous.java @@ -0,0 +1,19 @@ +package com.ruoyi.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 匿名访问不鉴权注解 + * + * @author ruoyi + */ +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Anonymous +{ +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/BindDict.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/BindDict.java new file mode 100644 index 0000000..3d69482 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/BindDict.java @@ -0,0 +1,20 @@ +package com.ruoyi.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author ntxz + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface BindDict { + + //绑定的字段映射 + String filedMapping() default ""; + + //字典类型 + String type() default ""; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataScope.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataScope.java new file mode 100644 index 0000000..be49c80 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataScope.java @@ -0,0 +1,33 @@ +package com.ruoyi.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 数据权限过滤注解 + * + * @author ruoyi + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface DataScope +{ + /** + * 部门表的别名 + */ + public String deptAlias() default ""; + + /** + * 用户表的别名 + */ + public String userAlias() default ""; + + /** + * 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@ss获取,多个权限用逗号分隔开来 + */ + public String permission() default ""; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataSource.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataSource.java new file mode 100644 index 0000000..79cd191 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataSource.java @@ -0,0 +1,28 @@ +package com.ruoyi.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.ruoyi.common.enums.DataSourceType; + +/** + * 自定义多数据源切换注解 + * + * 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准 + * + * @author ruoyi + */ +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +public @interface DataSource +{ + /** + * 切换数据源名称 + */ + public DataSourceType value() default DataSourceType.MASTER; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java new file mode 100644 index 0000000..f7aaca5 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java @@ -0,0 +1,187 @@ +package com.ruoyi.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.math.BigDecimal; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import com.ruoyi.common.utils.poi.ExcelHandlerAdapter; + +/** + * 自定义导出Excel数据注解 + * + * @author ruoyi + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Excel +{ + /** + * 导出时在excel中排序 + */ + public int sort() default Integer.MAX_VALUE; + + /** + * 导出到Excel中的名字. + */ + public String name() default ""; + + /** + * 日期格式, 如: yyyy-MM-dd + */ + public String dateFormat() default ""; + + /** + * 如果是字典类型,请设置字典的type值 (如: sys_user_sex) + */ + public String dictType() default ""; + + /** + * 读取内容转表达式 (如: 0=男,1=女,2=未知) + */ + public String readConverterExp() default ""; + + /** + * 分隔符,读取字符串组内容 + */ + public String separator() default ","; + + /** + * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化) + */ + public int scale() default -1; + + /** + * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN + */ + public int roundingMode() default BigDecimal.ROUND_HALF_EVEN; + + /** + * 导出时在excel中每个列的高度 单位为字符 + */ + public double height() default 14; + + /** + * 导出时在excel中每个列的宽 单位为字符 + */ + public double width() default 16; + + /** + * 文字后缀,如% 90 变成90% + */ + public String suffix() default ""; + + /** + * 当值为空时,字段的默认值 + */ + public String defaultValue() default ""; + + /** + * 提示信息 + */ + public String prompt() default ""; + + /** + * 设置只能选择不能输入的列内容. + */ + public String[] combo() default {}; + + /** + * 是否需要纵向合并单元格,应对需求:含有list集合单元格) + */ + public boolean needMerge() default false; + + /** + * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写. + */ + public boolean isExport() default true; + + /** + * 另一个类中的属性名称,支持多级获取,以小数点隔开 + */ + public String targetAttr() default ""; + + /** + * 是否自动统计数据,在最后追加一行统计数据总和 + */ + public boolean isStatistics() default false; + + /** + * 导出类型(0数字 1字符串 2图片) + */ + public ColumnType cellType() default ColumnType.STRING; + + /** + * 导出列头背景色 + */ + public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT; + + /** + * 导出列头字体颜色 + */ + public IndexedColors headerColor() default IndexedColors.WHITE; + + /** + * 导出单元格背景色 + */ + public IndexedColors backgroundColor() default IndexedColors.WHITE; + + /** + * 导出单元格字体颜色 + */ + public IndexedColors color() default IndexedColors.BLACK; + + /** + * 导出字段对齐方式 + */ + public HorizontalAlignment align() default HorizontalAlignment.CENTER; + + /** + * 自定义数据处理器 + */ + public Class handler() default ExcelHandlerAdapter.class; + + /** + * 自定义数据处理器参数 + */ + public String[] args() default {}; + + /** + * 字段类型(0:导出导入;1:仅导出;2:仅导入) + */ + Type type() default Type.ALL; + + public enum Type + { + ALL(0), EXPORT(1), IMPORT(2); + private final int value; + + Type(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } + + public enum ColumnType + { + NUMERIC(0), STRING(1), IMAGE(2); + private final int value; + + ColumnType(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excels.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excels.java new file mode 100644 index 0000000..1f1cc81 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excels.java @@ -0,0 +1,18 @@ +package com.ruoyi.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Excel注解集 + * + * @author ruoyi + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Excels +{ + public Excel[] value(); +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Log.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Log.java new file mode 100644 index 0000000..ca02c6c --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Log.java @@ -0,0 +1,46 @@ +package com.ruoyi.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.enums.OperatorType; + +/** + * 自定义操作日志记录注解 + * + * @author ruoyi + * + */ +@Target({ ElementType.PARAMETER, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Log +{ + /** + * 模块 + */ + public String title() default ""; + + /** + * 功能 + */ + public BusinessType businessType() default BusinessType.OTHER; + + /** + * 操作人类别 + */ + public OperatorType operatorType() default OperatorType.MANAGE; + + /** + * 是否保存请求的参数 + */ + public boolean isSaveRequestData() default true; + + /** + * 是否保存响应的参数 + */ + public boolean isSaveResponseData() default true; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RateLimiter.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RateLimiter.java new file mode 100644 index 0000000..0f024c7 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RateLimiter.java @@ -0,0 +1,40 @@ +package com.ruoyi.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.enums.LimitType; + +/** + * 限流注解 + * + * @author ruoyi + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RateLimiter +{ + /** + * 限流key + */ + public String key() default CacheConstants.RATE_LIMIT_KEY; + + /** + * 限流时间,单位秒 + */ + public int time() default 60; + + /** + * 限流次数 + */ + public int count() default 100; + + /** + * 限流类型 + */ + public LimitType limitType() default LimitType.DEFAULT; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java new file mode 100644 index 0000000..3f6b7e3 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java @@ -0,0 +1,35 @@ +package com.ruoyi.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 自定义注解防止表单重复提交 + * + * @author ruoyi + * + */ +@Inherited +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RepeatSubmit +{ + /** + * 间隔时间(ms),小于此时间视为重复提交 + */ + public int interval() default 5000; + + /** + * 提示消息 + */ + public String message() default "不允许重复提交,请稍候再试"; + + public boolean enable() default true; + + public int num() default 9; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/config/MinioConfig.java b/ruoyi-common/src/main/java/com/ruoyi/common/config/MinioConfig.java new file mode 100644 index 0000000..2e38001 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/config/MinioConfig.java @@ -0,0 +1,82 @@ +package com.ruoyi.common.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import io.minio.MinioClient; + +/** + * Minio 配置信息 + * + * @author ruoyi + */ +@Configuration +@ConfigurationProperties(prefix = "minio") +public class MinioConfig +{ + /** + * 服务地址 + */ + private static String url; + + /** + * 用户名 + */ + private static String accessKey; + + /** + * 密码 + */ + private static String secretKey; + + /** + * 存储桶名称 + */ + private static String bucketName; + + public static String getUrl() + { + return url; + } + + public void setUrl(String url) + { + MinioConfig.url = url; + } + + public static String getAccessKey() + { + return accessKey; + } + + public void setAccessKey(String accessKey) + { + MinioConfig.accessKey = accessKey; + } + + public static String getSecretKey() + { + return secretKey; + } + + public void setSecretKey(String secretKey) + { + MinioConfig.secretKey = secretKey; + } + + public static String getBucketName() + { + return bucketName; + } + + public void setBucketName(String bucketName) + { + MinioConfig.bucketName = bucketName; + } + + @Bean + public MinioClient getMinioClient() + { + return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java b/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java new file mode 100644 index 0000000..00f70f6 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java @@ -0,0 +1,135 @@ +package com.ruoyi.common.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 读取项目相关配置 + * + * @author ruoyi + */ +@Component +@ConfigurationProperties(prefix = "ruoyi") +public class RuoYiConfig +{ + /** 项目名称 */ + private String name; + + /** 版本 */ + private String version; + + /** 版权年份 */ + private String copyrightYear; + + /** 实例演示开关 */ + private boolean demoEnabled; + + /** 上传路径 */ + private static String profile; + + /** 获取地址开关 */ + private static boolean addressEnabled; + + /** 验证码类型 */ + private static String captchaType; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getVersion() + { + return version; + } + + public void setVersion(String version) + { + this.version = version; + } + + public String getCopyrightYear() + { + return copyrightYear; + } + + public void setCopyrightYear(String copyrightYear) + { + this.copyrightYear = copyrightYear; + } + + public boolean isDemoEnabled() + { + return demoEnabled; + } + + public void setDemoEnabled(boolean demoEnabled) + { + this.demoEnabled = demoEnabled; + } + + public static String getProfile() + { + return profile; + } + + public void setProfile(String profile) + { + RuoYiConfig.profile = profile; + } + + public static boolean isAddressEnabled() + { + return addressEnabled; + } + + public void setAddressEnabled(boolean addressEnabled) + { + RuoYiConfig.addressEnabled = addressEnabled; + } + + public static String getCaptchaType() { + return captchaType; + } + + public void setCaptchaType(String captchaType) { + RuoYiConfig.captchaType = captchaType; + } + + /** + * 获取导入上传路径 + */ + public static String getImportPath() + { + return getProfile() + "/import"; + } + + /** + * 获取头像上传路径 + */ + public static String getAvatarPath() + { + return getProfile() + "/avatar"; + } + + /** + * 获取下载路径 + */ + public static String getDownloadPath() + { + return getProfile() + "/download/"; + } + + /** + * 获取上传路径 + */ + public static String getUploadPath() + { + return getProfile() + "/upload"; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/AlarmConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/AlarmConstants.java new file mode 100644 index 0000000..1b0d0cd --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/AlarmConstants.java @@ -0,0 +1,13 @@ +package com.ruoyi.common.constant; + +public class AlarmConstants { + + public static final String NoRecover = "0"; + + public static final String Recover = "1"; + + public static final String RedInLine = "Y"; + + public static final String RedOutLine = "N"; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java new file mode 100644 index 0000000..17a1053 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java @@ -0,0 +1,104 @@ +package com.ruoyi.common.constant; + +/** + * 缓存的key 常量 + * + * @author ruoyi + */ +public class CacheConstants +{ + /** + * 登录用户 redis key + */ + public static final String LOGIN_TOKEN_KEY = "login_tokens:"; + + /** + * 验证码 redis key + */ + public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; + + + /** + * 参数管理 cache key + */ + public static final String SYS_CONFIG_KEY = "sys_config:"; + + /** + * 物资信息 cache key + */ + public static final String YW_MATERIALS_INFO = "yw_materials_info"; + + /** + * 性能监控15分钟 cache key + */ + public static final String YW_KPIMONITORCELL_INFO = "yw_kpimonitorcell_info"; + + /** + * 性能监控1分钟 cache key + */ + public static final String YW_KPIMONITORMIN_INFO = "yw_kpimonitormin_info"; + + + public static final String YW_MATERIALS_CLASS = "yw_materials_class"; + + public static final String YW_VENUES = "yw_venues"; + + /** + * 字典管理 cache key + */ + public static final String SYS_DICT_KEY = "sys_dict:"; + + /** + * 防重提交 redis key + */ + public static final String REPEAT_SUBMIT_KEY = "repeat_submit:"; + + /** + * 限流 redis key + */ + public static final String RATE_LIMIT_KEY = "rate_limit:"; + + /** + * 登录账户密码错误次数 redis key + */ + public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; + + public static final String SMS_ERR_CNT_KEY = "sms_err_cnt:"; + + + public static final String DP_DATA = "dp_"; + + /** + * 登录账户密码错误次数 + * {@value} + */ + public static int PWD_ERR_CNT= 5; + + /** + * 登录账户锁定时间 + * {@value} + */ + public static int LOCK_TIME= 900; + + /** + * 缓存过期时间-600分钟 10小时 + * {@value} + */ + public static int REDIS_TIME_OUT_300MINUTES = 36000; + + + public static String YW_TRANS_ALARM = "yw_trans_alarm"; + public static String YW_TRANS_MAP = "yw_trans_map"; + public static String YW_MACHINEROOM_ALARM = "yw_machineroom_alarm"; + public static String YW_GB_TOP5 = "yw_gb_top5"; + public static String YW_OPTICALPOWER = "yw_opticalpower"; + public static String YW_NET_ALARM = "yw_net_alarm"; + public static String YW_NET_MAP = "yw_net_map"; + public static String YW_NET_CODE_AGIS = "yw_net_code_agis"; + public static String YW_COM_MANAGE_SCENE = "ym_dp_commamage_scene"; + public static String YW_COM_MANAGE_ALL = "ym_dp_commamage_all"; + + + public static String ZXP_TOKEN = "zxp_token"; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java new file mode 100644 index 0000000..6ec69da --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -0,0 +1,150 @@ +package com.ruoyi.common.constant; + +import io.jsonwebtoken.Claims; + +/** + * 通用常量信息 + * + * @author ruoyi + */ +public class Constants +{ + /** + * UTF-8 字符集 + */ + public static final String UTF8 = "UTF-8"; + + /** + * GBK 字符集 + */ + public static final String GBK = "GBK"; + + /** + * www主域 + */ + public static final String WWW = "www."; + + /** + * http请求 + */ + public static final String HTTP = "http://"; + + /** + * https请求 + */ + public static final String HTTPS = "https://"; + + /** + * 通用成功标识 + */ + public static final String SUCCESS = "0"; + + /** + * 通用失败标识 + */ + public static final String FAIL = "1"; + + /** + * 登录成功 + */ + public static final String LOGIN_SUCCESS = "Success"; + + /** + * 注销 + */ + public static final String LOGOUT = "Logout"; + + /** + * 注册 + */ + public static final String REGISTER = "Register"; + + /** + * 登录失败 + */ + public static final String LOGIN_FAIL = "Error"; + + /** + * 验证码有效期(分钟) + */ + public static final Integer CAPTCHA_EXPIRATION = 2; + + /** + * 令牌 + */ + public static final String TOKEN = "token"; + + /** + * 令牌前缀 + */ + public static final String TOKEN_PREFIX = "Bearer "; + + /** + * 令牌前缀 + */ + public static final String LOGIN_USER_KEY = "login_user_key"; + + /** + * 用户ID + */ + public static final String JWT_USERID = "userid"; + + /** + * 用户名称 + */ + public static final String JWT_USERNAME = Claims.SUBJECT; + + /** + * 用户头像 + */ + public static final String JWT_AVATAR = "avatar"; + + /** + * 创建时间 + */ + public static final String JWT_CREATED = "created"; + + /** + * 用户权限 + */ + public static final String JWT_AUTHORITIES = "authorities"; + /** + * 安全相关 + */ + public static final String JWT_SIGN_KEY = "icloud"; + /** + * 资源映射路径 前缀 + */ + public static final String RESOURCE_PREFIX = "/profile"; + + /** + * RMI 远程方法调用 + */ + public static final String LOOKUP_RMI = "rmi:"; + + /** + * LDAP 远程方法调用 + */ + public static final String LOOKUP_LDAP = "ldap:"; + + /** + * LDAPS 远程方法调用 + */ + public static final String LOOKUP_LDAPS = "ldaps:"; + + /** + * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) + */ + public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" }; + + /** + * 定时任务违规的字符 + */ + public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", + "org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config" }; + + /** + * 登录用户编号 redis key + */ + public static final String LOGIN_USERID_KEY = "login_userid:"; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/GenConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/GenConstants.java new file mode 100644 index 0000000..7d899d4 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/GenConstants.java @@ -0,0 +1,117 @@ +package com.ruoyi.common.constant; + +/** + * 代码生成通用常量 + * + * @author ruoyi + */ +public class GenConstants +{ + /** 单表(增删改查) */ + public static final String TPL_CRUD = "crud"; + + /** 树表(增删改查) */ + public static final String TPL_TREE = "tree"; + + /** 主子表(增删改查) */ + public static final String TPL_SUB = "sub"; + + /** 树编码字段 */ + public static final String TREE_CODE = "treeCode"; + + /** 树父编码字段 */ + public static final String TREE_PARENT_CODE = "treeParentCode"; + + /** 树名称字段 */ + public static final String TREE_NAME = "treeName"; + + /** 上级菜单ID字段 */ + public static final String PARENT_MENU_ID = "parentMenuId"; + + /** 上级菜单名称字段 */ + public static final String PARENT_MENU_NAME = "parentMenuName"; + + /** 数据库字符串类型 */ + public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" }; + + /** 数据库文本类型 */ + public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" }; + + /** 数据库时间类型 */ + public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" }; + + /** 数据库数字类型 */ + public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer", + "bit", "bigint", "float", "double", "decimal" }; + + /** 页面不需要编辑字段 */ + public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" }; + + /** 页面不需要显示的列表字段 */ + public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by", + "update_time" }; + + /** 页面不需要查询字段 */ + public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by", + "update_time", "remark" }; + + /** Entity基类字段 */ + public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" }; + + /** Tree基类字段 */ + public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" }; + + /** 文本框 */ + public static final String HTML_INPUT = "input"; + + /** 文本域 */ + public static final String HTML_TEXTAREA = "textarea"; + + /** 下拉框 */ + public static final String HTML_SELECT = "select"; + + /** 单选框 */ + public static final String HTML_RADIO = "radio"; + + /** 复选框 */ + public static final String HTML_CHECKBOX = "checkbox"; + + /** 日期控件 */ + public static final String HTML_DATETIME = "datetime"; + + /** 图片上传控件 */ + public static final String HTML_IMAGE_UPLOAD = "imageUpload"; + + /** 文件上传控件 */ + public static final String HTML_FILE_UPLOAD = "fileUpload"; + + /** 富文本控件 */ + public static final String HTML_EDITOR = "editor"; + + /** 字符串类型 */ + public static final String TYPE_STRING = "String"; + + /** 整型 */ + public static final String TYPE_INTEGER = "Integer"; + + /** 长整型 */ + public static final String TYPE_LONG = "Long"; + + /** 浮点型 */ + public static final String TYPE_DOUBLE = "Double"; + + /** 高精度计算类型 */ + public static final String TYPE_BIGDECIMAL = "BigDecimal"; + + /** 时间类型 */ + public static final String TYPE_DATE = "Date"; + + /** 模糊查询 */ + public static final String QUERY_LIKE = "LIKE"; + + /** 相等查询 */ + public static final String QUERY_EQ = "EQ"; + + /** 需要 */ + public static final String REQUIRE = "1"; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/HttpStatus.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/HttpStatus.java new file mode 100644 index 0000000..a983c77 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/HttpStatus.java @@ -0,0 +1,94 @@ +package com.ruoyi.common.constant; + +/** + * 返回状态码 + * + * @author ruoyi + */ +public class HttpStatus +{ + /** + * 操作成功 + */ + public static final int SUCCESS = 200; + + /** + * 对象创建成功 + */ + public static final int CREATED = 201; + + /** + * 请求已经被接受 + */ + public static final int ACCEPTED = 202; + + /** + * 操作已经执行成功,但是没有返回数据 + */ + public static final int NO_CONTENT = 204; + + /** + * 资源已被移除 + */ + public static final int MOVED_PERM = 301; + + /** + * 重定向 + */ + public static final int SEE_OTHER = 303; + + /** + * 资源没有被修改 + */ + public static final int NOT_MODIFIED = 304; + + /** + * 参数列表错误(缺少,格式不匹配) + */ + public static final int BAD_REQUEST = 400; + + /** + * 未授权 + */ + public static final int UNAUTHORIZED = 401; + + /** + * 访问受限,授权过期 + */ + public static final int FORBIDDEN = 403; + + /** + * 资源,服务未找到 + */ + public static final int NOT_FOUND = 404; + + /** + * 不允许的http方法 + */ + public static final int BAD_METHOD = 405; + + /** + * 资源冲突,或者资源被锁 + */ + public static final int CONFLICT = 409; + + /** + * 不支持的数据,媒体类型 + */ + public static final int UNSUPPORTED_TYPE = 415; + + /** + * 系统内部错误 + */ + public static final int ERROR = 500; + + /** + * 接口未实现 + */ + public static final int NOT_IMPLEMENTED = 501; + + /** + * 系统警告消息 + */ + public static final int WARN = 601; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java new file mode 100644 index 0000000..62ad815 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java @@ -0,0 +1,50 @@ +package com.ruoyi.common.constant; + +/** + * 任务调度通用常量 + * + * @author ruoyi + */ +public class ScheduleConstants +{ + public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME"; + + /** 执行目标key */ + public static final String TASK_PROPERTIES = "TASK_PROPERTIES"; + + /** 默认 */ + public static final String MISFIRE_DEFAULT = "0"; + + /** 立即触发执行 */ + public static final String MISFIRE_IGNORE_MISFIRES = "1"; + + /** 触发一次执行 */ + public static final String MISFIRE_FIRE_AND_PROCEED = "2"; + + /** 不触发立即执行 */ + public static final String MISFIRE_DO_NOTHING = "3"; + + public enum Status + { + /** + * 正常 + */ + NORMAL("0"), + /** + * 暂停 + */ + PAUSE("1"); + + private String value; + + private Status(String value) + { + this.value = value; + } + + public String getValue() + { + return value; + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/TaskConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/TaskConstants.java new file mode 100644 index 0000000..f26c3ec --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/TaskConstants.java @@ -0,0 +1,13 @@ +package com.ruoyi.common.constant; + +public class TaskConstants { + + public static final String ALARM = "告警处理"; + + public static final String INSPECT = "巡检任务"; + + public static final String WIRE = "布线"; + + public static final String MATERIAL = "物资"; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/UserConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/UserConstants.java new file mode 100644 index 0000000..e1f8230 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/UserConstants.java @@ -0,0 +1,82 @@ +package com.ruoyi.common.constant; + +/** + * 用户常量信息 + * + * @author ruoyi + */ +public class UserConstants +{ + /** + * 平台内系统用户的唯一标志 + */ + public static final String SYS_USER = "SYS_USER"; + + /** 正常状态 */ + public static final String NORMAL = "0"; + + /** 异常状态 */ + public static final String EXCEPTION = "1"; + + /** 用户封禁状态 */ + public static final String USER_DISABLE = "1"; + + /** 角色封禁状态 */ + public static final String ROLE_DISABLE = "1"; + + /** 部门正常状态 */ + public static final String DEPT_NORMAL = "0"; + + /** 部门停用状态 */ + public static final String DEPT_DISABLE = "1"; + + /** 字典正常状态 */ + public static final String DICT_NORMAL = "0"; + + /** 是否为系统默认(是) */ + public static final String YES = "Y"; + + public static final String APP = "app"; + + public static final String PC = "pc"; + + /** 是否菜单外链(是) */ + public static final String YES_FRAME = "0"; + + /** 是否菜单外链(否) */ + public static final String NO_FRAME = "1"; + + /** 菜单类型(目录) */ + public static final String TYPE_DIR = "M"; + + /** 菜单类型(菜单) */ + public static final String TYPE_MENU = "C"; + + /** 菜单类型(按钮) */ + public static final String TYPE_BUTTON = "F"; + + /** Layout组件标识 */ + public final static String LAYOUT = "Layout"; + + /** ParentView组件标识 */ + public final static String PARENT_VIEW = "ParentView"; + + /** InnerLink组件标识 */ + public final static String INNER_LINK = "InnerLink"; + + /** 校验返回结果码 */ + public final static String UNIQUE = "0"; + public final static String NOT_UNIQUE = "1"; + + /** + * 用户名长度限制 + */ + public static final int USERNAME_MIN_LENGTH = 2; + public static final int USERNAME_MAX_LENGTH = 20; + + /** + * 密码长度限制 + */ + public static final int PASSWORD_MIN_LENGTH = 5; + public static final int PASSWORD_MAX_LENGTH = 20; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/WordConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/WordConstants.java new file mode 100644 index 0000000..e30b8dc --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/WordConstants.java @@ -0,0 +1,13 @@ +package com.ruoyi.common.constant; + +public class WordConstants { + + public final static String DOC_SUF = ".doc"; + + public final static String DOCX_SUF = ".docx"; + + public final static String PDF_SUF = ".pdf"; + + public final static String CONVERT_SUF = "(\\.docx)|(\\.doc)|(\\.xml)"; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java new file mode 100644 index 0000000..be89847 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java @@ -0,0 +1,216 @@ +package com.ruoyi.common.core.controller; + +import java.beans.PropertyEditorSupport; +import java.util.Date; +import java.util.List; + +import com.alibaba.fastjson2.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.page.PageDomain; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.page.TableSupport; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.sql.SqlUtil; + +/** + * web层通用数据处理 + * + * @author ruoyi + */ +public class BaseController +{ + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + + + /** + * 将前台传递过来的日期格式的字符串,自动转化为Date类型 + */ + @InitBinder + public void initBinder(WebDataBinder binder) + { + // Date 类型转换 + binder.registerCustomEditor(Date.class, new PropertyEditorSupport() + { + @Override + public void setAsText(String text) + { + setValue(DateUtils.parseDate(text)); + } + }); + } + + /** + * 设置请求分页数据 + */ + protected void startPage() + { + PageUtils.startPage(); + } + + /** + * 设置请求排序数据 + */ + protected void startOrderBy() + { + PageDomain pageDomain = TableSupport.buildPageRequest(); + if (StringUtils.isNotEmpty(pageDomain.getOrderBy())) + { + String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); + PageHelper.orderBy(orderBy); + } + } + + /** + * 清理分页的线程变量 + */ + protected void clearPage() + { + PageUtils.clearPage(); + } + + /** + * 响应请求分页数据 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected TableDataInfo getDataTable(List list) + { + TableDataInfo rspData = new TableDataInfo(); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setMsg("查询成功"); + rspData.setRows(list); + rspData.setTotal(new PageInfo(list).getTotal()); + return rspData; + } + + protected TableDataInfo getDataTable(List List,Long total) + { + TableDataInfo rspData = new TableDataInfo(); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setMsg("查询成功"); + rspData.setRows(List); + rspData.setTotal(total); + return rspData; + } + + /** + * 返回成功 + */ + public AjaxResult success() + { + return AjaxResult.success(); + } + + /** + * 返回失败消息 + */ + public AjaxResult error() + { + return AjaxResult.error(); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(String message) + { + return AjaxResult.success(message); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(Object data) + { + return AjaxResult.success(data); + } + + /** + * 返回失败消息 + */ + public AjaxResult error(String message) + { + return AjaxResult.error(message); + } + + /** + * 返回警告消息 + */ + public AjaxResult warn(String message) + { + return AjaxResult.warn(message); + } + + /** + * 响应返回结果 + * + * @param rows 影响行数 + * @return 操作结果 + */ + protected AjaxResult toAjax(int rows) + { + return rows > 0 ? AjaxResult.success() : AjaxResult.error(); + } + + /** + * 响应返回结果 + * + * @param result 结果 + * @return 操作结果 + */ + protected AjaxResult toAjax(boolean result) + { + return result ? success() : error(); + } + + /** + * 页面跳转 + */ + public String redirect(String url) + { + return StringUtils.format("redirect:{}", url); + } + + /** + * 获取用户缓存信息 + */ + public LoginUser getLoginUser() + { + return SecurityUtils.getLoginUser(); + } + + /** + * 获取登录用户id + */ + public Long getUserId() + { + return getLoginUser().getUserId(); + } + + /** + * 获取登录部门id + */ + public Long getDeptId() + { + return getLoginUser().getDeptId(); + } + + /** + * 获取登录用户名 + */ + public String getUsername() + { + return getLoginUser().getUsername(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AjaxResult.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AjaxResult.java new file mode 100644 index 0000000..42fbd9c --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AjaxResult.java @@ -0,0 +1,185 @@ +package com.ruoyi.common.core.domain; + +import java.util.HashMap; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.utils.StringUtils; + +/** + * 操作消息提醒 + * + * @author ruoyi + */ +public class AjaxResult extends HashMap +{ + private static final long serialVersionUID = 1L; + + /** 状态码 */ + public static final String CODE_TAG = "code"; + + /** 返回内容 */ + public static final String MSG_TAG = "msg"; + + /** 数据对象 */ + public static final String DATA_TAG = "data"; + + /** + * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。 + */ + public AjaxResult() + { + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + */ + public AjaxResult(int code, String msg) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + * @param data 数据对象 + */ + public AjaxResult(int code, String msg, Object data) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + if (StringUtils.isNotNull(data)) + { + super.put(DATA_TAG, data); + } + } + + /** + * 返回成功消息 + * + * @return 成功消息 + */ + public static AjaxResult success() + { + return AjaxResult.success("操作成功"); + } + + /** + * 返回成功数据 + * + * @return 成功消息 + */ + public static AjaxResult success(Object data) + { + return AjaxResult.success("操作成功", data); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @return 成功消息 + */ + public static AjaxResult success(String msg) + { + return AjaxResult.success(msg, null); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 成功消息 + */ + public static AjaxResult success(String msg, Object data) + { + return new AjaxResult(HttpStatus.SUCCESS, msg, data); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @return 警告消息 + */ + public static AjaxResult warn(String msg) + { + return AjaxResult.warn(msg, null); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 警告消息 + */ + public static AjaxResult warn(String msg, Object data) + { + return new AjaxResult(HttpStatus.WARN, msg, data); + } + + /** + * 返回错误消息 + * + * @return 错误消息 + */ + public static AjaxResult error() + { + return AjaxResult.error("操作失败"); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(String msg) + { + return AjaxResult.error(msg, null); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 错误消息 + */ + public static AjaxResult error(String msg, Object data) + { + return new AjaxResult(HttpStatus.ERROR, msg, data); + } + + /** + * 返回错误消息 + * + * @param code 状态码 + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(int code, String msg) + { + return new AjaxResult(code, msg, null); + } + + /** + * 方便链式调用 + * + * @param key 键 + * @param value 值 + * @return 数据对象 + */ + @Override + public AjaxResult put(String key, Object value) + { + super.put(key, value); + return this; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java new file mode 100644 index 0000000..38e47b2 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java @@ -0,0 +1,129 @@ +package com.ruoyi.common.core.domain; + +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.ruoyi.common.annotation.Excel; + +/** + * Entity基类 + * + * @author ruoyi + */ +public class BaseEntity implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 搜索值 */ + @JsonIgnore + @TableField(exist = false) + private String searchValue; + + /** 创建者 */ + @TableField(value = "create_by",fill = FieldFill.INSERT) + private String createBy; + + /** 创建时间 */ + // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") + @TableField(value = "create_time",fill = FieldFill.INSERT) + @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss",sort = 30) + private Date createTime; + + /** 更新者 */ + @TableField(value = "update_by",fill = FieldFill.INSERT_UPDATE) + private String updateBy; + + /** 更新时间 */ + // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") + @TableField(value = "update_time",fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + + /** 备注 */ + @Excel(name = "备注", type = Excel.Type.ALL, sort = 31) + private String remark; + + /** 请求参数 */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private Map params; + + public String getSearchValue() + { + return searchValue; + } + + public void setSearchValue(String searchValue) + { + this.searchValue = searchValue; + } + + public String getCreateBy() + { + return createBy; + } + + public void setCreateBy(String createBy) + { + this.createBy = createBy; + } + + public Date getCreateTime() + { + return createTime; + } + + public void setCreateTime(Date createTime) + { + this.createTime = createTime; + } + + public String getUpdateBy() + { + return updateBy; + } + + public void setUpdateBy(String updateBy) + { + this.updateBy = updateBy; + } + + public Date getUpdateTime() + { + return updateTime; + } + + public void setUpdateTime(Date updateTime) + { + this.updateTime = updateTime; + } + + public String getRemark() + { + return remark; + } + + public void setRemark(String remark) + { + this.remark = remark; + } + + public Map getParams() + { + if (params == null) + { + params = new HashMap<>(); + } + return params; + } + + public void setParams(Map params) + { + this.params = params; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/R.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/R.java new file mode 100644 index 0000000..ef15802 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/R.java @@ -0,0 +1,115 @@ +package com.ruoyi.common.core.domain; + +import java.io.Serializable; +import com.ruoyi.common.constant.HttpStatus; + +/** + * 响应信息主体 + * + * @author ruoyi + */ +public class R implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 成功 */ + public static final int SUCCESS = HttpStatus.SUCCESS; + + /** 失败 */ + public static final int FAIL = HttpStatus.ERROR; + + private int code; + + private String msg; + + private T data; + + public static R ok() + { + return restResult(null, SUCCESS, "操作成功"); + } + + public static R ok(T data) + { + return restResult(data, SUCCESS, "操作成功"); + } + + public static R ok(T data, String msg) + { + return restResult(data, SUCCESS, msg); + } + + public static R fail() + { + return restResult(null, FAIL, "操作失败"); + } + + public static R fail(String msg) + { + return restResult(null, FAIL, msg); + } + + public static R fail(T data) + { + return restResult(data, FAIL, "操作失败"); + } + + public static R fail(T data, String msg) + { + return restResult(data, FAIL, msg); + } + + public static R fail(int code, String msg) + { + return restResult(null, code, msg); + } + + private static R restResult(T data, int code, String msg) + { + R apiResult = new R<>(); + apiResult.setCode(code); + apiResult.setData(data); + apiResult.setMsg(msg); + return apiResult; + } + + public int getCode() + { + return code; + } + + public void setCode(int code) + { + this.code = code; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public T getData() + { + return data; + } + + public void setData(T data) + { + this.data = data; + } + + public static Boolean isError(R ret) + { + return !isSuccess(ret); + } + + public static Boolean isSuccess(R ret) + { + return R.SUCCESS == ret.getCode(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeEntity.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeEntity.java new file mode 100644 index 0000000..a180a18 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeEntity.java @@ -0,0 +1,79 @@ +package com.ruoyi.common.core.domain; + +import java.util.ArrayList; +import java.util.List; + +/** + * Tree基类 + * + * @author ruoyi + */ +public class TreeEntity extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 父菜单名称 */ + private String parentName; + + /** 父菜单ID */ + private Long parentId; + + /** 显示顺序 */ + private Integer orderNum; + + /** 祖级列表 */ + private String ancestors; + + /** 子部门 */ + private List children = new ArrayList<>(); + + public String getParentName() + { + return parentName; + } + + public void setParentName(String parentName) + { + this.parentName = parentName; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer orderNum) + { + this.orderNum = orderNum; + } + + public String getAncestors() + { + return ancestors; + } + + public void setAncestors(String ancestors) + { + this.ancestors = ancestors; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java new file mode 100644 index 0000000..564f082 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java @@ -0,0 +1,85 @@ +package com.ruoyi.common.core.domain; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.ruoyi.common.core.domain.entity.SysAppMenu; +import com.ruoyi.common.core.domain.entity.SysDept; +import com.ruoyi.common.core.domain.entity.SysMenu; + +/** + * Treeselect树结构实体类 + * + * @author ruoyi + */ +public class TreeSelect implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 节点ID */ + private Long id; + + /** 节点名称 */ + private String label; + + /** 子节点 */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List children; + + public TreeSelect() + { + + } + + public TreeSelect(SysDept dept) + { + this.id = dept.getDeptId(); + this.label = dept.getDeptName(); + this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + public TreeSelect(SysMenu menu) + { + this.id = menu.getMenuId(); + this.label = menu.getMenuName(); + this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + public TreeSelect(SysAppMenu menu) + { + this.id = menu.getMenuId(); + this.label = menu.getMenuName(); + this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + public Long getId() + { + return id; + } + + public void setId(Long id) + { + this.id = id; + } + + public String getLabel() + { + return label; + } + + public void setLabel(String label) + { + this.label = label; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/HandleDataDTO.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/HandleDataDTO.java new file mode 100644 index 0000000..2d929ea --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/HandleDataDTO.java @@ -0,0 +1,46 @@ +package com.ruoyi.common.core.domain.dto; + +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.core.domain.dto.json.UserInfo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * @author LoveMyOrange + * @create 2022-10-15 16:27 + */ +@Data +@ApiModel("各个按钮 处理数据需要传递的参数") +public class HandleDataDTO { + @ApiModelProperty("任务id") + private String taskId; + @ApiModelProperty("流程实例id") + private String processInstanceId; + @ApiModelProperty("表单数据") + private JSONObject formData; + @ApiModelProperty("附件") + private List attachments; + @ApiModelProperty("意见") + private String comments; + @ApiModelProperty("签名信息") + private String signInfo; + @ApiModelProperty("转办类型") + private Integer transferType; + @ApiModelProperty("转办用户信息") + private UserInfo transferUserInfo; + @ApiModelProperty("加签用户信息") + private UserInfo multiAddUserInfo; + @ApiModelProperty("退回节点id") + private String rollbackId; + @ApiModelProperty("当前用户信息") + private UserInfo currentUserInfo; + @ApiModelProperty("任务名称") + private String taskName; + @ApiModelProperty("委派的人") + private UserInfo delegateUserInfo; + @ApiModelProperty("是否需要获取原来的fromData") + private String oldFromData; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/SearchInfo.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/SearchInfo.java new file mode 100644 index 0000000..c1decce --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/SearchInfo.java @@ -0,0 +1,26 @@ +package com.ruoyi.common.core.domain.dto; + +import lombok.Data; + +/** + * @Author:LoveMyOrange + * @Description: + * @Date:Created in 2022/10/9 16:10 + */ +@Data +public class SearchInfo { + //地市 + private String city; + //区县 + private String county; + //子场景,场馆 + private String venue; + //状态 + private String status; + //开始时间 + private String startDate; + //结束时间 + private String endDate; + //任务类型 + private String taskType; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/StartProcessInstanceDTO.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/StartProcessInstanceDTO.java new file mode 100644 index 0000000..d96e001 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/StartProcessInstanceDTO.java @@ -0,0 +1,20 @@ +package com.ruoyi.common.core.domain.dto; + +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.core.domain.dto.json.UserInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @author LoveMyOrange + * @create 2022-10-14 23:27 + */ +@Data +public class StartProcessInstanceDTO { + private String processDefinitionId; + private JSONObject formData; + private Map> processUsers; + private UserInfo startUserInfo; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/TaskDTO.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/TaskDTO.java new file mode 100644 index 0000000..78e2ccb --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/TaskDTO.java @@ -0,0 +1,27 @@ +package com.ruoyi.common.core.domain.dto; + +import com.ruoyi.common.core.domain.dto.json.UserInfo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author LoveMyOrange + * @create 2022-10-14 23:47 + */ +@Data +@ApiModel("待办 需要返回给前端的VO") +public class TaskDTO { + + @ApiModelProperty(value = "第几页",required = true) + private Integer pageNo; + @ApiModelProperty(value = "多少条",required = true) + private Integer pageSize; + + private UserInfo currentUserInfo; + + private SearchInfo searchInfo; + + private String isApp; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/json/UserInfo.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/json/UserInfo.java new file mode 100644 index 0000000..5226a01 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/json/UserInfo.java @@ -0,0 +1,22 @@ +package com.ruoyi.common.core.domain.dto.json; + +import lombok.Data; + +import java.util.List; + +/** + * @Author:LoveMyOrange + * @Description: + * @Date:Created in 2022/10/9 16:10 + */ +@Data +public class UserInfo { + private String id; + private String name; + private String type; + private String sex; + private String specialty; + private Boolean selected; + private List roles; + private List venue; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysAppMenu.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysAppMenu.java new file mode 100644 index 0000000..da429a6 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysAppMenu.java @@ -0,0 +1,298 @@ +package com.ruoyi.common.core.domain.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.ArrayList; +import java.util.List; + +/** + * 菜单权限表 sys_app_menu + * + * @author ruoyi + */ +@TableName("sys_app_menu") +public class SysAppMenu extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 菜单ID + */ + @TableId(value = "menu_id") + private Long menuId; + + /** + * 菜单名称 + */ + @TableField(value = "menu_name") + private String menuName; + + /** 父菜单名称 */ +// private String parentName; + + /** + * 父菜单ID + */ + @TableField(value = "parent_id") + private Long parentId; + + /** + * 显示顺序 + */ + @TableField(value = "order_num") + private Integer orderNum; + + /** + * 路由地址 + */ + private String path; + + /** + * 组件路径 + */ + private String component; + + /** + * 路由参数 + */ + private String query; + + /** + * 是否为外链(0是 1否) + */ + @TableField(value = "is_frame") + private String isFrame; + + /** + * 是否缓存(0缓存 1不缓存) + */ + @TableField(value = "is_cache") + private String isCache; + + /** + * 是否已添加(0否 1已添加) + */ + @TableField(exist = false) + private Integer isAdd=0; + + /** + * 类型(M目录 C菜单 F按钮) + */ + @TableField(value = "menu_type") + private String menuType; + + /** + * 显示状态(0显示 1隐藏) + */ + private String visible; + + /** + * 菜单状态(0正常 1停用) + */ + private String status; + + /** + * 权限字符串 + */ + private String perms; + + /** + * 菜单图标 + */ + private String icon; + + /** + * 菜单图标2 + */ + private String icon2; + + public String getIcon2() { + return icon2; + } + + public void setIcon2(String icon2) { + this.icon2 = icon2; + } + + /** + * 子菜单 + */ + private List children = new ArrayList(); + + public Long getMenuId() { + return menuId; + } + + public void setMenuId(Long menuId) { + this.menuId = menuId; + } + + @NotBlank(message = "菜单名称不能为空") + @Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符") + public String getMenuName() { + return menuName; + } + + public void setMenuName(String menuName) { + this.menuName = menuName; + } + +// public String getParentName() +// { +// return parentName; +// } +// +// public void setParentName(String parentName) +// { +// this.parentName = parentName; +// } + + public Long getParentId() { + return parentId; + } + + public void setParentId(Long parentId) { + this.parentId = parentId; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getOrderNum() { + return orderNum; + } + + public void setOrderNum(Integer orderNum) { + this.orderNum = orderNum; + } + + @Size(min = 0, max = 200, message = "路由地址不能超过200个字符") + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + @Size(min = 0, max = 200, message = "组件路径不能超过255个字符") + public String getComponent() { + return component; + } + + public void setComponent(String component) { + this.component = component; + } + + public String getQuery() { + return query; + } + + public void setQuery(String query) { + this.query = query; + } + + public String getIsFrame() { + return isFrame; + } + + public void setIsFrame(String isFrame) { + this.isFrame = isFrame; + } + + public String getIsCache() { + return isCache; + } + + public void setIsCache(String isCache) { + this.isCache = isCache; + } + + public Integer getIsAdd() { + return isAdd; + } + + public void setIsAdd(Integer isAdd) { + this.isAdd = isAdd; + } + + @NotBlank(message = "菜单类型不能为空") + public String getMenuType() { + return menuType; + } + + public void setMenuType(String menuType) { + this.menuType = menuType; + } + + public String getVisible() { + return visible; + } + + public void setVisible(String visible) { + this.visible = visible; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + @Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符") + public String getPerms() { + return perms; + } + + public void setPerms(String perms) { + this.perms = perms; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("menuId", getMenuId()) + .append("menuName", getMenuName()) + .append("parentId", getParentId()) + .append("orderNum", getOrderNum()) + .append("path", getPath()) + .append("component", getComponent()) + .append("isFrame", getIsFrame()) + .append("IsCache", getIsCache()) + .append("menuType", getMenuType()) + .append("visible", getVisible()) + .append("status ", getStatus()) + .append("perms", getPerms()) + .append("icon", getIcon()) + .append("icon2", getIcon2()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java new file mode 100644 index 0000000..c1366ce --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java @@ -0,0 +1,215 @@ +package com.ruoyi.common.core.domain.entity; + +import java.util.ArrayList; +import java.util.List; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 部门表 sys_dept + * + * @author ruoyi + */ +@TableName("sys_dept") +public class SysDept extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 部门ID */ + + @TableId(value = "dept_id") + private Long deptId; + + /** 父部门ID */ + @TableField(value = "parent_id") + private Long parentId; + + /** 祖级列表 */ + private String ancestors; + + /** 部门名称 */ + @TableField(value = "dept_name") + private String deptName; + + /** 显示顺序 */ + + @TableField(value = "order_num") + private Integer orderNum; + + /** 负责人 */ + private String leader; + + /** 联系电话 */ + private String phone; + + /** 邮箱 */ + private String email; + + /** 部门状态:0正常,1停用 */ + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + @TableField(value = "del_flag") + private String delFlag; + + /** 父部门名称 */ + private String parentName; + + /** 子部门 */ + private List children = new ArrayList(); + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + public String getAncestors() + { + return ancestors; + } + + public void setAncestors(String ancestors) + { + this.ancestors = ancestors; + } + + @NotBlank(message = "部门名称不能为空") + @Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符") + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer orderNum) + { + this.orderNum = orderNum; + } + + public String getLeader() + { + return leader; + } + + public void setLeader(String leader) + { + this.leader = leader; + } + + @Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符") + public String getPhone() + { + return phone; + } + + public void setPhone(String phone) + { + this.phone = phone; + } + + @Email(message = "邮箱格式不正确") + @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符") + public String getEmail() + { + return email; + } + + public void setEmail(String email) + { + this.email = email; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getParentName() + { + return parentName; + } + + public void setParentName(String parentName) + { + this.parentName = parentName; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("deptId", getDeptId()) + .append("parentId", getParentId()) + .append("ancestors", getAncestors()) + .append("deptName", getDeptName()) + .append("orderNum", getOrderNum()) + .append("leader", getLeader()) + .append("phone", getPhone()) + .append("email", getEmail()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictData.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictData.java new file mode 100644 index 0000000..65427f6 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictData.java @@ -0,0 +1,189 @@ +package com.ruoyi.common.core.domain.entity; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.annotation.Excel.ColumnType; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 字典数据表 sys_dict_data + * + * @author ruoyi + */ +@TableName("sys_dict_data") +public class SysDictData extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 字典编码 */ + @Excel(name = "字典编码", cellType = ColumnType.NUMERIC) + @TableId(value = "dict_code") + private Long dictCode; + + /** 字典排序 */ + @Excel(name = "字典排序", cellType = ColumnType.NUMERIC) + @TableField(value = "dict_sort") + private Long dictSort; + + /** 字典标签 */ + @Excel(name = "字典标签") + @TableField(value = "dict_label") + private String dictLabel; + + /** 字典键值 */ + @Excel(name = "字典键值") + @TableField(value = "dict_value") + private String dictValue; + + /** 字典类型 */ + @Excel(name = "字典类型") + @TableField(value = "dict_type") + private String dictType; + + /** 样式属性(其他样式扩展) */ + @TableField(value = "css_class") + private String cssClass; + + /** 表格字典样式 */ + @TableField(value = "list_class") + private String listClass; + + /** 是否默认(Y是 N否) */ + @Excel(name = "是否默认", readConverterExp = "Y=是,N=否") + @TableField(value = "is_default") + private String isDefault; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=停用") + private String status; + + public Long getDictCode() + { + return dictCode; + } + + public void setDictCode(Long dictCode) + { + this.dictCode = dictCode; + } + + public Long getDictSort() + { + return dictSort; + } + + public void setDictSort(Long dictSort) + { + this.dictSort = dictSort; + } + + @NotBlank(message = "字典标签不能为空") + @Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符") + public String getDictLabel() + { + return dictLabel; + } + + public void setDictLabel(String dictLabel) + { + this.dictLabel = dictLabel; + } + + @NotBlank(message = "字典键值不能为空") + @Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符") + public String getDictValue() + { + return dictValue; + } + + public void setDictValue(String dictValue) + { + this.dictValue = dictValue; + } + + @NotBlank(message = "字典类型不能为空") + @Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符") + public String getDictType() + { + return dictType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + @Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符") + public String getCssClass() + { + return cssClass; + } + + public void setCssClass(String cssClass) + { + this.cssClass = cssClass; + } + + public String getListClass() + { + return listClass; + } + + public void setListClass(String listClass) + { + this.listClass = listClass; + } + + public boolean getDefault() + { + return UserConstants.YES.equals(this.isDefault); + } + + public String getIsDefault() + { + return isDefault; + } + + public void setIsDefault(String isDefault) + { + this.isDefault = isDefault; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("dictCode", getDictCode()) + .append("dictSort", getDictSort()) + .append("dictLabel", getDictLabel()) + .append("dictValue", getDictValue()) + .append("dictType", getDictType()) + .append("cssClass", getCssClass()) + .append("listClass", getListClass()) + .append("isDefault", getIsDefault()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictType.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictType.java new file mode 100644 index 0000000..fff0842 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictType.java @@ -0,0 +1,104 @@ +package com.ruoyi.common.core.domain.entity; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.annotation.Excel.ColumnType; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 字典类型表 sys_dict_type + * + * @author ruoyi + */ +@TableName("sys_dict_type") +public class SysDictType extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 字典主键 */ + @Excel(name = "字典主键", cellType = ColumnType.NUMERIC) + @TableId(value = "dict_id") + private Long dictId; + + /** 字典名称 */ + @Excel(name = "字典名称") + @TableField(value = "dict_name") + private String dictName; + + /** 字典类型 */ + @Excel(name = "字典类型") + @TableField(value = "dict_type") + private String dictType; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=停用") + private String status; + + public Long getDictId() + { + return dictId; + } + + public void setDictId(Long dictId) + { + this.dictId = dictId; + } + + @NotBlank(message = "字典名称不能为空") + @Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符") + public String getDictName() + { + return dictName; + } + + public void setDictName(String dictName) + { + this.dictName = dictName; + } + + @NotBlank(message = "字典类型不能为空") + @Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符") + @Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)") + public String getDictType() + { + return dictType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("dictId", getDictId()) + .append("dictName", getDictName()) + .append("dictType", getDictType()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java new file mode 100644 index 0000000..1ed2c25 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java @@ -0,0 +1,271 @@ +package com.ruoyi.common.core.domain.entity; + +import java.util.ArrayList; +import java.util.List; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 菜单权限表 sys_menu + * + * @author ruoyi + */ +@TableName("sys_menu") +public class SysMenu extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 菜单ID */ + @TableId(value = "menu_id") + private Long menuId; + + /** 菜单名称 */ + @TableField(value = "menu_name") + private String menuName; + + /** 父菜单名称 */ +// private String parentName; + + /** 父菜单ID */ + @TableField(value = "parent_id") + private Long parentId; + + /** 显示顺序 */ + @TableField(value = "order_num") + private Integer orderNum; + + /** 路由地址 */ + private String path; + + /** 组件路径 */ + private String component; + + /** 路由参数 */ + private String query; + + /** 是否为外链(0是 1否) */ + @TableField(value = "is_frame") + private String isFrame; + + /** 是否缓存(0缓存 1不缓存) */ + @TableField(value = "is_cache") + private String isCache; + + /** 类型(M目录 C菜单 F按钮) */ + @TableField(value = "menu_type") + private String menuType; + + /** 显示状态(0显示 1隐藏) */ + private String visible; + + /** 菜单状态(0正常 1停用) */ + private String status; + + /** 权限字符串 */ + private String perms; + + /** 菜单图标 */ + private String icon; + + /** 子菜单 */ + private List children = new ArrayList(); + + public Long getMenuId() + { + return menuId; + } + + public void setMenuId(Long menuId) + { + this.menuId = menuId; + } + + @NotBlank(message = "菜单名称不能为空") + @Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符") + public String getMenuName() + { + return menuName; + } + + public void setMenuName(String menuName) + { + this.menuName = menuName; + } + +// public String getParentName() +// { +// return parentName; +// } +// +// public void setParentName(String parentName) +// { +// this.parentName = parentName; +// } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer orderNum) + { + this.orderNum = orderNum; + } + + @Size(min = 0, max = 200, message = "路由地址不能超过200个字符") + public String getPath() + { + return path; + } + + public void setPath(String path) + { + this.path = path; + } + + @Size(min = 0, max = 200, message = "组件路径不能超过255个字符") + public String getComponent() + { + return component; + } + + public void setComponent(String component) + { + this.component = component; + } + + public String getQuery() + { + return query; + } + + public void setQuery(String query) + { + this.query = query; + } + + public String getIsFrame() + { + return isFrame; + } + + public void setIsFrame(String isFrame) + { + this.isFrame = isFrame; + } + + public String getIsCache() + { + return isCache; + } + + public void setIsCache(String isCache) + { + this.isCache = isCache; + } + + @NotBlank(message = "菜单类型不能为空") + public String getMenuType() + { + return menuType; + } + + public void setMenuType(String menuType) + { + this.menuType = menuType; + } + + public String getVisible() + { + return visible; + } + + public void setVisible(String visible) + { + this.visible = visible; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符") + public String getPerms() + { + return perms; + } + + public void setPerms(String perms) + { + this.perms = perms; + } + + public String getIcon() + { + return icon; + } + + public void setIcon(String icon) + { + this.icon = icon; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("menuId", getMenuId()) + .append("menuName", getMenuName()) + .append("parentId", getParentId()) + .append("orderNum", getOrderNum()) + .append("path", getPath()) + .append("component", getComponent()) + .append("isFrame", getIsFrame()) + .append("IsCache", getIsCache()) + .append("menuType", getMenuType()) + .append("visible", getVisible()) + .append("status ", getStatus()) + .append("perms", getPerms()) + .append("icon", getIcon()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java new file mode 100644 index 0000000..8d6b314 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java @@ -0,0 +1,286 @@ +package com.ruoyi.common.core.domain.entity; + +import java.util.Set; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.annotation.Excel.ColumnType; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 角色表 sys_role + * + * @author ruoyi + */ +@TableName("sys_role") +public class SysRole extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 角色ID */ + @Excel(name = "ID", cellType = ColumnType.NUMERIC,sort = 1) + @TableId(value = "role_id") + private Long roleId; + + /** 角色名称 */ + @Excel(name = "角色名称",sort = 2) + @TableField(value = "role_name") + private String roleName; + + /** 角色权限 */ + @Excel(name = "权限范围",sort = 3) + @TableField(value = "role_key") + private String roleKey; + + /** 角色排序 */ + @TableField(value = "role_sort") + private Integer roleSort; + + /** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */ +// @Excel(name = "权限范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限") + @TableField(value = "data_scope") + private String dataScope; + + /** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */ + @TableField(value = "menu_check_strictly") + private boolean menuCheckStrictly; + + /** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */ + @TableField(value = "dept_check_strictly") + private boolean deptCheckStrictly; + + /** 角色状态(0正常 1停用) */ + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + @TableField(value = "del_flag") + private String delFlag; + + /** 用户是否存在此角色标识 默认不存在 */ + private boolean flag = false; + + /** 菜单组 */ + private Long[] menuIds; + + public String getStrMenuNames() { + return strMenuNames; + } + + public void setStrMenuNames(String strMenuNames) { + this.strMenuNames = strMenuNames; + } + + @Excel(name = "菜单权限",sort = 4) + private String strMenuNames; + + public Long[] getUserIds() { + return userIds; + } + + public void setUserIds(Long[] userIds) { + this.userIds = userIds; + } + + private Long[] userIds; + + /** app菜单组 */ + private Long[] appMenuIds; + + /** 部门组(数据权限) */ + private Long[] deptIds; + + /** 角色菜单权限 */ + private Set permissions; + + public SysRole() + { + + } + + public SysRole(Long roleId) + { + this.roleId = roleId; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public boolean isAdmin() + { + return isAdmin(this.roleId); + } + + public static boolean isAdmin(Long roleId) + { + return roleId != null && 1L == roleId; + } + + @NotBlank(message = "角色名称不能为空") + @Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符") + public String getRoleName() + { + return roleName; + } + + public void setRoleName(String roleName) + { + this.roleName = roleName; + } + + @NotBlank(message = "权限字符不能为空") + @Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符") + public String getRoleKey() + { + return roleKey; + } + + public void setRoleKey(String roleKey) + { + this.roleKey = roleKey; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getRoleSort() + { + return roleSort; + } + + public void setRoleSort(Integer roleSort) + { + this.roleSort = roleSort; + } + + public String getDataScope() + { + return dataScope; + } + + public void setDataScope(String dataScope) + { + this.dataScope = dataScope; + } + + public boolean isMenuCheckStrictly() + { + return menuCheckStrictly; + } + + public void setMenuCheckStrictly(boolean menuCheckStrictly) + { + this.menuCheckStrictly = menuCheckStrictly; + } + + public boolean isDeptCheckStrictly() + { + return deptCheckStrictly; + } + + public void setDeptCheckStrictly(boolean deptCheckStrictly) + { + this.deptCheckStrictly = deptCheckStrictly; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public boolean isFlag() + { + return flag; + } + + public void setFlag(boolean flag) + { + this.flag = flag; + } + + public Long[] getMenuIds() + { + return menuIds; + } + + public void setMenuIds(Long[] menuIds) + { + this.menuIds = menuIds; + } + + public Long[] getAppMenuIds() + { + return appMenuIds; + } + + public void setAppMenuIds(Long[] appMenuIds) + { + this.appMenuIds = appMenuIds; + } + + public Long[] getDeptIds() + { + return deptIds; + } + + public void setDeptIds(Long[] deptIds) + { + this.deptIds = deptIds; + } + + public Set getPermissions() + { + return permissions; + } + + public void setPermissions(Set permissions) + { + this.permissions = permissions; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("roleName", getRoleName()) + .append("roleKey", getRoleKey()) + .append("roleSort", getRoleSort()) + .append("dataScope", getDataScope()) + .append("menuCheckStrictly", isMenuCheckStrictly()) + .append("deptCheckStrictly", isDeptCheckStrictly()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java new file mode 100644 index 0000000..1531930 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java @@ -0,0 +1,575 @@ +package com.ruoyi.common.core.domain.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.annotation.Excel.Type; +import com.ruoyi.common.core.domain.BaseEntity; +import com.ruoyi.common.xss.Xss; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.util.Date; +import java.util.List; + +/** + * 用户对象 sys_user + * + * @author ruoyi + */ +@TableName("sys_user") +public class SysUser extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 用户ID */ + @Excel(name = "ID",sort = 1) + @TableId(value = "user_id") + private Long userId; + + /** 部门ID */ + @TableField(value = "dept_id") + private Long deptId; + + /** 用户账号 */ + @TableField(value = "user_name") + private String userName; + + /** 用户昵称 */ + @Excel(name = "用户姓名" , type = Type.ALL , sort = 2) + @TableField(value = "nick_name") + private String nickName; + + public String getUserType() { + return userType; + } + + public void setUserType(String userType) { + this.userType = userType; + } + + + @Excel(name = "专业", type = Type.ALL, sort = 3 ) + @TableField(value = "user_type") + private String userType; + + + public String getUserTypeStr() { + return userTypeStr; + } + + public void setUserTypeStr(String userTypeStr) { + this.userTypeStr = userTypeStr; + } + + + @TableField(exist = false) + private String userTypeStr; + + /** 用户邮箱 */ +// @Excel(name = "用户邮箱") + private String email; + + /** 手机号码 */ + @Excel(name = "手机号码", type = Type.ALL , sort = 4) + @TableField(value = "phonenumber") + private String phonenumber; + + /** 用户性别 */ +// @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知") + private String sex; + + /** 用户头像 */ + @Excel(name = "用户头像URL", sort = 4) + private String avatar; + + /** 密码 */ + private String password; + + /** 账号状态(0正常 1锁定 2冻结) */ + @Excel(name = "账号状态", readConverterExp = "0=正常,1=锁定,2=冻结", sort = 5) + private String status; + + /** 删除标志(0代表存在 2代表删除) */ +// @Excel(name = "是否删除", readConverterExp = "0=否,2=是", sort = 6) + @TableField(value = "del_flag") + private String delFlag; + + /** 最后登录IP */ + @Excel(name = "最后登录IP", sort = 7) + @TableField(value = "login_ip") + private String loginIp; + + public String getFirstPage() { + return firstPage; + } + + public void setFirstPage(String firstPage) { + this.firstPage = firstPage; + } + + @TableField(value = "first_page") + private String firstPage; + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCounty() { + return county; + } + + public void setCounty(String county) { + this.county = county; + } + + public String getDistinctArea() { + return distinctArea; + } + + public void setDistinctArea(String distinctArea) { + this.distinctArea = distinctArea; + } + + @Excel(name = "地市",type = Type.ALL, sort = 9) + private String city; + + + @Excel(name = "区县",type = Type.ALL, sort = 10) + private String county; + + @Excel(name = "场馆分区",type = Type.ALL, sort = 11) + private String distinctArea; + + public String getUserVenue() { + return userVenue; + } + + public void setUserVenue(String userVenue) { + this.userVenue = userVenue; + } + + private String userVenue; + + public String getUserVenueId() { + return userVenueId; + } + + public void setUserVenueId(String userVenueId) { + this.userVenueId = userVenueId; + } + + private String userVenueId; + + /** 最后登录时间 */ + @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT, sort = 8) + @TableField(value = "login_date") + private Date loginDate; + + /** 部门对象 */ +// @Excels({ +// @Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT), +// @Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT) +// }) + private SysDept dept; + + /** 角色对象 */ + private List roles; + + /** 角色组 */ + private Long[] roleIds; + + /** 岗位组 */ + private Long[] postIds; + + /** 角色ID */ + private Long roleId; + + /** 用户顺序,按用户拥有角色排列,如场馆经理、场馆助理、通信主管....., 取最前的角色 */ + @TableField(exist = false) + private Integer userSort; + + public Integer getUserSort() { + return userSort; + } + + public void setUserSort(Integer userSort) { + this.userSort = userSort; + } + + public String getBelongArea() { + return belongArea; + } + + public void setBelongArea(String belongArea) { + this.belongArea = belongArea; + } + + private String belongArea; + + public Long[] getVenueIds() { + return venueIds; + } + + public void setVenueIds(Long[] venueIds) { + this.venueIds = venueIds; + } + + public List getVenueNames() { + return venueNames; + } + + public void setVenueNames(List venueNames) { + this.venueNames = venueNames; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + private Long[] venueIds; + + private List venueNames; + + @Excel(name = "角色", sort = 12) + private String strRoles; + + @Excel(name = "所属场馆", sort = 13) + private String strVenueNames; + + @Excel(name = "自有/三方",type = Type.ALL,sort = 14) + private String ywUserBelong; + + public String getYwUserBelong() { + return ywUserBelong; + } + + public void setYwUserBelong(String ywUserBelong) { + this.ywUserBelong = ywUserBelong; + } + + public String getStrRoles() { + return strRoles; + } + + public void setStrRoles(String strRoles) { + this.strRoles = strRoles; + } + + public String getStrVenueNames() { + return strVenueNames; + } + + public void setStrVenueNames(String strVenueNames) { + this.strVenueNames = strVenueNames; + } + + public String getStrBelongArea() { + return strBelongArea; + } + + + public void setStrBelongArea(String strBelongArea) { + this.strBelongArea = strBelongArea; + } + + + private String strBelongArea; + + private List roleNames; + + public SysUser() + { + + } + + + public SysUser(Long userId) + { + this.userId = userId; + } + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public boolean isAdmin() + { + return isAdmin(this.userId); + } + + public static boolean isAdmin(Long userId) + { + return userId != null && 1L == userId; + } + + public boolean isAdmin(SysUser user) { + Boolean isAdmin=false; + if(ObjectUtils.isNotEmpty(user.getRoles())) { + for (SysRole sysRole : user.getRoles()) { + if (sysRole.getRoleKey().contains("admin") || "monitor" .equals(sysRole.getRoleKey()) || "noticemaster" .equals(sysRole.getRoleKey())) +// if(sysRole.getRoleKey().contains("admin")||sysRole.getRoleKey().contains("monitor")) + { + isAdmin = true; + break; + } + } + } + return isAdmin; + } + + public boolean isLeader(SysUser user) { + Boolean isLeader=false; + if(ObjectUtils.isNotEmpty(user.getRoles())) { + for (SysRole sysRole : user.getRoles()) { + if (sysRole.getRoleKey().contains("leader")) +// if(sysRole.getRoleKey().contains("admin")||sysRole.getRoleKey().contains("monitor")) + { + isLeader = true; + break; + } + } + } + return isLeader; + } + + public boolean isCenter(SysUser user) { + Boolean isCenter=false; + if(ObjectUtils.isNotEmpty(user.getRoles())) { + for (SysRole sysRole : user.getRoles()) { + if (sysRole.getRoleKey().contains("centerstorage")) +// if(sysRole.getRoleKey().contains("admin")||sysRole.getRoleKey().contains("monitor")) + { + isCenter = true; + break; + } + } + } + return isCenter; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + @Xss(message = "用户昵称不能包含脚本字符") + @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符") + public String getNickName() + { + return nickName; + } + + public void setNickName(String nickName) + { + this.nickName = nickName; + } + + @Xss(message = "用户账号不能包含脚本字符") + @NotBlank(message = "用户账号不能为空") + @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符") + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + @Email(message = "邮箱格式不正确") + @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符") + public String getEmail() + { + return email; + } + + public void setEmail(String email) + { + this.email = email; + } + + @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符") + public String getPhonenumber() + { + return phonenumber; + } + + public void setPhonenumber(String phonenumber) + { + this.phonenumber = phonenumber; + } + + public String getSex() + { + return sex; + } + + public void setSex(String sex) + { + this.sex = sex; + } + + public String getAvatar() + { + return avatar; + } + + public void setAvatar(String avatar) + { + this.avatar = avatar; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getLoginIp() + { + return loginIp; + } + + public void setLoginIp(String loginIp) + { + this.loginIp = loginIp; + } + + public Date getLoginDate() + { + return loginDate; + } + + public void setLoginDate(Date loginDate) + { + this.loginDate = loginDate; + } + + public SysDept getDept() + { + return dept; + } + + public void setDept(SysDept dept) + { + this.dept = dept; + } + + public List getRoles() + { + return roles; + } + + public void setRoles(List roles) + { + this.roles = roles; + } + + public Long[] getRoleIds() + { + return roleIds; + } + + public void setRoleIds(Long[] roleIds) + { + this.roleIds = roleIds; + } + + public Long[] getPostIds() + { + return postIds; + } + + public void setPostIds(Long[] postIds) + { + this.postIds = postIds; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("deptId", getDeptId()) + .append("userName", getUserName()) + .append("nickName", getNickName()) + .append("userType", getUserType()) + .append("email", getEmail()) + .append("phonenumber", getPhonenumber()) + .append("sex", getSex()) + .append("avatar", getAvatar()) + .append("password", getPassword()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("loginIp", getLoginIp()) + .append("loginDate", getLoginDate()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .append("firstPage", getFirstPage()) + .append("dept", getDept()) + .append("ywUserBelong", getYwUserBelong()) + .toString(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/ExcelSelector.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/ExcelSelector.java new file mode 100644 index 0000000..acb5f33 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/ExcelSelector.java @@ -0,0 +1,41 @@ +package com.ruoyi.common.core.domain.model; + +import lombok.Data; + +/** + * @author huamile + */ +@Data +public class ExcelSelector { + + /** + * 第几个sheet,从0开始 + */ + private int sheetIndex; + + /** + * 下拉单元格行号,从0开始 + */ + private int firstRow = 2; + + /** + * 下拉单元格行(结束) + */ + private int lastRow = 102; + + /** + * 下拉单元格列号,从0开始 + */ + private int firstCol; + + /** + * 下拉单元格列(结束) + */ + private int lastCol; + + /** + * 动态生成的下拉内容,easypoi使用的是字符数组 + */ + private String[] datas; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java new file mode 100644 index 0000000..70ba901 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java @@ -0,0 +1,94 @@ +package com.ruoyi.common.core.domain.model; + +/** + * 用户登录对象 + * + * @author ruoyi + */ +public class LoginBody +{ + /** + * 用户名 + */ + private String username; + + /** + * 用户密码 + */ + private String password; + + /** + * 手机号 + */ + private String phone; + + /** + * 验证码 + */ + private String code; + + private String loginType; + + /** + * 唯一标识 + */ + private String uuid; + + public String getUsername() + { + return username; + } + + public void setUsername(String username) + { + this.username = username; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getCode() + { + return code; + } + + public void setCode(String code) + { + this.code = code; + } + + public String getUuid() + { + return uuid; + } + + public void setUuid(String uuid) + { + this.uuid = uuid; + } + + public String getLoginType() + { + return loginType; + } + + public void setLoginType(String loginType) + { + this.loginType = loginType; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java new file mode 100644 index 0000000..ccede75 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java @@ -0,0 +1,310 @@ +package com.ruoyi.common.core.domain.model; + +import java.util.Collection; +import java.util.Set; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import com.alibaba.fastjson2.annotation.JSONField; +import com.ruoyi.common.core.domain.entity.SysUser; + +/** + * 登录用户身份权限 + * + * @author ruoyi + */ +public class LoginUser implements UserDetails +{ + private static final long serialVersionUID = 1L; + + /** + * 用户ID + */ + private Long userId; + + /** + * 部门ID + */ + private Long deptId; + + /** + * 用户唯一标识 + */ + private String token; + + /** + * 登录时间 + */ + private Long loginTime; + + /** + * 过期时间 + */ + private Long expireTime; + + public Long[] getVenueIds() { + return venueIds; + } + + public void setVenueIds(Long[] venueIds) { + this.venueIds = venueIds; + } + + private Long[] venueIds; + + /** + * 登录IP地址 + */ + private String ipaddr; + + /** + * 登录地点 + */ + private String loginLocation; + + /** + * 浏览器类型 + */ + private String browser; + + /** + * 操作系统 + */ + private String os; + + public String getLoginType() { + return loginType; + } + + public void setLoginType(String loginType) { + this.loginType = loginType; + } + + /** + * 登录类型 + */ + private String loginType; + + /** + * 权限列表 + */ + private Set permissions; + + /** + * app权限列表 + */ + private Set appPermissions; + + /** + * 用户信息 + */ + private SysUser user; + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public String getToken() + { + return token; + } + + public void setToken(String token) + { + this.token = token; + } + + public LoginUser() + { + } + + public LoginUser(SysUser user, Set permissions) + { + this.user = user; + this.permissions = permissions; + } + + public LoginUser(Long userId, Long deptId, SysUser user, Set permissions,Set appPermissions) + { + this.userId = userId; + this.deptId = deptId; + this.user = user; + this.permissions = permissions; + this.appPermissions = appPermissions; + } + + @JSONField(serialize = false) + @Override + public String getPassword() + { + return user.getPassword(); + } + + @Override + public String getUsername() + { + return user.getUserName(); + } + + public String getNickName() + { + return user.getNickName(); + } + + /** + * 账户是否未过期,过期无法验证 + */ + @JSONField(serialize = false) + @Override + public boolean isAccountNonExpired() + { + return true; + } + + /** + * 指定用户是否解锁,锁定的用户无法进行身份验证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isAccountNonLocked() + { + return true; + } + + /** + * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isCredentialsNonExpired() + { + return true; + } + + /** + * 是否可用 ,禁用的用户不能身份验证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isEnabled() + { + return true; + } + + public Long getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Long loginTime) + { + this.loginTime = loginTime; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getLoginLocation() + { + return loginLocation; + } + + public void setLoginLocation(String loginLocation) + { + this.loginLocation = loginLocation; + } + + public String getBrowser() + { + return browser; + } + + public void setBrowser(String browser) + { + this.browser = browser; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public Long getExpireTime() + { + return expireTime; + } + + public void setExpireTime(Long expireTime) + { + this.expireTime = expireTime; + } + + public Set getPermissions() + { + return permissions; + } + + public void setPermissions(Set permissions) + { + this.permissions = permissions; + } + + public Set getAppPermissions() + { + return appPermissions; + } + + public void setAppPermissions(Set appPermissions) + { + this.appPermissions = appPermissions; + } + + public SysUser getUser() + { + return user; + } + + public void setUser(SysUser user) + { + this.user = user; + } + + @Override + public Collection getAuthorities() + { + return null; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/RegisterBody.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/RegisterBody.java new file mode 100644 index 0000000..868a1fc --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/RegisterBody.java @@ -0,0 +1,11 @@ +package com.ruoyi.common.core.domain.model; + +/** + * 用户注册对象 + * + * @author ruoyi + */ +public class RegisterBody extends LoginBody +{ + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/page/PageDomain.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/page/PageDomain.java new file mode 100644 index 0000000..8966cb4 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/page/PageDomain.java @@ -0,0 +1,101 @@ +package com.ruoyi.common.core.page; + +import com.ruoyi.common.utils.StringUtils; + +/** + * 分页数据 + * + * @author ruoyi + */ +public class PageDomain +{ + /** 当前记录起始索引 */ + private Integer pageNum; + + /** 每页显示记录数 */ + private Integer pageSize; + + /** 排序列 */ + private String orderByColumn; + + /** 排序的方向desc或者asc */ + private String isAsc = "asc"; + + /** 分页参数合理化 */ + private Boolean reasonable = true; + + public String getOrderBy() + { + if (StringUtils.isEmpty(orderByColumn)) + { + return ""; + } + return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc; + } + + public Integer getPageNum() + { + return pageNum; + } + + public void setPageNum(Integer pageNum) + { + this.pageNum = pageNum; + } + + public Integer getPageSize() + { + return pageSize; + } + + public void setPageSize(Integer pageSize) + { + this.pageSize = pageSize; + } + + public String getOrderByColumn() + { + return orderByColumn; + } + + public void setOrderByColumn(String orderByColumn) + { + this.orderByColumn = orderByColumn; + } + + public String getIsAsc() + { + return isAsc; + } + + public void setIsAsc(String isAsc) + { + if (StringUtils.isNotEmpty(isAsc)) + { + // 兼容前端排序类型 + if ("ascending".equals(isAsc)) + { + isAsc = "asc"; + } + else if ("descending".equals(isAsc)) + { + isAsc = "desc"; + } + this.isAsc = isAsc; + } + } + + public Boolean getReasonable() + { + if (StringUtils.isNull(reasonable)) + { + return Boolean.TRUE; + } + return reasonable; + } + + public void setReasonable(Boolean reasonable) + { + this.reasonable = reasonable; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableDataInfo.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableDataInfo.java new file mode 100644 index 0000000..8813e0a --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableDataInfo.java @@ -0,0 +1,96 @@ +package com.ruoyi.common.core.page; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; + +/** + * 表格分页数据对象 + * + * @author ruoyi + */ +public class TableDataInfo implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 总记录数 */ + private long total; + + /** 列表数据 */ + private List rows; + + public HashMap getMaps() { + return maps; + } + + public void setMaps(HashMap maps) { + this.maps = maps; + } + + private HashMap maps; + + /** 消息状态码 */ + private int code; + + /** 消息内容 */ + private String msg; + + /** + * 表格数据对象 + */ + public TableDataInfo() + { + } + + /** + * 分页 + * + * @param list 列表数据 + * @param total 总记录数 + */ + public TableDataInfo(List list, int total) + { + this.rows = list; + this.total = total; + } + + public long getTotal() + { + return total; + } + + public void setTotal(long total) + { + this.total = total; + } + + public List getRows() + { + return rows; + } + + public void setRows(List rows) + { + this.rows = rows; + } + + public int getCode() + { + return code; + } + + public void setCode(int code) + { + this.code = code; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableSupport.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableSupport.java new file mode 100644 index 0000000..a120c30 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableSupport.java @@ -0,0 +1,56 @@ +package com.ruoyi.common.core.page; + +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.utils.ServletUtils; + +/** + * 表格数据处理 + * + * @author ruoyi + */ +public class TableSupport +{ + /** + * 当前记录起始索引 + */ + public static final String PAGE_NUM = "pageNum"; + + /** + * 每页显示记录数 + */ + public static final String PAGE_SIZE = "pageSize"; + + /** + * 排序列 + */ + public static final String ORDER_BY_COLUMN = "orderByColumn"; + + /** + * 排序的方向 "desc" 或者 "asc". + */ + public static final String IS_ASC = "isAsc"; + + /** + * 分页参数合理化 + */ + public static final String REASONABLE = "reasonable"; + + /** + * 封装分页对象 + */ + public static PageDomain getPageDomain() + { + PageDomain pageDomain = new PageDomain(); + pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1)); + pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10)); + pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN)); + pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC)); + pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE)); + return pageDomain; + } + + public static PageDomain buildPageRequest() + { + return getPageDomain(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java new file mode 100644 index 0000000..44e80d8 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java @@ -0,0 +1,268 @@ +package com.ruoyi.common.core.redis; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.BoundSetOperations; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Component; + +/** + * spring redis 工具类 + * + * @author ruoyi + **/ +@SuppressWarnings(value = { "unchecked", "rawtypes" }) +@Component +public class RedisCache +{ + @Autowired + public RedisTemplate redisTemplate; + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + */ + public void setCacheObject(final String key, final T value) + { + redisTemplate.opsForValue().set(key, value); + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param timeout 时间 + * @param timeUnit 时间颗粒度 + */ + public void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) + { + redisTemplate.opsForValue().set(key, value, timeout, timeUnit); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout) + { + return expire(key, timeout, TimeUnit.SECONDS); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @param unit 时间单位 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout, final TimeUnit unit) + { + return redisTemplate.expire(key, timeout, unit); + } + + /** + * 获取有效时间 + * + * @param key Redis键 + * @return 有效时间 + */ + public long getExpire(final String key) + { + return redisTemplate.getExpire(key); + } + + /** + * 判断 key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public Boolean hasKey(String key) + { + return redisTemplate.hasKey(key); + } + + /** + * 获得缓存的基本对象。 + * + * @param key 缓存键值 + * @return 缓存键值对应的数据 + */ + public T getCacheObject(final String key) + { + ValueOperations operation = redisTemplate.opsForValue(); + return operation.get(key); + } + + /** + * 删除单个对象 + * + * @param key + */ + public boolean deleteObject(final String key) + { + return redisTemplate.delete(key); + } + + /** + * 删除集合对象 + * + * @param collection 多个对象 + * @return + */ + public boolean deleteObject(final Collection collection) + { + return redisTemplate.delete(collection) > 0; + } + + /** + * 缓存List数据 + * + * @param key 缓存的键值 + * @param dataList 待缓存的List数据 + * @return 缓存的对象 + */ + public long setCacheList(final String key, final List dataList) + { + Long count = redisTemplate.opsForList().rightPushAll(key, dataList); + return count == null ? 0 : count; + } + + /** + * 获得缓存的list对象 + * + * @param key 缓存的键值 + * @return 缓存键值对应的数据 + */ + public List getCacheList(final String key) + { + return redisTemplate.opsForList().range(key, 0, -1); + } + + /** + * 缓存Set + * + * @param key 缓存键值 + * @param dataSet 缓存的数据 + * @return 缓存数据的对象 + */ + public BoundSetOperations setCacheSet(final String key, final Set dataSet) + { + BoundSetOperations setOperation = redisTemplate.boundSetOps(key); + Iterator it = dataSet.iterator(); + while (it.hasNext()) + { + setOperation.add(it.next()); + } + return setOperation; + } + + /** + * 获得缓存的set + * + * @param key + * @return + */ + public Set getCacheSet(final String key) + { + return redisTemplate.opsForSet().members(key); + } + + /** + * 缓存Map + * + * @param key + * @param dataMap + */ + public void setCacheMap(final String key, final Map dataMap) + { + if (dataMap != null) { + redisTemplate.opsForHash().putAll(key, dataMap); + } + } + + /** + * 获得缓存的Map + * + * @param key + * @return + */ + public Map getCacheMap(final String key) + { + return redisTemplate.opsForHash().entries(key); + } + + /** + * 往Hash中存入数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @param value 值 + */ + public void setCacheMapValue(final String key, final String hKey, final T value) + { + redisTemplate.opsForHash().put(key, hKey, value); + } + + /** + * 获取Hash中的数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return Hash中的对象 + */ + public T getCacheMapValue(final String key, final String hKey) + { + HashOperations opsForHash = redisTemplate.opsForHash(); + return opsForHash.get(key, hKey); + } + + /** + * 获取多个Hash中的数据 + * + * @param key Redis键 + * @param hKeys Hash键集合 + * @return Hash对象集合 + */ + public List getMultiCacheMapValue(final String key, final Collection hKeys) + { + return redisTemplate.opsForHash().multiGet(key, hKeys); + } + + /** + * 删除Hash中的某条数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return 是否成功 + */ + public boolean deleteCacheMapValue(final String key, final String hKey) + { + return redisTemplate.opsForHash().delete(key, hKey) > 0; + } + + /** + * 获得缓存的基本对象列表 + * + * @param pattern 字符串前缀 + * @return 对象列表 + */ + public Collection keys(final String pattern) + { + return redisTemplate.keys(pattern); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/text/CharsetKit.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/text/CharsetKit.java new file mode 100644 index 0000000..84124aa --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/text/CharsetKit.java @@ -0,0 +1,86 @@ +package com.ruoyi.common.core.text; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import com.ruoyi.common.utils.StringUtils; + +/** + * 字符集工具类 + * + * @author ruoyi + */ +public class CharsetKit +{ + /** ISO-8859-1 */ + public static final String ISO_8859_1 = "ISO-8859-1"; + /** UTF-8 */ + public static final String UTF_8 = "UTF-8"; + /** GBK */ + public static final String GBK = "GBK"; + + /** ISO-8859-1 */ + public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1); + /** UTF-8 */ + public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8); + /** GBK */ + public static final Charset CHARSET_GBK = Charset.forName(GBK); + + /** + * 转换为Charset对象 + * + * @param charset 字符集,为空则返回默认字符集 + * @return Charset + */ + public static Charset charset(String charset) + { + return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, String srcCharset, String destCharset) + { + return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset)); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, Charset srcCharset, Charset destCharset) + { + if (null == srcCharset) + { + srcCharset = StandardCharsets.ISO_8859_1; + } + + if (null == destCharset) + { + destCharset = StandardCharsets.UTF_8; + } + + if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset)) + { + return source; + } + return new String(source.getBytes(srcCharset), destCharset); + } + + /** + * @return 系统字符集编码 + */ + public static String systemCharset() + { + return Charset.defaultCharset().name(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/text/Convert.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/text/Convert.java new file mode 100644 index 0000000..b82321c --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/text/Convert.java @@ -0,0 +1,1000 @@ +package com.ruoyi.common.core.text; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.text.NumberFormat; +import java.util.Set; +import com.ruoyi.common.utils.StringUtils; +import org.apache.commons.lang3.ArrayUtils; + +/** + * 类型转换器 + * + * @author ruoyi + */ +public class Convert +{ + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static String toStr(Object value, String defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof String) + { + return (String) value; + } + return value.toString(); + } + + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static String toStr(Object value) + { + return toStr(value, null); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Character toChar(Object value, Character defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof Character) + { + return (Character) value; + } + + final String valueStr = toStr(value, null); + return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Character toChar(Object value) + { + return toChar(value, null); + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Byte toByte(Object value, Byte defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Byte) + { + return (Byte) value; + } + if (value instanceof Number) + { + return ((Number) value).byteValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Byte.parseByte(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Byte toByte(Object value) + { + return toByte(value, null); + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Short toShort(Object value, Short defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Short) + { + return (Short) value; + } + if (value instanceof Number) + { + return ((Number) value).shortValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Short.parseShort(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Short toShort(Object value) + { + return toShort(value, null); + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Number toNumber(Object value, Number defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Number) + { + return (Number) value; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return NumberFormat.getInstance().parse(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Number toNumber(Object value) + { + return toNumber(value, null); + } + + /** + * 转换为int
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Integer toInt(Object value, Integer defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Integer) + { + return (Integer) value; + } + if (value instanceof Number) + { + return ((Number) value).intValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Integer.parseInt(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为int
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Integer toInt(Object value) + { + return toInt(value, null); + } + + /** + * 转换为Integer数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String str) + { + return toIntArray(",", str); + } + + /** + * 转换为Long数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String str) + { + return toLongArray(",", str); + } + + /** + * 转换为Integer数组
+ * + * @param split 分隔符 + * @param split 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Integer[] {}; + } + String[] arr = str.split(split); + final Integer[] ints = new Integer[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Integer v = toInt(arr[i], 0); + ints[i] = v; + } + return ints; + } + + /** + * 转换为Long数组
+ * + * @param split 分隔符 + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Long[] {}; + } + String[] arr = str.split(split); + final Long[] longs = new Long[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Long v = toLong(arr[i], null); + longs[i] = v; + } + return longs; + } + + /** + * 转换为String数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String str) + { + return toStrArray(",", str); + } + + /** + * 转换为String数组
+ * + * @param split 分隔符 + * @param split 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String split, String str) + { + return str.split(split); + } + + /** + * 转换为long
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Long toLong(Object value, Long defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Long) + { + return (Long) value; + } + if (value instanceof Number) + { + return ((Number) value).longValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).longValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为long
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Long toLong(Object value) + { + return toLong(value, null); + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Double toDouble(Object value, Double defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Double) + { + return (Double) value; + } + if (value instanceof Number) + { + return ((Number) value).doubleValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).doubleValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Double toDouble(Object value) + { + return toDouble(value, null); + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Float toFloat(Object value, Float defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Float) + { + return (Float) value; + } + if (value instanceof Number) + { + return ((Number) value).floatValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Float.parseFloat(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Float toFloat(Object value) + { + return toFloat(value, null); + } + + /** + * 转换为boolean
+ * String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Boolean toBool(Object value, Boolean defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Boolean) + { + return (Boolean) value; + } + String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + valueStr = valueStr.trim().toLowerCase(); + switch (valueStr) + { + case "true": + case "yes": + case "ok": + case "1": + return true; + case "false": + case "no": + case "0": + return false; + default: + return defaultValue; + } + } + + /** + * 转换为boolean
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Boolean toBool(Object value) + { + return toBool(value, null); + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * + * @param clazz Enum的Class + * @param value 值 + * @param defaultValue 默认值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value, E defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (clazz.isAssignableFrom(value.getClass())) + { + @SuppressWarnings("unchecked") + E myE = (E) value; + return myE; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Enum.valueOf(clazz, valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * + * @param clazz Enum的Class + * @param value 值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value) + { + return toEnum(clazz, value, null); + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value, BigInteger defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigInteger) + { + return (BigInteger) value; + } + if (value instanceof Long) + { + return BigInteger.valueOf((Long) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigInteger(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value) + { + return toBigInteger(value, null); + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigDecimal) + { + return (BigDecimal) value; + } + if (value instanceof Long) + { + return new BigDecimal((Long) value); + } + if (value instanceof Double) + { + return new BigDecimal((Double) value); + } + if (value instanceof Integer) + { + return new BigDecimal((Integer) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigDecimal(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value) + { + return toBigDecimal(value, null); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @return 字符串 + */ + public static String utf8Str(Object obj) + { + return str(obj, CharsetKit.CHARSET_UTF_8); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charsetName 字符集 + * @return 字符串 + */ + public static String str(Object obj, String charsetName) + { + return str(obj, Charset.forName(charsetName)); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(Object obj, Charset charset) + { + if (null == obj) + { + return null; + } + + if (obj instanceof String) + { + return (String) obj; + } + else if (obj instanceof byte[]) + { + return str((byte[]) obj, charset); + } + else if (obj instanceof Byte[]) + { + byte[] bytes = ArrayUtils.toPrimitive((Byte[]) obj); + return str(bytes, charset); + } + else if (obj instanceof ByteBuffer) + { + return str((ByteBuffer) obj, charset); + } + return obj.toString(); + } + + /** + * 将byte数组转为字符串 + * + * @param bytes byte数组 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(byte[] bytes, String charset) + { + return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset)); + } + + /** + * 解码字节码 + * + * @param data 字符串 + * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 + * @return 解码后的字符串 + */ + public static String str(byte[] data, Charset charset) + { + if (data == null) + { + return null; + } + + if (null == charset) + { + return new String(data); + } + return new String(data, charset); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, String charset) + { + if (data == null) + { + return null; + } + + return str(data, Charset.forName(charset)); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, Charset charset) + { + if (null == charset) + { + charset = Charset.defaultCharset(); + } + return charset.decode(data).toString(); + } + + // ----------------------------------------------------------------------- 全角半角转换 + /** + * 半角转全角 + * + * @param input String. + * @return 全角字符串. + */ + public static String toSBC(String input) + { + return toSBC(input, null); + } + + /** + * 半角转全角 + * + * @param input String + * @param notConvertSet 不替换的字符集合 + * @return 全角字符串. + */ + public static String toSBC(String input, Set notConvertSet) + { + char[] c = input.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 跳过不替换的字符 + continue; + } + + if (c[i] == ' ') + { + c[i] = '\u3000'; + } + else if (c[i] < '\177') + { + c[i] = (char) (c[i] + 65248); + + } + } + return new String(c); + } + + /** + * 全角转半角 + * + * @param input String. + * @return 半角字符串 + */ + public static String toDBC(String input) + { + return toDBC(input, null); + } + + /** + * 替换全角为半角 + * + * @param text 文本 + * @param notConvertSet 不替换的字符集合 + * @return 替换后的字符 + */ + public static String toDBC(String text, Set notConvertSet) + { + char[] c = text.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 跳过不替换的字符 + continue; + } + + if (c[i] == '\u3000') + { + c[i] = ' '; + } + else if (c[i] > '\uFF00' && c[i] < '\uFF5F') + { + c[i] = (char) (c[i] - 65248); + } + } + String returnString = new String(c); + + return returnString; + } + + /** + * 数字金额大写转换 先写个完整的然后将如零拾替换成零 + * + * @param n 数字 + * @return 中文大写数字 + */ + public static String digitUppercase(double n) + { + String[] fraction = { "角", "分" }; + String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }; + String[][] unit = { { "元", "万", "亿" }, { "", "拾", "佰", "仟" } }; + + String head = n < 0 ? "负" : ""; + n = Math.abs(n); + + String s = ""; + for (int i = 0; i < fraction.length; i++) + { + s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", ""); + } + if (s.length() < 1) + { + s = "整"; + } + int integerPart = (int) Math.floor(n); + + for (int i = 0; i < unit[0].length && integerPart > 0; i++) + { + String p = ""; + for (int j = 0; j < unit[1].length && n > 0; j++) + { + p = digit[integerPart % 10] + unit[1][j] + p; + integerPart = integerPart / 10; + } + s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s; + } + return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整"); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/text/StrFormatter.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/text/StrFormatter.java new file mode 100644 index 0000000..c78ac77 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/text/StrFormatter.java @@ -0,0 +1,92 @@ +package com.ruoyi.common.core.text; + +import com.ruoyi.common.utils.StringUtils; + +/** + * 字符串格式化 + * + * @author ruoyi + */ +public class StrFormatter +{ + public static final String EMPTY_JSON = "{}"; + public static final char C_BACKSLASH = '\\'; + public static final char C_DELIM_START = '{'; + public static final char C_DELIM_END = '}'; + + /** + * 格式化字符串
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ * + * @param strPattern 字符串模板 + * @param argArray 参数列表 + * @return 结果 + */ + public static String format(final String strPattern, final Object... argArray) + { + if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray)) + { + return strPattern; + } + final int strPatternLength = strPattern.length(); + + // 初始化定义好的长度以获得更好的性能 + StringBuilder sbuf = new StringBuilder(strPatternLength + 50); + + int handledPosition = 0; + int delimIndex;// 占位符所在位置 + for (int argIndex = 0; argIndex < argArray.length; argIndex++) + { + delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition); + if (delimIndex == -1) + { + if (handledPosition == 0) + { + return strPattern; + } + else + { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 + sbuf.append(strPattern, handledPosition, strPatternLength); + return sbuf.toString(); + } + } + else + { + if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) + { + if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) + { + // 转义符之前还有一个转义符,占位符依旧有效 + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + else + { + // 占位符被转义 + argIndex--; + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(C_DELIM_START); + handledPosition = delimIndex + 1; + } + } + else + { + // 正常占位符 + sbuf.append(strPattern, handledPosition, delimIndex); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + } + } + // 加入最后一个占位符后所有的字符 + sbuf.append(strPattern, handledPosition, strPattern.length()); + + return sbuf.toString(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/BusinessStatus.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/BusinessStatus.java new file mode 100644 index 0000000..10b7306 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/BusinessStatus.java @@ -0,0 +1,20 @@ +package com.ruoyi.common.enums; + +/** + * 操作状态 + * + * @author ruoyi + * + */ +public enum BusinessStatus +{ + /** + * 成功 + */ + SUCCESS, + + /** + * 失败 + */ + FAIL, +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/BusinessType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/BusinessType.java new file mode 100644 index 0000000..2e17c4a --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/BusinessType.java @@ -0,0 +1,59 @@ +package com.ruoyi.common.enums; + +/** + * 业务操作类型 + * + * @author ruoyi + */ +public enum BusinessType +{ + /** + * 其它 + */ + OTHER, + + /** + * 新增 + */ + INSERT, + + /** + * 修改 + */ + UPDATE, + + /** + * 删除 + */ + DELETE, + + /** + * 授权 + */ + GRANT, + + /** + * 导出 + */ + EXPORT, + + /** + * 导入 + */ + IMPORT, + + /** + * 强退 + */ + FORCE, + + /** + * 生成代码 + */ + GENCODE, + + /** + * 清空数据 + */ + CLEAN, +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/DataSourceType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/DataSourceType.java new file mode 100644 index 0000000..0d945be --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/DataSourceType.java @@ -0,0 +1,19 @@ +package com.ruoyi.common.enums; + +/** + * 数据源 + * + * @author ruoyi + */ +public enum DataSourceType +{ + /** + * 主库 + */ + MASTER, + + /** + * 从库 + */ + SLAVE +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/FlowDealStatus.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/FlowDealStatus.java new file mode 100644 index 0000000..1530d74 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/FlowDealStatus.java @@ -0,0 +1,59 @@ +package com.ruoyi.common.enums; + +public enum FlowDealStatus { + + BUSINESS_STATUS_0("0", "待处理") ,BUSINESS_STATUS_1("1", "正在处理") ,BUSINESS_STATUS_2("2", "挂起") , + BUSINESS_STATUS_3("3","驳回"),BUSINESS_STATUS_4("4","已结束") ,BUSINESS_STATUS_5("5","撤销"); + + /** code */ + private String code; + + /** 显示标签 */ + private String label; + + FlowDealStatus(String code, String label){ + + this.code = code; + + this.label = label; + } + + public static String getLabelByCode (String code) { + + for (FlowDealStatus enuma : FlowDealStatus.values()) { + + if (enuma.getCode().equals(code)) { + + return enuma.getLabel(); + + } + + } + + return ""; + + } + + + @Override + public String toString(){ + + return label; + + } + + public String getLabel() { + + return label; + + } + + + public String getCode(){ + + return this.code; + + } + + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/HttpMethod.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/HttpMethod.java new file mode 100644 index 0000000..be6f739 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/HttpMethod.java @@ -0,0 +1,36 @@ +package com.ruoyi.common.enums; + +import java.util.HashMap; +import java.util.Map; +import org.springframework.lang.Nullable; + +/** + * 请求方式 + * + * @author ruoyi + */ +public enum HttpMethod +{ + GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE; + + private static final Map mappings = new HashMap<>(16); + + static + { + for (HttpMethod httpMethod : values()) + { + mappings.put(httpMethod.name(), httpMethod); + } + } + + @Nullable + public static HttpMethod resolve(@Nullable String method) + { + return (method != null ? mappings.get(method) : null); + } + + public boolean matches(String method) + { + return (this == resolve(method)); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/LimitType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/LimitType.java new file mode 100644 index 0000000..c609fd8 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/LimitType.java @@ -0,0 +1,20 @@ +package com.ruoyi.common.enums; + +/** + * 限流类型 + * + * @author ruoyi + */ + +public enum LimitType +{ + /** + * 默认策略全局限流 + */ + DEFAULT, + + /** + * 根据请求者IP进行限流 + */ + IP +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/NoticeType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/NoticeType.java new file mode 100644 index 0000000..6d1a8e5 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/NoticeType.java @@ -0,0 +1,47 @@ +package com.ruoyi.common.enums; + +import lombok.Data; + +/** + * 操作状态 + * + * @author ruoyi + * + */ +public enum NoticeType +{ + /** + * 短信 + */ + message("message","短信"), + + /** + * 微信 + */ + webchat("webchat","微信"), + + /** + * 邮件 + */ + mail("mail","邮件"); + + private final String code; + private final String info; + + NoticeType(String code, String info) + { + this.code = code; + this.info = info; + } + + public String getCode() + { + return code; + } + + public String getInfo() + { + return info; + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/OperatorType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/OperatorType.java new file mode 100644 index 0000000..bdd143c --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/OperatorType.java @@ -0,0 +1,24 @@ +package com.ruoyi.common.enums; + +/** + * 操作人类别 + * + * @author ruoyi + */ +public enum OperatorType +{ + /** + * 其它 + */ + OTHER, + + /** + * 后台用户 + */ + MANAGE, + + /** + * 手机端用户 + */ + MOBILE +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/UserStatus.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/UserStatus.java new file mode 100644 index 0000000..306514b --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/UserStatus.java @@ -0,0 +1,30 @@ +package com.ruoyi.common.enums; + +/** + * 用户状态 + * + * @author ruoyi + */ +public enum UserStatus +{ + OK("0", "正常"), DISABLE("1", "停用"), SLEEP("2", "冻结"), DELETED("2", "删除"); + + private final String code; + private final String info; + + UserStatus(String code, String info) + { + this.code = code; + this.info = info; + } + + public String getCode() + { + return code; + } + + public String getInfo() + { + return info; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/DemoModeException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/DemoModeException.java new file mode 100644 index 0000000..f6ad2ab --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/DemoModeException.java @@ -0,0 +1,15 @@ +package com.ruoyi.common.exception; + +/** + * 演示模式异常 + * + * @author ruoyi + */ +public class DemoModeException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public DemoModeException() + { + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/GlobalException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/GlobalException.java new file mode 100644 index 0000000..81a71b5 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/GlobalException.java @@ -0,0 +1,58 @@ +package com.ruoyi.common.exception; + +/** + * 全局异常 + * + * @author ruoyi + */ +public class GlobalException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 错误提示 + */ + private String message; + + /** + * 错误明细,内部调试错误 + * + * 和 {@link CommonResult#getDetailMessage()} 一致的设计 + */ + private String detailMessage; + + /** + * 空构造方法,避免反序列化问题 + */ + public GlobalException() + { + } + + public GlobalException(String message) + { + this.message = message; + } + + public String getDetailMessage() + { + return detailMessage; + } + + public GlobalException setDetailMessage(String detailMessage) + { + this.detailMessage = detailMessage; + return this; + } + + @Override + public String getMessage() + { + return message; + } + + public GlobalException setMessage(String message) + { + this.message = message; + return this; + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/ServiceException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/ServiceException.java new file mode 100644 index 0000000..8479cee --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/ServiceException.java @@ -0,0 +1,80 @@ +package com.ruoyi.common.exception; + +/** + * 业务异常 + * + * @author ruoyi + */ +public final class ServiceException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 错误码 + */ + private Integer code; + + /** + * 错误提示 + */ + private String message; + + /** + * 错误明细,内部调试错误 + * + * 和 {@link CommonResult#getDetailMessage()} 一致的设计 + */ + private String detailMessage; + + /** + * 空构造方法,避免反序列化问题 + */ + public ServiceException() + { + } + + public ServiceException(String message) + { + this.message = message; + } + + public ServiceException(String message, Integer code) + { + this.message = message; + this.code = code; + } + public ServiceException(String message, Throwable cause) { + super(message, cause); + } + public ServiceException(Throwable cause) { + super(cause); + } + + public String getDetailMessage() + { + return detailMessage; + } + + @Override + public String getMessage() + { + return message; + } + + public Integer getCode() + { + return code; + } + + public ServiceException setMessage(String message) + { + this.message = message; + return this; + } + + public ServiceException setDetailMessage(String detailMessage) + { + this.detailMessage = detailMessage; + return this; + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/UtilException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/UtilException.java new file mode 100644 index 0000000..980fa46 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/UtilException.java @@ -0,0 +1,26 @@ +package com.ruoyi.common.exception; + +/** + * 工具类异常 + * + * @author ruoyi + */ +public class UtilException extends RuntimeException +{ + private static final long serialVersionUID = 8247610319171014183L; + + public UtilException(Throwable e) + { + super(e.getMessage(), e); + } + + public UtilException(String message) + { + super(message); + } + + public UtilException(String message, Throwable throwable) + { + super(message, throwable); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/base/BaseException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/base/BaseException.java new file mode 100644 index 0000000..b55d72e --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/base/BaseException.java @@ -0,0 +1,97 @@ +package com.ruoyi.common.exception.base; + +import com.ruoyi.common.utils.MessageUtils; +import com.ruoyi.common.utils.StringUtils; + +/** + * 基础异常 + * + * @author ruoyi + */ +public class BaseException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 所属模块 + */ + private String module; + + /** + * 错误码 + */ + private String code; + + /** + * 错误码对应的参数 + */ + private Object[] args; + + /** + * 错误消息 + */ + private String defaultMessage; + + public BaseException(String module, String code, Object[] args, String defaultMessage) + { + this.module = module; + this.code = code; + this.args = args; + this.defaultMessage = defaultMessage; + } + + public BaseException(String module, String code, Object[] args) + { + this(module, code, args, null); + } + + public BaseException(String module, String defaultMessage) + { + this(module, null, null, defaultMessage); + } + + public BaseException(String code, Object[] args) + { + this(null, code, args, null); + } + + public BaseException(String defaultMessage) + { + this(null, null, null, defaultMessage); + } + + @Override + public String getMessage() + { + String message = null; + if (!StringUtils.isEmpty(code)) + { + message = MessageUtils.message(code, args); + } + if (message == null) + { + message = defaultMessage; + } + return message; + } + + public String getModule() + { + return module; + } + + public String getCode() + { + return code; + } + + public Object[] getArgs() + { + return args; + } + + public String getDefaultMessage() + { + return defaultMessage; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileException.java new file mode 100644 index 0000000..871f09b --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileException.java @@ -0,0 +1,19 @@ +package com.ruoyi.common.exception.file; + +import com.ruoyi.common.exception.base.BaseException; + +/** + * 文件信息异常类 + * + * @author ruoyi + */ +public class FileException extends BaseException +{ + private static final long serialVersionUID = 1L; + + public FileException(String code, Object[] args) + { + super("file", code, args, null); + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileNameLengthLimitExceededException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileNameLengthLimitExceededException.java new file mode 100644 index 0000000..70e0ec9 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileNameLengthLimitExceededException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.exception.file; + +/** + * 文件名称超长限制异常类 + * + * @author ruoyi + */ +public class FileNameLengthLimitExceededException extends FileException +{ + private static final long serialVersionUID = 1L; + + public FileNameLengthLimitExceededException(int defaultFileNameLength) + { + super("upload.filename.exceed.length", new Object[] { defaultFileNameLength }); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileSizeLimitExceededException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileSizeLimitExceededException.java new file mode 100644 index 0000000..ec6ab05 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileSizeLimitExceededException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.exception.file; + +/** + * 文件名大小限制异常类 + * + * @author ruoyi + */ +public class FileSizeLimitExceededException extends FileException +{ + private static final long serialVersionUID = 1L; + + public FileSizeLimitExceededException(long defaultMaxSize) + { + super("upload.exceed.maxSize", new Object[] { defaultMaxSize }); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java new file mode 100644 index 0000000..8b2af16 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java @@ -0,0 +1,81 @@ +package com.ruoyi.common.exception.file; + +import java.util.Arrays; +import org.apache.commons.fileupload.FileUploadException; + +/** + * 文件上传 误异常类 + * + * @author ruoyi + */ +public class InvalidExtensionException extends FileUploadException +{ + private static final long serialVersionUID = 1L; + + private String[] allowedExtension; + private String extension; + private String filename; + + public InvalidExtensionException(String[] allowedExtension, String extension, String filename) + { + super("文件[" + filename + "]后缀[" + extension + "]不正确,请上传" + Arrays.toString(allowedExtension) + "格式"); + this.allowedExtension = allowedExtension; + this.extension = extension; + this.filename = filename; + } + + public String[] getAllowedExtension() + { + return allowedExtension; + } + + public String getExtension() + { + return extension; + } + + public String getFilename() + { + return filename; + } + + public static class InvalidImageExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidFlashExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidMediaExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidVideoExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/job/TaskException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/job/TaskException.java new file mode 100644 index 0000000..a567b40 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/job/TaskException.java @@ -0,0 +1,34 @@ +package com.ruoyi.common.exception.job; + +/** + * 计划策略异常 + * + * @author ruoyi + */ +public class TaskException extends Exception +{ + private static final long serialVersionUID = 1L; + + private Code code; + + public TaskException(String msg, Code code) + { + this(msg, code, null); + } + + public TaskException(String msg, Code code, Exception nestedEx) + { + super(msg, nestedEx); + this.code = code; + } + + public Code getCode() + { + return code; + } + + public enum Code + { + TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/CaptchaException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/CaptchaException.java new file mode 100644 index 0000000..389dbc7 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/CaptchaException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.exception.user; + +/** + * 验证码错误异常类 + * + * @author ruoyi + */ +public class CaptchaException extends UserException +{ + private static final long serialVersionUID = 1L; + + public CaptchaException() + { + super("user.jcaptcha.error", null); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/CaptchaExpireException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/CaptchaExpireException.java new file mode 100644 index 0000000..85f9486 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/CaptchaExpireException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.exception.user; + +/** + * 验证码失效异常类 + * + * @author ruoyi + */ +public class CaptchaExpireException extends UserException +{ + private static final long serialVersionUID = 1L; + + public CaptchaExpireException() + { + super("user.jcaptcha.expire", null); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserException.java new file mode 100644 index 0000000..c292d70 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserException.java @@ -0,0 +1,18 @@ +package com.ruoyi.common.exception.user; + +import com.ruoyi.common.exception.base.BaseException; + +/** + * 用户信息异常类 + * + * @author ruoyi + */ +public class UserException extends BaseException +{ + private static final long serialVersionUID = 1L; + + public UserException(String code, Object[] args) + { + super("user", code, args, null); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserPasswordNotMatchException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserPasswordNotMatchException.java new file mode 100644 index 0000000..a7f3e5f --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserPasswordNotMatchException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.exception.user; + +/** + * 用户密码不正确或不符合规范异常类 + * + * @author ruoyi + */ +public class UserPasswordNotMatchException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserPasswordNotMatchException() + { + super("user.password.not.match", null); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserPasswordRetryLimitExceedException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserPasswordRetryLimitExceedException.java new file mode 100644 index 0000000..c887cf1 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserPasswordRetryLimitExceedException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.exception.user; + +/** + * 用户错误最大次数异常类 + * + * @author ruoyi + */ +public class UserPasswordRetryLimitExceedException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserPasswordRetryLimitExceedException(int retryLimitCount, int lockTime) + { + super("user.password.retry.limit.exceed", new Object[] { retryLimitCount, lockTime }); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserSmsNotMatchException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserSmsNotMatchException.java new file mode 100644 index 0000000..8c80afe --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserSmsNotMatchException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.exception.user; + +/** + * 用户密码不正确或不符合规范异常类 + * + * @author ruoyi + */ +public class UserSmsNotMatchException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserSmsNotMatchException(Integer surplusCount) + { + super("user.sms.not.match", new Object[] { surplusCount }); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserSmsRetryLimitExceedException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserSmsRetryLimitExceedException.java new file mode 100644 index 0000000..bb72b33 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserSmsRetryLimitExceedException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.exception.user; + +/** + * 用户错误最大次数异常类 + * + * @author ruoyi + */ +public class UserSmsRetryLimitExceedException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserSmsRetryLimitExceedException(int retryLimitCount, int lockTime) + { + super("user.sms.retry.limit.exceed", new Object[] { retryLimitCount, lockTime }); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/PropertyPreExcludeFilter.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/PropertyPreExcludeFilter.java new file mode 100644 index 0000000..e1e431b --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/PropertyPreExcludeFilter.java @@ -0,0 +1,24 @@ +package com.ruoyi.common.filter; + +import com.alibaba.fastjson2.filter.SimplePropertyPreFilter; + +/** + * 排除JSON敏感属性 + * + * @author ruoyi + */ +public class PropertyPreExcludeFilter extends SimplePropertyPreFilter +{ + public PropertyPreExcludeFilter() + { + } + + public PropertyPreExcludeFilter addExcludes(String... filters) + { + for (int i = 0; i < filters.length; i++) + { + this.getExcludes().add(filters[i]); + } + return this; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatableFilter.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatableFilter.java new file mode 100644 index 0000000..a1bcfe2 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatableFilter.java @@ -0,0 +1,52 @@ +package com.ruoyi.common.filter; + +import java.io.IOException; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import org.springframework.http.MediaType; +import com.ruoyi.common.utils.StringUtils; + +/** + * Repeatable 过滤器 + * + * @author ruoyi + */ +public class RepeatableFilter implements Filter +{ + @Override + public void init(FilterConfig filterConfig) throws ServletException + { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException + { + ServletRequest requestWrapper = null; + if (request instanceof HttpServletRequest + && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) + { + requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response); + } + if (null == requestWrapper) + { + chain.doFilter(request, response); + } + else + { + chain.doFilter(requestWrapper, response); + } + } + + @Override + public void destroy() + { + + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java new file mode 100644 index 0000000..407d1ba --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java @@ -0,0 +1,76 @@ +package com.ruoyi.common.filter; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import com.ruoyi.common.utils.http.HttpHelper; +import com.ruoyi.common.constant.Constants; + +/** + * 构建可重复读取inputStream的request + * + * @author ruoyi + */ +public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper +{ + private final byte[] body; + + public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException + { + super(request); + request.setCharacterEncoding(Constants.UTF8); + response.setCharacterEncoding(Constants.UTF8); + + body = HttpHelper.getBodyString(request).getBytes(Constants.UTF8); + } + + @Override + public BufferedReader getReader() throws IOException + { + return new BufferedReader(new InputStreamReader(getInputStream())); + } + + @Override + public ServletInputStream getInputStream() throws IOException + { + final ByteArrayInputStream bais = new ByteArrayInputStream(body); + return new ServletInputStream() + { + @Override + public int read() throws IOException + { + return bais.read(); + } + + @Override + public int available() throws IOException + { + return body.length; + } + + @Override + public boolean isFinished() + { + return false; + } + + @Override + public boolean isReady() + { + return false; + } + + @Override + public void setReadListener(ReadListener readListener) + { + + } + }; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssFilter.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssFilter.java new file mode 100644 index 0000000..9052f0d --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssFilter.java @@ -0,0 +1,75 @@ +package com.ruoyi.common.filter; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.enums.HttpMethod; + +/** + * 防止XSS攻击的过滤器 + * + * @author ruoyi + */ +public class XssFilter implements Filter +{ + /** + * 排除链接 + */ + public List excludes = new ArrayList<>(); + + @Override + public void init(FilterConfig filterConfig) throws ServletException + { + String tempExcludes = filterConfig.getInitParameter("excludes"); + if (StringUtils.isNotEmpty(tempExcludes)) + { + String[] url = tempExcludes.split(","); + for (int i = 0; url != null && i < url.length; i++) + { + excludes.add(url[i]); + } + } + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException + { + HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse resp = (HttpServletResponse) response; + if (handleExcludeURL(req, resp)) + { + chain.doFilter(request, response); + return; + } + XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request); + chain.doFilter(xssRequest, response); + } + + private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) + { + String url = request.getServletPath(); + String method = request.getMethod(); + // GET DELETE 不过滤 + if (method == null || HttpMethod.GET.matches(method) || HttpMethod.DELETE.matches(method)) + { + return true; + } + return StringUtils.matches(url, excludes); + } + + @Override + public void destroy() + { + + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java new file mode 100644 index 0000000..b1eeb65 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java @@ -0,0 +1,111 @@ +package com.ruoyi.common.filter; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import org.apache.commons.io.IOUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.html.EscapeUtil; + +/** + * XSS过滤处理 + * + * @author ruoyi + */ +public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper +{ + /** + * @param request + */ + public XssHttpServletRequestWrapper(HttpServletRequest request) + { + super(request); + } + + @Override + public String[] getParameterValues(String name) + { + String[] values = super.getParameterValues(name); + if (values != null) + { + int length = values.length; + String[] escapseValues = new String[length]; + for (int i = 0; i < length; i++) + { + // 防xss攻击和过滤前后空格 + escapseValues[i] = EscapeUtil.clean(values[i]).trim(); + } + return escapseValues; + } + return super.getParameterValues(name); + } + + @Override + public ServletInputStream getInputStream() throws IOException + { + // 非json类型,直接返回 + if (!isJsonRequest()) + { + return super.getInputStream(); + } + + // 为空,直接返回 + String json = IOUtils.toString(super.getInputStream(), "utf-8"); + if (StringUtils.isEmpty(json)) + { + return super.getInputStream(); + } + + // xss过滤 + json = EscapeUtil.clean(json).trim(); + byte[] jsonBytes = json.getBytes("utf-8"); + final ByteArrayInputStream bis = new ByteArrayInputStream(jsonBytes); + return new ServletInputStream() + { + @Override + public boolean isFinished() + { + return true; + } + + @Override + public boolean isReady() + { + return true; + } + + @Override + public int available() throws IOException + { + return jsonBytes.length; + } + + @Override + public void setReadListener(ReadListener readListener) + { + } + + @Override + public int read() throws IOException + { + return bis.read(); + } + }; + } + + /** + * 是否是Json请求 + * + * @param request + */ + public boolean isJsonRequest() + { + String header = super.getHeader(HttpHeaders.CONTENT_TYPE); + return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE); + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/importer/ImporterBase.java b/ruoyi-common/src/main/java/com/ruoyi/common/importer/ImporterBase.java new file mode 100644 index 0000000..c03f285 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/importer/ImporterBase.java @@ -0,0 +1,527 @@ +package com.ruoyi.common.importer; + +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.importer.beans.CellFormatBean; +import com.ruoyi.common.importer.beans.ResultBean; +import com.ruoyi.common.importer.beans.enums.ImportResultType; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * 导入模块基类 + * + * @author lqz + */ +@Slf4j +public abstract class ImporterBase { + + @Setter + @Getter + protected Class className; + + protected List cellFormatBeans = new ArrayList<>(); + + String no = "false"; + + String yes = "true"; + + protected Long sceneBigId; + protected String importType; + protected Object[] args; + + /** + * 值唯一的列名,并且至少有一个不能为空 + */ + private List uniqueColumnNameList; + /** + * 值唯一的列的数据,外列里行 + */ + private List> uniqueColumnValues; + private String uniqueColumnNames; + /** + * 导入结果排除特定列 + */ + @Setter + private String[] hiddenResultColumns; + /** + * 临时保存组合唯一字段的值 + */ + private List tempUniqueColumnValue = new ArrayList<>(); + + /** + * 获取泛型对应的Class对象 + * + * @param clazz importer + * @param i 参数索引 + * @return CLass对象 + */ + public Class getActualTypeArgument(Class clazz, int i) { + Class entitiClass = null; + Type genericSuperclass = clazz.getGenericSuperclass(); + if (genericSuperclass instanceof ParameterizedType) { + Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass) + .getActualTypeArguments(); + if (actualTypeArguments != null && actualTypeArguments.length > 0) { + entitiClass = (Class) actualTypeArguments[i]; + } + } + return entitiClass; + } + + /** + * 获取isUnique为"true”的字段 + * + * @param ruleList 核查规则 + * @return Unique + */ + private List getUniqueColumnNameList(List ruleList) { + List uniqueColumnNameList = new ArrayList<>(); + + for (CellFormatBean bean : ruleList) { + if (yes.equalsIgnoreCase(bean.getIsUnique())) { + uniqueColumnNameList.add(bean.getColumnCn()); + } + } + return uniqueColumnNameList; + } + + /** + * 初始化唯一列的列名 + * + * @param ruleList 核查规则 + */ + private void disposeUniqueColumns(List ruleList) { + // 值唯一的列名 + uniqueColumnNameList = this.getUniqueColumnNameList(ruleList); + + // 值唯一的列的数据 + uniqueColumnValues = new ArrayList<>(); + uniqueColumnNames = ""; + for (String s : uniqueColumnNameList) { + uniqueColumnValues.add(new ArrayList<>()); + uniqueColumnNames = uniqueColumnNames + s + ","; + } + if (uniqueColumnNames.length() > 0) { + uniqueColumnNames = uniqueColumnNames.substring(0, uniqueColumnNames.length() - 1); + } + } + + /** + * 导入 + * + * @param datas 数据 + * @param args 可选参数 + * @return 导入结果 + * @throws Exception 异常 + */ + public AjaxResult doAdd(List datas, Object... args) throws Exception { + return doAdd(datas, null, "", args); + } + + /** + * 核查规则放到importer里面 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 参数 + * @return 导入结果 + * @throws Exception 异常 + */ + public AjaxResult doAdd(List datas, Long sceneBigId, String importType, Object... args) throws Exception { + return doAdd(datas, cellFormatBeans, sceneBigId, importType, args); + } + + /** + * 导入 + * + * @param datas 数据 + * @param formats 核查规则 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @return 导入结果 + */ + public AjaxResult doAdd(List datas, List formats, Long sceneBigId, String importType, Object... args) throws Exception { + // 核查数据是否为空 + if (StringUtils.isNull(datas) || datas.size() == 0) { + return AjaxResult.error(ImportResultType.DATA_EMPTY.getValue()); + } + if (!validTemplate(datas)) { + return AjaxResult.error(ImportResultType.TEMPLATE_ERR.getValue()); + } + + // 参数赋值 + this.sceneBigId = sceneBigId; + this.importType = importType; + this.args = args; + + // 初始化唯一列的列名 + this.disposeUniqueColumns(formats); + boolean f = true; + for (int i = 0; i < datas.size(); i++) { + StringBuilder reasonB = new StringBuilder(); + for (int j = 0; j < formats.size(); j++) { + try { + Class aClass = datas.get(i).getClass(); + Field field = aClass.getDeclaredField(formats.get(j).getColumnEn()); + field.setAccessible(true); + String s = (String) field.get(datas.get(i)); + if (isNotEmpty(s)) { + s = preHandleCellValue(s, formats.get(j)); + } + StringBuilder reasonS = new StringBuilder(); + StringBuilder reasonL = new StringBuilder(); + StringBuilder reasonSh = new StringBuilder(); + if (basicCheck(s, formats.get(j), reasonS)) { + specialCheck(s, formats.get(j), reasonS, sceneBigId, importType, args, i, j); + checkRegionCountyComboLink(s, formats.get(j), reasonS); + } + checkUniqueColumns(s, formats.get(j), reasonS); + if (j == formats.size() - 1) { + checkAtRowEnd(s, formats.get(j), reasonL, sceneBigId, importType, args, i); + if (i == datas.size() - 1) { + checkAtLastEnd(s, formats.get(j), reasonSh, sceneBigId, importType, args); + } + } + if (isNotEmpty(reasonS.toString())) { + reasonB.append("【").append(formats.get(j).getColumnCn()).append("】").append(reasonS); + } + if (isNotEmpty(reasonL.toString())) { + reasonB.append(reasonL); + } + if (isNotEmpty(reasonSh.toString())) { + reasonB.append(reasonSh); + } + field.set(datas.get(i), s); + } catch (Exception e) { + e.printStackTrace(); + reasonB.append("【").append(formats.get(j).getColumnCn()).append("】").append("未知错误,请仔细阅读填写规范确保填写正确。"); + } + } + datas.get(i).setReason(reasonB.toString()); + if (isNotEmpty(datas.get(i).getReason())) { + f = false; + } + } + if (!f) { + className = getActualTypeArgument(this.getClass(), 0); + ExcelUtil util = new ExcelUtil<>(className); + util.hideColumn(hiddenResultColumns); + String name = (String) util.exportExcel(datas, "导入结果").get(AjaxResult.MSG_TAG); + return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", name); + } + + try { + insertDataToDB(datas, sceneBigId, importType, args); + } catch (Exception e) { + e.printStackTrace(); + throw new ServiceException("数据库异常。"); + } + + return AjaxResult.success(); + } + + /** + * 数据预处理 + * + * @param s cell + * @param cellFormatBean 校验规则 + */ + protected String preHandleCellValue(String s, CellFormatBean cellFormatBean) { + return s.trim(); + } + + private String city; + private String county; + + /** + * 地市区县联动核查 + * + * @param s 值 + * @param cellFormatBean 规则 + * @param reasonS 结果 + */ + private void checkRegionCountyComboLink(String s, CellFormatBean cellFormatBean, StringBuilder reasonS) { + if ("city".equals(cellFormatBean.getColumnEn())) { + city = DictUtils.getDictValue("yw_city", s); + } + if ("county".equals(cellFormatBean.getColumnEn())) { + county = DictUtils.getDictValue("yw_county", s); + if (isNotEmpty(city) && isNotEmpty(county) && !county.substring(0, 4).equals(city)) { + reasonS.append("区县不在该地市下"); + } + } + } + + /** + * 表尾核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonSh 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + protected abstract void checkAtLastEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonSh, Long sceneBigId, String importType, Object[] args) throws Exception; + + /** + * 行末核查 + * + * @param s 数据 + * @param cellFormatBean 校验格式 + * @param reasonL 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @throws Exception 异常 + */ + protected abstract void checkAtRowEnd(String s, CellFormatBean cellFormatBean, StringBuilder reasonL, Long sceneBigId, String importType, Object[] args, int i) throws Exception; + + /** + * 核查字段唯一性 + * + * @param s 字段 + * @param format 核查规则 + * @param reasonS 核查结果 + */ + private void checkUniqueColumns(String s, CellFormatBean format, StringBuilder reasonS) { + if (uniqueColumnNameList.size() == 1) { + if (format.getColumnCn().equals(uniqueColumnNameList.get(0))) { + if (!"".equals(s)) { + if (uniqueColumnValues.get(0).contains(s)) { + reasonS.append("不唯一,存在重复值。"); + } else { + uniqueColumnValues.get(0).add(s); + } + } else { + reasonS.append(uniqueColumnNameList).append("不能为空。"); + } + } + } else if (uniqueColumnNameList.size() > 1) { + if (uniqueColumnNameList.contains(format.getColumnCn())) { + + int index = uniqueColumnNameList.indexOf(format.getColumnCn()); + tempUniqueColumnValue.add(s); + + if (index == uniqueColumnNameList.size() - 1) { + + boolean flagAllSame = false; + boolean flagAllSameIn; + for (int i = 0; i < uniqueColumnValues.get(0).size(); i++) { + flagAllSameIn = true; + for (int m = 0; m < tempUniqueColumnValue.size(); m++) { + if (!uniqueColumnValues.get(m).get(i).equals(tempUniqueColumnValue.get(m))) { + flagAllSameIn = false; + break; + } + } + if (flagAllSameIn) { + flagAllSame = true; + break; + } + } + + boolean flagAllNull = true; + for (String value : tempUniqueColumnValue) { + if (!"".equals(value)) { + flagAllNull = false; + break; + } + } + + if (flagAllSame) { + reasonS.append(uniqueColumnNames).append("组合后的值不唯一,存在重复值。"); + tempUniqueColumnValue.clear(); + } else { + for (int k = 0; k < tempUniqueColumnValue.size(); k++) { + uniqueColumnValues.get(k).add(tempUniqueColumnValue.get(k)); + } + tempUniqueColumnValue.clear(); + } + + if (flagAllNull) { + reasonS.append(uniqueColumnNameList.toString()).append("至少有一个值不能为空。"); + } + + tempUniqueColumnValue = new ArrayList<>(); + } + } + } + } + + /** + * 子类核查 + * + * @param s 数据 + * @param format 校验格式 + * @param reasonS 失败原因 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @param i 行 + * @param j 列 + * @throws Exception 异常 + */ + protected abstract void specialCheck(String s, CellFormatBean format, StringBuilder reasonS, Long sceneBigId, String importType, Object[] args, int i, int j) throws Exception; + + /** + * 通用核查 + * + * @param s 数据 + * @param format 核查规则 + * @param reasonS 失败原因 + * @return 核查结果 + */ + private boolean basicCheck(String s, CellFormatBean format, StringBuilder reasonS) { + + boolean flag = true; + + if (no.equalsIgnoreCase(format.getIsNull())) { + if (isEmpty(s)) { + flag = false; + reasonS.append("值不能为空。"); + } + } + if (isNotEmpty(s)) { + if (yes.equalsIgnoreCase(format.getIsDate())) { + if (!StringUtils.isDate(s, format.getDateFormat())) { + flag = false; + reasonS.append("日期格式不正确,必须符合").append(format.getDateFormat()).append("。"); + } + } + if (yes.equalsIgnoreCase(format.getIsNum())) { + if (!StringUtils.isNum(s)) { + flag = false; + reasonS.append("必须是数字。"); + } + if ("nonNegative".equalsIgnoreCase(format.getNumType())) { + if (!StringUtils.isUnNegativeInt(s)) { + flag = false; + reasonS.append("必须是非负整数。"); + } + } else if ("integer".equalsIgnoreCase(format.getNumType())) { + if (!StringUtils.isInt(s)) { + flag = false; + reasonS.append("必须是整数。"); + } + } else if ("positiveInt".equalsIgnoreCase(format.getNumType())) { + if (!StringUtils.isPositiveInt(s)) { + flag = false; + reasonS.append("必须是正整数。"); + } + } else if ("phone".equalsIgnoreCase(format.getNumType())) { + if (!StringUtils.isPhone(s)) { + flag = false; + reasonS.append("必须是合法的手机号码格式。"); + } + } + } + if (isNotEmpty(format.getDictType())) { + String id = getDictValue(format.getDictType(), s); + if (isEmpty(id)) { + flag = false; + reasonS.append("枚举值不正确。"); + } + } + if (isNotEmpty(format.getOptVal())) { + String[] val = format.getOptVal().split(","); + if (!Arrays.asList(val).contains(s)) { + flag = false; + reasonS.append("枚举值不正确。"); + } + } + } + + return flag; + } + + /** + * 数据更新 + * + * @param datas 数据 + * @param sceneBigId 大场景id + * @param importType 导入类型 + * @param args 可选参数 + * @throws Exception 异常 + */ + protected abstract void insertDataToDB(List datas, Long sceneBigId, String importType, Object[] args) throws Exception; + + /** + * 核查模板 + * + * @param datas 数据 + * @return 是否核查通过 + */ + private boolean validTemplate(List datas) { + for (T data : datas) { + if (StringUtils.isNull(data)) { + return false; + } + } + return true; + } + + protected boolean isEmpty(String s) { + return StringUtils.isEmpty(s); + } + + protected boolean isNotEmpty(String s) { + return StringUtils.isNotEmpty(s); + } + + protected String getDictValue(String dictType, String dictLabel) { + return getDictValue(dictType, dictLabel, DictUtils.SEPARATOR); + } + + /** + * 根据字典label获取字典值 + * + * @param dictType 字典类型 + * @param dictLabel label + * @param separator 分隔符 + * @return 字典值 + */ + protected String getDictValue(String dictType, String dictLabel, String separator) { + + StringBuilder propertyString = new StringBuilder(); + List datas = DictUtils.getDictCache(dictType); + + if (StringUtils.containsAny(separator, dictLabel) && StringUtils.isNotEmpty(datas)) { + for (SysDictData dict : datas) { + for (String label : dictLabel.split(separator)) { + if (label.equals(dict.getDictLabel())) { + propertyString.append(dict.getDictValue()).append(separator); + break; + } + } + } + } else { + for (SysDictData dict : datas) { + if (dictLabel.equals(dict.getDictLabel())) { + return dict.getDictValue(); + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/importer/beans/CellFormatBean.java b/ruoyi-common/src/main/java/com/ruoyi/common/importer/beans/CellFormatBean.java new file mode 100644 index 0000000..96327a3 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/importer/beans/CellFormatBean.java @@ -0,0 +1,79 @@ +package com.ruoyi.common.importer.beans; + +import lombok.Data; + +/** + * 单元格校验实体 + * + * @author los + */ +@Data +public class CellFormatBean { + + /** + * 字段中文名 + */ + private String columnCn; + /** + * 字段英文名 + */ + private String columnEn; + /** + * 是否可以为空 + */ + private String isNull; + /** + * 是否为日期 + */ + private String isDate; + /** + * 是否是数字 + */ + private String isNum; + /** + * 数字类型 + */ + private String numType; + /** + * 日期格式 + */ + private String dateFormat; + /** + * 字典类型 + */ + private String dictType; + /** + * 枚举值 + */ + private String optVal; + /** + * 是否唯一 + */ + private String isUnique; + + public CellFormatBean(String columnCn, String columnEn, String isNull, String isDate, String isNum, String dateFormat, String dictType, String optVal, String isUnique) { + this.columnCn = columnCn; + this.columnEn = columnEn; + this.isNull = isNull; + this.isDate = isDate; + this.isNum = isNum; + this.dateFormat = dateFormat; + this.dictType = dictType; + this.optVal = optVal; + this.isUnique = isUnique; + } + + public CellFormatBean(String columnCn, String columnEn, String isNull, String isDate, String isNum, String numType, String dateFormat, String dictType, String optVal, String isUnique) { + this.columnCn = columnCn; + this.columnEn = columnEn; + this.isNull = isNull; + this.isDate = isDate; + this.isNum = isNum; + this.numType = numType; + this.dateFormat = dateFormat; + this.dictType = dictType; + this.optVal = optVal; + this.isUnique = isUnique; + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/importer/beans/ResultBean.java b/ruoyi-common/src/main/java/com/ruoyi/common/importer/beans/ResultBean.java new file mode 100644 index 0000000..9158326 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/importer/beans/ResultBean.java @@ -0,0 +1,17 @@ +package com.ruoyi.common.importer.beans; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +/** + * 导入结果 + * + * @author los + */ +@Data +public class ResultBean { + @Excel(name = "失败原因", type = Excel.Type.EXPORT) + @TableField(exist = false) + private String reason; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/importer/beans/enums/ImportResultType.java b/ruoyi-common/src/main/java/com/ruoyi/common/importer/beans/enums/ImportResultType.java new file mode 100644 index 0000000..fdde517 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/importer/beans/enums/ImportResultType.java @@ -0,0 +1,39 @@ +package com.ruoyi.common.importer.beans.enums; + +import lombok.Getter; +import lombok.ToString; + +/** + * 核查失败原因 + * + * @author los + */ +@Getter +@ToString +public enum ImportResultType { + + /** + * 模板不对 + */ + TEMPLATE_ERR(1, "导入失败,模板不正确。"), + /** + * 核查失败 + */ + CHECK_ERR(2, "导入失败,核查失败。"), + /** + * 数据为空 + */ + DATA_EMPTY(3, "导入失败,数据为空。"), + /** + * 导入成功 + */ + SUCCESS(4, "导入成功。"); + private Integer code; + private String value; + + ImportResultType(Integer code, String value) { + this.code = code; + this.value = value; + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/importer/service/YwBatchAddService.java b/ruoyi-common/src/main/java/com/ruoyi/common/importer/service/YwBatchAddService.java new file mode 100644 index 0000000..1e1ab6e --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/importer/service/YwBatchAddService.java @@ -0,0 +1,47 @@ +package com.ruoyi.common.importer.service; + +import cn.hutool.core.collection.CollUtil; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 批量插入 + * + * @author los + */ +public interface YwBatchAddService { + + /** + * 批量导入,单次1000 + * + * @param all 记录 + */ + default void add(List all) { + add(all, 0L, 1000L); + } + + /** + * 批量导入 + * + * @param all 记录 + * @param strart 起始 + * @param limit 单次 + */ + default void add(List all, long strart, long limit) { + List collect = all.stream().skip(strart).limit(limit).collect(Collectors.toList()); + if (CollUtil.isEmpty(collect)) { + return; + } + insertB(collect); + this.add(all, strart + limit, limit); + } + + /** + * 实现类提供具体插入方法 + * + * @param collect 数据 + */ + void insertB(List collect); + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/mybatis/JsonListLongTypeHandler.java b/ruoyi-common/src/main/java/com/ruoyi/common/mybatis/JsonListLongTypeHandler.java new file mode 100644 index 0000000..144a170 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/mybatis/JsonListLongTypeHandler.java @@ -0,0 +1,62 @@ +package com.ruoyi.common.mybatis; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.ibatis.type.BaseTypeHandler; +import org.apache.ibatis.type.JdbcType; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +/* + + */ +public class JsonListLongTypeHandler extends BaseTypeHandler> { + private static final ObjectMapper mapper = new ObjectMapper(); + + @Override + public void setNonNullParameter(PreparedStatement ps, int i, List parameter, JdbcType jdbcType) + throws SQLException { + ps.setString(i, toJson(parameter)); + } + + @Override + public List getNullableResult(ResultSet rs, String columnName) throws SQLException { + return this.toObject(rs.getString(columnName)); + } + + @Override + public List getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + return this.toObject(rs.getString(columnIndex)); + } + + @Override + public List getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + return this.toObject(cs.getString(columnIndex)); + } + + private String toJson(List params) { + try { + return mapper.writeValueAsString(params); + } catch (Exception e) { + e.printStackTrace(); + } + return "[]"; + } + + private List toObject(String content) { + if (content != null && !content.isEmpty()) { + try { + return mapper.readValue(content, new TypeReference>() { + }); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + return null; + } + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/AppUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/AppUtils.java new file mode 100644 index 0000000..5b2b716 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/AppUtils.java @@ -0,0 +1,85 @@ +package com.ruoyi.common.utils; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.UUID; + +/** + * @author los + */ +public class AppUtils { + + //生成 app_secret 密钥 + private final static String SERVER_NAME = "杭州YY中小屏大屏对接接口-告警统计列表查询"; + private final static String[] chars = new String[]{"a", "b", "c", "d", "e", "f", + "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", + "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", + "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", + "W", "X", "Y", "Z"}; + + /** + * @Description:

+ * 短8位UUID思想其实借鉴微博短域名的生成方式,但是其重复概率过高,而且每次生成4个,需要随即选取一个。 + * 本算法利用62个可打印字符,通过随机生成32位UUID,由于UUID都为十六进制,所以将UUID分成8组,每4个为一组,然后通过模62操作,结果作为索引取出字符, + * 这样重复率大大降低。 + * 经测试,在生成一千万个数据也没有出现重复,完全满足大部分需求。 + *

+ * @date 2023-02-15 + */ + public static String getAppId() { + StringBuffer shortBuffer = new StringBuffer(); + String uuid = UUID.randomUUID().toString().replace("-", ""); + for (int i = 0; i < 8; i++) { + String str = uuid.substring(i * 4, i * 4 + 4); + int x = Integer.parseInt(str, 16); + shortBuffer.append(chars[x % 0x3E]); + } + return shortBuffer.toString(); + } + + /** + *

+ * 通过appId和内置关键词生成APP Secret + *

+ * + * @date 2023-02-15 + */ + public static String getAppSecret(String appId) { + try { + String[] array = new String[]{appId, SERVER_NAME}; + StringBuffer sb = new StringBuffer(); + // 字符串排序 + Arrays.sort(array); + for (int i = 0; i < array.length; i++) { + sb.append(array[i]); + } + String str = sb.toString(); + MessageDigest md = MessageDigest.getInstance("SHA-256"); + md.update(str.getBytes()); + byte[] digest = md.digest(); + + StringBuffer hexstr = new StringBuffer(); + String shaHex = ""; + for (int i = 0; i < digest.length; i++) { + shaHex = Integer.toHexString(digest[i] & 0xFF); + if (shaHex.length() < 2) { + hexstr.append(0); + } + hexstr.append(shaHex); + } + return hexstr.toString(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + throw new RuntimeException(); + } + } + + /*public static void main(String[] args) { + String appId = getAppId(); + System.out.println(appId); + System.out.println(getAppSecret(appId)); + }*/ + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/Arith.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/Arith.java new file mode 100644 index 0000000..b6326c2 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/Arith.java @@ -0,0 +1,114 @@ +package com.ruoyi.common.utils; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * 精确的浮点数运算 + * + * @author ruoyi + */ +public class Arith +{ + + /** 默认除法运算精度 */ + private static final int DEF_DIV_SCALE = 10; + + /** 这个类不能实例化 */ + private Arith() + { + } + + /** + * 提供精确的加法运算。 + * @param v1 被加数 + * @param v2 加数 + * @return 两个参数的和 + */ + public static double add(double v1, double v2) + { + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.add(b2).doubleValue(); + } + + /** + * 提供精确的减法运算。 + * @param v1 被减数 + * @param v2 减数 + * @return 两个参数的差 + */ + public static double sub(double v1, double v2) + { + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.subtract(b2).doubleValue(); + } + + /** + * 提供精确的乘法运算。 + * @param v1 被乘数 + * @param v2 乘数 + * @return 两个参数的积 + */ + public static double mul(double v1, double v2) + { + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.multiply(b2).doubleValue(); + } + + /** + * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 + * 小数点以后10位,以后的数字四舍五入。 + * @param v1 被除数 + * @param v2 除数 + * @return 两个参数的商 + */ + public static double div(double v1, double v2) + { + return div(v1, v2, DEF_DIV_SCALE); + } + + /** + * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 + * 定精度,以后的数字四舍五入。 + * @param v1 被除数 + * @param v2 除数 + * @param scale 表示表示需要精确到小数点以后几位。 + * @return 两个参数的商 + */ + public static double div(double v1, double v2, int scale) + { + if (scale < 0) + { + throw new IllegalArgumentException( + "The scale must be a positive integer or zero"); + } + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + if (b1.compareTo(BigDecimal.ZERO) == 0) + { + return BigDecimal.ZERO.doubleValue(); + } + return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue(); + } + + /** + * 提供精确的小数位四舍五入处理。 + * @param v 需要四舍五入的数字 + * @param scale 小数点后保留几位 + * @return 四舍五入后的结果 + */ + public static double round(double v, int scale) + { + if (scale < 0) + { + throw new IllegalArgumentException( + "The scale must be a positive integer or zero"); + } + BigDecimal b = new BigDecimal(Double.toString(v)); + BigDecimal one = BigDecimal.ONE; + return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/CoordinateConversionUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/CoordinateConversionUtils.java new file mode 100644 index 0000000..45448ff --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/CoordinateConversionUtils.java @@ -0,0 +1,168 @@ +package com.ruoyi.common.utils; + +/** + * 坐标转换工具 + * 目前国内主要有以下三种坐标系: + *

+ * WGS84:为一种大地坐标系,也是目前广泛使用的GPS全球卫星定位系统使用的坐标系。 + *

+ * GCJ02:又称火星坐标系,是由中国国家测绘局制订的地理信息系统的坐标系统。由WGS84坐标系经加密后的坐标系。 + *

+ * BD09:为百度坐标系,在GCJ02坐标系基础上再次加密。其中bd09ll表示百度经纬度坐标,bd09mc表示百度墨卡托米制坐标。 + *

+ * 非中国地区地图,服务坐标统一使用WGS84坐标。 + */ +public class CoordinateConversionUtils { + static double x_PI = 3.14159265358979324 * 3000.0 / 180.0; + static double PI = 3.1415926535897932384626; + static double a = 6378245.0; + static double ee = 0.00669342162296594323; + + /** + * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换 + * 即 百度 转 谷歌、高德 + * + * @param bd_lon + * @param bd_lat + * @returns {*[]} + */ + public String bd09togcj02(double bd_lon, double bd_lat) { + double x = bd_lon - 0.0065; + double y = bd_lat - 0.006; + double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI); + double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_PI); + double gg_lng = z * Math.cos(theta); + double gg_lat = z * Math.sin(theta); + // Point point=new Point(gg_lng, gg_lat); + // return point; + return gg_lng + "," + gg_lat; + } + + /** + * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换 + * 即谷歌、高德 转 百度 + * + * @param lng + * @param lat + * @returns {*[]} + */ + public static String gcj02tobd09(double lng, double lat) { + double z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI); + double theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI); + double bd_lng = z * Math.cos(theta) + 0.0065; + double bd_lat = z * Math.sin(theta) + 0.006; + //Point point=new Point(bd_lng, bd_lat); + // return point; + return bd_lng + "," + bd_lat; + } + + ; + + /** + * WGS84转GCj02 + * + * @param lng + * @param lat + * @returns {*[]} + */ + public static String wgs84togcj02(double lng, double lat) { + double dlat = transformlat(lng - 105.0, lat - 35.0); + double dlng = transformlng(lng - 105.0, lat - 35.0); + double radlat = lat / 180.0 * PI; + double magic = Math.sin(radlat); + magic = 1 - ee * magic * magic; + double sqrtmagic = Math.sqrt(magic); + dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI); + dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI); + double mglat = lat + dlat; + double mglng = lng + dlng; + //Point point=new Point(mglng, mglat); + // return point; + return mglng + "," + mglat; + } + + ; + + /** + * GCJ02 转换为 WGS84 + * + * @param lng + * @param lat + * @returns {*[]} + */ + public String gcj02towgs84(double lng, double lat) { + double dlat = transformlat(lng - 105.0, lat - 35.0); + double dlng = transformlng(lng - 105.0, lat - 35.0); + double radlat = lat / 180.0 * PI; + double magic = Math.sin(radlat); + magic = 1 - ee * magic * magic; + double sqrtmagic = Math.sqrt(magic); + dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI); + dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI); + double mglat = lat + dlat; + double mglng = lng + dlng; + // Point point=new Point(mglng, mglat); + // return point; + return mglat + "," + mglng; + } + + ; + + /** + * WGS84 转换为 BD-09 + * + * @param lng + * @param lat + * @returns {*[]} + */ + public static String wgs84tobd09(double lng, double lat) { + //第一次转换 + double dlat = transformlat(lng - 105.0, lat - 35.0); + double dlng = transformlng(lng - 105.0, lat - 35.0); + double radlat = lat / 180.0 * PI; + double magic = Math.sin(radlat); + magic = 1 - ee * magic * magic; + double sqrtmagic = Math.sqrt(magic); + dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI); + dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI); + double mglat = lat + dlat; + double mglng = lng + dlng; + + //第二次转换 + double z = Math.sqrt(mglng * mglng + mglat * mglat) + 0.00002 * Math.sin(mglat * x_PI); + double theta = Math.atan2(mglat, mglng) + 0.000003 * Math.cos(mglng * x_PI); + double bd_lng = z * Math.cos(theta) + 0.0065; + double bd_lat = z * Math.sin(theta) + 0.006; + return bd_lng + "," + bd_lat; + } + + private static double transformlat(double lng, double lat) { + double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng)); + ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; + ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0; + ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0; + return ret; + } + + private static double transformlng(double lng, double lat) { + double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng)); + ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; + ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0; + ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0; + return ret; + } + + public static void main(String[] args) { + // 两次谷歌转换为百度坐标 + // 第一次 WGS84转GCj02 + String lnglat = wgs84togcj02(117.20296517261839, 31.841652709281103); + double lng = Double.parseDouble(lnglat.split(",")[0]); + double lat = Double.parseDouble(lnglat.split(",")[1]); + System.out.println("第一次转换的结果:" + lng + "," + lat); + // 第二次 gcj02tobd09 + System.out.println("第二次转换的结果:" + gcj02tobd09(lng, lat)); + + // 谷歌转百度一次转换 + System.out.println("谷歌转换为百度一次转换的结果:" + wgs84tobd09(117.20296517261839, 31.841652709281103)); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java new file mode 100644 index 0000000..b2295d5 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java @@ -0,0 +1,193 @@ +package com.ruoyi.common.utils; + +import java.lang.management.ManagementFactory; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Date; +import org.apache.commons.lang3.time.DateFormatUtils; + +/** + * 时间工具类 + * + * @author ruoyi + */ +public class DateUtils extends org.apache.commons.lang3.time.DateUtils +{ + public static String YYYY = "yyyy"; + + public static String YYYY_MM = "yyyy-MM"; + + public static String YYYY_MM_DD = "yyyy-MM-dd"; + + public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; + + public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + + private static String[] parsePatterns = { + "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", + "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", + "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; + + /** + * 获取当前Date型日期 + * + * @return Date() 当前日期 + */ + public static Date getNowDate() + { + return new Date(); + } + + /** + * 获取当前日期, 默认格式为yyyy-MM-dd + * + * @return String + */ + public static String getDate() + { + return dateTimeNow(YYYY_MM_DD); + } + + public static final String getTime() + { + return dateTimeNow(YYYY_MM_DD_HH_MM_SS); + } + + public static final String dateTimeNow() + { + return dateTimeNow(YYYYMMDDHHMMSS); + } + + public static final String dateTimeNow(final String format) + { + return parseDateToStr(format, new Date()); + } + + public static final String dateTime(final Date date) + { + return parseDateToStr(YYYY_MM_DD, date); + } + + public static final String parseDateToStr(final String format, final Date date) + { + return new SimpleDateFormat(format).format(date); + } + + public static final Date dateTime(final String format, final String ts) + { + try + { + return new SimpleDateFormat(format).parse(ts); + } + catch (ParseException e) + { + throw new RuntimeException(e); + } + } + + /** + * 日期路径 即年/月/日 如2018/08/08 + */ + public static final String datePath() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyy/MM/dd"); + } + + /** + * 日期路径 即年/月/日 如20180808 + */ + public static final String dateDate() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyyMMdd"); + } + + public static final String dateTime() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyyMMddhhmmss"); + } + + /** + * 日期型字符串转化为日期 格式 + */ + public static Date parseDate(Object str) + { + if (str == null) + { + return null; + } + try + { + return parseDate(str.toString(), parsePatterns); + } + catch (ParseException e) + { + return null; + } + } + + /** + * 获取服务器启动时间 + */ + public static Date getServerStartDate() + { + long time = ManagementFactory.getRuntimeMXBean().getStartTime(); + return new Date(time); + } + + /** + * 计算相差天数 + */ + public static int differentDaysByMillisecond(Date date1, Date date2) + { + return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24))); + } + + /** + * 计算两个时间差 + */ + public static String getDatePoor(Date endDate, Date nowDate) + { + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + // long ns = 1000; + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - nowDate.getTime(); + // 计算差多少天 + long day = diff / nd; + // 计算差多少小时 + long hour = diff % nd / nh; + // 计算差多少分钟 + long min = diff % nd % nh / nm; + // 计算差多少秒//输出结果 + // long sec = diff % nd % nh % nm / ns; + return day + "天" + hour + "小时" + min + "分钟"; + } + + /** + * 增加 LocalDateTime ==> Date + */ + public static Date toDate(LocalDateTime temporalAccessor) + { + ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault()); + return Date.from(zdt.toInstant()); + } + + /** + * 增加 LocalDate ==> Date + */ + public static Date toDate(LocalDate temporalAccessor) + { + LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0)); + ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); + return Date.from(zdt.toInstant()); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java new file mode 100644 index 0000000..8c9c779 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java @@ -0,0 +1,188 @@ +package com.ruoyi.common.utils; + +import java.util.Collection; +import java.util.List; +import com.alibaba.fastjson2.JSONArray; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.utils.spring.SpringUtils; + +/** + * 字典工具类 + * + * @author ruoyi + */ +public class DictUtils +{ + /** + * 分隔符 + */ + public static final String SEPARATOR = ","; + + /** + * 设置字典缓存 + * + * @param key 参数键 + * @param dictDatas 字典数据列表 + */ + public static void setDictCache(String key, List dictDatas) + { + SpringUtils.getBean(RedisCache.class).setCacheObject(getCacheKey(key), dictDatas); + } + + /** + * 获取字典缓存 + * + * @param key 参数键 + * @return dictDatas 字典数据列表 + */ + public static List getDictCache(String key) + { + JSONArray arrayCache = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key)); + if (StringUtils.isNotNull(arrayCache)) + { + return arrayCache.toList(SysDictData.class); + } + return null; + } + + /** + * 根据字典类型和字典值获取字典标签 + * + * @param dictType 字典类型 + * @param dictValue 字典值 + * @return 字典标签 + */ + public static String getDictLabel(String dictType, String dictValue) + { + return getDictLabel(dictType, dictValue, SEPARATOR); + } + + /** + * 根据字典类型和字典标签获取字典值 + * + * @param dictType 字典类型 + * @param dictLabel 字典标签 + * @return 字典值 + */ + public static String getDictValue(String dictType, String dictLabel) + { + return getDictValue(dictType, dictLabel, SEPARATOR); + } + + /** + * 根据字典类型和字典值获取字典标签 + * + * @param dictType 字典类型 + * @param dictValue 字典值 + * @param separator 分隔符 + * @return 字典标签 + */ + public static String getDictLabel(String dictType, String dictValue, String separator) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + + if (StringUtils.isNotNull(datas)) + { + if (StringUtils.containsAny(separator, dictValue)) + { + for (SysDictData dict : datas) + { + for (String value : dictValue.split(separator)) + { + if (value.equals(dict.getDictValue())) + { + propertyString.append(dict.getDictLabel()).append(separator); + break; + } + } + } + } + else + { + for (SysDictData dict : datas) + { + if (dictValue.equals(dict.getDictValue())) + { + return dict.getDictLabel(); + } + } + } + } + return dictValue; +// return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 根据字典类型和字典标签获取字典值 + * + * @param dictType 字典类型 + * @param dictLabel 字典标签 + * @param separator 分隔符 + * @return 字典值 + */ + public static String getDictValue(String dictType, String dictLabel, String separator) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + + if (StringUtils.containsAny(separator, dictLabel) && StringUtils.isNotEmpty(datas)) + { + for (SysDictData dict : datas) + { + for (String label : dictLabel.split(separator)) + { + if (label.equals(dict.getDictLabel())) + { + propertyString.append(dict.getDictValue()).append(separator); + break; + } + } + } + } + else + { + for (SysDictData dict : datas) + { + if (dictLabel.equals(dict.getDictLabel())) + { + return dict.getDictValue(); + } + } + } + return dictLabel; +// return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 删除指定字典缓存 + * + * @param key 字典键 + */ + public static void removeDictCache(String key) + { + SpringUtils.getBean(RedisCache.class).deleteObject(getCacheKey(key)); + } + + /** + * 清空字典缓存 + */ + public static void clearDictCache() + { + Collection keys = SpringUtils.getBean(RedisCache.class).keys(CacheConstants.SYS_DICT_KEY + "*"); + SpringUtils.getBean(RedisCache.class).deleteObject(keys); + } + + /** + * 设置cache key + * + * @param configKey 参数键 + * @return 缓存键key + */ + public static String getCacheKey(String configKey) + { + return CacheConstants.SYS_DICT_KEY + configKey; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ExceptionUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ExceptionUtil.java new file mode 100644 index 0000000..214e4a0 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ExceptionUtil.java @@ -0,0 +1,39 @@ +package com.ruoyi.common.utils; + +import java.io.PrintWriter; +import java.io.StringWriter; +import org.apache.commons.lang3.exception.ExceptionUtils; + +/** + * 错误信息处理类。 + * + * @author ruoyi + */ +public class ExceptionUtil +{ + /** + * 获取exception的详细错误信息。 + */ + public static String getExceptionMessage(Throwable e) + { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw, true)); + return sw.toString(); + } + + public static String getRootErrorMessage(Exception e) + { + Throwable root = ExceptionUtils.getRootCause(e); + root = (root == null ? e : root); + if (root == null) + { + return ""; + } + String msg = root.getMessage(); + if (msg == null) + { + return "null"; + } + return StringUtils.defaultString(msg); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/GeoUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/GeoUtils.java new file mode 100644 index 0000000..80d6eaf --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/GeoUtils.java @@ -0,0 +1,18 @@ +package com.ruoyi.common.utils; + +import org.gavaghan.geodesy.Ellipsoid; +import org.gavaghan.geodesy.GeodeticCalculator; +import org.gavaghan.geodesy.GeodeticCurve; +import org.gavaghan.geodesy.GlobalCoordinates; + +public class GeoUtils { + + /** + * 经纬度计算 + */ + public static double getDistanceMeter(GlobalCoordinates gpsFrom, GlobalCoordinates gpsTo, Ellipsoid ellipsoid) { + //创建GeodeticCalculator,调用计算方法,传入坐标系、经纬度用于计算距离 + GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(ellipsoid, gpsFrom, gpsTo); + return geoCurve.getEllipsoidalDistance(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/LogUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/LogUtils.java new file mode 100644 index 0000000..0de30c6 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/LogUtils.java @@ -0,0 +1,18 @@ +package com.ruoyi.common.utils; + +/** + * 处理并记录日志文件 + * + * @author ruoyi + */ +public class LogUtils +{ + public static String getBlock(Object msg) + { + if (msg == null) + { + msg = ""; + } + return "[" + msg.toString() + "]"; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/MessageUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/MessageUtils.java new file mode 100644 index 0000000..7dac75a --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/MessageUtils.java @@ -0,0 +1,26 @@ +package com.ruoyi.common.utils; + +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import com.ruoyi.common.utils.spring.SpringUtils; + +/** + * 获取i18n资源文件 + * + * @author ruoyi + */ +public class MessageUtils +{ + /** + * 根据消息键和参数 获取消息 委托给spring messageSource + * + * @param code 消息键 + * @param args 参数 + * @return 获取国际化翻译值 + */ + public static String message(String code, Object... args) + { + MessageSource messageSource = SpringUtils.getBean(MessageSource.class); + return messageSource.getMessage(code, args, LocaleContextHolder.getLocale()); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java new file mode 100644 index 0000000..8381055 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java @@ -0,0 +1,62 @@ +package com.ruoyi.common.utils; + +import com.github.pagehelper.PageHelper; +import com.ruoyi.common.core.page.PageDomain; +import com.ruoyi.common.core.page.TableSupport; +import com.ruoyi.common.utils.sql.SqlUtil; + +import java.lang.reflect.Field; + +/** + * 分页工具类 + * + * @author ruoyi + */ +public class PageUtils extends PageHelper +{ + /** + * 设置请求分页数据 + */ + public static void startPage() + { + PageDomain pageDomain = TableSupport.buildPageRequest(); + Integer pageNum = pageDomain.getPageNum(); + Integer pageSize = pageDomain.getPageSize(); + String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); + Boolean reasonable = pageDomain.getReasonable(); + PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable); + } + + /** + * 清理分页的线程变量 + */ + public static void clearPage() + { + PageHelper.clearPage(); + } + + public static void startPage(Object o,Class clazz) { + Integer pageNum = 1; + Integer pageSize = 10; + + try { + Field num = clazz.getSuperclass().getDeclaredField("pageNum"); + num.setAccessible(true); + if (num.get(o) != null) { + pageNum = Integer.valueOf(num.get(o).toString()); + } + + Field size = clazz.getSuperclass().getDeclaredField("pageSize"); + size.setAccessible(true); + if (size.get(o) != null) { + pageSize = Integer.valueOf(size.get(o).toString()); + } + + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + + PageHelper.startPage(pageNum, pageSize); + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/PasswordUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PasswordUtil.java new file mode 100644 index 0000000..26434cb --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PasswordUtil.java @@ -0,0 +1,963 @@ +package com.ruoyi.common.utils; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map.Entry; +import java.util.Random; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 密码强度检测工具类 + * 密碼最低要求8字元 + * 最少符合下列四項中三項規則: + * 大寫英文字元 + * 小寫英文字元 + * 數字字元 + * 符號字元 + *

+ * 增加字元的變化能提高分數. + * 最後的分數為加分項目和減分項目的總和. + * 分數的範圍為0~100分. + * 分數不需達到最低字元即可計算. + */ +public class PasswordUtil { + + /** + * 正则_大写字母 + */ + private static final Pattern REGEX_UPPERCASE = Pattern.compile("[A-Z]"); + /** + * 正则_小写字母 + */ + private static final Pattern REGEX_LOWERCASE = Pattern.compile("[a-z]"); + /** + * 正则_数字 + */ + private static final Pattern NUM_REGEX = Pattern.compile("[0-9]"); + + /**----------------------------加分项------------------------------**/ + + /** + * 获取密码长度积分 + * + * @param password + * + * @return + */ + public static int CheckPswLength(String password) { + return password.length() * 4; + } + + /** + * 获取大写字母积分 + * + * @param password + * + * @return + */ + public static int CheckPswUpper(String password) { + String reg = "[A-Z]"; + Pattern pattern = Pattern.compile(reg); + Matcher matcher = pattern.matcher(password); + int iUpper = 0; + while (matcher.find()) { + iUpper++; + } + if (iUpper <= 0) { + return 0; + } + return (password.length() - iUpper) * 2; + } + + /** + * 获取小写字母长度积分 + * + * @param password + * + * @return + */ + public static int CheckPwsLower(String password) { + String reg = "[a-z]"; + Pattern pattern = Pattern.compile(reg); + Matcher matcher = pattern.matcher(password); + int iLower = 0; + while (matcher.find()) { + iLower++; + } + if (iLower <= 0) { + return 0; + } + return (password.length() - iLower) * 2; + } + + /** + * 获取数字长度积分 + * + * @param password + * + * @return + */ + public static int checkNum(String password) { + String reg = "[0-9]"; + Pattern pattern = Pattern.compile(reg); + Matcher matcher = pattern.matcher(password); + int iNum = 0; + while (matcher.find()) { + iNum++; + } + if (iNum == password.length()) { + return 0; + } + return iNum * 4; + } + //测试符号字元 + + /** + * 获取特殊字符长度积分 + * + * @param password + * + * @return + */ + public static int checkChar(String password) { + String regUpper = "[A-Z]"; + Pattern patternUpper = Pattern.compile(regUpper); + Matcher matcherUpper = patternUpper.matcher(password); + int iUpper = 0; + while (matcherUpper.find()) { + iUpper++; + } + String regLower = "[a-z]"; + Pattern patternLower = Pattern.compile(regLower); + Matcher matcherLower = patternLower.matcher(password); + int iLower = 0; + while (matcherLower.find()) { + iLower++; + } + String regNum = "[0-9]"; + Pattern patternNum = Pattern.compile(regNum); + Matcher matcherNum = patternNum.matcher(password); + int iNum = 0; + while (matcherNum.find()) { + iNum++; + } + int iChar = password.length() - iUpper - iLower - iNum; + return iChar * 6; + } + + /** + * 获取密码中间穿插数字或字符积分 + * + * @param password + * + * @return + */ + public static int checkNumOrCharInStr(String password) { + String regUpper = "[A-Z]"; + Pattern patternUpper = Pattern.compile(regUpper); + Matcher matcherUpper = patternUpper.matcher(password); + int iUpper = 0; + while (matcherUpper.find()) { + iUpper++; + } + String regLower = "[a-z]"; + Pattern patternLower = Pattern.compile(regLower); + Matcher matcherLower = patternLower.matcher(password); + int iLower = 0; + while (matcherLower.find()) { + iLower++; + } + String regNum = "[0-9]"; + Pattern patternNum = Pattern.compile(regNum); + Matcher matcherNum = patternNum.matcher(password); + int iNum = 0; + while (matcherNum.find()) { + iNum++; + } + int iChar = password.length() - iUpper - iLower - iNum; + + int jCharOrNum = iNum + iChar - 1; + if (jCharOrNum < 0) { + jCharOrNum = 0; + } + if (iNum + iChar == password.length()) { + jCharOrNum = password.length() - 2; + } + return jCharOrNum * 2; + } + + /** + * 最低要求标准 + * + * @param password + * + * @return + */ + public static int LowerQuest(String password) { + String regUpper = "[A-Z]"; + Pattern patternUpper = Pattern.compile(regUpper); + Matcher matcherUpper = patternUpper.matcher(password); + int iUpper = 0; + while (matcherUpper.find()) { + iUpper++; + } + String regLower = "[a-z]"; + Pattern patternLower = Pattern.compile(regLower); + Matcher matcherLower = patternLower.matcher(password); + int iLower = 0; + while (matcherLower.find()) { + iLower++; + } + String regNum = "[0-9]"; + Pattern patternNum = Pattern.compile(regNum); + Matcher matcherNum = patternNum.matcher(password); + int iNum = 0; + while (matcherNum.find()) { + iNum++; + } + int iChar = password.length() - iUpper - iLower - iNum; + + int iLowerQuest = 0; + if (password.length() >= 8) { + iLowerQuest++; + } + if (iUpper > 0) { + iLowerQuest++; + } + if (iLower > 0) { + iLowerQuest++; + } + if (iNum > 0) { + iLowerQuest++; + } + if (iChar > 0) { + iLowerQuest++; + } + if (iLowerQuest >= 4) { + + } else { + iLowerQuest = 0; + } + return iLowerQuest * 2; + } + + /**=================扣分项目=====================**/ + + /** + * 只包含字母积分 + * + * @param password + * + * @return + */ + public static int OnlyHasAlp(String password) { + String regUpper = "[A-Z]"; + Pattern patternUpper = Pattern.compile(regUpper); + Matcher matcherUpper = patternUpper.matcher(password); + int iUpper = 0; + while (matcherUpper.find()) { + iUpper++; + } + String regLower = "[a-z]"; + Pattern patternLower = Pattern.compile(regLower); + Matcher matcherLower = patternLower.matcher(password); + int iLower = 0; + while (matcherLower.find()) { + iLower++; + } + if (password.length() == (iUpper + iLower)) { + return -password.length(); + } + return 0; + } + + /** + * 只包含数字积分 + * + * @param password + * + * @return + */ + public static int OnlyHasNum(String password) { + String regNum = "[0-9]"; + Pattern patternNum = Pattern.compile(regNum); + Matcher matcherNum = patternNum.matcher(password); + int iNum = 0; + while (matcherNum.find()) { + iNum++; + } + if (password.length() == iNum) { + return -password.length(); + } + return 0; + } + + + /** + * 重复字符积分 + * + * @param password + * + * @return + */ + public static int repeatDex(String password) { + char[] c = password.toLowerCase().toCharArray(); + HashMap hashMap = + new HashMap(); + for (int i = 0; i < c.length; i++) { + if (hashMap.containsKey(c[i])) { + hashMap.put(c[i], hashMap.get(c[i]) + 1); + } else { + hashMap.put(c[i], 1); + } + } + int sum = 0; + Iterator> iterator = + hashMap.entrySet().iterator(); + while (iterator.hasNext()) { + int j = iterator.next().getValue(); + if (j > 0) { + sum = sum + j * (j - 1); + } + } + return -sum; + } + + /** + * 连续英文大写字母扣分项 + * + * @param password + * + * @return + */ + public static int seriseUpperAlp(String password) { + int j = 0; + char[] c = password.toCharArray(); + for (int i = 0; i < c.length - 1; i++) { + if (REGEX_UPPERCASE.matcher(c[i] + "").find()) { + if (REGEX_UPPERCASE.matcher(c[i + 1] + "").find()) { + j++; + } + } + } + return -2 * j; + } + + /** + * 连续英文字母扣分项 + * + * @param password + * + * @return + */ + public static int seriseLowerAlp(String password) { + int j = 0; + char[] c = password.toCharArray(); + for (int i = 0; i < c.length - 1; i++) { + if (REGEX_LOWERCASE.matcher(c[i] + "").find()) { + if (REGEX_LOWERCASE.matcher(c[i + 1] + "").find()) { + j++; + } + } + } + return -2 * j; + } + + /** + * 连续数字扣分项 + * + * @param password + * + * @return + */ + public static int seriseNum(String password) { + String reg = "[0-9]"; + Pattern pattern = Pattern.compile(reg); + char[] c = password.toCharArray(); + int j = 0; + for (int i = 0; i < c.length - 1; i++) { + if (pattern.matcher(c[i] + "").matches() + && pattern.matcher(c[i + 1] + "").matches()) { + j++; + } + } + return -2 * j; + } + + /** + * 连续字母abc def之类超过3个,不区分大小写字母 + * + * @param password + * + * @return + */ + public static int seriesAlp2Three(String password) { + int j = 0; + char[] c = password.toLowerCase(Locale.CHINA).toCharArray(); + for (int i = 0; i < c.length - 2; i++) { + if (REGEX_LOWERCASE.matcher(c[i] + "").find()) { + if ((c[i + 1] == c[i] + 1) && (c[i + 2] == c[i] + 2)) { + j++; + } + } + } + return -3 * j; + } + + /** + * 连续数字123 234之类超过3个扣分 + * + * @param password + * + * @return + */ + public static int seriesNum2Three(String password) { + int j = 0; + char[] c = password.toLowerCase(Locale.CHINA).toCharArray(); + for (int i = 0; i < c.length - 2; i++) { + if (NUM_REGEX.matcher(c[i] + "").find()) { + if ((c[i + 1] == c[i] + 1) && (c[i + 2] == c[i] + 2)) { + j++; + } + } + } + return -3 * j; + } + + /** + * 获取密码强度分数 + * + * @param password + * + * @return + */ + public static int getPasswordScore(String password) { + // System.out.println("密码长度加分="+CheckPswLength(password)); + // System.out.println("大写字母加分="+CheckPswUpper(password)); + // System.out.println("小写字母加分="+CheckPwsLower(password)); + // System.out.println("数字加分="+checkNum(password)); + // System.out.println("特殊符号加分="+checkChar(password)); + // System.out.println("密码中间穿插数字或特殊字符加分="+checkNumOrCharInStr(password)); + // System.out.println("最低要求加分="+LowerQuest(password)); + // System.out.println("只有英文字母扣分="+OnlyHasAlp(password)); + // System.out.println("只有數字扣分="+OnlyHasNum(password)); + // System.out.println("重复字符(不区分大小写)扣分="+repeatDex(password)); + // System.out.println("连续大写字母扣分="+seriseUpperAlp(password)); + // System.out.println("连续小写字母扣分="+seriseLowerAlp(password)); + // System.out.println("连续数字扣分="+seriseNum(password)); + // System.out.println("连续字母超过三个(如abc,def)扣分="+seriesAlp2Three(password)); + // System.out.println("连续数字超过三个(如123,234)扣分="+seriesNum2Three(password)); + int score = CheckPswLength(password) + CheckPswUpper(password) + CheckPwsLower(password) + checkNum(password) + checkChar(password) + + checkNumOrCharInStr(password) + LowerQuest(password) + OnlyHasAlp(password) + OnlyHasNum(password) + repeatDex(password) + + seriseUpperAlp(password) + seriseLowerAlp(password) + seriseNum(password) + seriesAlp2Three(password) + seriesNum2Three(password); + return score; + } + + /**-----------------------------------校验密码合规性-----------------------------------**/ + /** + * 获取大写字母数量 + * + * @param password + * + * @return + */ + public static int getNumOfUpperChar(String password) { + String reg = "[A-Z]"; + Pattern pattern = Pattern.compile(reg); + Matcher matcher = pattern.matcher(password); + int iUpper = 0; + while (matcher.find()) { + iUpper++; + } + return iUpper; + } + + /** + * 获取小写字母数量 + * + * @param password + * + * @return + */ + public static int getNumOfLowerChar(String password) { + String reg = "[a-z]"; + Pattern pattern = Pattern.compile(reg); + Matcher matcher = pattern.matcher(password); + int iLower = 0; + while (matcher.find()) { + iLower++; + } + return iLower; + } + + /** + * 获取数字字母数量 + * + * @param password + * + * @return + */ + public static int getNumOfNum(String password) { + String reg = "[0-9]"; + Pattern pattern = Pattern.compile(reg); + Matcher matcher = pattern.matcher(password); + int iNum = 0; + while (matcher.find()) { + iNum++; + } + return iNum; + } + + /** + * 获取特殊字符长度积分 + * + * @param password + * + * @return + */ + public static int getNumOfSpecChar(String password) { + String regUpper = "[A-Z]"; + Pattern patternUpper = Pattern.compile(regUpper); + Matcher matcherUpper = patternUpper.matcher(password); + int iUpper = 0; + while (matcherUpper.find()) { + iUpper++; + } + String regLower = "[a-z]"; + Pattern patternLower = Pattern.compile(regLower); + Matcher matcherLower = patternLower.matcher(password); + int iLower = 0; + while (matcherLower.find()) { + iLower++; + } + String regNum = "[0-9]"; + Pattern patternNum = Pattern.compile(regNum); + Matcher matcherNum = patternNum.matcher(password); + int iNum = 0; + while (matcherNum.find()) { + iNum++; + } + int iChar = password.length() - iUpper - iLower - iNum; + return iChar; + } + + /** + * 获取连续字母abc def之类超过3个的个数 + * + * @param password + * + * @return + */ + public static int getNumOfSeriesCharThree(String password) { + int j = 0; + char[] c = password.toLowerCase().toCharArray(); + for (int i = 0; i < c.length - 2; i++) { + if (REGEX_LOWERCASE.matcher(c[i] + "").find()) { + if ((c[i + 1] == c[i] + 1) && (c[i + 2] == c[i] + 2)) { + j++; + } + } + } + return j; + } + + /** + * 连续数字123 234之类超过3个的数量 + * + * @param password + * + * @return + */ + public static int getNumOfSeriesNumThree(String password) { + int j = 0; + char[] c = password.toLowerCase().toCharArray(); + for (int i = 0; i < c.length - 2; i++) { + if (NUM_REGEX.matcher(c[i] + "").find()) { + if ((c[i + 1] == c[i] + 1) && (c[i + 2] == c[i] + 2)) { + j++; + } + } + } + return j; + } + + /** + * 校验密码是否符合要求 + * + * @param password + * + * @return + */ + public static boolean validatePassword(String password) { + boolean bResult = true; + //如果密码长度8-16位 + if (password.length() < 8 || password.length() > 16) { + bResult = false; + } + //符号种类 + int iType = 0; + //检测是否包含字母 + if (getNumOfUpperChar(password) > 0 || getNumOfLowerChar(password) > 0) { + iType++; + } + //检测是否包含数字 + if (getNumOfNum(password) > 0) { + iType++; + } + //检测是否包含特殊符号 + if (getNumOfSpecialChar(password) > 0) { + iType++; + } + //如果字符种类少于3种不符合要求 + if (iType < 3) { + bResult = false; + } + //判断是否包行3个连续字母的个数(如abc,bcd) + //if (getNumOfSeriesCharThree(password) > 0) { + // bResult = false; + //} + //判断是否包行3个连续数字的个数(如123,345) + //if (getNumOfSeriesNumThree(password) > 0) { + // bResult = false; + //} + return bResult; + } + + private static int getNumOfSpecialChar(String password) { + String reg = "^.*[_!@#%&*]+.*$"; + Pattern pattern = Pattern.compile(reg); + Matcher matcher = pattern.matcher(password); + int iLower = 0; + while (matcher.find()) { + iLower++; + } + return iLower; + } + + /**-----------------------------------随机生成密码------------------------------------**/ + + + /** + * 生成指定长度随机数字密码 + * + * @param len + * @param len + * + * @return + */ + public static String createNumPassWord(int len) { + Random rd = new Random(); + final int maxNum = 70; + StringBuffer sb = new StringBuffer(); + int rdGet;//取得随机数 + char[] str = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + int count = 0; + while (count < len) { + rdGet = Math.abs(rd.nextInt(maxNum));//生成的数最大为10-1 + if (rdGet >= 0 && rdGet < str.length) { + sb.append(str[rdGet]); + count++; + } + } + return sb.toString(); + } + + /** + * 生成随机小写字母密码 + * + * @param len + * + * @return + */ + public static String createLowerCharPassWord(int len) { + Random rd = new Random(); + final int maxNum = 26; + StringBuffer sb = new StringBuffer(); + int rdGet;//取得随机数 + char[] str = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', + 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z'}; + int count = 0; + while (count < len) { + rdGet = Math.abs(rd.nextInt(maxNum));//生成的数最大为62-1 + if (rdGet >= 0 && rdGet < str.length) { + sb.append(str[rdGet]); + count++; + } + } + return sb.toString(); + } + + /** + * 生成随机小写字母密码 + * + * @param len + * + * @return + */ + public static String createUpperCharPassWord(int len) { + Random rd = new Random(); + final int maxNum = 26; + StringBuffer sb = new StringBuffer(); + int rdGet;//取得随机数 + char[] str = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z'}; + int count = 0; + while (count < len) { + rdGet = Math.abs(rd.nextInt(maxNum));//生成的数最大为62-1 + if (rdGet >= 0 && rdGet < str.length) { + sb.append(str[rdGet]); + count++; + } + } + return sb.toString(); + } + + /** + * 生成随机字母 + * + * @param len + * + * @return + */ + public static String createLowerCharNumPassWord(int len) { + Random rd = new Random(); + StringBuffer sb = new StringBuffer(); + final int maxNumChar = 26; + char[] strChar = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', + 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z'}; + final int maxNumNum = 10; + char[] strNum = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + int count = 0; + while (count < len) { + int rdGetChar = Math.abs(rd.nextInt(maxNumChar));//生成的数最大为26-1 + if (rdGetChar >= 0 && rdGetChar < strChar.length) { + sb.append(strChar[rdGetChar]); + count++; + } + if (count < len) { + int rdGetNum = Math.abs(rd.nextInt(maxNumNum));//生成的数最大为10-1 + if (rdGetNum >= 0 && rdGetNum < strNum.length) { + sb.append(strNum[rdGetNum]); + count++; + } + } + } + return sb.toString(); + } + + /** + * 生成随机字母 + * + * @param len + * + * @return + */ + public static String createCharNumPassWord(int len) { + + StringBuffer sb = new StringBuffer(); + final int maxNumChar = 52; + char[] strChar = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', + 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z'}; + final int maxNumNum = 10; + char[] strNum = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + int count = 0; + while (count < len) { + Random rdChar = new Random(); + int rdGetChar = Math.abs(rdChar.nextInt(maxNumChar));//生成的数最大为52-1 + if (rdGetChar >= 0 && rdGetChar < strChar.length) { + sb.append(strChar[rdGetChar]); + count++; + } + if (count < len) { + Random rdNum = new Random(); + int rdGetNum = Math.abs(rdNum.nextInt(maxNumNum));//生成的数最大为10-1 + if (rdGetNum >= 0 && rdGetNum < strNum.length) { + sb.append(strNum[rdGetNum]); + count++; + } + } + } + return sb.toString(); + } + + /** + * 生成随机大小写字母+数字+特殊字符的密码 + * + * @param len + * + * @return + */ + public static String createPassWord(int len) { + StringBuffer sb = new StringBuffer(); + final int maxNumChar = 52; + char[] strChar = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', + 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z'}; + final int maxNumNum = 10; + char[] strNum = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + + final int maxNumSpec = 10; + char[] strSpec = {'!', '@', '#', '$', '%', '^', '&', '*', '(', ')'}; + int count = 0; + while (count < len) { + Random rdChar = new Random(); + int rdGetChar = Math.abs(rdChar.nextInt(maxNumChar));//生成的数最大为52-1 + if (rdGetChar >= 0 && rdGetChar < strChar.length) { + sb.append(strChar[rdGetChar]); + count++; + } + if (count < len) { + Random rdNum = new Random(); + int rdGetNum = Math.abs(rdNum.nextInt(maxNumNum));//生成的数最大为10-1 + if (rdGetNum >= 0 && rdGetNum < strNum.length) { + sb.append(strNum[rdGetNum]); + count++; + } + } + if (count < len) { + Random rdSpec = new Random(); + int rdGetSpec = Math.abs(rdSpec.nextInt(maxNumSpec));//生成的数最大为10-1 + if (rdGetSpec >= 0 && rdGetSpec < strSpec.length) { + sb.append(strSpec[rdGetSpec]); + count++; + } + } + } + return sb.toString(); + } + + public static void main(String[] args) { + System.out.println(validatePassword("!avA2asfdas12")); + // for (int i=0;i<1000;i++){ + // String passwordNum = PasswordUtil.createNumPassWord(8); + // System.out.println("生成随机数字密码"+passwordNum); + // int iScoreNum = getPasswordScore(passwordNum); + // System.out.println("密码强度分数:"+iScoreNum); + // if (!validatePassword(passwordNum)){ + // System.out.println("密码不符合要求"); + // }else{ + // System.out.println("密码符合要求"); + // } + // + // String passwordLowerChar = PasswordUtil.createLowerCharPassWord(8); + // System.out.println("生成随机小写字母密码"+passwordLowerChar); + // int iScoreLowerChar = getPasswordScore(passwordLowerChar); + // System.out.println("密码强度分数:"+iScoreLowerChar); + // if (!validatePassword(passwordLowerChar)){ + // System.out.println("密码不符合要求"); + // }else{ + // System.out.println("密码符合要求"); + // } + // + // String passwordUpperChar = PasswordUtil.createUpperCharPassWord(8); + // System.out.println("生成随机大写字母密码"+passwordUpperChar); + // int iScoreUpperChar = getPasswordScore(passwordUpperChar); + // System.out.println("密码强度分数:"+iScoreUpperChar); + // if (!validatePassword(passwordUpperChar)){ + // System.out.println("密码不符合要求"); + // }else{ + // System.out.println("密码符合要求"); + // } + // + // String passwordLowerCharNum = PasswordUtil.createLowerCharNumPassWord(8); + // System.out.println("生成随机小写字母+数字密码"+passwordLowerCharNum); + // int iScoreLowerCharNum = getPasswordScore(passwordLowerCharNum); + // System.out.println("密码强度分数:"+iScoreLowerCharNum); + // if (!validatePassword(passwordLowerCharNum)){ + // System.out.println("密码不符合要求"); + // }else{ + // System.out.println("密码符合要求"); + // } + // + // String passwordCharNum = PasswordUtil.createCharNumPassWord(8); + // System.out.println("生成随机大小写字母+数字密码"+passwordCharNum); + // int iScoreCharNum = getPasswordScore(passwordCharNum); + // System.out.println("密码强度分数:"+iScoreCharNum); + // if (!validatePassword(passwordCharNum)){ + // System.out.println("密码不符合要求"); + // }else{ + // System.out.println("密码符合要求"); + // } + // + // String password = PasswordUtil.createPassWord(8); + // System.out.println("生成随机大小写字母+数字+特殊字符密码"+password); + // int iScore = getPasswordScore(password); + // System.out.println("密码强度分数:"+iScore); + // if (!validatePassword(password)){ + // System.out.println("密码不符合要求"); + // }else{ + // System.out.println("密码符合要求"); + // } + // } + // String pwd = "12345678"; + // System.out.println("密码"+pwd); + // int iScore = getPasswordScore(pwd); + // System.out.println("密码强度分数:"+iScore); + // if (!validatePassword(pwd)){ + // System.out.println("密码不符合要求"); + // }else{ + // System.out.println("密码符合要求"); + // } + // + // pwd = "and34353"; + // System.out.println("密码"+pwd); + // iScore = getPasswordScore(pwd); + // System.out.println("密码强度分数:"+iScore); + // if (!validatePassword(pwd)){ + // System.out.println("密码不符合要求"); + // }else{ + // System.out.println("密码符合要求"); + // } + // + // pwd = "And34353"; + // System.out.println("密码"+pwd); + // iScore = getPasswordScore(pwd); + // System.out.println("密码强度分数:"+iScore); + // if (!validatePassword(pwd)){ + // System.out.println("密码不符合要求"); + // }else{ + // System.out.println("密码符合要求"); + // } + // + // pwd = "abcd8239"; + // System.out.println("密码"+pwd); + // iScore = getPasswordScore(pwd); + // System.out.println("密码强度分数:"+iScore); + // if (!validatePassword(pwd)){ + // System.out.println("密码不符合要求"); + // }else{ + // System.out.println("密码符合要求"); + // } + // + // pwd = "wero1234"; + // System.out.println("密码"+pwd); + // iScore = getPasswordScore(pwd); + // System.out.println("密码强度分数:"+iScore); + // if (!validatePassword(pwd)){ + // System.out.println("密码不符合要求"); + // }else{ + // System.out.println("密码符合要求"); + // } + // + // pwd = "admin123"; + // System.out.println("密码"+pwd); + // iScore = getPasswordScore(pwd); + // System.out.println("密码强度分数:"+iScore); + // if (!validatePassword(pwd)){ + // System.out.println("密码不符合要求"); + // }else{ + // System.out.println("密码符合要求"); + // } + } + +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/RestTemplateUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/RestTemplateUtils.java new file mode 100644 index 0000000..5894e55 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/RestTemplateUtils.java @@ -0,0 +1,664 @@ +package com.ruoyi.common.utils; + +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +import java.util.Map; + +/** + * + * + * @author Johny + * @desc http请求工具类 + */ + +@Component +public class RestTemplateUtils { + // http模板 + private final RestTemplate restTemplate; + //注入RestTemplate + public RestTemplateUtils(RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + + // ----------------------------------GET------------------------------------------------------- + + /** + * GET请求调用方式 + * + * @param url 请求URL + * @param responseType 返回对象类型 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity get(String url, Class responseType) throws RestClientException { + return restTemplate.getForEntity(url, responseType); + } + + /** + * GET请求调用方式 + * + * @param url 请求URL + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity get(String url, Class responseType, Object... uriVariables) + throws RestClientException { + return restTemplate.getForEntity(url, responseType, uriVariables); + } + + /** + * GET请求调用方式 + * + * @param url 请求URL + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity get(String url, Class responseType, Map uriVariables) + throws RestClientException { + return restTemplate.getForEntity(url, responseType, uriVariables); + } + + /** + * 带请求头的GET请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity get(String url, Map headers, Class responseType, + Object... uriVariables) throws RestClientException { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setAll(headers); + return get(url, httpHeaders, responseType, uriVariables); + } + + /** + * 带请求头的GET请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity get(String url, HttpHeaders headers, Class responseType, Object... uriVariables) + throws RestClientException { + HttpEntity requestEntity = new HttpEntity<>(headers); + return exchange(url, HttpMethod.GET, requestEntity, responseType, uriVariables); + } + + /** + * 带请求头的GET请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity get(String url, Map headers, Class responseType, + Map uriVariables) throws RestClientException { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setAll(headers); + return get(url, httpHeaders, responseType, uriVariables); + } + + /** + * 带请求头的GET请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity get(String url, HttpHeaders headers, Class responseType, + Map uriVariables) throws RestClientException { + HttpEntity requestEntity = new HttpEntity<>(headers); + return exchange(url, HttpMethod.GET, requestEntity, responseType, uriVariables); + } + + // ----------------------------------POST------------------------------------------------------- + + /** + * POST请求调用方式 + * + * @param url 请求URL + * @param responseType 返回对象类型 + * @return + */ + public ResponseEntity post(String url, Class responseType) throws RestClientException { + return restTemplate.postForEntity(url, HttpEntity.EMPTY, responseType); + } + + /** + * POST请求调用方式 + * + * @param url 请求URL + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity post(String url, Object requestBody, Class responseType) + throws RestClientException { + return restTemplate.postForEntity(url, requestBody, responseType); + } + + /** + * POST请求调用方式 + * + * @param url 请求URL + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity post(String url, Object requestBody, Class responseType, Object... uriVariables) + throws RestClientException { + return restTemplate.postForEntity(url, requestBody, responseType, uriVariables); + } + + /** + * POST请求调用方式 + * + * @param url 请求URL + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity post(String url, Object requestBody, Class responseType, + Map uriVariables) throws RestClientException { + return restTemplate.postForEntity(url, requestBody, responseType, uriVariables); + } + + /** + * 带请求头的POST请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity post(String url, Map headers, Object requestBody, + Class responseType, Object... uriVariables) throws RestClientException { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setAll(headers); + return post(url, httpHeaders, requestBody, responseType, uriVariables); + } + + /** + * 带请求头的POST请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity post(String url, HttpHeaders headers, Object requestBody, Class responseType, + Object... uriVariables) throws RestClientException { + HttpEntity requestEntity = new HttpEntity(requestBody, headers); + return post(url, requestEntity, responseType, uriVariables); + } + + /** + * 带请求头的POST请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity post(String url, Map headers, Object requestBody, + Class responseType, Map uriVariables) throws RestClientException { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setAll(headers); + return post(url, httpHeaders, requestBody, responseType, uriVariables); + } + + /** + * 带请求头的POST请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity post(String url, HttpHeaders headers, Object requestBody, Class responseType, + Map uriVariables) throws RestClientException { + HttpEntity requestEntity = new HttpEntity(requestBody, headers); + return post(url, requestEntity, responseType, uriVariables); + } + + /** + * 自定义请求头和请求体的POST请求调用方式 + * + * @param url 请求URL + * @param requestEntity 请求头和请求体封装对象 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity post(String url, HttpEntity requestEntity, Class responseType, + Object... uriVariables) throws RestClientException { + return restTemplate.exchange(url, HttpMethod.POST, requestEntity, responseType, uriVariables); + } + + /** + * 自定义请求头和请求体的POST请求调用方式 + * + * @param url 请求URL + * @param requestEntity 请求头和请求体封装对象 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity post(String url, HttpEntity requestEntity, Class responseType, + Map uriVariables) throws RestClientException { + return restTemplate.exchange(url, HttpMethod.POST, requestEntity, responseType, uriVariables); + } + + // ----------------------------------PUT------------------------------------------------------- + + /** + * PUT请求调用方式 + * + * @param url 请求URL + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity put(String url, Class responseType, Object... uriVariables) + throws RestClientException { + return put(url, HttpEntity.EMPTY, responseType, uriVariables); + } + + /** + * PUT请求调用方式 + * + * @param url 请求URL + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity put(String url, Object requestBody, Class responseType, Object... uriVariables) + throws RestClientException { + HttpEntity requestEntity = new HttpEntity(requestBody); + return put(url, requestEntity, responseType, uriVariables); + } + + /** + * PUT请求调用方式 + * + * @param url 请求URL + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity put(String url, Object requestBody, Class responseType, Map uriVariables) + throws RestClientException { + HttpEntity requestEntity = new HttpEntity(requestBody); + return put(url, requestEntity, responseType, uriVariables); + } + + /** + * 带请求头的PUT请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity put(String url, Map headers, Object requestBody, Class responseType, + Object... uriVariables) throws RestClientException { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setAll(headers); + return put(url, httpHeaders, requestBody, responseType, uriVariables); + } + + /** + * 带请求头的PUT请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity put(String url, HttpHeaders headers, Object requestBody, Class responseType, + Object... uriVariables) throws RestClientException { + HttpEntity requestEntity = new HttpEntity(requestBody, headers); + return put(url, requestEntity, responseType, uriVariables); + } + + /** + * 带请求头的PUT请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity put(String url, Map headers, Object requestBody, Class responseType, + Map uriVariables) throws RestClientException { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setAll(headers); + return put(url, httpHeaders, requestBody, responseType, uriVariables); + } + + /** + * 带请求头的PUT请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity put(String url, HttpHeaders headers, Object requestBody, Class responseType, + Map uriVariables) throws RestClientException { + HttpEntity requestEntity = new HttpEntity(requestBody, headers); + return put(url, requestEntity, responseType, uriVariables); + } + + /** + * 自定义请求头和请求体的PUT请求调用方式 + * + * @param url 请求URL + * @param requestEntity 请求头和请求体封装对象 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity put(String url, HttpEntity requestEntity, Class responseType, + Object... uriVariables) throws RestClientException { + return restTemplate.exchange(url, HttpMethod.PUT, requestEntity, responseType, uriVariables); + } + + /** + * 自定义请求头和请求体的PUT请求调用方式 + * + * @param url 请求URL + * @param requestEntity 请求头和请求体封装对象 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity put(String url, HttpEntity requestEntity, Class responseType, + Map uriVariables) throws RestClientException { + return restTemplate.exchange(url, HttpMethod.PUT, requestEntity, responseType, uriVariables); + } + + // ----------------------------------DELETE------------------------------------------------------- + + /** + * DELETE请求调用方式 + * + * @param url 请求URL + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity delete(String url, Class responseType, Object... uriVariables) + throws RestClientException { + return delete(url, HttpEntity.EMPTY, responseType, uriVariables); + } + + /** + * DELETE请求调用方式 + * + * @param url 请求URL + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity delete(String url, Class responseType, Map uriVariables) + throws RestClientException { + return delete(url, HttpEntity.EMPTY, responseType, uriVariables); + } + + /** + * DELETE请求调用方式 + * + * @param url 请求URL + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity delete(String url, Object requestBody, Class responseType, Object... uriVariables) + throws RestClientException { + HttpEntity requestEntity = new HttpEntity(requestBody); + return delete(url, requestEntity, responseType, uriVariables); + } + + /** + * DELETE请求调用方式 + * + * @param url 请求URL + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity delete(String url, Object requestBody, Class responseType, + Map uriVariables) throws RestClientException { + HttpEntity requestEntity = new HttpEntity(requestBody); + return delete(url, requestEntity, responseType, uriVariables); + } + + /** + * 带请求头的DELETE请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity delete(String url, Map headers, Class responseType, + Object... uriVariables) throws RestClientException { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setAll(headers); + return delete(url, httpHeaders, responseType, uriVariables); + } + + /** + * 带请求头的DELETE请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity delete(String url, HttpHeaders headers, Class responseType, Object... uriVariables) + throws RestClientException { + HttpEntity requestEntity = new HttpEntity(headers); + return delete(url, requestEntity, responseType, uriVariables); + } + + /** + * 带请求头的DELETE请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity delete(String url, Map headers, Class responseType, + Map uriVariables) throws RestClientException { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setAll(headers); + return delete(url, httpHeaders, responseType, uriVariables); + } + + /** + * 带请求头的DELETE请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity delete(String url, HttpHeaders headers, Class responseType, + Map uriVariables) throws RestClientException { + HttpEntity requestEntity = new HttpEntity(headers); + return delete(url, requestEntity, responseType, uriVariables); + } + + /** + * 带请求头的DELETE请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity delete(String url, Map headers, Object requestBody, + Class responseType, Object... uriVariables) throws RestClientException { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setAll(headers); + return delete(url, httpHeaders, requestBody, responseType, uriVariables); + } + + /** + * 带请求头的DELETE请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity delete(String url, HttpHeaders headers, Object requestBody, Class responseType, + Object... uriVariables) throws RestClientException { + HttpEntity requestEntity = new HttpEntity(requestBody, headers); + return delete(url, requestEntity, responseType, uriVariables); + } + + /** + * 带请求头的DELETE请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity delete(String url, Map headers, Object requestBody, + Class responseType, Map uriVariables) throws RestClientException { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setAll(headers); + return delete(url, httpHeaders, requestBody, responseType, uriVariables); + } + + /** + * 带请求头的DELETE请求调用方式 + * + * @param url 请求URL + * @param headers 请求头参数 + * @param requestBody 请求参数体 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity delete(String url, HttpHeaders headers, Object requestBody, Class responseType, + Map uriVariables) throws RestClientException { + HttpEntity requestEntity = new HttpEntity(requestBody, headers); + return delete(url, requestEntity, responseType, uriVariables); + } + + /** + * 自定义请求头和请求体的DELETE请求调用方式 + * + * @param url 请求URL + * @param requestEntity 请求头和请求体封装对象 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity delete(String url, HttpEntity requestEntity, Class responseType, + Object... uriVariables) throws RestClientException { + return restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, responseType, uriVariables); + } + + /** + * 自定义请求头和请求体的DELETE请求调用方式 + * + * @param url 请求URL + * @param requestEntity 请求头和请求体封装对象 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity delete(String url, HttpEntity requestEntity, Class responseType, + Map uriVariables) throws RestClientException { + return restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, responseType, uriVariables); + } + + // ----------------------------------通用方法------------------------------------------------------- + + /** + * 通用调用方式 + * + * @param url 请求URL + * @param method 请求方法类型 + * @param requestEntity 请求头和请求体封装对象 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,按顺序依次对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity exchange(String url, HttpMethod method, HttpEntity requestEntity, + Class responseType, Object... uriVariables) throws RestClientException { + return restTemplate.exchange(url, method, requestEntity, responseType, uriVariables); + } + + /** + * 通用调用方式 + * + * @param url 请求URL + * @param method 请求方法类型 + * @param requestEntity 请求头和请求体封装对象 + * @param responseType 返回对象类型 + * @param uriVariables URL中的变量,与Map中的key对应 + * @return ResponseEntity 响应对象封装类 + */ + public ResponseEntity exchange(String url, HttpMethod method, HttpEntity requestEntity, + Class responseType, Map uriVariables) throws RestClientException { + return restTemplate.exchange(url, method, requestEntity, responseType, uriVariables); + } + + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/RsaUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/RsaUtils.java new file mode 100644 index 0000000..3d54730 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/RsaUtils.java @@ -0,0 +1,148 @@ +package com.ruoyi.common.utils; + +import org.apache.commons.codec.binary.Base64; +import org.springframework.beans.factory.annotation.Value; + +import javax.crypto.Cipher; +import java.security.*; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +/** + * RSA加密解密 + * + * @author ruoyi + **/ +public class RsaUtils +{ + // Rsa 私钥 静态取不到值 +// @Value("${login.privateKey}") + public static String privateKey="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMKqM8fJUnm70T53QIxjJzeYx1D9pz1Rl0X2jPYHGvpQMo1rH5mGf84BEqjMwDMfZylixviQY9hMc/OatuB6BsAILttMVIUUFKSi2+98Md35ht+DF81/9VvBzMyX8Tc4wfNEVuss7y/ejMD7bDYbKDRQBXoAaWJWtAcK4ogNhXQTAgMBAAECgYBAzlzytClK8aYVf6nzksbpkWk5o1hb55/O4OfIuFDY6H4L6o/YkphVwrGtlIyf+GJlusa21YsH5Vvsy6L6VGWOT/T1Q924zxwhPHFP8fzWrWJ60IT5jGDChJ1jls8GRWHgCnriQRMHU36eqENC5VZiYdfuulGN2bUNgMzUgmv9UQJBAOZio3CAQ+mwOsdRWixaput636qXoryleXiYrzGOulTzdYrRnJCIF3fE6H9uX5i2MwA3HtgTkN3qS4mtyBHvWP0CQQDYTt4KlkVJN3hsfV3qMk48zYE68lUg0umRaYXlQ0moLPO2P3wLFLLOq0jhWIwWz7ApIQXsR7x0RZOK2NadFFZPAkEA30Nh7klvBw2wuK3+/BLRxkxqavDOVZDq+dLFnPobWu4gz+m4l1w7mebqBWxaGi0fmarRKkcz0csXbxJJXBAepQJAKJtNpbEmGqOWMM+sJL4C3/k4TGeXwYy2mjy0DSD/n9moessaLz5YfuG60cr8qX+ds2rmoL+qyi0RkJw6VcyukwJAS5sxmn0YKbXw7GxDm7HmMcGuRYTo6ai+Olzk1GLwddTj56pfOgex+FF4FFyO33zzpEPeZbEzkbxkLC7Z8m0lWg=="; + /** + * 私钥解密 + * + * @param text 待解密的文本 + * @return 解密后的文本 + */ + public static String decryptByPrivateKey(String text) throws Exception + { + return decryptByPrivateKey(privateKey, text); + } + + /** + * 公钥解密 + * + * @param publicKeyString 公钥 + * @param text 待解密的信息 + * @return 解密后的文本 + */ + public static String decryptByPublicKey(String publicKeyString, String text) throws Exception + { + X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, publicKey); + byte[] result = cipher.doFinal(Base64.decodeBase64(text)); + return new String(result); + } + + /** + * 私钥加密 + * + * @param privateKeyString 私钥 + * @param text 待加密的信息 + * @return 加密后的文本 + */ + public static String encryptByPrivateKey(String privateKeyString, String text) throws Exception + { + PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + byte[] result = cipher.doFinal(text.getBytes()); + return Base64.encodeBase64String(result); + } + + /** + * 私钥解密 + * + * @param privateKeyString 私钥 + * @param text 待解密的文本 + * @return 解密后的文本 + */ + public static String decryptByPrivateKey(String privateKeyString, String text) throws Exception + { + PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + byte[] result = cipher.doFinal(Base64.decodeBase64(text)); + return new String(result); + } + + /** + * 公钥加密 + * + * @param publicKeyString 公钥 + * @param text 待加密的文本 + * @return 加密后的文本 + */ + public static String encryptByPublicKey(String publicKeyString, String text) throws Exception + { + X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] result = cipher.doFinal(text.getBytes()); + return Base64.encodeBase64String(result); + } + + /** + * 构建RSA密钥对 + * + * @return 生成后的公私钥信息 + */ + public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException + { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(1024); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); + RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); + String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded()); + String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded()); + return new RsaKeyPair(publicKeyString, privateKeyString); + } + + /** + * RSA密钥对对象 + */ + public static class RsaKeyPair + { + private final String publicKey; + private final String privateKey; + + public RsaKeyPair(String publicKey, String privateKey) + { + this.publicKey = publicKey; + this.privateKey = privateKey; + } + + public String getPublicKey() + { + return publicKey; + } + + public String getPrivateKey() + { + return privateKey; + } + } +} + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java new file mode 100644 index 0000000..a6f3d53 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java @@ -0,0 +1,120 @@ +package com.ruoyi.common.utils; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.exception.ServiceException; + +/** + * 安全服务工具类 + * + * @author ruoyi + */ +public class SecurityUtils +{ + /** + * 用户ID + **/ + public static Long getUserId() + { + try + { + return getLoginUser().getUserId(); + } + catch (Exception e) + { + throw new ServiceException("获取用户ID异常", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 获取部门ID + **/ + public static Long getDeptId() + { + try + { + return getLoginUser().getDeptId(); + } + catch (Exception e) + { + throw new ServiceException("获取部门ID异常", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 获取用户账户 + **/ + public static String getUsername() + { + try + { + return getLoginUser().getUsername(); + } + catch (Exception e) + { + throw new ServiceException("获取用户账户异常", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 获取用户 + **/ + public static LoginUser getLoginUser() + { + try + { + return (LoginUser) getAuthentication().getPrincipal(); + } + catch (Exception e) + { + throw new ServiceException("获取用户信息异常", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 获取Authentication + */ + public static Authentication getAuthentication() + { + return SecurityContextHolder.getContext().getAuthentication(); + } + + /** + * 生成BCryptPasswordEncoder密码 + * + * @param password 密码 + * @return 加密字符串 + */ + public static String encryptPassword(String password) + { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + return passwordEncoder.encode(password); + } + + /** + * 判断密码是否相同 + * + * @param rawPassword 真实密码 + * @param encodedPassword 加密后字符 + * @return 结果 + */ + public static boolean matchesPassword(String rawPassword, String encodedPassword) + { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + return passwordEncoder.matches(rawPassword, encodedPassword); + } + + /** + * 是否为管理员 + * + * @param userId 用户ID + * @return 结果 + */ + public static boolean isAdmin(Long userId) + { + return userId != null && 1L == userId; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java new file mode 100644 index 0000000..febb603 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java @@ -0,0 +1,218 @@ +package com.ruoyi.common.utils; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.text.Convert; + +/** + * 客户端工具类 + * + * @author ruoyi + */ +public class ServletUtils +{ + /** + * 获取String参数 + */ + public static String getParameter(String name) + { + return getRequest().getParameter(name); + } + + /** + * 获取String参数 + */ + public static String getParameter(String name, String defaultValue) + { + return Convert.toStr(getRequest().getParameter(name), defaultValue); + } + + /** + * 获取Integer参数 + */ + public static Integer getParameterToInt(String name) + { + return Convert.toInt(getRequest().getParameter(name)); + } + + /** + * 获取Integer参数 + */ + public static Integer getParameterToInt(String name, Integer defaultValue) + { + return Convert.toInt(getRequest().getParameter(name), defaultValue); + } + + /** + * 获取Boolean参数 + */ + public static Boolean getParameterToBool(String name) + { + return Convert.toBool(getRequest().getParameter(name)); + } + + /** + * 获取Boolean参数 + */ + public static Boolean getParameterToBool(String name, Boolean defaultValue) + { + return Convert.toBool(getRequest().getParameter(name), defaultValue); + } + + /** + * 获得所有请求参数 + * + * @param request 请求对象{@link ServletRequest} + * @return Map + */ + public static Map getParams(ServletRequest request) + { + final Map map = request.getParameterMap(); + return Collections.unmodifiableMap(map); + } + + /** + * 获得所有请求参数 + * + * @param request 请求对象{@link ServletRequest} + * @return Map + */ + public static Map getParamMap(ServletRequest request) + { + Map params = new HashMap<>(); + for (Map.Entry entry : getParams(request).entrySet()) + { + params.put(entry.getKey(), StringUtils.join(entry.getValue(), ",")); + } + return params; + } + + /** + * 获取request + */ + public static HttpServletRequest getRequest() + { + return getRequestAttributes().getRequest(); + } + + /** + * 获取response + */ + public static HttpServletResponse getResponse() + { + return getRequestAttributes().getResponse(); + } + + /** + * 获取session + */ + public static HttpSession getSession() + { + return getRequest().getSession(); + } + + public static ServletRequestAttributes getRequestAttributes() + { + RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); + return (ServletRequestAttributes) attributes; + } + + /** + * 将字符串渲染到客户端 + * + * @param response 渲染对象 + * @param string 待渲染的字符串 + */ + public static void renderString(HttpServletResponse response, String string) + { + try + { + response.setStatus(200); + response.setContentType("application/json"); + response.setCharacterEncoding("utf-8"); + response.getWriter().print(string); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + /** + * 是否是Ajax异步请求 + * + * @param request + */ + public static boolean isAjaxRequest(HttpServletRequest request) + { + String accept = request.getHeader("accept"); + if (accept != null && accept.contains("application/json")) + { + return true; + } + + String xRequestedWith = request.getHeader("X-Requested-With"); + if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) + { + return true; + } + + String uri = request.getRequestURI(); + if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) + { + return true; + } + + String ajax = request.getParameter("__ajax"); + return StringUtils.inStringIgnoreCase(ajax, "json", "xml"); + } + + /** + * 内容编码 + * + * @param str 内容 + * @return 编码后的内容 + */ + public static String urlEncode(String str) + { + try + { + return URLEncoder.encode(str, Constants.UTF8); + } + catch (UnsupportedEncodingException e) + { + return StringUtils.EMPTY; + } + } + + /** + * 内容解码 + * + * @param str 内容 + * @return 解码后的内容 + */ + public static String urlDecode(String str) + { + try + { + return URLDecoder.decode(str, Constants.UTF8); + } + catch (UnsupportedEncodingException e) + { + return StringUtils.EMPTY; + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/StringUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/StringUtils.java new file mode 100644 index 0000000..e364b8b --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/StringUtils.java @@ -0,0 +1,633 @@ +package com.ruoyi.common.utils; + +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.springframework.util.AntPathMatcher; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.text.StrFormatter; + +/** + * 字符串工具类 + * + * @author ruoyi + */ +public class StringUtils extends org.apache.commons.lang3.StringUtils { + /** + * 空字符串 + */ + private static final String NULLSTR = ""; + + /** + * 下划线 + */ + private static final char SEPARATOR = '_'; + + /** + * 获取参数不为空值 + * + * @param value defaultValue 要判断的value + * @return value 返回值 + */ + public static T nvl(T value, T defaultValue) { + return value != null ? value : defaultValue; + } + + /** + * * 判断一个Collection是否为空, 包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Collection coll) { + return isNull(coll) || coll.isEmpty(); + } + + /** + * * 判断一个Collection是否非空,包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Collection coll) { + return !isEmpty(coll); + } + + /** + * * 判断一个对象数组是否为空 + * + * @param objects 要判断的对象数组 + * * @return true:为空 false:非空 + */ + public static boolean isEmpty(Object[] objects) { + return isNull(objects) || (objects.length == 0); + } + + /** + * * 判断一个对象数组是否非空 + * + * @param objects 要判断的对象数组 + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Object[] objects) { + return !isEmpty(objects); + } + + /** + * * 判断一个Map是否为空 + * + * @param map 要判断的Map + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Map map) { + return isNull(map) || map.isEmpty(); + } + + /** + * * 判断一个Map是否为空 + * + * @param map 要判断的Map + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Map map) { + return !isEmpty(map); + } + + /** + * * 判断一个字符串是否为空串 + * + * @param str String + * @return true:为空 false:非空 + */ + public static boolean isEmpty(String str) { + return isNull(str) || NULLSTR.equals(str.trim()); + } + + /** + * * 判断一个字符串是否为非空串 + * + * @param str String + * @return true:非空串 false:空串 + */ + public static boolean isNotEmpty(String str) { + return !isEmpty(str); + } + + /** + * * 判断一个对象是否为空 + * + * @param object Object + * @return true:为空 false:非空 + */ + public static boolean isNull(Object object) { + return object == null; + } + + /** + * * 判断一个对象是否非空 + * + * @param object Object + * @return true:非空 false:空 + */ + public static boolean isNotNull(Object object) { + return !isNull(object); + } + + /** + * * 判断一个对象是否是数组类型(Java基本型别的数组) + * + * @param object 对象 + * @return true:是数组 false:不是数组 + */ + public static boolean isArray(Object object) { + return isNotNull(object) && object.getClass().isArray(); + } + + /** + * 去空格 + */ + public static String trim(String str) { + return (str == null ? "" : str.trim()); + } + + /** + * 截取字符串 + * + * @param str 字符串 + * @param start 开始 + * @return 结果 + */ + public static String substring(final String str, int start) { + if (str == null) { + return NULLSTR; + } + + if (start < 0) { + start = str.length() + start; + } + + if (start < 0) { + start = 0; + } + if (start > str.length()) { + return NULLSTR; + } + + return str.substring(start); + } + + /** + * 截取字符串 + * + * @param str 字符串 + * @param start 开始 + * @param end 结束 + * @return 结果 + */ + public static String substring(final String str, int start, int end) { + if (str == null) { + return NULLSTR; + } + + if (end < 0) { + end = str.length() + end; + } + if (start < 0) { + start = str.length() + start; + } + + if (end > str.length()) { + end = str.length(); + } + + if (start > end) { + return NULLSTR; + } + + if (start < 0) { + start = 0; + } + if (end < 0) { + end = 0; + } + + return str.substring(start, end); + } + + /** + * 格式化文本, {} 表示占位符
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ * + * @param template 文本模板,被替换的部分用 {} 表示 + * @param params 参数值 + * @return 格式化后的文本 + */ + public static String format(String template, Object... params) { + if (isEmpty(params) || isEmpty(template)) { + return template; + } + return StrFormatter.format(template, params); + } + + /** + * 是否为http(s)://开头 + * + * @param link 链接 + * @return 结果 + */ + public static boolean ishttp(String link) { + return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS); + } + + /** + * 字符串转set + * + * @param str 字符串 + * @param sep 分隔符 + * @return set集合 + */ + public static final Set str2Set(String str, String sep) { + return new HashSet(str2List(str, sep, true, false)); + } + + /** + * 字符串转list + * + * @param str 字符串 + * @param sep 分隔符 + * @param filterBlank 过滤纯空白 + * @param trim 去掉首尾空白 + * @return list集合 + */ + public static final List str2List(String str, String sep, boolean filterBlank, boolean trim) { + List list = new ArrayList(); + if (StringUtils.isEmpty(str)) { + return list; + } + + // 过滤空白字符串 + if (filterBlank && StringUtils.isBlank(str)) { + return list; + } + String[] split = str.split(sep); + for (String string : split) { + if (filterBlank && StringUtils.isBlank(string)) { + continue; + } + if (trim) { + string = string.trim(); + } + list.add(string); + } + + return list; + } + + /** + * 判断给定的set列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value + * + * @param collection 给定的集合 + * @param array 给定的数组 + * @return boolean 结果 + */ + public static boolean containsAny(Collection collection, String... array) { + if (isEmpty(collection) || isEmpty(array)) { + return false; + } else { + for (String str : array) { + if (collection.contains(str)) { + return true; + } + } + return false; + } + } + + /** + * 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写 + * + * @param cs 指定字符串 + * @param searchCharSequences 需要检查的字符串数组 + * @return 是否包含任意一个字符串 + */ + public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences) { + if (isEmpty(cs) || isEmpty(searchCharSequences)) { + return false; + } + for (CharSequence testStr : searchCharSequences) { + if (containsIgnoreCase(cs, testStr)) { + return true; + } + } + return false; + } + + /** + * 驼峰转下划线命名 + */ + public static String toUnderScoreCase(String str) { + if (str == null) { + return null; + } + StringBuilder sb = new StringBuilder(); + // 前置字符是否大写 + boolean preCharIsUpperCase = true; + // 当前字符是否大写 + boolean curreCharIsUpperCase = true; + // 下一字符是否大写 + boolean nexteCharIsUpperCase = true; + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (i > 0) { + preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1)); + } else { + preCharIsUpperCase = false; + } + + curreCharIsUpperCase = Character.isUpperCase(c); + + if (i < (str.length() - 1)) { + nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1)); + } + + if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) { + sb.append(SEPARATOR); + } else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) { + sb.append(SEPARATOR); + } + sb.append(Character.toLowerCase(c)); + } + + return sb.toString(); + } + + /** + * 是否包含字符串 + * + * @param str 验证字符串 + * @param strs 字符串组 + * @return 包含返回true + */ + public static boolean inStringIgnoreCase(String str, String... strs) { + if (str != null && strs != null) { + for (String s : strs) { + if (str.equalsIgnoreCase(trim(s))) { + return true; + } + } + } + return false; + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld + * + * @param name 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String convertToCamelCase(String name) { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || name.isEmpty()) { + // 没必要转换 + return ""; + } else if (!name.contains("_")) { + // 不含下划线,仅将首字母大写 + return name.substring(0, 1).toUpperCase() + name.substring(1); + } + // 用下划线将原始字符串分割 + String[] camels = name.split("_"); + for (String camel : camels) { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (camel.isEmpty()) { + continue; + } + // 首字母大写 + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + return result.toString(); + } + + /** + * 驼峰式命名法 例如:user_name->userName + */ + public static String toCamelCase(String s) { + if (s == null) { + return null; + } + s = s.toLowerCase(); + StringBuilder sb = new StringBuilder(s.length()); + boolean upperCase = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + + if (c == SEPARATOR) { + upperCase = true; + } else if (upperCase) { + sb.append(Character.toUpperCase(c)); + upperCase = false; + } else { + sb.append(c); + } + } + return sb.toString(); + } + + /** + * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串 + * + * @param str 指定字符串 + * @param strs 需要检查的字符串数组 + * @return 是否匹配 + */ + public static boolean matches(String str, List strs) { + if (isEmpty(str) || isEmpty(strs)) { + return false; + } + for (String pattern : strs) { + if (isMatch(pattern, str)) { + return true; + } + } + return false; + } + + /** + * 判断url是否与规则配置: + * ? 表示单个字符; + * * 表示一层路径内的任意字符串,不可跨层级; + * ** 表示任意层路径; + * + * @param pattern 匹配规则 + * @param url 需要匹配的url + * @return + */ + public static boolean isMatch(String pattern, String url) { + AntPathMatcher matcher = new AntPathMatcher(); + return matcher.match(pattern, url); + } + + @SuppressWarnings("unchecked") + public static T cast(Object obj) { + return (T) obj; + } + + /** + * 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。 + * + * @param num 数字对象 + * @param size 字符串指定长度 + * @return 返回数字的字符串格式,该字符串为指定长度。 + */ + public static final String padl(final Number num, final int size) { + return padl(num.toString(), size, '0'); + } + + // 日期校验 + public static boolean isDate(String value, String format) { + + if (isEmpty(value) || isEmpty(format)) { + return false; + } + + try { + SimpleDateFormat sdf = new SimpleDateFormat(format); + //sdf.setLenient(false);//严格parse时,分钟为0会parse为null,比如2015/11/11 3:00:00失败 + Date date = sdf.parse(value); + if (date == null) { + return false; + } else { + //反向验证,使得检测出2011/21/11不合法 + return value.equals(sdf.format(date)); + } + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + private static final Pattern pPositiveInt = Pattern.compile("[1-9][0-9]*"); + + //非负整数 + public static boolean isUnNegativeInt(String str) { + return "0".equals(str) || isPositiveInt(str); + } + + //正整数 + public static boolean isPositiveInt(String str) { + + if (null == str || "".equals(str) || "null".equals(str)) { + return false; + } + Matcher m = pPositiveInt.matcher(str); + return m.matches(); + + } + + private static final Pattern pNumCode = Pattern.compile("[0-9][0-9]*"); + + //数字编码 + public static boolean isNumCode(String str) { + + if (null == str || "".equals(str) || "null".equals(str)) { + return false; + } + Matcher m = pNumCode.matcher(str); + return m.matches(); + + } + + /** + * 校验是否是手机号 + * + * @param str 字符串 + * @return 校验结果 + */ + public static boolean isPhone(String str) { + if (null == str || "".equals(str) || "null".equals(str)) { + return false; + } + Matcher m = Pattern.compile("^1[3-9][0-9]{9}$").matcher(str); + return m.matches(); + } + + /** + * 是否是数字,包括小数 + * + * @param str + * @return + */ + public static boolean isNum(String str) { + if (null == str || "".equals(str) || "null".equals(str)) { + return false; + } + Pattern pattern = Pattern.compile("[-+]?([1-9]+[0-9]*|0)(\\.[\\d]+)?"); + Matcher isNum = pattern.matcher(str); + return isNum.matches(); + + } + + /** + * 是否是整数 + * + * @param str + * @return + */ + public static boolean isInt(String str) { + + if (null == str || "".equals(str) || "null".equals(str)) + return false; + Pattern pattern = Pattern.compile("[-+]?[0-9]*"); + Matcher isInt = pattern.matcher(str); + if (!isInt.matches()) { + return false; + } + return true; + + } + + /** + * 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。 + * + * @param s 原始字符串 + * @param size 字符串指定长度 + * @param c 用于补齐的字符 + * @return 返回指定长度的字符串,由原字符串左补齐或截取得到。 + */ + public static final String padl(final String s, final int size, final char c) { + final StringBuilder sb = new StringBuilder(size); + if (s != null) { + final int len = s.length(); + if (s.length() <= size) { + for (int i = size - len; i > 0; i--) { + sb.append(c); + } + sb.append(s); + } else { + return s.substring(len - size, len); + } + } else { + for (int i = size; i > 0; i--) { + sb.append(c); + } + } + return sb.toString(); + } + + public static final String nonNullString(Object o) { + if (isNull(o)) { + return ""; + } else { + return String.valueOf(o); + } + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/Threads.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/Threads.java new file mode 100644 index 0000000..71fe6d5 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/Threads.java @@ -0,0 +1,99 @@ +package com.ruoyi.common.utils; + +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 线程相关工具类. + * + * @author ruoyi + */ +public class Threads +{ + private static final Logger logger = LoggerFactory.getLogger(Threads.class); + + /** + * sleep等待,单位为毫秒 + */ + public static void sleep(long milliseconds) + { + try + { + Thread.sleep(milliseconds); + } + catch (InterruptedException e) + { + return; + } + } + + /** + * 停止线程池 + * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务. + * 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数. + * 如果仍然超時,則強制退出. + * 另对在shutdown时线程本身被调用中断做了处理. + */ + public static void shutdownAndAwaitTermination(ExecutorService pool) + { + if (pool != null && !pool.isShutdown()) + { + pool.shutdown(); + try + { + if (!pool.awaitTermination(120, TimeUnit.SECONDS)) + { + pool.shutdownNow(); + if (!pool.awaitTermination(120, TimeUnit.SECONDS)) + { + logger.info("Pool did not terminate"); + } + } + } + catch (InterruptedException ie) + { + pool.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + } + + /** + * 打印线程异常信息 + */ + public static void printException(Runnable r, Throwable t) + { + if (t == null && r instanceof Future) + { + try + { + Future future = (Future) r; + if (future.isDone()) + { + future.get(); + } + } + catch (CancellationException ce) + { + t = ce; + } + catch (ExecutionException ee) + { + t = ee.getCause(); + } + catch (InterruptedException ie) + { + Thread.currentThread().interrupt(); + } + } + if (t != null) + { + logger.error(t.getMessage(), t); + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ZipUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ZipUtils.java new file mode 100644 index 0000000..bdb33e4 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ZipUtils.java @@ -0,0 +1,84 @@ +package com.ruoyi.common.utils; + +import java.io.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * @author yqf + * @date 2023/6/6 + */ +public class ZipUtils { + + /** + * 需要压缩的文件 例如 ["/woke/file/1.jpg", "/woke/file/2.jpg"...] + * @param files + * @param zipFile + */ + public static void zip(String[] files, File zipFile) { + + FileInputStream fileInputStream = null; + FileOutputStream fileOutputStream = null; + ZipOutputStream zipOutputStream = null; + BufferedInputStream bufferInputStream = null; + try { + // zipFileName为压缩文件的名称(xx.zip),首先在某个目录下(C:/temp/路径可以根据自己的需求进行修改)创建一个.zip结尾的文件 + fileOutputStream = new FileOutputStream(zipFile); + zipOutputStream = new ZipOutputStream(new BufferedOutputStream(fileOutputStream)); + // 创建读写缓冲区 + byte[] bufs = new byte[1024 * 10]; + for (String file : files) { + File voiceFile = new File(file); + if (voiceFile.exists()) { + ZipEntry zipEntry; + // 压缩文件下的目录分级,如果不分目录可以直接用fileName.文件后缀 + zipEntry = new ZipEntry("pRRU_topo_config." + getFileExtension(voiceFile)); + + // 创建ZIP实体,并添加进压缩包 + zipOutputStream.putNextEntry(zipEntry); + + // 读取待压缩的文件并写进压缩包里 + fileInputStream = new FileInputStream(voiceFile); + bufferInputStream = new BufferedInputStream(fileInputStream, 1024 * 10); + int read = 0; + while ((read = bufferInputStream.read(bufs, 0, 1024 * 10)) != -1) { + zipOutputStream.write(bufs, 0, read); + } + + } + + } + + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (bufferInputStream != null) { + bufferInputStream.close(); + } + if (zipOutputStream != null) { + zipOutputStream.close(); + } + + } catch (IOException e) { + e.printStackTrace(); + } + + } + } + + + /** + * 获取文件后缀名 + * @param file + * @return + */ + private static String getFileExtension(File file) { + String fileName = file.getName(); + if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) + return fileName.substring(fileName.lastIndexOf(".") + 1); + else return " "; + } + + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanUtils.java new file mode 100644 index 0000000..4463662 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanUtils.java @@ -0,0 +1,110 @@ +package com.ruoyi.common.utils.bean; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Bean 工具类 + * + * @author ruoyi + */ +public class BeanUtils extends org.springframework.beans.BeanUtils +{ + /** Bean方法名中属性名开始的下标 */ + private static final int BEAN_METHOD_PROP_INDEX = 3; + + /** * 匹配getter方法的正则表达式 */ + private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)"); + + /** * 匹配setter方法的正则表达式 */ + private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)"); + + /** + * Bean属性复制工具方法。 + * + * @param dest 目标对象 + * @param src 源对象 + */ + public static void copyBeanProp(Object dest, Object src) + { + try + { + copyProperties(src, dest); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * 获取对象的setter方法。 + * + * @param obj 对象 + * @return 对象的setter方法列表 + */ + public static List getSetterMethods(Object obj) + { + // setter方法列表 + List setterMethods = new ArrayList(); + + // 获取所有方法 + Method[] methods = obj.getClass().getMethods(); + + // 查找setter方法 + + for (Method method : methods) + { + Matcher m = SET_PATTERN.matcher(method.getName()); + if (m.matches() && (method.getParameterTypes().length == 1)) + { + setterMethods.add(method); + } + } + // 返回setter方法列表 + return setterMethods; + } + + /** + * 获取对象的getter方法。 + * + * @param obj 对象 + * @return 对象的getter方法列表 + */ + + public static List getGetterMethods(Object obj) + { + // getter方法列表 + List getterMethods = new ArrayList(); + // 获取所有方法 + Method[] methods = obj.getClass().getMethods(); + // 查找getter方法 + for (Method method : methods) + { + Matcher m = GET_PATTERN.matcher(method.getName()); + if (m.matches() && (method.getParameterTypes().length == 0)) + { + getterMethods.add(method); + } + } + // 返回getter方法列表 + return getterMethods; + } + + /** + * 检查Bean方法名中的属性名是否相等。
+ * 如getName()和setName()属性名一样,getName()和setAge()属性名不一样。 + * + * @param m1 方法名1 + * @param m2 方法名2 + * @return 属性名一样返回true,否则返回false + */ + + public static boolean isMethodPropEquals(String m1, String m2) + { + return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX)); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanValidators.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanValidators.java new file mode 100644 index 0000000..80bfed7 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanValidators.java @@ -0,0 +1,24 @@ +package com.ruoyi.common.utils.bean; + +import java.util.Set; +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.Validator; + +/** + * bean对象属性验证 + * + * @author ruoyi + */ +public class BeanValidators +{ + public static void validateWithException(Validator validator, Object object, Class... groups) + throws ConstraintViolationException + { + Set> constraintViolations = validator.validate(object, groups); + if (!constraintViolations.isEmpty()) + { + throw new ConstraintViolationException(constraintViolations); + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileTypeUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileTypeUtils.java new file mode 100644 index 0000000..68130b9 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileTypeUtils.java @@ -0,0 +1,76 @@ +package com.ruoyi.common.utils.file; + +import java.io.File; +import org.apache.commons.lang3.StringUtils; + +/** + * 文件类型工具类 + * + * @author ruoyi + */ +public class FileTypeUtils +{ + /** + * 获取文件类型 + *

+ * 例如: ruoyi.txt, 返回: txt + * + * @param file 文件名 + * @return 后缀(不含".") + */ + public static String getFileType(File file) + { + if (null == file) + { + return StringUtils.EMPTY; + } + return getFileType(file.getName()); + } + + /** + * 获取文件类型 + *

+ * 例如: ruoyi.txt, 返回: txt + * + * @param fileName 文件名 + * @return 后缀(不含".") + */ + public static String getFileType(String fileName) + { + int separatorIndex = fileName.lastIndexOf("."); + if (separatorIndex < 0) + { + return ""; + } + return fileName.substring(separatorIndex + 1).toLowerCase(); + } + + /** + * 获取文件类型 + * + * @param photoByte 文件字节码 + * @return 后缀(不含".") + */ + public static String getFileExtendName(byte[] photoByte) + { + String strFileExtendName = "JPG"; + if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56) + && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) + { + strFileExtendName = "GIF"; + } + else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) + { + strFileExtendName = "JPG"; + } + else if ((photoByte[0] == 66) && (photoByte[1] == 77)) + { + strFileExtendName = "BMP"; + } + else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) + { + strFileExtendName = "PNG"; + } + return strFileExtendName; + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java new file mode 100644 index 0000000..4365253 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java @@ -0,0 +1,319 @@ +package com.ruoyi.common.utils.file; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Objects; + +import cn.hutool.core.util.RandomUtil; +import org.apache.commons.io.FilenameUtils; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.config.MinioConfig; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.exception.file.FileNameLengthLimitExceededException; +import com.ruoyi.common.exception.file.FileSizeLimitExceededException; +import com.ruoyi.common.exception.file.InvalidExtensionException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.uuid.Seq; + +/** + * 文件上传工具类 + * + * @author ruoyi + */ +public class FileUploadUtils +{ + /** + * 默认大小 50M + */ + public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024; + + /** + * 默认的文件名最大长度 100 + */ + public static final int DEFAULT_FILE_NAME_LENGTH = 100; + + /** + * 本地默认上传的地址 + */ + private static String defaultBaseDir = RuoYiConfig.getProfile(); + + /** + * Minio默认上传的地址 + */ + private static String bucketName = MinioConfig.getBucketName(); + + public static void setDefaultBaseDir(String defaultBaseDir) + { + FileUploadUtils.defaultBaseDir = defaultBaseDir; + } + + public static String getDefaultBaseDir() + { + return defaultBaseDir; + } + + public static String getBucketName() + { + return bucketName; + } + + /** + * 以默认配置进行文件上传 + * + * @param file 上传的文件 + * @return 文件名称 + * @throws Exception + */ + public static final String upload(MultipartFile file) throws IOException + { + try + { + return upload(getDefaultBaseDir(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + + /** + * 根据文件路径上传 + * + * @param baseDir 相对应用的基目录 + * @param file 上传的文件 + * @return 文件名称 + * @throws IOException + */ + public static final String upload(String baseDir, MultipartFile file) throws IOException + { + try + { + return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + + /** + * 文件上传 + * + * @param baseDir 相对应用的基目录 + * @param file 上传的文件 + * @param allowedExtension 上传文件类型 + * @return 返回上传成功的文件名 + * @throws FileSizeLimitExceededException 如果超出最大大小 + * @throws FileNameLengthLimitExceededException 文件名太长 + * @throws IOException 比如读写文件出错时 + * @throws InvalidExtensionException 文件校验异常 + */ + public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, + InvalidExtensionException + { + int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length(); + if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) + { + throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); + } + + assertAllowed(file, allowedExtension); + + String fileName = extractFilename(file); + + String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath(); + file.transferTo(Paths.get(absPath)); + return getPathFileName(baseDir, fileName); + } + + /** + * 以默认BucketName配置上传到Minio服务器 + * + * @param file 上传的文件 + * @return 文件名称 + * @throws Exception + */ + public static final String uploadMinio(MultipartFile file) throws IOException + { + try + { + return uploadMinio(getBucketName(),file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + + /** + * 自定义bucketName配置上传到Minio服务器 + * + * @param file 上传的文件 + * @return 文件名称 + * @throws Exception + */ + public static final String uploadMinio(String bucketName,MultipartFile file) throws IOException + { + try + { + return uploadMinio(bucketName,file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + + public static final String uploadMinio(MultipartFile file,String[] allowedExtension) throws IOException + { + try + { + return uploadMinio(getBucketName(),file, allowedExtension); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + + public static final String uploadMinio(String bucketName, MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, + InvalidExtensionException + { + int fileNamelength = file.getOriginalFilename().length(); + if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) + { + throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); + } + assertAllowed(file, allowedExtension); + try + { + String fileName = extractFilename(file); + String pathFileName = MinioUtil.uploadFile(bucketName, fileName, file); + return pathFileName; + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + + /** + * 编码文件名 + */ + public static final String extractFilename(MultipartFile file) + { + return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(), + FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file)); +// return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(), +// FilenameUtils.getBaseName(RandomUtil.randomNumbers(16)), Seq.getId(Seq.uploadSeqType), getExtension(file)); + } + + public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException + { + File desc = new File(uploadDir + File.separator + fileName); + + if (!desc.exists()) + { + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + } + return desc; + } + + public static final String getPathFileName(String uploadDir, String fileName) throws IOException + { + int dirLastIndex = RuoYiConfig.getProfile().length() + 1; + String currentDir = StringUtils.substring(uploadDir, dirLastIndex); + return Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName; + } + + /** + * 文件大小校验 + * + * @param file 上传的文件 + * @return + * @throws FileSizeLimitExceededException 如果超出最大大小 + * @throws InvalidExtensionException + */ + public static final void assertAllowed(MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, InvalidExtensionException + { + long size = file.getSize(); + if (size > DEFAULT_MAX_SIZE) + { + throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024); + } + + String fileName = file.getOriginalFilename(); + String extension = getExtension(file); + if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) + { + if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION) + { + throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION) + { + throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION) + { + throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION) + { + throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension, + fileName); + } + else + { + throw new InvalidExtensionException(allowedExtension, extension, fileName); + } + } + } + + /** + * 判断MIME类型是否是允许的MIME类型 + * + * @param extension + * @param allowedExtension + * @return + */ + public static final boolean isAllowedExtension(String extension, String[] allowedExtension) + { + for (String str : allowedExtension) + { + if (str.equalsIgnoreCase(extension)) + { + return true; + } + } + return false; + } + + /** + * 获取文件名的后缀 + * + * @param file 表单文件 + * @return 后缀名 + */ + public static final String getExtension(MultipartFile file) + { + String extension = FilenameUtils.getExtension(file.getOriginalFilename()); + if (StringUtils.isEmpty(extension)) + { + extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType())); + } + return extension; + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java new file mode 100644 index 0000000..f844270 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java @@ -0,0 +1,293 @@ +package com.ruoyi.common.utils.file; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.ArrayUtils; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.uuid.IdUtils; +import org.apache.commons.io.FilenameUtils; + +/** + * 文件处理工具类 + * + * @author ruoyi + */ +public class FileUtils +{ + public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+"; + + /** + * 输出指定文件的byte数组 + * + * @param filePath 文件路径 + * @param os 输出流 + * @return + */ + public static void writeBytes(String filePath, OutputStream os) throws IOException + { + FileInputStream fis = null; + try + { + File file = new File(filePath); + if (!file.exists()) + { + throw new FileNotFoundException(filePath); + } + fis = new FileInputStream(file); + byte[] b = new byte[1024]; + int length; + while ((length = fis.read(b)) > 0) + { + os.write(b, 0, length); + } + } + catch (IOException e) + { + throw e; + } + finally + { + IOUtils.close(os); + IOUtils.close(fis); + } + } + + /** + * 写数据到文件中 + * + * @param data 数据 + * @return 目标文件 + * @throws IOException IO异常 + */ + public static String writeImportBytes(byte[] data) throws IOException + { + return writeBytes(data, RuoYiConfig.getImportPath()); + } + + /** + * 写数据到文件中 + * + * @param data 数据 + * @param uploadDir 目标文件 + * @return 目标文件 + * @throws IOException IO异常 + */ + public static String writeBytes(byte[] data, String uploadDir) throws IOException + { + FileOutputStream fos = null; + String pathName = ""; + try + { + String extension = getFileExtendName(data); + pathName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension; + File file = FileUploadUtils.getAbsoluteFile(uploadDir, pathName); + fos = new FileOutputStream(file); + fos.write(data); + } + finally + { + IOUtils.close(fos); + } + return FileUploadUtils.getPathFileName(uploadDir, pathName); + } + + /** + * 删除文件 + * + * @param filePath 文件 + * @return + */ + public static boolean deleteFile(String filePath) + { + boolean flag = false; + File file = new File(filePath); + // 路径为文件且不为空则进行删除 + if (file.isFile() && file.exists()) + { + file.delete(); + flag = true; + } + return flag; + } + + /** + * 文件名称验证 + * + * @param filename 文件名称 + * @return true 正常 false 非法 + */ + public static boolean isValidFilename(String filename) + { + return filename.matches(FILENAME_PATTERN); + } + + /** + * 检查文件是否可下载 + * + * @param resource 需要下载的文件 + * @return true 正常 false 非法 + */ + public static boolean checkAllowDownload(String resource) + { + // 禁止目录上跳级别 + if (StringUtils.contains(resource, "..")) + { + return false; + } + + // 检查允许下载的文件规则 + if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource))) + { + return true; + } + + // 不在允许下载的文件规则 + return false; + } + + /** + * 下载文件名重新编码 + * + * @param request 请求对象 + * @param fileName 文件名 + * @return 编码后的文件名 + */ + public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException + { + final String agent = request.getHeader("USER-AGENT"); + String filename = fileName; + if (agent.contains("MSIE")) + { + // IE浏览器 + filename = URLEncoder.encode(filename, "utf-8"); + filename = filename.replace("+", " "); + } + else if (agent.contains("Firefox")) + { + // 火狐浏览器 + filename = new String(fileName.getBytes(), "ISO8859-1"); + } + else if (agent.contains("Chrome")) + { + // google浏览器 + filename = URLEncoder.encode(filename, "utf-8"); + } + else + { + // 其它浏览器 + filename = URLEncoder.encode(filename, "utf-8"); + } + return filename; + } + + /** + * 下载文件名重新编码 + * + * @param response 响应对象 + * @param realFileName 真实文件名 + */ + public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException + { + String percentEncodedFileName = percentEncode(realFileName); + + StringBuilder contentDispositionValue = new StringBuilder(); + contentDispositionValue.append("attachment; filename=") + .append(percentEncodedFileName) + .append(";") + .append("filename*=") + .append("utf-8''") + .append(percentEncodedFileName); + + response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename"); + response.setHeader("Content-disposition", contentDispositionValue.toString()); + response.setHeader("download-filename", percentEncodedFileName); + } + + /** + * 百分号编码工具方法 + * + * @param s 需要百分号编码的字符串 + * @return 百分号编码后的字符串 + */ + public static String percentEncode(String s) throws UnsupportedEncodingException + { + String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString()); + return encode.replaceAll("\\+", "%20"); + } + + /** + * 获取图像后缀 + * + * @param photoByte 图像数据 + * @return 后缀名 + */ + public static String getFileExtendName(byte[] photoByte) + { + String strFileExtendName = "jpg"; + if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56) + && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) + { + strFileExtendName = "gif"; + } + else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) + { + strFileExtendName = "jpg"; + } + else if ((photoByte[0] == 66) && (photoByte[1] == 77)) + { + strFileExtendName = "bmp"; + } + else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) + { + strFileExtendName = "png"; + } + return strFileExtendName; + } + + /** + * 获取文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi.png + * + * @param fileName 路径名称 + * @return 没有文件路径的名称 + */ + public static String getName(String fileName) + { + if (fileName == null) + { + return null; + } + int lastUnixPos = fileName.lastIndexOf('/'); + int lastWindowsPos = fileName.lastIndexOf('\\'); + int index = Math.max(lastUnixPos, lastWindowsPos); + return fileName.substring(index + 1); + } + + /** + * 获取不带后缀文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi + * + * @param fileName 路径名称 + * @return 没有文件路径和后缀的名称 + */ + public static String getNameNotSuffix(String fileName) + { + if (fileName == null) + { + return null; + } + String baseName = FilenameUtils.getBaseName(fileName); + return baseName; + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/ImageUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/ImageUtils.java new file mode 100644 index 0000000..432dfda --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/ImageUtils.java @@ -0,0 +1,98 @@ +package com.ruoyi.common.utils.file; + +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Arrays; +import org.apache.poi.util.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.utils.StringUtils; + +/** + * 图片处理工具类 + * + * @author ruoyi + */ +public class ImageUtils +{ + private static final Logger log = LoggerFactory.getLogger(ImageUtils.class); + + public static byte[] getImage(String imagePath) + { + InputStream is = getFile(imagePath); + try + { + return IOUtils.toByteArray(is); + } + catch (Exception e) + { + log.error("图片加载异常 {}", e); + return null; + } + finally + { + IOUtils.closeQuietly(is); + } + } + + public static InputStream getFile(String imagePath) + { + try + { + byte[] result = readFile(imagePath); + result = Arrays.copyOf(result, result.length); + return new ByteArrayInputStream(result); + } + catch (Exception e) + { + log.error("获取图片异常 {}", e); + } + return null; + } + + /** + * 读取文件为字节数据 + * + * @param url 地址 + * @return 字节数据 + */ + public static byte[] readFile(String url) + { + InputStream in = null; + try + { + if (url.startsWith("http")) + { + // 网络地址 + URL urlObj = new URL(url); + URLConnection urlConnection = urlObj.openConnection(); + urlConnection.setConnectTimeout(30 * 1000); + urlConnection.setReadTimeout(60 * 1000); + urlConnection.setDoInput(true); + in = urlConnection.getInputStream(); + } + else + { + // 本机地址 + String localPath = RuoYiConfig.getProfile(); + String downloadPath = localPath + StringUtils.substringAfter(url, Constants.RESOURCE_PREFIX); + in = new FileInputStream(downloadPath); + } + return IOUtils.toByteArray(in); + } + catch (Exception e) + { + log.error("获取文件路径异常 {}", e); + return null; + } + finally + { + IOUtils.closeQuietly(in); + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java new file mode 100644 index 0000000..8fb163c --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java @@ -0,0 +1,59 @@ +package com.ruoyi.common.utils.file; + +/** + * 媒体类型工具类 + * + * @author ruoyi + */ +public class MimeTypeUtils +{ + public static final String IMAGE_PNG = "image/png"; + + public static final String IMAGE_JPG = "image/jpg"; + + public static final String IMAGE_JPEG = "image/jpeg"; + + public static final String IMAGE_BMP = "image/bmp"; + + public static final String IMAGE_GIF = "image/gif"; + + public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" }; + + public static final String[] FLASH_EXTENSION = { "swf", "flv" }; + + public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg", + "asf", "rm", "rmvb" }; + + public static final String[] VIDEO_EXTENSION = { "mp4", "avi", "rmvb" }; + + public static final String[] DEFAULT_ALLOWED_EXTENSION = { + // 图片 + "bmp", "gif", "jpg", "jpeg", "png", "json", + // word excel powerpoint + "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt", + // 压缩文件 + "rar", "zip", "gz", "bz2", + // 视频格式 + "mp4", "avi", "rmvb", + // pdf + "pdf" }; + + public static String getExtension(String prefix) + { + switch (prefix) + { + case IMAGE_PNG: + return "png"; + case IMAGE_JPG: + return "jpg"; + case IMAGE_JPEG: + return "jpeg"; + case IMAGE_BMP: + return "bmp"; + case IMAGE_GIF: + return "gif"; + default: + return ""; + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MinioUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MinioUtil.java new file mode 100644 index 0000000..30ea4b1 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MinioUtil.java @@ -0,0 +1,43 @@ +package com.ruoyi.common.utils.file; + +import java.io.IOException; +import java.io.InputStream; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import io.minio.GetPresignedObjectUrlArgs; +import io.minio.MinioClient; +import io.minio.PutObjectArgs; +import io.minio.http.Method; + +/** + * Minio 文件存储工具类 + * + * @author ruoyi + */ +public class MinioUtil +{ + /** + * 上传文件 + * + * @param bucketName 桶名称 + * @param fileName + * @throws IOException + */ + public static String uploadFile(String bucketName, String fileName, MultipartFile multipartFile) throws IOException + { + String url = ""; + MinioClient minioClient = SpringUtils.getBean(MinioClient.class); + try (InputStream inputStream = multipartFile.getInputStream()) + { + minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(inputStream, multipartFile.getSize(), -1).contentType(multipartFile.getContentType()).build()); + url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(fileName).method(Method.GET).build()); + url = url.substring(0, url.indexOf('?')); + return ServletUtils.urlDecode(url); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/XmlDocToDocxUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/XmlDocToDocxUtil.java new file mode 100644 index 0000000..bccfcdb --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/XmlDocToDocxUtil.java @@ -0,0 +1,41 @@ +package com.ruoyi.common.utils.file; + +import com.ruoyi.common.constant.WordConstants; +import org.docx4j.Docx4J; +import org.docx4j.openpackaging.packages.WordprocessingMLPackage; + + +import java.io.FileInputStream; +import java.io.FileOutputStream; + +/** + * 转换xml格式的doc文档为docx + */ +public class XmlDocToDocxUtil { + + + private XmlDocToDocxUtil(){}; + /** + * 转换执行方法,转换后和原始路径 + * @param xmlPath 原始路径 + */ + public static boolean invoke(String xmlPath){ + + //DOC文档才转换 + String docxPath = xmlPath.replaceAll(WordConstants.CONVERT_SUF,WordConstants.DOCX_SUF); + try(FileInputStream inputStream = new FileInputStream(xmlPath);){ + + WordprocessingMLPackage wmlPackage = Docx4J.load(inputStream); + //转换为DOCX + try(FileOutputStream docx = new FileOutputStream(docxPath);){ + Docx4J.save(wmlPackage, docx, Docx4J.FLAG_SAVE_ZIP_FILE); + xmlPath = docxPath; + } + } catch (Exception e) { + System.out.println(xmlPath+":不需要转换:"+e.getLocalizedMessage()); + } + +// System.out.println("WORD 路径:"+xmlPath); + return true; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java new file mode 100644 index 0000000..f52e83e --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java @@ -0,0 +1,167 @@ +package com.ruoyi.common.utils.html; + +import com.ruoyi.common.utils.StringUtils; + +/** + * 转义和反转义工具类 + * + * @author ruoyi + */ +public class EscapeUtil +{ + public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)"; + + private static final char[][] TEXT = new char[64][]; + + static + { + for (int i = 0; i < 64; i++) + { + TEXT[i] = new char[] { (char) i }; + } + + // special HTML characters + TEXT['\''] = "'".toCharArray(); // 单引号 + TEXT['"'] = """.toCharArray(); // 双引号 + TEXT['&'] = "&".toCharArray(); // &符 + TEXT['<'] = "<".toCharArray(); // 小于号 + TEXT['>'] = ">".toCharArray(); // 大于号 + } + + /** + * 转义文本中的HTML字符为安全的字符 + * + * @param text 被转义的文本 + * @return 转义后的文本 + */ + public static String escape(String text) + { + return encode(text); + } + + /** + * 还原被转义的HTML特殊字符 + * + * @param content 包含转义符的HTML内容 + * @return 转换后的字符串 + */ + public static String unescape(String content) + { + return decode(content); + } + + /** + * 清除所有HTML标签,但是不删除标签内的内容 + * + * @param content 文本 + * @return 清除标签后的文本 + */ + public static String clean(String content) + { + return new HTMLFilter().filter(content); + } + + /** + * Escape编码 + * + * @param text 被编码的文本 + * @return 编码后的字符 + */ + private static String encode(String text) + { + if (StringUtils.isEmpty(text)) + { + return StringUtils.EMPTY; + } + + final StringBuilder tmp = new StringBuilder(text.length() * 6); + char c; + for (int i = 0; i < text.length(); i++) + { + c = text.charAt(i); + if (c < 256) + { + tmp.append("%"); + if (c < 16) + { + tmp.append("0"); + } + tmp.append(Integer.toString(c, 16)); + } + else + { + tmp.append("%u"); + if (c <= 0xfff) + { + // issue#I49JU8@Gitee + tmp.append("0"); + } + tmp.append(Integer.toString(c, 16)); + } + } + return tmp.toString(); + } + + /** + * Escape解码 + * + * @param content 被转义的内容 + * @return 解码后的字符串 + */ + public static String decode(String content) + { + if (StringUtils.isEmpty(content)) + { + return content; + } + + StringBuilder tmp = new StringBuilder(content.length()); + int lastPos = 0, pos = 0; + char ch; + while (lastPos < content.length()) + { + pos = content.indexOf("%", lastPos); + if (pos == lastPos) + { + if (content.charAt(pos + 1) == 'u') + { + ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16); + tmp.append(ch); + lastPos = pos + 6; + } + else + { + ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16); + tmp.append(ch); + lastPos = pos + 3; + } + } + else + { + if (pos == -1) + { + tmp.append(content.substring(lastPos)); + lastPos = content.length(); + } + else + { + tmp.append(content.substring(lastPos, pos)); + lastPos = pos; + } + } + } + return tmp.toString(); + } + + public static void main(String[] args) + { + String html = ""; + String escape = EscapeUtil.escape(html); + // String html = "ipt>alert(\"XSS\")ipt>"; + // String html = "<123"; + // String html = "123>"; + System.out.println("clean: " + EscapeUtil.clean(html)); + System.out.println("escape: " + escape); + System.out.println("unescape: " + EscapeUtil.unescape(escape)); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java new file mode 100644 index 0000000..ebff3fd --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java @@ -0,0 +1,570 @@ +package com.ruoyi.common.utils.html; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * HTML过滤器,用于去除XSS漏洞隐患。 + * + * @author ruoyi + */ +public final class HTMLFilter +{ + /** + * regex flag union representing /si modifiers in php + **/ + private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL; + private static final Pattern P_COMMENTS = Pattern.compile("", Pattern.DOTALL); + private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI); + private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL); + private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI); + private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI); + private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI); + private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI); + private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI); + private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?"); + private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?"); + private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?"); + private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))"); + private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL); + private static final Pattern P_END_ARROW = Pattern.compile("^>"); + private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_AMP = Pattern.compile("&"); + private static final Pattern P_QUOTE = Pattern.compile("\""); + private static final Pattern P_LEFT_ARROW = Pattern.compile("<"); + private static final Pattern P_RIGHT_ARROW = Pattern.compile(">"); + private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>"); + + // @xxx could grow large... maybe use sesat's ReferenceMap + private static final ConcurrentMap P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<>(); + private static final ConcurrentMap P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>(); + + /** + * set of allowed html elements, along with allowed attributes for each element + **/ + private final Map> vAllowed; + /** + * counts of open tags for each (allowable) html element + **/ + private final Map vTagCounts = new HashMap<>(); + + /** + * html elements which must always be self-closing (e.g. "") + **/ + private final String[] vSelfClosingTags; + /** + * html elements which must always have separate opening and closing tags (e.g. "") + **/ + private final String[] vNeedClosingTags; + /** + * set of disallowed html elements + **/ + private final String[] vDisallowed; + /** + * attributes which should be checked for valid protocols + **/ + private final String[] vProtocolAtts; + /** + * allowed protocols + **/ + private final String[] vAllowedProtocols; + /** + * tags which should be removed if they contain no content (e.g. "" or "") + **/ + private final String[] vRemoveBlanks; + /** + * entities allowed within html markup + **/ + private final String[] vAllowedEntities; + /** + * flag determining whether comments are allowed in input String. + */ + private final boolean stripComment; + private final boolean encodeQuotes; + /** + * flag determining whether to try to make tags when presented with "unbalanced" angle brackets (e.g. "" + * becomes " text "). If set to false, unbalanced angle brackets will be html escaped. + */ + private final boolean alwaysMakeTags; + + /** + * Default constructor. + */ + public HTMLFilter() + { + vAllowed = new HashMap<>(); + + final ArrayList a_atts = new ArrayList<>(); + a_atts.add("href"); + a_atts.add("target"); + vAllowed.put("a", a_atts); + + final ArrayList img_atts = new ArrayList<>(); + img_atts.add("src"); + img_atts.add("width"); + img_atts.add("height"); + img_atts.add("alt"); + vAllowed.put("img", img_atts); + + final ArrayList no_atts = new ArrayList<>(); + vAllowed.put("b", no_atts); + vAllowed.put("strong", no_atts); + vAllowed.put("i", no_atts); + vAllowed.put("em", no_atts); + + vSelfClosingTags = new String[] { "img" }; + vNeedClosingTags = new String[] { "a", "b", "strong", "i", "em" }; + vDisallowed = new String[] {}; + vAllowedProtocols = new String[] { "http", "mailto", "https" }; // no ftp. + vProtocolAtts = new String[] { "src", "href" }; + vRemoveBlanks = new String[] { "a", "b", "strong", "i", "em" }; + vAllowedEntities = new String[] { "amp", "gt", "lt", "quot" }; + stripComment = true; + encodeQuotes = true; + alwaysMakeTags = false; + } + + /** + * Map-parameter configurable constructor. + * + * @param conf map containing configuration. keys match field names. + */ + @SuppressWarnings("unchecked") + public HTMLFilter(final Map conf) + { + + assert conf.containsKey("vAllowed") : "configuration requires vAllowed"; + assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags"; + assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags"; + assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed"; + assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols"; + assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts"; + assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks"; + assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities"; + + vAllowed = Collections.unmodifiableMap((HashMap>) conf.get("vAllowed")); + vSelfClosingTags = (String[]) conf.get("vSelfClosingTags"); + vNeedClosingTags = (String[]) conf.get("vNeedClosingTags"); + vDisallowed = (String[]) conf.get("vDisallowed"); + vAllowedProtocols = (String[]) conf.get("vAllowedProtocols"); + vProtocolAtts = (String[]) conf.get("vProtocolAtts"); + vRemoveBlanks = (String[]) conf.get("vRemoveBlanks"); + vAllowedEntities = (String[]) conf.get("vAllowedEntities"); + stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true; + encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true; + alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true; + } + + private void reset() + { + vTagCounts.clear(); + } + + // --------------------------------------------------------------- + // my versions of some PHP library functions + public static String chr(final int decimal) + { + return String.valueOf((char) decimal); + } + + public static String htmlSpecialChars(final String s) + { + String result = s; + result = regexReplace(P_AMP, "&", result); + result = regexReplace(P_QUOTE, """, result); + result = regexReplace(P_LEFT_ARROW, "<", result); + result = regexReplace(P_RIGHT_ARROW, ">", result); + return result; + } + + // --------------------------------------------------------------- + + /** + * given a user submitted input String, filter out any invalid or restricted html. + * + * @param input text (i.e. submitted by a user) than may contain html + * @return "clean" version of input, with only valid, whitelisted html elements allowed + */ + public String filter(final String input) + { + reset(); + String s = input; + + s = escapeComments(s); + + s = balanceHTML(s); + + s = checkTags(s); + + s = processRemoveBlanks(s); + + // s = validateEntities(s); + + return s; + } + + public boolean isAlwaysMakeTags() + { + return alwaysMakeTags; + } + + public boolean isStripComments() + { + return stripComment; + } + + private String escapeComments(final String s) + { + final Matcher m = P_COMMENTS.matcher(s); + final StringBuffer buf = new StringBuffer(); + if (m.find()) + { + final String match = m.group(1); // (.*?) + m.appendReplacement(buf, Matcher.quoteReplacement("")); + } + m.appendTail(buf); + + return buf.toString(); + } + + private String balanceHTML(String s) + { + if (alwaysMakeTags) + { + // + // try and form html + // + s = regexReplace(P_END_ARROW, "", s); + // 不追加结束标签 + s = regexReplace(P_BODY_TO_END, "<$1>", s); + s = regexReplace(P_XML_CONTENT, "$1<$2", s); + + } + else + { + // + // escape stray brackets + // + s = regexReplace(P_STRAY_LEFT_ARROW, "<$1", s); + s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2><", s); + + // + // the last regexp causes '<>' entities to appear + // (we need to do a lookahead assertion so that the last bracket can + // be used in the next pass of the regexp) + // + s = regexReplace(P_BOTH_ARROWS, "", s); + } + + return s; + } + + private String checkTags(String s) + { + Matcher m = P_TAGS.matcher(s); + + final StringBuffer buf = new StringBuffer(); + while (m.find()) + { + String replaceStr = m.group(1); + replaceStr = processTag(replaceStr); + m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr)); + } + m.appendTail(buf); + + // these get tallied in processTag + // (remember to reset before subsequent calls to filter method) + final StringBuilder sBuilder = new StringBuilder(buf.toString()); + for (String key : vTagCounts.keySet()) + { + for (int ii = 0; ii < vTagCounts.get(key); ii++) + { + sBuilder.append(""); + } + } + s = sBuilder.toString(); + + return s; + } + + private String processRemoveBlanks(final String s) + { + String result = s; + for (String tag : vRemoveBlanks) + { + if (!P_REMOVE_PAIR_BLANKS.containsKey(tag)) + { + P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?>")); + } + result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result); + if (!P_REMOVE_SELF_BLANKS.containsKey(tag)) + { + P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>")); + } + result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result); + } + + return result; + } + + private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) + { + Matcher m = regex_pattern.matcher(s); + return m.replaceAll(replacement); + } + + private String processTag(final String s) + { + // ending tags + Matcher m = P_END_TAG.matcher(s); + if (m.find()) + { + final String name = m.group(1).toLowerCase(); + if (allowed(name)) + { + if (!inArray(name, vSelfClosingTags)) + { + if (vTagCounts.containsKey(name)) + { + vTagCounts.put(name, vTagCounts.get(name) - 1); + return ""; + } + } + } + } + + // starting tags + m = P_START_TAG.matcher(s); + if (m.find()) + { + final String name = m.group(1).toLowerCase(); + final String body = m.group(2); + String ending = m.group(3); + + // debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" ); + if (allowed(name)) + { + final StringBuilder params = new StringBuilder(); + + final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body); + final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body); + final List paramNames = new ArrayList<>(); + final List paramValues = new ArrayList<>(); + while (m2.find()) + { + paramNames.add(m2.group(1)); // ([a-z0-9]+) + paramValues.add(m2.group(3)); // (.*?) + } + while (m3.find()) + { + paramNames.add(m3.group(1)); // ([a-z0-9]+) + paramValues.add(m3.group(3)); // ([^\"\\s']+) + } + + String paramName, paramValue; + for (int ii = 0; ii < paramNames.size(); ii++) + { + paramName = paramNames.get(ii).toLowerCase(); + paramValue = paramValues.get(ii); + + // debug( "paramName='" + paramName + "'" ); + // debug( "paramValue='" + paramValue + "'" ); + // debug( "allowed? " + vAllowed.get( name ).contains( paramName ) ); + + if (allowedAttribute(name, paramName)) + { + if (inArray(paramName, vProtocolAtts)) + { + paramValue = processParamProtocol(paramValue); + } + params.append(' ').append(paramName).append("=\\\"").append(paramValue).append("\\\""); + } + } + + if (inArray(name, vSelfClosingTags)) + { + ending = " /"; + } + + if (inArray(name, vNeedClosingTags)) + { + ending = ""; + } + + if (ending == null || ending.length() < 1) + { + if (vTagCounts.containsKey(name)) + { + vTagCounts.put(name, vTagCounts.get(name) + 1); + } + else + { + vTagCounts.put(name, 1); + } + } + else + { + ending = " /"; + } + return "<" + name + params + ending + ">"; + } + else + { + return ""; + } + } + + // comments + m = P_COMMENT.matcher(s); + if (!stripComment && m.find()) + { + return "<" + m.group() + ">"; + } + + return ""; + } + + private String processParamProtocol(String s) + { + s = decodeEntities(s); + final Matcher m = P_PROTOCOL.matcher(s); + if (m.find()) + { + final String protocol = m.group(1); + if (!inArray(protocol, vAllowedProtocols)) + { + // bad protocol, turn into local anchor link instead + s = "#" + s.substring(protocol.length() + 1); + if (s.startsWith("#//")) + { + s = "#" + s.substring(3); + } + } + } + + return s; + } + + private String decodeEntities(String s) + { + StringBuffer buf = new StringBuffer(); + + Matcher m = P_ENTITY.matcher(s); + while (m.find()) + { + final String match = m.group(1); + final int decimal = Integer.decode(match).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENTITY_UNICODE.matcher(s); + while (m.find()) + { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENCODE.matcher(s); + while (m.find()) + { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + s = validateEntities(s); + return s; + } + + private String validateEntities(final String s) + { + StringBuffer buf = new StringBuffer(); + + // validate entities throughout the string + Matcher m = P_VALID_ENTITIES.matcher(s); + while (m.find()) + { + final String one = m.group(1); // ([^&;]*) + final String two = m.group(2); // (?=(;|&|$)) + m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two))); + } + m.appendTail(buf); + + return encodeQuotes(buf.toString()); + } + + private String encodeQuotes(final String s) + { + if (encodeQuotes) + { + StringBuffer buf = new StringBuffer(); + Matcher m = P_VALID_QUOTES.matcher(s); + while (m.find()) + { + final String one = m.group(1); // (>|^) + final String two = m.group(2); // ([^<]+?) + final String three = m.group(3); // (<|$) + // 不替换双引号为",防止json格式无效 regexReplace(P_QUOTE, """, two) + m.appendReplacement(buf, Matcher.quoteReplacement(one + two + three)); + } + m.appendTail(buf); + return buf.toString(); + } + else + { + return s; + } + } + + private String checkEntity(final String preamble, final String term) + { + + return ";".equals(term) && isValidEntity(preamble) ? '&' + preamble : "&" + preamble; + } + + private boolean isValidEntity(final String entity) + { + return inArray(entity, vAllowedEntities); + } + + private static boolean inArray(final String s, final String[] array) + { + for (String item : array) + { + if (item != null && item.equals(s)) + { + return true; + } + } + return false; + } + + private boolean allowed(final String name) + { + return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed); + } + + private boolean allowedAttribute(final String name, final String paramName) + { + return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName)); + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpHelper.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpHelper.java new file mode 100644 index 0000000..589d123 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpHelper.java @@ -0,0 +1,55 @@ +package com.ruoyi.common.utils.http; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import javax.servlet.ServletRequest; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 通用http工具封装 + * + * @author ruoyi + */ +public class HttpHelper +{ + private static final Logger LOGGER = LoggerFactory.getLogger(HttpHelper.class); + + public static String getBodyString(ServletRequest request) + { + StringBuilder sb = new StringBuilder(); + BufferedReader reader = null; + try (InputStream inputStream = request.getInputStream()) + { + reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); + String line = ""; + while ((line = reader.readLine()) != null) + { + sb.append(line); + } + } + catch (IOException e) + { + LOGGER.warn("getBodyString出现问题!"); + } + finally + { + if (reader != null) + { + try + { + reader.close(); + } + catch (IOException e) + { + LOGGER.error(ExceptionUtils.getMessage(e)); + } + } + } + return sb.toString(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java new file mode 100644 index 0000000..b5b25cc --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java @@ -0,0 +1,328 @@ +package com.ruoyi.common.utils.http; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.StandardCharsets; +import java.security.cert.X509Certificate; +import java.util.Map; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.RequestEntity; +import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.utils.StringUtils; + +/** + * 通用http发送方法 + * + * @author ruoyi + */ +public class HttpUtils +{ + private static final Logger log = LoggerFactory.getLogger(HttpUtils.class); + + /** + * 向指定 URL 发送GET方法的请求 + * + * @param url 发送请求的 URL + * @return 所代表远程资源的响应结果 + */ + public static String sendGet(String url) + { + return sendGet(url, StringUtils.EMPTY); + } + + /** + * 向指定 URL 发送GET方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @return 所代表远程资源的响应结果 + */ + public static String sendGet(String url, String param) + { + return sendGet(url, param, Constants.UTF8); + } + + /** + * 向指定 URL 发送GET方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @param contentType 编码类型 + * @return 所代表远程资源的响应结果 + */ + public static String sendGet(String url, String param, String contentType) + { + StringBuilder result = new StringBuilder(); + BufferedReader in = null; + try + { + String urlNameString = StringUtils.isNotBlank(param) ? url + "?" + param : url; + log.info("sendGet - {}", urlNameString); + URL realUrl = new URL(urlNameString); + URLConnection connection = realUrl.openConnection(); + connection.setRequestProperty("accept", "*/*"); + connection.setRequestProperty("connection", "Keep-Alive"); + connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + connection.connect(); + in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType)); + String line; + while ((line = in.readLine()) != null) + { + result.append(line); + } + log.info("recv - {}", result); + } + catch (ConnectException e) + { + log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e); + } + catch (SocketTimeoutException e) + { + log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e); + } + catch (IOException e) + { + log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e); + } + catch (Exception e) + { + log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e); + } + finally + { + try + { + if (in != null) + { + in.close(); + } + } + catch (Exception ex) + { + log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); + } + } + return result.toString(); + } + + /** + * 向指定 URL 发送POST方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @return 所代表远程资源的响应结果 + */ + public static String sendPost(String url, String param) + { + PrintWriter out = null; + BufferedReader in = null; + StringBuilder result = new StringBuilder(); + try + { + log.info("sendPost - {}", url); + URL realUrl = new URL(url); + URLConnection conn = realUrl.openConnection(); + conn.setRequestProperty("accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + conn.setRequestProperty("Accept-Charset", "utf-8"); + conn.setRequestProperty("contentType", "utf-8"); + conn.setDoOutput(true); + conn.setDoInput(true); + out = new PrintWriter(conn.getOutputStream()); + out.print(param); + out.flush(); + in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)); + String line; + while ((line = in.readLine()) != null) + { + result.append(line); + } + log.info("recv - {}", result); + } + catch (ConnectException e) + { + log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e); + } + catch (SocketTimeoutException e) + { + log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e); + } + catch (IOException e) + { + log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e); + } + catch (Exception e) + { + log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e); + } + finally + { + try + { + if (out != null) + { + out.close(); + } + if (in != null) + { + in.close(); + } + } + catch (IOException ex) + { + log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); + } + } + return result.toString(); + } + + public static String sendSSLPost(String url, String param) + { + StringBuilder result = new StringBuilder(); + String urlNameString = url + "?" + param; + try + { + log.info("sendSSLPost - {}", urlNameString); + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); + URL console = new URL(urlNameString); + HttpsURLConnection conn = (HttpsURLConnection) console.openConnection(); + conn.setRequestProperty("accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + conn.setRequestProperty("Accept-Charset", "utf-8"); + conn.setRequestProperty("contentType", "utf-8"); + conn.setDoOutput(true); + conn.setDoInput(true); + + conn.setSSLSocketFactory(sc.getSocketFactory()); + conn.setHostnameVerifier(new TrustAnyHostnameVerifier()); + conn.connect(); + InputStream is = conn.getInputStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + String ret = ""; + while ((ret = br.readLine()) != null) + { + if (ret != null && !"".equals(ret.trim())) + { + result.append(new String(ret.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8)); + } + } + log.info("recv - {}", result); + conn.disconnect(); + br.close(); + } + catch (ConnectException e) + { + log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e); + } + catch (SocketTimeoutException e) + { + log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e); + } + catch (IOException e) + { + log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e); + } + catch (Exception e) + { + log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e); + } + return result.toString(); + } + + /** + * post请求 + * + * @param url + * @param json + * @return + */ + public static String postJosnContent(String url, String json) { + return postJosnContent(url, json, null); + } + + /** + * post请求 + * + * @param url + * @param json + * @return + */ + public static String postJosnContent(String url, String json, Map header) { + log.info("请求接口参数:" + json); + PostMethod method = new PostMethod(url); + HttpClient httpClient = new HttpClient(); + try { + RequestEntity entity = new StringRequestEntity(json, "application/json", "UTF-8"); + method.setRequestEntity(entity); + + httpClient.executeMethod(method); + log.info("请求接口路径url:" + method.getURI().toString()); + InputStream in = method.getResponseBodyAsStream(); + //下面将stream转换为String + StringBuffer sb = new StringBuffer(); + InputStreamReader isr = new InputStreamReader(in, StandardCharsets.UTF_8); + char[] b = new char[4096]; + for (int n; (n = isr.read(b)) != -1; ) { + sb.append(new String(b, 0, n)); + } + String returnStr = sb.toString(); + log.info("请求返回结果:" + returnStr); + return returnStr; + } catch (Exception e) { + e.printStackTrace(); + } finally { + method.releaseConnection(); + } + return ""; + } + + + private static class TrustAnyTrustManager implements X509TrustManager + { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) + { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) + { + } + + @Override + public X509Certificate[] getAcceptedIssuers() + { + return new X509Certificate[] {}; + } + } + + private static class TrustAnyHostnameVerifier implements HostnameVerifier + { + @Override + public boolean verify(String hostname, SSLSession session) + { + return true; + } + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java new file mode 100644 index 0000000..edfe419 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java @@ -0,0 +1,56 @@ +package com.ruoyi.common.utils.ip; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.http.HttpUtils; + +/** + * 获取地址类 + * + * @author ruoyi + */ +public class AddressUtils +{ + private static final Logger log = LoggerFactory.getLogger(AddressUtils.class); + + // IP地址查询 + public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp"; + + // 未知地址 + public static final String UNKNOWN = "XX XX"; + + public static String getRealAddressByIP(String ip) + { + // 内网不查询 + if (IpUtils.internalIp(ip)) + { + return "内网IP"; + } + if (RuoYiConfig.isAddressEnabled()) + { + try + { + String rspStr = HttpUtils.sendGet(IP_URL, "ip=" + ip + "&json=true", Constants.GBK); + if (StringUtils.isEmpty(rspStr)) + { + log.error("获取地理位置异常 {}", ip); + return UNKNOWN; + } + JSONObject obj = JSON.parseObject(rspStr); + String region = obj.getString("pro"); + String city = obj.getString("city"); + return String.format("%s %s", region, city); + } + catch (Exception e) + { + log.error("获取地理位置异常 {}", ip); + } + } + return UNKNOWN; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java new file mode 100644 index 0000000..c18c56a --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java @@ -0,0 +1,264 @@ +package com.ruoyi.common.utils.ip; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import javax.servlet.http.HttpServletRequest; +import com.ruoyi.common.utils.StringUtils; + +/** + * 获取IP方法 + * + * @author ruoyi + */ +public class IpUtils +{ + /** + * 获取客户端IP + * + * @param request 请求对象 + * @return IP地址 + */ + public static String getIpAddr(HttpServletRequest request) + { + if (request == null) + { + return "unknown"; + } + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("X-Forwarded-For"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("X-Real-IP"); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getRemoteAddr(); + } + + return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip); + } + + /** + * 检查是否为内部IP地址 + * + * @param ip IP地址 + * @return 结果 + */ + public static boolean internalIp(String ip) + { + byte[] addr = textToNumericFormatV4(ip); + return internalIp(addr) || "127.0.0.1".equals(ip); + } + + /** + * 检查是否为内部IP地址 + * + * @param addr byte地址 + * @return 结果 + */ + private static boolean internalIp(byte[] addr) + { + if (StringUtils.isNull(addr) || addr.length < 2) + { + return true; + } + final byte b0 = addr[0]; + final byte b1 = addr[1]; + // 10.x.x.x/8 + final byte SECTION_1 = 0x0A; + // 172.16.x.x/12 + final byte SECTION_2 = (byte) 0xAC; + final byte SECTION_3 = (byte) 0x10; + final byte SECTION_4 = (byte) 0x1F; + // 192.168.x.x/16 + final byte SECTION_5 = (byte) 0xC0; + final byte SECTION_6 = (byte) 0xA8; + switch (b0) + { + case SECTION_1: + return true; + case SECTION_2: + if (b1 >= SECTION_3 && b1 <= SECTION_4) + { + return true; + } + case SECTION_5: + switch (b1) + { + case SECTION_6: + return true; + } + default: + return false; + } + } + + /** + * 将IPv4地址转换成字节 + * + * @param text IPv4地址 + * @return byte 字节 + */ + public static byte[] textToNumericFormatV4(String text) + { + if (text.length() == 0) + { + return null; + } + + byte[] bytes = new byte[4]; + String[] elements = text.split("\\.", -1); + try + { + long l; + int i; + switch (elements.length) + { + case 1: + l = Long.parseLong(elements[0]); + if ((l < 0L) || (l > 4294967295L)) + { + return null; + } + bytes[0] = (byte) (int) (l >> 24 & 0xFF); + bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 2: + l = Integer.parseInt(elements[0]); + if ((l < 0L) || (l > 255L)) + { + return null; + } + bytes[0] = (byte) (int) (l & 0xFF); + l = Integer.parseInt(elements[1]); + if ((l < 0L) || (l > 16777215L)) + { + return null; + } + bytes[1] = (byte) (int) (l >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 3: + for (i = 0; i < 2; ++i) + { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) + { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + l = Integer.parseInt(elements[2]); + if ((l < 0L) || (l > 65535L)) + { + return null; + } + bytes[2] = (byte) (int) (l >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 4: + for (i = 0; i < 4; ++i) + { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) + { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + break; + default: + return null; + } + } + catch (NumberFormatException e) + { + return null; + } + return bytes; + } + + /** + * 获取IP地址 + * + * @return 本地IP地址 + */ + public static String getHostIp() + { + try + { + return InetAddress.getLocalHost().getHostAddress(); + } + catch (UnknownHostException e) + { + } + return "127.0.0.1"; + } + + /** + * 获取主机名 + * + * @return 本地主机名 + */ + public static String getHostName() + { + try + { + return InetAddress.getLocalHost().getHostName(); + } + catch (UnknownHostException e) + { + } + return "未知"; + } + + /** + * 从多级反向代理中获得第一个非unknown IP地址 + * + * @param ip 获得的IP地址 + * @return 第一个非unknown IP地址 + */ + public static String getMultistageReverseProxyIp(String ip) + { + // 多级反向代理检测 + if (ip != null && ip.indexOf(",") > 0) + { + final String[] ips = ip.trim().split(","); + for (String subIp : ips) + { + if (false == isUnknown(subIp)) + { + ip = subIp; + break; + } + } + } + return ip; + } + + /** + * 检测给定字符串是否为未知,多用于检测HTTP请求相关 + * + * @param checkString 被检测的字符串 + * @return 是否未知 + */ + public static boolean isUnknown(String checkString) + { + return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString); + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/EasyPoiExcelUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/EasyPoiExcelUtil.java new file mode 100644 index 0000000..8f393e3 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/EasyPoiExcelUtil.java @@ -0,0 +1,104 @@ +package com.ruoyi.common.utils.poi; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.ExcelImportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.ImportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult; +import cn.hutool.core.collection.CollectionUtil; +import com.ruoyi.common.core.domain.model.ExcelSelector; +import org.apache.poi.hssf.usermodel.DVConstraint; +import org.apache.poi.hssf.usermodel.HSSFDataValidation; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * @author huamile + */ +public class EasyPoiExcelUtil { + + public static void exportExcel(String title, Class pojoClass, Collection dataSet, HttpServletRequest request, HttpServletResponse response) { + ExportParams params = new ExportParams(); + params.setTitle(title); + params.setSheetName(title); + Workbook wb = ExcelExportUtil.exportExcel(params, pojoClass, dataSet); + writeOutStream(wb,request,response); + } + + public static void exportMultiSheetExcel(List> list, List selectorList, HttpServletRequest request, HttpServletResponse response) { + Workbook wb = ExcelExportUtil.exportExcel(list, ExcelType.HSSF); + generateSelector(wb,selectorList); + writeOutStream(wb,request,response); + } + + private static void generateSelector(Workbook wb,List selectorList) { + if (CollectionUtil.isNotEmpty(selectorList)) { + Sheet sheet; + CellRangeAddressList cellRangeAddressList; + DVConstraint dvConstraint; + HSSFDataValidation dataValidation; + for (ExcelSelector selector : selectorList) { + sheet = wb.getSheetAt(selector.getSheetIndex()); + cellRangeAddressList = new CellRangeAddressList(selector.getFirstRow(),selector.getLastRow(),selector.getFirstCol(),selector.getLastCol()); + dvConstraint = DVConstraint.createExplicitListConstraint(selector.getDatas()); + dataValidation = new HSSFDataValidation(cellRangeAddressList, dvConstraint); + sheet.addValidationData(dataValidation); + } + } + } + + private static void writeOutStream(Workbook workbook,HttpServletRequest request, HttpServletResponse response) { + try { + response.setCharacterEncoding("UTF-8"); + response.setHeader("content-Type", "application/vnd.ms-excel"); + String filename = System.currentTimeMillis() + ".xls"; + if ("IE".equals(getBrowser(request))){ + filename = URLEncoder.encode(filename,"UTF-8"); + } else { + filename = new String(filename.getBytes("UTF-8"),"ISO-8859-1"); + } + response.setHeader("Content-Disposition", "attachment;filename=" + filename); + + response.setHeader("Pargam", "no-cache"); + response.setHeader("Cache-Control", "no-cache"); + ServletOutputStream outStream = null; + try { + outStream = response.getOutputStream(); + workbook.write(outStream); + outStream.flush(); + } finally { + outStream.close(); + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println("excel导出报错 : " + e.getMessage()); + } + } + + private static String getBrowser(HttpServletRequest request){ + String userAgent = request.getHeader("User-Agent").toLowerCase(); + if (userAgent.indexOf("firefox") >= 0){ + return "FF"; + } else if (userAgent.indexOf("safari") >= 0){ + return "Chrome"; + } else { + return "IE"; + } + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelHandlerAdapter.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelHandlerAdapter.java new file mode 100644 index 0000000..5ea74c1 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelHandlerAdapter.java @@ -0,0 +1,19 @@ +package com.ruoyi.common.utils.poi; + +/** + * Excel数据格式处理适配器 + * + * @author ruoyi + */ +public interface ExcelHandlerAdapter +{ + /** + * 格式化 + * + * @param value 单元格数据值 + * @param args excel注解args参数组 + * + * @return 处理后的值 + */ + Object format(Object value, String[] args); +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java new file mode 100644 index 0000000..f505fd4 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java @@ -0,0 +1,1721 @@ +package com.ruoyi.common.utils.poi; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.annotation.Excel.ColumnType; +import com.ruoyi.common.annotation.Excel.Type; +import com.ruoyi.common.annotation.Excels; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.exception.UtilException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.FileTypeUtils; +import com.ruoyi.common.utils.file.FileUtils; +import com.ruoyi.common.utils.file.ImageUtils; +import com.ruoyi.common.utils.reflect.ReflectUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.RegExUtils; +import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.poi.hssf.usermodel.*; +import org.apache.poi.ooxml.POIXMLDocumentPart; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.*; +import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.lang.reflect.*; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +/** + * Excel相关处理 + * + * @author ruoyi + */ +public class ExcelUtil +{ + private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); + + public static final String FORMULA_REGEX_STR = "=|-|\\+|@"; + + public static final String[] FORMULA_STR = { "=", "-", "+", "@" }; + + /** + * Excel sheet最大行数,默认65536 + */ + public static final int sheetSize = 65536; + + /** + * 工作表名称 + */ + private String sheetName; + + /** + * 导出类型(EXPORT:导出数据;IMPORT:导入模板) + */ + private Type type; + + /** + * 工作薄对象 + */ + private Workbook wb; + + /** + * 工作表对象 + */ + private Sheet sheet; + + /** + * 样式列表 + */ + private Map styles; + + /** + * 导入导出数据列表 + */ + private List list; + + /** + * 注解列表 + */ + private List fields; + + /** + * 当前行号 + */ + private int rownum; + + /** + * 标题 + */ + private String title; + + /** + * 最大高度 + */ + private short maxHeight; + + /** + * 合并后最后行数 + */ + private int subMergedLastRowNum = 0; + + /** + * 合并后开始行数 + */ + private int subMergedFirstRowNum = 1; + + /** + * 对象的子列表方法 + */ + private Method subMethod; + + /** + * 对象的子列表属性 + */ + private List subFields; + + /** + * 统计列表 + */ + private Map statistics = new HashMap(); + + /** + * 数字格式 + */ + private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00"); + + /** + * 实体对象 + */ + public Class clazz; + + /** + * 需要排除列属性 + */ + public String[] excludeFields; + + public ExcelUtil(Class clazz) + { + this.clazz = clazz; + } + + /** + * 隐藏Excel中列属性 + * + * @param fields 列属性名 示例[单个"name"/多个"id","name"] + * @throws Exception + */ + public void hideColumn(String... fields) + { + this.excludeFields = fields; + } + + public void init(List list, String sheetName, String title, Type type) + { + if (list == null) + { + list = new ArrayList(); + } + this.list = list; + this.sheetName = sheetName; + this.type = type; + this.title = title; + createExcelField(); + createWorkbook(); + createTitle(); + createSubHead(); + } + + /** + * 创建excel第一行标题 + */ + public void createTitle() + { + if (StringUtils.isNotEmpty(title)) + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + int titleLastCol = this.fields.size() - 1; + if (isSubList()) + { + titleLastCol = titleLastCol + subFields.size() - 1; + } + Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0); + titleRow.setHeightInPoints(30); + Cell titleCell = titleRow.createCell(0); + titleCell.setCellStyle(styles.get("title")); + titleCell.setCellValue(title); + sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), titleLastCol)); + } + } + + /** + * 创建对象的子列表名称 + */ + public void createSubHead() + { + if (isSubList()) + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + Row subRow = sheet.createRow(rownum); + int excelNum = 0; + for (Object[] objects : fields) + { + Excel attr = (Excel) objects[1]; + Cell headCell1 = subRow.createCell(excelNum); + headCell1.setCellValue(attr.name()); + headCell1.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + excelNum++; + } + int headFirstRow = excelNum - 1; + int headLastRow = headFirstRow + subFields.size() - 1; + if (headLastRow > headFirstRow) + { + sheet.addMergedRegion(new CellRangeAddress(rownum, rownum, headFirstRow, headLastRow)); + } + rownum++; + } + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(InputStream is) throws Exception + { + return importExcel(is, 0); + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @param titleNum 标题占用行数 + * @return 转换后集合 + */ + public List importExcel(InputStream is, int titleNum) throws Exception + { + return importExcel(StringUtils.EMPTY, is, titleNum); + } + + /** + * 对excel表单指定表格索引名转换成list + * + * @param sheetName 表格索引名 + * @param titleNum 标题占用行数 + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(String sheetName, InputStream is, int titleNum) throws Exception + { + this.type = Type.IMPORT; + this.wb = WorkbookFactory.create(is); + List list = new ArrayList(); + // 如果指定sheet名,则取指定sheet中的内容 否则默认指向第1个sheet + Sheet sheet = StringUtils.isNotEmpty(sheetName) ? wb.getSheet(sheetName) : wb.getSheetAt(0); + if (sheet == null) + { + throw new IOException("文件sheet不存在"); + } + boolean isXSSFWorkbook = !(wb instanceof HSSFWorkbook); + Map pictures; + if (isXSSFWorkbook) + { + pictures = getSheetPictures07((XSSFSheet) sheet, (XSSFWorkbook) wb); + } + else + { + pictures = getSheetPictures03((HSSFSheet) sheet, (HSSFWorkbook) wb); + } + // 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1 + int rows = sheet.getLastRowNum(); + + if (rows > 0) + { + // 定义一个map用于存放excel列的序号和field. + Map cellMap = new HashMap(); + // 获取表头 + Row tableHeader = sheet.getRow(titleNum); + for (int i = 0; i < tableHeader.getPhysicalNumberOfCells(); i++) + { + Cell cell = tableHeader.getCell(i); + if (StringUtils.isNotNull(cell)) + { + String value = this.getCellValue(tableHeader, i).toString(); + cellMap.put(value, i); + } + else + { + cellMap.put(null, i); + } + } + // 有数据时才处理 得到类的所有field. + List fields = this.getFields(); + Map fieldsMap = new HashMap(); + for (Object[] objects : fields) + { + Excel attr = (Excel) objects[1]; + Integer column = cellMap.get(attr.name()); + if (column != null) + { + fieldsMap.put(column, objects); + } + } + for (int i = titleNum + 1; i <= rows; i++) + { + // 从第2行开始取数据,默认第一行是表头. + Row row = sheet.getRow(i); + // 判断当前行是否是空行 + if (isRowEmpty(row) || isRowEmptyAfterRemoveSpace(row)) + { + continue; + } + T entity = null; + for (Map.Entry entry : fieldsMap.entrySet()) + { + Object val = this.getCellValue(row, entry.getKey()); + + // 如果不存在实例则新建. + entity = (entity == null ? clazz.newInstance() : entity); + // 从map中得到对应列的field. + Field field = (Field) entry.getValue()[0]; + Excel attr = (Excel) entry.getValue()[1]; + // 取得类型,并根据对象类型设置值. + Class fieldType = field.getType(); + if (String.class == fieldType) + { + String s = Convert.toStr(val); + if (StringUtils.endsWith(s, ".0")) + { + val = StringUtils.substringBefore(s, ".0"); + } + else + { + String dateFormat = field.getAnnotation(Excel.class).dateFormat(); + if (StringUtils.isNotEmpty(dateFormat)) + { + val = parseDateToStr(dateFormat, val); + } + else + { + val = Convert.toStr(val); + } + } + } + else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) + { + val = Convert.toInt(val); + } + else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) + { + val = Convert.toLong(val); + } + else if (Double.TYPE == fieldType || Double.class == fieldType) + { + val = Convert.toDouble(val); + } + else if (Float.TYPE == fieldType || Float.class == fieldType) + { + val = Convert.toFloat(val); + } + else if (BigDecimal.class == fieldType) + { + val = Convert.toBigDecimal(val); + } + else if (Date.class == fieldType) + { + if (val instanceof String) + { + val = DateUtils.parseDate(val); + } + else if (val instanceof Double) + { + val = DateUtil.getJavaDate((Double) val); + } + } + else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) + { + val = Convert.toBool(val, false); + } + if (StringUtils.isNotNull(fieldType)) + { + String propertyName = field.getName(); + if (StringUtils.isNotEmpty(attr.targetAttr())) + { + propertyName = field.getName() + "." + attr.targetAttr(); + } + else if (StringUtils.isNotEmpty(attr.readConverterExp())) + { + val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator()); + } + else if (StringUtils.isNotEmpty(attr.dictType())) + { + val = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator()); + } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + val = dataFormatHandlerAdapter(val, attr); + } + else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures)) + { + PictureData image = pictures.get(row.getRowNum() + "_" + entry.getKey()); + if (image == null) + { + val = ""; + } + else + { + byte[] data = image.getData(); + val = FileUtils.writeImportBytes(data); + } + } + ReflectUtils.invokeSetter(entity, propertyName, val); + } + } + list.add(entity); + } + } + return list; + } + + /** + * 去除前后空白后是否存在空行 + * + * @param row 行对象 + * @return 是否存在空行 + */ + private boolean isRowEmptyAfterRemoveSpace(Row row) { + for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) { + Cell cell = row.getCell(i); + if (cell != null && cell.getCellType() == CellType.STRING && StringUtils.isNotEmpty(cell.getStringCellValue())) { + return false; + } + } + return true; + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public AjaxResult exportExcel(List list, String sheetName) + { + return exportExcel(list, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public AjaxResult exportExcel(List list, String sheetName, String title) + { + this.init(list, sheetName, title, Type.EXPORT); + return exportExcel(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName) + { + exportExcel(response, list, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName, String title) + { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(list, sheetName, title, Type.EXPORT); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @return 结果 + */ + public AjaxResult importTemplateExcel(String sheetName) + { + return importTemplateExcel(sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public AjaxResult importTemplateExcel(String sheetName, String title) + { + this.init(null, sheetName, title, Type.IMPORT); + return exportExcel(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @return 结果 + */ + public void importTemplateExcel(HttpServletResponse response, String sheetName) + { + importTemplateExcel(response, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void importTemplateExcel(HttpServletResponse response, String sheetName, String title) + { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(null, sheetName, title, Type.IMPORT); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public void exportExcel(HttpServletResponse response) + { + try + { + writeSheet(); + wb.write(response.getOutputStream()); + } + catch (Exception e) + { + log.error("导出Excel异常{}", e.getMessage()); + } + finally + { + IOUtils.closeQuietly(wb); + } + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public AjaxResult exportExcel() + { + OutputStream out = null; + try + { + writeSheet(); + String filename = encodingFilename(sheetName); + out = new FileOutputStream(getAbsoluteFile(filename)); + wb.write(out); + return AjaxResult.success(filename); + } + catch (Exception e) + { + log.error("导出Excel异常{}", e.getMessage()); + throw new UtilException("导出Excel失败,请联系网站管理员!"); + } + finally + { + IOUtils.closeQuietly(wb); + IOUtils.closeQuietly(out); + } + } + + /** + * 创建写入数据到Sheet + */ + public void writeSheet() + { + // 取出一共有多少个sheet. + int sheetNo = Math.max(1, (int) Math.ceil(list.size() * 1.0 / sheetSize)); + for (int index = 0; index < sheetNo; index++) + { + createSheet(sheetNo, index); + + // 产生一行 + Row row = sheet.createRow(rownum); + int column = 0; + // 写入各个字段的列头名称 + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType())) + { + for (Field subField : subFields) + { + Excel subExcel = subField.getAnnotation(Excel.class); + this.createHeadCell(subExcel, row, column++); + } + } + else + { + this.createHeadCell(excel, row, column++); + } + } + if (Type.EXPORT.equals(type)) + { + fillExcelData(index, row); + addStatisticsRow(); + } + } + } + + /** + * 填充excel数据 + * + * @param index 序号 + * @param row 单元格行 + */ + @SuppressWarnings("unchecked") + public void fillExcelData(int index, Row row) + { + int startNo = index * sheetSize; + int endNo = Math.min(startNo + sheetSize, list.size()); + int rowNo = (1 + rownum) - startNo; + for (int i = startNo; i < endNo; i++) + { + rowNo = isSubList() ? (i > 1 ? rowNo + 1 : rowNo + i) : i + 1 + rownum - startNo; + row = sheet.createRow(rowNo); + // 得到导出对象. + T vo = (T) list.get(i); + Collection subList = null; + if (isSubList()) + { + if (isSubListValue(vo)) + { + subList = getListCellValue(vo); + subMergedLastRowNum = subMergedLastRowNum + subList.size(); + } + else + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + } + } + int column = 0; + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType()) && StringUtils.isNotNull(subList)) + { + boolean subFirst = false; + for (Object obj : subList) + { + if (subFirst) + { + rowNo++; + row = sheet.createRow(rowNo); + } + List subFields = FieldUtils.getFieldsListWithAnnotation(obj.getClass(), Excel.class); + int subIndex = 0; + for (Field subField : subFields) + { + if (subField.isAnnotationPresent(Excel.class)) + { + subField.setAccessible(true); + Excel attr = subField.getAnnotation(Excel.class); + this.addCell(attr, row, (T) obj, subField, column + subIndex); + } + subIndex++; + } + subFirst = true; + } + this.subMergedFirstRowNum = this.subMergedFirstRowNum + subList.size(); + } + else + { + this.addCell(excel, row, vo, field, column++); + } + } + } + } + + /** + * 创建表格样式 + * + * @param wb 工作薄对象 + * @return 样式列表 + */ + private Map createStyles(Workbook wb) + { + // 写入各条记录,每条记录对应excel表中的一行 + Map styles = new HashMap(); + CellStyle style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font titleFont = wb.createFont(); + titleFont.setFontName("Arial"); + titleFont.setFontHeightInPoints((short) 16); + titleFont.setBold(true); + style.setFont(titleFont); + styles.put("title", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + style.setFont(dataFont); + styles.put("data", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font totalFont = wb.createFont(); + totalFont.setFontName("Arial"); + totalFont.setFontHeightInPoints((short) 10); + style.setFont(totalFont); + styles.put("total", style); + + styles.putAll(annotationHeaderStyles(wb, styles)); + + styles.putAll(annotationDataStyles(wb)); + + return styles; + } + + /** + * 根据Excel注解创建表格头样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationHeaderStyles(Workbook wb, Map styles) + { + Map headerStyles = new HashMap(); + for (Object[] os : fields) + { + Excel excel = (Excel) os[1]; + String key = StringUtils.format("header_{}_{}", excel.headerColor(), excel.headerBackgroundColor()); + if (!headerStyles.containsKey(key)) + { + CellStyle style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setFillForegroundColor(excel.headerBackgroundColor().index); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Font headerFont = wb.createFont(); + headerFont.setFontName("Arial"); + headerFont.setFontHeightInPoints((short) 10); + headerFont.setBold(true); + headerFont.setColor(excel.headerColor().index); + style.setFont(headerFont); + headerStyles.put(key, style); + } + } + return headerStyles; + } + + /** + * 根据Excel注解创建表格列样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationDataStyles(Workbook wb) + { + Map styles = new HashMap(); + for (Object[] os : fields) + { + Excel excel = (Excel) os[1]; + String key = StringUtils.format("data_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor()); + if (!styles.containsKey(key)) + { + CellStyle style = wb.createCellStyle(); + style.setAlignment(excel.align()); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + style.setFillForegroundColor(excel.backgroundColor().getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + dataFont.setColor(excel.color().index); + style.setFont(dataFont); + styles.put(key, style); + } + } + return styles; + } + + /** + * 创建单元格 + */ + public Cell createHeadCell(Excel attr, Row row, int column) + { + // 创建列 + Cell cell = row.createCell(column); + // 写入列信息 + cell.setCellValue(attr.name()); + setDataValidation(attr, row, column); + cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + if (isSubList()) + { + // 填充默认样式,防止合并单元格样式失效 + sheet.setDefaultColumnStyle(column, styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor()))); + if (attr.needMerge()) + { + sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column)); + } + } + return cell; + } + + /** + * 设置单元格信息 + * + * @param value 单元格值 + * @param attr 注解相关 + * @param cell 单元格信息 + */ + public void setCellVo(Object value, Excel attr, Cell cell,Field field) + { + if (ColumnType.STRING == attr.cellType()) + { + String cellValue = Convert.toStr(value); + // 对于任何以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。 + if (StringUtils.startsWithAny(cellValue, FORMULA_STR)) + { + cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0"); + } + if (value instanceof Collection && StringUtils.equals("[]", cellValue)) + { + cellValue = StringUtils.EMPTY; + } + cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix()); + } + else if (ColumnType.NUMERIC == attr.cellType()) + { + if (StringUtils.isNotNull(value)) + { + try { + cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value)); + } catch (Exception e) { + cell.setCellValue(""); + } + } + } + else if (ColumnType.IMAGE == attr.cellType()) + { + ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1); + String imagePath = Convert.toStr(value); + if (StringUtils.isNotEmpty(imagePath)) + { + byte[] data = ImageUtils.getImage(imagePath); + getDrawingPatriarch(cell.getSheet()).createPicture(anchor, + cell.getSheet().getWorkbook().addPicture(data, getImageType(data))); + } + } + } + + /** + * 获取画布 + */ + public static Drawing getDrawingPatriarch(Sheet sheet) + { + if (sheet.getDrawingPatriarch() == null) + { + sheet.createDrawingPatriarch(); + } + return sheet.getDrawingPatriarch(); + } + + /** + * 获取图片类型,设置图片插入类型 + */ + public int getImageType(byte[] value) + { + String type = FileTypeUtils.getFileExtendName(value); + if ("JPG".equalsIgnoreCase(type)) + { + return Workbook.PICTURE_TYPE_JPEG; + } + else if ("PNG".equalsIgnoreCase(type)) + { + return Workbook.PICTURE_TYPE_PNG; + } + return Workbook.PICTURE_TYPE_JPEG; + } + + /** + * 创建表格样式 + */ + public void setDataValidation(Excel attr, Row row, int column) + { + if (attr.name().indexOf("注:") >= 0) + { + sheet.setColumnWidth(column, 6000); + } + else + { + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); + } + if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0) + { + if (attr.combo().length > 15 || StringUtils.join(attr.combo()).length() > 255) + { + // 如果下拉数大于15或字符串长度大于255,则使用一个新sheet存储,避免生成的模板下拉值获取不到 + setXSSFValidationWithHidden(sheet, attr.combo(), attr.prompt(), 1, 100, column, column); + } + else + { + // 提示信息或只能选择不能输入的列内容. + setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column); + } + } + } + + /** + * 添加单元格 + */ + public Cell addCell(Excel attr, Row row, T vo, Field field, int column) + { + Cell cell = null; + try + { + // 设置行高 + row.setHeight(maxHeight); + // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. + if (attr.isExport()) + { + // 创建cell + cell = row.createCell(column); + if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge()) + { + CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column); + sheet.addMergedRegion(cellAddress); + } + cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor()))); + + // 用于读取对象中的属性 + Object value = getTargetValue(vo, field, attr); + String dateFormat = attr.dateFormat(); + String readConverterExp = attr.readConverterExp(); + String separator = attr.separator(); + String dictType = attr.dictType(); + if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) + { + cell.setCellValue(parseDateToStr(dateFormat, value)); + } + else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) + { + cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator)); + } + else if (StringUtils.isNotEmpty(dictType) && StringUtils.isNotNull(value)) + { + cell.setCellValue(convertDictByExp(Convert.toStr(value), dictType, separator)); + } + else if (value instanceof BigDecimal && -1 != attr.scale()) + { + cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue()); + } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + cell.setCellValue(dataFormatHandlerAdapter(value, attr)); + } + else + { + // 设置列类型 + setCellVo(value, attr, cell,field); + } + addStatisticsData(column, Convert.toStr(value), attr); + } + } + catch (Exception e) + { + log.error(field.getName()); + log.error("导出Excel失败{}", e); + } + return cell; + } + + /** + * 设置 POI XSSFSheet 单元格提示或选择框 + * + * @param sheet 表单 + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setPromptOrValidation(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, + int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + DataValidationConstraint constraint = textlist.length > 0 ? helper.createExplicitListConstraint(textlist) : helper.createCustomConstraint("DD1"); + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) + { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + sheet.addValidationData(dataValidation); + } + + /** + * 设置某些列的值只能输入预制的数据,显示下拉框(兼容超出一定数量的下拉框). + * + * @param sheet 要设置的sheet. + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol) + { + String hideSheetName = "combo_" + firstCol + "_" + endCol; + Sheet hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据 + for (int i = 0; i < textlist.length; i++) + { + hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]); + } + // 创建名称,可被其他单元格引用 + Name name = wb.createName(); + name.setNameName(hideSheetName + "_data"); + name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length); + DataValidationHelper helper = sheet.getDataValidationHelper(); + // 加载下拉列表内容 + DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetName + "_data"); + // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + // 数据有效性对象 + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) + { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + + sheet.addValidationData(dataValidation); + // 设置hiddenSheet隐藏 + wb.setSheetHidden(wb.getSheetIndex(hideSheet), true); + } + + /** + * 解析导出值 0=男,1=女,2=未知 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String convertByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[0].equals(value)) + { + propertyString.append(itemArray[1] + separator); + break; + } + } + } + else + { + if (itemArray[0].equals(propertyValue)) + { + return itemArray[1]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 反向解析值 男=0,女=1,未知=2 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String reverseByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[1].equals(value)) + { + propertyString.append(itemArray[0] + separator); + break; + } + } + } + else + { + if (itemArray[1].equals(propertyValue)) + { + return itemArray[0]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 解析字典值 + * + * @param dictValue 字典值 + * @param dictType 字典类型 + * @param separator 分隔符 + * @return 字典标签 + */ + public static String convertDictByExp(String dictValue, String dictType, String separator) + { + return DictUtils.getDictLabel(dictType, dictValue, separator); + } + + /** + * 反向解析值字典值 + * + * @param dictLabel 字典标签 + * @param dictType 字典类型 + * @param separator 分隔符 + * @return 字典值 + */ + public static String reverseDictByExp(String dictLabel, String dictType, String separator) + { + return DictUtils.getDictValue(dictType, dictLabel, separator); + } + + /** + * 数据处理器 + * + * @param value 数据值 + * @param excel 数据注解 + * @return + */ + public String dataFormatHandlerAdapter(Object value, Excel excel) + { + try + { + Object instance = excel.handler().newInstance(); + Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class }); + value = formatMethod.invoke(instance, value, excel.args()); + } + catch (Exception e) + { + log.error("不能格式化数据 " + excel.handler(), e.getMessage()); + } + return Convert.toStr(value); + } + + /** + * 合计统计信息 + */ + private void addStatisticsData(Integer index, String text, Excel entity) + { + if (entity != null && entity.isStatistics()) + { + Double temp = 0D; + if (!statistics.containsKey(index)) + { + statistics.put(index, temp); + } + try + { + temp = Double.valueOf(text); + } + catch (NumberFormatException e) + { + } + statistics.put(index, statistics.get(index) + temp); + } + } + + /** + * 创建统计行 + */ + public void addStatisticsRow() + { + if (statistics.size() > 0) + { + Row row = sheet.createRow(sheet.getLastRowNum() + 1); + Set keys = statistics.keySet(); + Cell cell = row.createCell(0); + cell.setCellStyle(styles.get("total")); + cell.setCellValue("合计"); + + for (Integer key : keys) + { + cell = row.createCell(key); + cell.setCellStyle(styles.get("total")); + cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key))); + } + statistics.clear(); + } + } + + /** + * 编码文件名 + */ + public String encodingFilename(String filename) + { + filename = UUID.randomUUID().toString() + "_" + filename + ".xlsx"; + return filename; + } + + /** + * 获取下载路径 + * + * @param filename 文件名称 + */ + public String getAbsoluteFile(String filename) + { + String downloadPath = RuoYiConfig.getDownloadPath() + filename; + File desc = new File(downloadPath); + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + return downloadPath; + } + + /** + * 获取bean中的属性值 + * + * @param vo 实体对象 + * @param field 字段 + * @param excel 注解 + * @return 最终的属性值 + * @throws Exception + */ + private Object getTargetValue(T vo, Field field, Excel excel) throws Exception + { + Object o = field.get(vo); + if (StringUtils.isNotEmpty(excel.targetAttr())) + { + String target = excel.targetAttr(); + if (target.contains(".")) + { + String[] targets = target.split("[.]"); + for (String name : targets) + { + o = getValue(o, name); + } + } + else + { + o = getValue(o, target); + } + } + return o; + } + + /** + * 以类的属性的get方法方法形式获取值 + * + * @param o + * @param name + * @return value + * @throws Exception + */ + private Object getValue(Object o, String name) throws Exception + { + if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name)) + { + Class clazz = o.getClass(); + Field field = clazz.getDeclaredField(name); + field.setAccessible(true); + o = field.get(o); + } + return o; + } + + /** + * 得到所有定义字段 + */ + private void createExcelField() + { + this.fields = getFields(); + this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList()); + this.maxHeight = getRowHeight(); + } + + /** + * 获取字段注解信息 + */ + public List getFields() + { + List fields = new ArrayList(); + List tempFields = new ArrayList<>(); + tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); + tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); + for (Field field : tempFields) + { + if (!ArrayUtils.contains(this.excludeFields, field.getName())) + { + // 单注解 + if (field.isAnnotationPresent(Excel.class)) + { + Excel attr = field.getAnnotation(Excel.class); + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } + if (Collection.class.isAssignableFrom(field.getType())) + { + subMethod = getSubMethod(field.getName(), clazz); + ParameterizedType pt = (ParameterizedType) field.getGenericType(); + Class subClass = (Class) pt.getActualTypeArguments()[0]; + this.subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class); + } + } + + // 多注解 + if (field.isAnnotationPresent(Excels.class)) + { + Excels attrs = field.getAnnotation(Excels.class); + Excel[] excels = attrs.value(); + for (Excel attr : excels) + { + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } + } + } + } + } + return fields; + } + + /** + * 根据注解获取最大行高 + */ + public short getRowHeight() + { + double maxHeight = 0; + for (Object[] os : this.fields) + { + Excel excel = (Excel) os[1]; + maxHeight = Math.max(maxHeight, excel.height()); + } + return (short) (maxHeight * 20); + } + + /** + * 创建一个工作簿 + */ + public void createWorkbook() + { + this.wb = new SXSSFWorkbook(500); + this.sheet = wb.createSheet(); + wb.setSheetName(0, sheetName); + this.styles = createStyles(wb); + } + + /** + * 创建工作表 + * + * @param sheetNo sheet数量 + * @param index 序号 + */ + public void createSheet(int sheetNo, int index) + { + // 设置工作表的名称. + if (sheetNo > 1 && index > 0) + { + this.sheet = wb.createSheet(); + this.createTitle(); + wb.setSheetName(index, sheetName + index); + } + } + + /** + * 获取单元格值 + * + * @param row 获取的行 + * @param column 获取单元格列号 + * @return 单元格值 + */ + public Object getCellValue(Row row, int column) + { + if (row == null) + { + return row; + } + Object val = ""; + try + { + Cell cell = row.getCell(column); + if (StringUtils.isNotNull(cell)) + { + if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA) + { + val = cell.getNumericCellValue(); + if (DateUtil.isCellDateFormatted(cell)) + { + val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换 + } + else + { + if ((Double) val % 1 != 0) + { + val = new BigDecimal(val.toString()); + } + else + { + val = new DecimalFormat("0").format(val); + } + } + } + else if (cell.getCellType() == CellType.STRING) + { + val = cell.getStringCellValue(); + } + else if (cell.getCellType() == CellType.BOOLEAN) + { + val = cell.getBooleanCellValue(); + } + else if (cell.getCellType() == CellType.ERROR) + { + val = cell.getErrorCellValue(); + } + + } + } + catch (Exception e) + { + return val; + } + return val; + } + + /** + * 判断是否是空行 + * + * @param row 判断的行 + * @return + */ + private boolean isRowEmpty(Row row) + { + if (row == null) + { + return true; + } + for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) + { + Cell cell = row.getCell(i); + if (cell != null && cell.getCellType() != CellType.BLANK) + { + return false; + } + } + return true; + } + + /** + * 获取Excel2003图片 + * + * @param sheet 当前sheet对象 + * @param workbook 工作簿对象 + * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData + */ + public static Map getSheetPictures03(HSSFSheet sheet, HSSFWorkbook workbook) + { + Map sheetIndexPicMap = new HashMap(); + List pictures = workbook.getAllPictures(); + if (!pictures.isEmpty()) + { + for (HSSFShape shape : sheet.getDrawingPatriarch().getChildren()) + { + HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor(); + if (shape instanceof HSSFPicture) + { + HSSFPicture pic = (HSSFPicture) shape; + int pictureIndex = pic.getPictureIndex() - 1; + HSSFPictureData picData = pictures.get(pictureIndex); + String picIndex = String.valueOf(anchor.getRow1()) + "_" + String.valueOf(anchor.getCol1()); + sheetIndexPicMap.put(picIndex, picData); + } + } + return sheetIndexPicMap; + } + else + { + return sheetIndexPicMap; + } + } + + /** + * 获取Excel2007图片 + * + * @param sheet 当前sheet对象 + * @param workbook 工作簿对象 + * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData + */ + public static Map getSheetPictures07(XSSFSheet sheet, XSSFWorkbook workbook) + { + Map sheetIndexPicMap = new HashMap(); + for (POIXMLDocumentPart dr : sheet.getRelations()) + { + if (dr instanceof XSSFDrawing) + { + XSSFDrawing drawing = (XSSFDrawing) dr; + List shapes = drawing.getShapes(); + for (XSSFShape shape : shapes) + { + if (shape instanceof XSSFPicture) + { + XSSFPicture pic = (XSSFPicture) shape; + XSSFClientAnchor anchor = pic.getPreferredSize(); + CTMarker ctMarker = anchor.getFrom(); + String picIndex = ctMarker.getRow() + "_" + ctMarker.getCol(); + sheetIndexPicMap.put(picIndex, pic.getPictureData()); + } + } + } + } + return sheetIndexPicMap; + } + + /** + * 格式化不同类型的日期对象 + * + * @param dateFormat 日期格式 + * @param val 被格式化的日期对象 + * @return 格式化后的日期字符 + */ + public String parseDateToStr(String dateFormat, Object val) + { + if (val == null) + { + return ""; + } + String str; + if (val instanceof Date) + { + str = DateUtils.parseDateToStr(dateFormat, (Date) val); + } + else if (val instanceof LocalDateTime) + { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDateTime) val)); + } + else if (val instanceof LocalDate) + { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDate) val)); + } + else + { + str = val.toString(); + } + return str; + } + + /** + * 是否有对象的子列表 + */ + public boolean isSubList() + { + return StringUtils.isNotNull(subFields) && subFields.size() > 0; + } + + /** + * 是否有对象的子列表,集合不为空 + */ + public boolean isSubListValue(T vo) + { + return StringUtils.isNotNull(subFields) && subFields.size() > 0 && StringUtils.isNotNull(getListCellValue(vo)) && getListCellValue(vo).size() > 0; + } + + /** + * 获取集合的值 + */ + public Collection getListCellValue(Object obj) + { + Object value; + try + { + value = subMethod.invoke(obj, new Object[] {}); + } + catch (Exception e) + { + return new ArrayList(); + } + return (Collection) value; + } + + /** + * 获取对象的子列表方法 + * + * @param name 名称 + * @param pojoClass 类对象 + * @return 子列表方法 + */ + public Method getSubMethod(String name, Class pojoClass) + { + StringBuffer getMethodName = new StringBuffer("get"); + getMethodName.append(name.substring(0, 1).toUpperCase()); + getMethodName.append(name.substring(1)); + Method method = null; + try { + method = pojoClass.getMethod(getMethodName.toString(), new Class[]{}); + } catch (Exception e) { + log.error("获取对象异常{}", e.getMessage()); + } + return method; + } + + public void setExcelAnnotationValue(String annotatedColumnName, String annotationFieldName, String newAnnotationFieldValue,Class myClass) { + try { + Field classDeclaredField = myClass.getDeclaredField(annotatedColumnName); + Excel excel = classDeclaredField.getAnnotation(Excel.class); + InvocationHandler excelInvocationHandler = Proxy.getInvocationHandler(excel); + Field excelInvocationHandlerField = excelInvocationHandler.getClass().getDeclaredField("memberValues"); + excelInvocationHandlerField.setAccessible(true); + Map map = (Map) excelInvocationHandlerField.get(excelInvocationHandler); + map.put(annotationFieldName, newAnnotationFieldValue); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/LocalDateExcelHandlerAdapter.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/LocalDateExcelHandlerAdapter.java new file mode 100644 index 0000000..10b0839 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/LocalDateExcelHandlerAdapter.java @@ -0,0 +1,13 @@ +package com.ruoyi.common.utils.poi; + +import java.time.LocalDate; + +public class LocalDateExcelHandlerAdapter implements ExcelHandlerAdapter { + @Override + public LocalDate format(Object value, String[] args) { + String s = value.toString(); + LocalDate parse = LocalDate.parse(s); + + return parse; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/LocalDateTimeExcelHandlerAdapter.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/LocalDateTimeExcelHandlerAdapter.java new file mode 100644 index 0000000..998f794 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/LocalDateTimeExcelHandlerAdapter.java @@ -0,0 +1,14 @@ +package com.ruoyi.common.utils.poi; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +public class LocalDateTimeExcelHandlerAdapter implements ExcelHandlerAdapter { + @Override + public LocalDateTime format(Object value, String[] args) { + String s = value.toString(); + LocalDateTime parse = LocalDateTime.parse(s); + + return parse; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/WordUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/WordUtil.java new file mode 100644 index 0000000..cb2cd5b --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/WordUtil.java @@ -0,0 +1,47 @@ +package com.ruoyi.common.utils.poi; + +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateException; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +import static freemarker.template.Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS; + + +public class WordUtil { + private final Configuration configuration; + + public WordUtil() { + configuration = new Configuration(DEFAULT_INCOMPATIBLE_IMPROVEMENTS); + configuration.setDefaultEncoding("UTF-8"); + } + + public boolean createWord(Map dataMap, String templateName, String fileName) { + // 模板文件所在路径 + configuration.setClassForTemplateLoading(this.getClass(), "/templates"); + Template t = null; + try { + // 获取模板文件 + t = configuration.getTemplate(templateName, "UTF-8"); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + // 导出文件 + File outFile = new File(fileName); + try (Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), StandardCharsets.UTF_8))) { + if (t != null) { + // 将填充数据填入模板文件并输出到目标文件 + t.process(dataMap, out); + } + } catch (IOException | TemplateException e1) { + e1.printStackTrace(); + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java new file mode 100644 index 0000000..7c5daa3 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java @@ -0,0 +1,489 @@ +package com.ruoyi.common.utils.reflect; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.StrUtil; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.apache.poi.ss.formula.functions.T; +import org.apache.poi.ss.usermodel.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.utils.DateUtils; + +/** + * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数. + * + * @author ruoyi + */ +@SuppressWarnings("rawtypes") +public class ReflectUtils +{ + private static final String SETTER_PREFIX = "set"; + + private static final String GETTER_PREFIX = "get"; + + private static final String CGLIB_CLASS_SEPARATOR = "$$"; + + private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class); + + /** + * 调用Getter方法. + * 支持多级,如:对象名.对象名.方法 + */ + @SuppressWarnings("unchecked") + public static E invokeGetter(Object obj, String propertyName) + { + Object object = obj; + for (String name : StringUtils.split(propertyName, ".")) + { + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + return (E) object; + } + + /** + * 调用Setter方法, 仅匹配方法名。 + * 支持多级,如:对象名.对象名.方法 + */ + public static void invokeSetter(Object obj, String propertyName, E value) + { + Object object = obj; + String[] names = StringUtils.split(propertyName, "."); + for (int i = 0; i < names.length; i++) + { + if (i < names.length - 1) + { + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + else + { + String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]); + invokeMethodByName(object, setterMethodName, new Object[] { value }); + } + } + } + + /** + * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数. + */ + @SuppressWarnings("unchecked") + public static E getFieldValue(final Object obj, final String fieldName) + { + Field field = getAccessibleField(obj, fieldName); + if (field == null) + { + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + return null; + } + E result = null; + try + { + result = (E) field.get(obj); + } + catch (IllegalAccessException e) + { + logger.error("不可能抛出的异常{}", e.getMessage()); + } + return result; + } + + /** + * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数. + */ + public static void setFieldValue(final Object obj, final String fieldName, final E value) + { + Field field = getAccessibleField(obj, fieldName); + if (field == null) + { + // throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + return; + } + try + { + field.set(obj, value); + } + catch (IllegalAccessException e) + { + logger.error("不可能抛出的异常: {}", e.getMessage()); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符. + * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用. + * 同时匹配方法名+参数类型, + */ + @SuppressWarnings("unchecked") + public static E invokeMethod(final Object obj, final String methodName, final Class[] parameterTypes, + final Object[] args) + { + if (obj == null || methodName == null) + { + return null; + } + Method method = getAccessibleMethod(obj, methodName, parameterTypes); + if (method == null) + { + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 "); + return null; + } + try + { + return (E) method.invoke(obj, args); + } + catch (Exception e) + { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符, + * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用. + * 只匹配函数名,如果有多个同名函数调用第一个。 + */ + @SuppressWarnings("unchecked") + public static E invokeMethodByName(final Object obj, final String methodName, final Object[] args) + { + Method method = getAccessibleMethodByName(obj, methodName, args.length); + if (method == null) + { + // 如果为空不报错,直接返回空。 + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 "); + return null; + } + try + { + // 类型转换(将参数数据类型转换为目标方法参数类型) + Class[] cs = method.getParameterTypes(); + for (int i = 0; i < cs.length; i++) + { + if (args[i] != null && !args[i].getClass().equals(cs[i])) + { + if (cs[i] == String.class) + { + args[i] = Convert.toStr(args[i]); + if (StringUtils.endsWith((String) args[i], ".0")) + { + args[i] = StringUtils.substringBefore((String) args[i], ".0"); + } + } + else if (cs[i] == Integer.class) + { + args[i] = Convert.toInt(args[i]); + } + else if (cs[i] == Long.class) + { + args[i] = Convert.toLong(args[i]); + } + else if (cs[i] == Double.class) + { + args[i] = Convert.toDouble(args[i]); + } + else if (cs[i] == Float.class) + { + args[i] = Convert.toFloat(args[i]); + } + else if (cs[i] == Date.class) + { + if (args[i] instanceof String) + { + args[i] = DateUtils.parseDate(args[i]); + } + else + { + args[i] = DateUtil.getJavaDate((Double) args[i]); + } + } + else if (cs[i] == LocalDate.class) + { + if (args[i] instanceof String) + { + if(StrUtil.isBlank(args[i].toString())){ + args[i]=null; + }else { + SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US); + SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + try { + String str = sdf1.format(sdf.parse(args[i].toString())); + args[i] = LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + } catch (ParseException e) { + try { + args[i] = LocalDate.parse(args[i].toString(), DateTimeFormatter.ofPattern("yyyy-MM-dd")); + } catch (Exception ex) { + args[i]=null; + } + } + } + } + } + else if (cs[i] == LocalDateTime.class) + { + if (args[i] instanceof String) + { + if(StrUtil.isBlank(args[i].toString())){ + args[i]=null; + }else { + SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US); + SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + try { + String str = sdf1.format(sdf.parse(args[i].toString())); + args[i] = LocalDateTime.parse(str, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + } catch (ParseException e) { + try { + args[i] = LocalDateTime.parse(args[i].toString(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + } catch (Exception ex) { + args[i]=null; + } + } + } + } + else + { + if(StrUtil.isBlank(args[i].toString())){ + args[i]=null; + }else { + args[i] = LocalDateTimeUtil.of(Long.parseLong(args[i].toString())); + } + } + } + else if (cs[i] == boolean.class || cs[i] == Boolean.class) + { + args[i] = Convert.toBool(args[i]); + } + } + } + return (E) method.invoke(obj, args); + } + catch (Exception e) + { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + */ + public static Field getAccessibleField(final Object obj, final String fieldName) + { + // 为空不报错。直接返回 null + if (obj == null) + { + return null; + } + Validate.notBlank(fieldName, "fieldName can't be blank"); + for (Class superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) + { + try + { + Field field = superClass.getDeclaredField(fieldName); + makeAccessible(field); + return field; + } + catch (NoSuchFieldException e) + { + continue; + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 匹配函数名+参数类型。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethod(final Object obj, final String methodName, + final Class... parameterTypes) + { + // 为空不报错。直接返回 null + if (obj == null) + { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) + { + try + { + Method method = searchType.getDeclaredMethod(methodName, parameterTypes); + makeAccessible(method); + return method; + } + catch (NoSuchMethodException e) + { + continue; + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 只匹配函数名。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum) + { + // 为空不报错。直接返回 null + if (obj == null) + { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) + { + Method[] methods = searchType.getDeclaredMethods(); + for (Method method : methods) + { + if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum) + { + makeAccessible(method); + return method; + } + } + } + return null; + } + + /** + * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Method method) + { + if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) + && !method.isAccessible()) + { + method.setAccessible(true); + } + } + + /** + * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Field field) + { + if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) + || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) + { + field.setAccessible(true); + } + } + + /** + * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处 + * 如无法找到, 返回Object.class. + */ + @SuppressWarnings("unchecked") + public static Class getClassGenricType(final Class clazz) + { + return getClassGenricType(clazz, 0); + } + + /** + * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. + * 如无法找到, 返回Object.class. + */ + public static Class getClassGenricType(final Class clazz, final int index) + { + Type genType = clazz.getGenericSuperclass(); + + if (!(genType instanceof ParameterizedType)) + { + logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType"); + return Object.class; + } + + Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); + + if (index >= params.length || index < 0) + { + logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + + params.length); + return Object.class; + } + if (!(params[index] instanceof Class)) + { + logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); + return Object.class; + } + + return (Class) params[index]; + } + + public static Class getUserClass(Object instance) + { + if (instance == null) + { + throw new RuntimeException("Instance must not be null"); + } + Class clazz = instance.getClass(); + if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) + { + Class superClass = clazz.getSuperclass(); + if (superClass != null && !Object.class.equals(superClass)) + { + return superClass; + } + } + return clazz; + + } + + + + public static List toList(Object obj, Class cla) { + List list = new ArrayList(); + //判断参数是否为List类型 + if (obj instanceof List) { + for (Object o : (List) obj) { + //将父类对象强制转换为子类对象 + list.add(cla.cast(o)); + } + return list; + } + return null; + } + + /** + * 将反射时的checked exception转换为unchecked exception. + */ + public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e) + { + if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException + || e instanceof NoSuchMethodException) + { + return new IllegalArgumentException(msg, e); + } + else if (e instanceof InvocationTargetException) + { + return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException()); + } + return new RuntimeException(msg, e); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/sign/Base64.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/sign/Base64.java new file mode 100644 index 0000000..ca1cd92 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/sign/Base64.java @@ -0,0 +1,291 @@ +package com.ruoyi.common.utils.sign; + +/** + * Base64工具类 + * + * @author ruoyi + */ +public final class Base64 +{ + static private final int BASELENGTH = 128; + static private final int LOOKUPLENGTH = 64; + static private final int TWENTYFOURBITGROUP = 24; + static private final int EIGHTBIT = 8; + static private final int SIXTEENBIT = 16; + static private final int FOURBYTE = 4; + static private final int SIGN = -128; + static private final char PAD = '='; + static final private byte[] base64Alphabet = new byte[BASELENGTH]; + static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH]; + + static + { + for (int i = 0; i < BASELENGTH; ++i) + { + base64Alphabet[i] = -1; + } + for (int i = 'Z'; i >= 'A'; i--) + { + base64Alphabet[i] = (byte) (i - 'A'); + } + for (int i = 'z'; i >= 'a'; i--) + { + base64Alphabet[i] = (byte) (i - 'a' + 26); + } + + for (int i = '9'; i >= '0'; i--) + { + base64Alphabet[i] = (byte) (i - '0' + 52); + } + + base64Alphabet['+'] = 62; + base64Alphabet['/'] = 63; + + for (int i = 0; i <= 25; i++) + { + lookUpBase64Alphabet[i] = (char) ('A' + i); + } + + for (int i = 26, j = 0; i <= 51; i++, j++) + { + lookUpBase64Alphabet[i] = (char) ('a' + j); + } + + for (int i = 52, j = 0; i <= 61; i++, j++) + { + lookUpBase64Alphabet[i] = (char) ('0' + j); + } + lookUpBase64Alphabet[62] = (char) '+'; + lookUpBase64Alphabet[63] = (char) '/'; + } + + private static boolean isWhiteSpace(char octect) + { + return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); + } + + private static boolean isPad(char octect) + { + return (octect == PAD); + } + + private static boolean isData(char octect) + { + return (octect < BASELENGTH && base64Alphabet[octect] != -1); + } + + /** + * Encodes hex octects into Base64 + * + * @param binaryData Array containing binaryData + * @return Encoded Base64 array + */ + public static String encode(byte[] binaryData) + { + if (binaryData == null) + { + return null; + } + + int lengthDataBits = binaryData.length * EIGHTBIT; + if (lengthDataBits == 0) + { + return ""; + } + + int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP; + int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; + int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets; + char encodedData[] = null; + + encodedData = new char[numberQuartet * 4]; + + byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0; + + int encodedIndex = 0; + int dataIndex = 0; + + for (int i = 0; i < numberTriplets; i++) + { + b1 = binaryData[dataIndex++]; + b2 = binaryData[dataIndex++]; + b3 = binaryData[dataIndex++]; + + l = (byte) (b2 & 0x0f); + k = (byte) (b1 & 0x03); + + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); + byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); + byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc); + + encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f]; + } + + // form integral number of 6-bit groups + if (fewerThan24bits == EIGHTBIT) + { + b1 = binaryData[dataIndex]; + k = (byte) (b1 & 0x03); + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); + encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4]; + encodedData[encodedIndex++] = PAD; + encodedData[encodedIndex++] = PAD; + } + else if (fewerThan24bits == SIXTEENBIT) + { + b1 = binaryData[dataIndex]; + b2 = binaryData[dataIndex + 1]; + l = (byte) (b2 & 0x0f); + k = (byte) (b1 & 0x03); + + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); + byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); + + encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2]; + encodedData[encodedIndex++] = PAD; + } + return new String(encodedData); + } + + /** + * Decodes Base64 data into octects + * + * @param encoded string containing Base64 data + * @return Array containind decoded data. + */ + public static byte[] decode(String encoded) + { + if (encoded == null) + { + return null; + } + + char[] base64Data = encoded.toCharArray(); + // remove white spaces + int len = removeWhiteSpace(base64Data); + + if (len % FOURBYTE != 0) + { + return null;// should be divisible by four + } + + int numberQuadruple = (len / FOURBYTE); + + if (numberQuadruple == 0) + { + return new byte[0]; + } + + byte decodedData[] = null; + byte b1 = 0, b2 = 0, b3 = 0, b4 = 0; + char d1 = 0, d2 = 0, d3 = 0, d4 = 0; + + int i = 0; + int encodedIndex = 0; + int dataIndex = 0; + decodedData = new byte[(numberQuadruple) * 3]; + + for (; i < numberQuadruple - 1; i++) + { + + if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++])) + || !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++]))) + { + return null; + } // if found "no data" just return null + + b1 = base64Alphabet[d1]; + b2 = base64Alphabet[d2]; + b3 = base64Alphabet[d3]; + b4 = base64Alphabet[d4]; + + decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); + decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); + decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); + } + + if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) + { + return null;// if found "no data" just return null + } + + b1 = base64Alphabet[d1]; + b2 = base64Alphabet[d2]; + + d3 = base64Data[dataIndex++]; + d4 = base64Data[dataIndex++]; + if (!isData((d3)) || !isData((d4))) + {// Check if they are PAD characters + if (isPad(d3) && isPad(d4)) + { + if ((b2 & 0xf) != 0)// last 4 bits should be zero + { + return null; + } + byte[] tmp = new byte[i * 3 + 1]; + System.arraycopy(decodedData, 0, tmp, 0, i * 3); + tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); + return tmp; + } + else if (!isPad(d3) && isPad(d4)) + { + b3 = base64Alphabet[d3]; + if ((b3 & 0x3) != 0)// last 2 bits should be zero + { + return null; + } + byte[] tmp = new byte[i * 3 + 2]; + System.arraycopy(decodedData, 0, tmp, 0, i * 3); + tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); + tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); + return tmp; + } + else + { + return null; + } + } + else + { // No PAD e.g 3cQl + b3 = base64Alphabet[d3]; + b4 = base64Alphabet[d4]; + decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); + decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); + decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); + + } + return decodedData; + } + + /** + * remove WhiteSpace from MIME containing encoded Base64 data. + * + * @param data the byte array of base64 data (with WS) + * @return the new length + */ + private static int removeWhiteSpace(char[] data) + { + if (data == null) + { + return 0; + } + + // count characters that's not whitespace + int newSize = 0; + int len = data.length; + for (int i = 0; i < len; i++) + { + if (!isWhiteSpace(data[i])) + { + data[newSize++] = data[i]; + } + } + return newSize; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/sign/Md5Utils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/sign/Md5Utils.java new file mode 100644 index 0000000..c1c58db --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/sign/Md5Utils.java @@ -0,0 +1,67 @@ +package com.ruoyi.common.utils.sign; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Md5加密方法 + * + * @author ruoyi + */ +public class Md5Utils +{ + private static final Logger log = LoggerFactory.getLogger(Md5Utils.class); + + private static byte[] md5(String s) + { + MessageDigest algorithm; + try + { + algorithm = MessageDigest.getInstance("MD5"); + algorithm.reset(); + algorithm.update(s.getBytes("UTF-8")); + byte[] messageDigest = algorithm.digest(); + return messageDigest; + } + catch (Exception e) + { + log.error("MD5 Error...", e); + } + return null; + } + + private static final String toHex(byte hash[]) + { + if (hash == null) + { + return null; + } + StringBuffer buf = new StringBuffer(hash.length * 2); + int i; + + for (i = 0; i < hash.length; i++) + { + if ((hash[i] & 0xff) < 0x10) + { + buf.append("0"); + } + buf.append(Long.toString(hash[i] & 0xff, 16)); + } + return buf.toString(); + } + + public static String hash(String s) + { + try + { + return new String(toHex(md5(s)).getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8); + } + catch (Exception e) + { + log.error("not supported charset...{}", e); + return s; + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java new file mode 100644 index 0000000..f290ec3 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java @@ -0,0 +1,158 @@ +package com.ruoyi.common.utils.spring; + +import org.springframework.aop.framework.AopContext; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; +import com.ruoyi.common.utils.StringUtils; + +/** + * spring工具类 方便在非spring管理环境中获取bean + * + * @author ruoyi + */ +@Component +public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware +{ + /** Spring应用上下文环境 */ + private static ConfigurableListableBeanFactory beanFactory; + + private static ApplicationContext applicationContext; + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException + { + SpringUtils.beanFactory = beanFactory; + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException + { + SpringUtils.applicationContext = applicationContext; + } + + /** + * 获取对象 + * + * @param name + * @return Object 一个以所给名字注册的bean的实例 + * @throws org.springframework.beans.BeansException + * + */ + @SuppressWarnings("unchecked") + public static T getBean(String name) throws BeansException + { + return (T) beanFactory.getBean(name); + } + + /** + * 获取类型为requiredType的对象 + * + * @param clz + * @return + * @throws org.springframework.beans.BeansException + * + */ + public static T getBean(Class clz) throws BeansException + { + T result = (T) beanFactory.getBean(clz); + return result; + } + + /** + * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true + * + * @param name + * @return boolean + */ + public static boolean containsBean(String name) + { + return beanFactory.containsBean(name); + } + + /** + * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException) + * + * @param name + * @return boolean + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.isSingleton(name); + } + + /** + * @param name + * @return Class 注册对象的类型 + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static Class getType(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.getType(name); + } + + /** + * 如果给定的bean名字在bean定义中有别名,则返回这些别名 + * + * @param name + * @return + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static String[] getAliases(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.getAliases(name); + } + + /** + * 获取aop代理对象 + * + * @param invoker + * @return + */ + @SuppressWarnings("unchecked") + public static T getAopProxy(T invoker) + { + return (T) AopContext.currentProxy(); + } + + /** + * 获取当前的环境配置,无配置返回null + * + * @return 当前的环境配置 + */ + public static String[] getActiveProfiles() + { + return applicationContext.getEnvironment().getActiveProfiles(); + } + + /** + * 获取当前的环境配置,当有多个环境配置时,只获取第一个 + * + * @return 当前的环境配置 + */ + public static String getActiveProfile() + { + final String[] activeProfiles = getActiveProfiles(); + return StringUtils.isNotEmpty(activeProfiles) ? activeProfiles[0] : null; + } + + /** + * 获取配置文件中的值 + * + * @param key 配置文件的key + * @return 当前的配置文件的值 + * + */ + public static String getRequiredProperty(String key) + { + return applicationContext.getEnvironment().getRequiredProperty(key); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java new file mode 100644 index 0000000..246a9cf --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java @@ -0,0 +1,61 @@ +package com.ruoyi.common.utils.sql; + +import com.ruoyi.common.exception.UtilException; +import com.ruoyi.common.utils.StringUtils; + +/** + * sql操作工具类 + * + * @author ruoyi + */ +public class SqlUtil +{ + /** + * 定义常用的 sql关键字 + */ + public static String SQL_REGEX = "select |insert |delete |update |drop |count |exec |chr |mid |master |truncate |char |and |declare "; + + /** + * 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序) + */ + public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+"; + + /** + * 检查字符,防止注入绕过 + */ + public static String escapeOrderBySql(String value) + { + if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) + { + throw new UtilException("参数不符合规范,不能进行查询"); + } + return value; + } + + /** + * 验证 order by 语法是否符合规范 + */ + public static boolean isValidOrderBySql(String value) + { + return value.matches(SQL_PATTERN); + } + + /** + * SQL关键字检查 + */ + public static void filterKeyword(String value) + { + if (StringUtils.isEmpty(value)) + { + return; + } + String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|"); + for (String sqlKeyword : sqlKeywords) + { + if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) + { + throw new UtilException("参数存在SQL注入风险"); + } + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/IdUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/IdUtils.java new file mode 100644 index 0000000..2c84427 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/IdUtils.java @@ -0,0 +1,49 @@ +package com.ruoyi.common.utils.uuid; + +/** + * ID生成器工具类 + * + * @author ruoyi + */ +public class IdUtils +{ + /** + * 获取随机UUID + * + * @return 随机UUID + */ + public static String randomUUID() + { + return UUID.randomUUID().toString(); + } + + /** + * 简化的UUID,去掉了横线 + * + * @return 简化的UUID,去掉了横线 + */ + public static String simpleUUID() + { + return UUID.randomUUID().toString(true); + } + + /** + * 获取随机UUID,使用性能更好的ThreadLocalRandom生成UUID + * + * @return 随机UUID + */ + public static String fastUUID() + { + return UUID.fastUUID().toString(); + } + + /** + * 简化的UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID + * + * @return 简化的UUID,去掉了横线 + */ + public static String fastSimpleUUID() + { + return UUID.fastUUID().toString(true); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/Seq.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/Seq.java new file mode 100644 index 0000000..528f3c1 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/Seq.java @@ -0,0 +1,86 @@ +package com.ruoyi.common.utils.uuid; + +import java.util.concurrent.atomic.AtomicInteger; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; + +/** + * @author ruoyi 序列生成类 + */ +public class Seq +{ + // 通用序列类型 + public static final String commSeqType = "COMMON"; + + // 上传序列类型 + public static final String uploadSeqType = "UPLOAD"; + + // 通用接口序列数 + private static AtomicInteger commSeq = new AtomicInteger(1); + + // 上传接口序列数 + private static AtomicInteger uploadSeq = new AtomicInteger(1); + + // 机器标识 + private static String machineCode = "A"; + + /** + * 获取通用序列号 + * + * @return 序列值 + */ + public static String getId() + { + return getId(commSeqType); + } + + /** + * 默认16位序列号 yyMMddHHmmss + 一位机器标识 + 3长度循环递增字符串 + * + * @return 序列值 + */ + public static String getId(String type) + { + AtomicInteger atomicInt = commSeq; + if (uploadSeqType.equals(type)) + { + atomicInt = uploadSeq; + } + return getId(atomicInt, 3); + } + + /** + * 通用接口序列号 yyMMddHHmmss + 一位机器标识 + length长度循环递增字符串 + * + * @param atomicInt 序列数 + * @param length 数值长度 + * @return 序列值 + */ + public static String getId(AtomicInteger atomicInt, int length) + { + String result = DateUtils.dateTimeNow(); + result += machineCode; + result += getSeq(atomicInt, length); + return result; + } + + /** + * 序列循环递增字符串[1, 10 的 (length)幂次方), 用0左补齐length位数 + * + * @return 序列值 + */ + private synchronized static String getSeq(AtomicInteger atomicInt, int length) + { + // 先取值再+1 + int value = atomicInt.getAndIncrement(); + + // 如果更新后值>=10 的 (length)幂次方则重置为1 + int maxSeq = (int) Math.pow(10, length); + if (atomicInt.get() >= maxSeq) + { + atomicInt.set(1); + } + // 转字符串,用0左补齐 + return StringUtils.padl(value, length); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/UUID.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/UUID.java new file mode 100644 index 0000000..dfda46c --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/UUID.java @@ -0,0 +1,484 @@ +package com.ruoyi.common.utils.uuid; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import com.ruoyi.common.exception.UtilException; + +/** + * 提供通用唯一识别码(universally unique identifier)(UUID)实现 + * + * @author ruoyi + */ +public final class UUID implements java.io.Serializable, Comparable +{ + private static final long serialVersionUID = -1185015143654744140L; + + /** + * SecureRandom 的单例 + * + */ + private static class Holder + { + static final SecureRandom numberGenerator = getSecureRandom(); + } + + /** 此UUID的最高64有效位 */ + private final long mostSigBits; + + /** 此UUID的最低64有效位 */ + private final long leastSigBits; + + /** + * 私有构造 + * + * @param data 数据 + */ + private UUID(byte[] data) + { + long msb = 0; + long lsb = 0; + assert data.length == 16 : "data must be 16 bytes in length"; + for (int i = 0; i < 8; i++) + { + msb = (msb << 8) | (data[i] & 0xff); + } + for (int i = 8; i < 16; i++) + { + lsb = (lsb << 8) | (data[i] & 0xff); + } + this.mostSigBits = msb; + this.leastSigBits = lsb; + } + + /** + * 使用指定的数据构造新的 UUID。 + * + * @param mostSigBits 用于 {@code UUID} 的最高有效 64 位 + * @param leastSigBits 用于 {@code UUID} 的最低有效 64 位 + */ + public UUID(long mostSigBits, long leastSigBits) + { + this.mostSigBits = mostSigBits; + this.leastSigBits = leastSigBits; + } + + /** + * 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的本地线程伪随机数生成器生成该 UUID。 + * + * @return 随机生成的 {@code UUID} + */ + public static UUID fastUUID() + { + return randomUUID(false); + } + + /** + * 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。 + * + * @return 随机生成的 {@code UUID} + */ + public static UUID randomUUID() + { + return randomUUID(true); + } + + /** + * 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。 + * + * @param isSecure 是否使用{@link SecureRandom}如果是可以获得更安全的随机码,否则可以得到更好的性能 + * @return 随机生成的 {@code UUID} + */ + public static UUID randomUUID(boolean isSecure) + { + final Random ng = isSecure ? Holder.numberGenerator : getRandom(); + + byte[] randomBytes = new byte[16]; + ng.nextBytes(randomBytes); + randomBytes[6] &= 0x0f; /* clear version */ + randomBytes[6] |= 0x40; /* set to version 4 */ + randomBytes[8] &= 0x3f; /* clear variant */ + randomBytes[8] |= 0x80; /* set to IETF variant */ + return new UUID(randomBytes); + } + + /** + * 根据指定的字节数组获取类型 3(基于名称的)UUID 的静态工厂。 + * + * @param name 用于构造 UUID 的字节数组。 + * + * @return 根据指定数组生成的 {@code UUID} + */ + public static UUID nameUUIDFromBytes(byte[] name) + { + MessageDigest md; + try + { + md = MessageDigest.getInstance("MD5"); + } + catch (NoSuchAlgorithmException nsae) + { + throw new InternalError("MD5 not supported"); + } + byte[] md5Bytes = md.digest(name); + md5Bytes[6] &= 0x0f; /* clear version */ + md5Bytes[6] |= 0x30; /* set to version 3 */ + md5Bytes[8] &= 0x3f; /* clear variant */ + md5Bytes[8] |= 0x80; /* set to IETF variant */ + return new UUID(md5Bytes); + } + + /** + * 根据 {@link #toString()} 方法中描述的字符串标准表示形式创建{@code UUID}。 + * + * @param name 指定 {@code UUID} 字符串 + * @return 具有指定值的 {@code UUID} + * @throws IllegalArgumentException 如果 name 与 {@link #toString} 中描述的字符串表示形式不符抛出此异常 + * + */ + public static UUID fromString(String name) + { + String[] components = name.split("-"); + if (components.length != 5) + { + throw new IllegalArgumentException("Invalid UUID string: " + name); + } + for (int i = 0; i < 5; i++) + { + components[i] = "0x" + components[i]; + } + + long mostSigBits = Long.decode(components[0]).longValue(); + mostSigBits <<= 16; + mostSigBits |= Long.decode(components[1]).longValue(); + mostSigBits <<= 16; + mostSigBits |= Long.decode(components[2]).longValue(); + + long leastSigBits = Long.decode(components[3]).longValue(); + leastSigBits <<= 48; + leastSigBits |= Long.decode(components[4]).longValue(); + + return new UUID(mostSigBits, leastSigBits); + } + + /** + * 返回此 UUID 的 128 位值中的最低有效 64 位。 + * + * @return 此 UUID 的 128 位值中的最低有效 64 位。 + */ + public long getLeastSignificantBits() + { + return leastSigBits; + } + + /** + * 返回此 UUID 的 128 位值中的最高有效 64 位。 + * + * @return 此 UUID 的 128 位值中最高有效 64 位。 + */ + public long getMostSignificantBits() + { + return mostSigBits; + } + + /** + * 与此 {@code UUID} 相关联的版本号. 版本号描述此 {@code UUID} 是如何生成的。 + *

+ * 版本号具有以下含意: + *

    + *
  • 1 基于时间的 UUID + *
  • 2 DCE 安全 UUID + *
  • 3 基于名称的 UUID + *
  • 4 随机生成的 UUID + *
+ * + * @return 此 {@code UUID} 的版本号 + */ + public int version() + { + // Version is bits masked by 0x000000000000F000 in MS long + return (int) ((mostSigBits >> 12) & 0x0f); + } + + /** + * 与此 {@code UUID} 相关联的变体号。变体号描述 {@code UUID} 的布局。 + *

+ * 变体号具有以下含意: + *

    + *
  • 0 为 NCS 向后兼容保留 + *
  • 2 IETF RFC 4122(Leach-Salz), 用于此类 + *
  • 6 保留,微软向后兼容 + *
  • 7 保留供以后定义使用 + *
+ * + * @return 此 {@code UUID} 相关联的变体号 + */ + public int variant() + { + // This field is composed of a varying number of bits. + // 0 - - Reserved for NCS backward compatibility + // 1 0 - The IETF aka Leach-Salz variant (used by this class) + // 1 1 0 Reserved, Microsoft backward compatibility + // 1 1 1 Reserved for future definition. + return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62))) & (leastSigBits >> 63)); + } + + /** + * 与此 UUID 相关联的时间戳值。 + * + *

+ * 60 位的时间戳值根据此 {@code UUID} 的 time_low、time_mid 和 time_hi 字段构造。
+ * 所得到的时间戳以 100 毫微秒为单位,从 UTC(通用协调时间) 1582 年 10 月 15 日零时开始。 + * + *

+ * 时间戳值仅在在基于时间的 UUID(其 version 类型为 1)中才有意义。
+ * 如果此 {@code UUID} 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。 + * + * @throws UnsupportedOperationException 如果此 {@code UUID} 不是 version 为 1 的 UUID。 + */ + public long timestamp() throws UnsupportedOperationException + { + checkTimeBase(); + return (mostSigBits & 0x0FFFL) << 48// + | ((mostSigBits >> 16) & 0x0FFFFL) << 32// + | mostSigBits >>> 32; + } + + /** + * 与此 UUID 相关联的时钟序列值。 + * + *

+ * 14 位的时钟序列值根据此 UUID 的 clock_seq 字段构造。clock_seq 字段用于保证在基于时间的 UUID 中的时间唯一性。 + *

+ * {@code clockSequence} 值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。 如果此 UUID 不是基于时间的 UUID,则此方法抛出 + * UnsupportedOperationException。 + * + * @return 此 {@code UUID} 的时钟序列 + * + * @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1 + */ + public int clockSequence() throws UnsupportedOperationException + { + checkTimeBase(); + return (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48); + } + + /** + * 与此 UUID 相关的节点值。 + * + *

+ * 48 位的节点值根据此 UUID 的 node 字段构造。此字段旨在用于保存机器的 IEEE 802 地址,该地址用于生成此 UUID 以保证空间唯一性。 + *

+ * 节点值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。
+ * 如果此 UUID 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。 + * + * @return 此 {@code UUID} 的节点值 + * + * @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1 + */ + public long node() throws UnsupportedOperationException + { + checkTimeBase(); + return leastSigBits & 0x0000FFFFFFFFFFFFL; + } + + /** + * 返回此{@code UUID} 的字符串表现形式。 + * + *

+ * UUID 的字符串表示形式由此 BNF 描述: + * + *

+     * {@code
+     * UUID                   = ----
+     * time_low               = 4*
+     * time_mid               = 2*
+     * time_high_and_version  = 2*
+     * variant_and_sequence   = 2*
+     * node                   = 6*
+     * hexOctet               = 
+     * hexDigit               = [0-9a-fA-F]
+     * }
+     * 
+ * + * + * + * @return 此{@code UUID} 的字符串表现形式 + * @see #toString(boolean) + */ + @Override + public String toString() + { + return toString(false); + } + + /** + * 返回此{@code UUID} 的字符串表现形式。 + * + *

+ * UUID 的字符串表示形式由此 BNF 描述: + * + *

+     * {@code
+     * UUID                   = ----
+     * time_low               = 4*
+     * time_mid               = 2*
+     * time_high_and_version  = 2*
+     * variant_and_sequence   = 2*
+     * node                   = 6*
+     * hexOctet               = 
+     * hexDigit               = [0-9a-fA-F]
+     * }
+     * 
+ * + * + * + * @param isSimple 是否简单模式,简单模式为不带'-'的UUID字符串 + * @return 此{@code UUID} 的字符串表现形式 + */ + public String toString(boolean isSimple) + { + final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36); + // time_low + builder.append(digits(mostSigBits >> 32, 8)); + if (!isSimple) + { + builder.append('-'); + } + // time_mid + builder.append(digits(mostSigBits >> 16, 4)); + if (!isSimple) + { + builder.append('-'); + } + // time_high_and_version + builder.append(digits(mostSigBits, 4)); + if (!isSimple) + { + builder.append('-'); + } + // variant_and_sequence + builder.append(digits(leastSigBits >> 48, 4)); + if (!isSimple) + { + builder.append('-'); + } + // node + builder.append(digits(leastSigBits, 12)); + + return builder.toString(); + } + + /** + * 返回此 UUID 的哈希码。 + * + * @return UUID 的哈希码值。 + */ + @Override + public int hashCode() + { + long hilo = mostSigBits ^ leastSigBits; + return ((int) (hilo >> 32)) ^ (int) hilo; + } + + /** + * 将此对象与指定对象比较。 + *

+ * 当且仅当参数不为 {@code null}、而是一个 UUID 对象、具有与此 UUID 相同的 varriant、包含相同的值(每一位均相同)时,结果才为 {@code true}。 + * + * @param obj 要与之比较的对象 + * + * @return 如果对象相同,则返回 {@code true};否则返回 {@code false} + */ + @Override + public boolean equals(Object obj) + { + if ((null == obj) || (obj.getClass() != UUID.class)) + { + return false; + } + UUID id = (UUID) obj; + return (mostSigBits == id.mostSigBits && leastSigBits == id.leastSigBits); + } + + // Comparison Operations + + /** + * 将此 UUID 与指定的 UUID 比较。 + * + *

+ * 如果两个 UUID 不同,且第一个 UUID 的最高有效字段大于第二个 UUID 的对应字段,则第一个 UUID 大于第二个 UUID。 + * + * @param val 与此 UUID 比较的 UUID + * + * @return 在此 UUID 小于、等于或大于 val 时,分别返回 -1、0 或 1。 + * + */ + @Override + public int compareTo(UUID val) + { + // The ordering is intentionally set up so that the UUIDs + // can simply be numerically compared as two numbers + return (this.mostSigBits < val.mostSigBits ? -1 : // + (this.mostSigBits > val.mostSigBits ? 1 : // + (this.leastSigBits < val.leastSigBits ? -1 : // + (this.leastSigBits > val.leastSigBits ? 1 : // + 0)))); + } + + // ------------------------------------------------------------------------------------------------------------------- + // Private method start + /** + * 返回指定数字对应的hex值 + * + * @param val 值 + * @param digits 位 + * @return 值 + */ + private static String digits(long val, int digits) + { + long hi = 1L << (digits * 4); + return Long.toHexString(hi | (val & (hi - 1))).substring(1); + } + + /** + * 检查是否为time-based版本UUID + */ + private void checkTimeBase() + { + if (version() != 1) + { + throw new UnsupportedOperationException("Not a time-based UUID"); + } + } + + /** + * 获取{@link SecureRandom},类提供加密的强随机数生成器 (RNG) + * + * @return {@link SecureRandom} + */ + public static SecureRandom getSecureRandom() + { + try + { + return SecureRandom.getInstance("SHA1PRNG"); + } + catch (NoSuchAlgorithmException e) + { + throw new UtilException(e); + } + } + + /** + * 获取随机数生成器对象
+ * ThreadLocalRandom是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。 + * + * @return {@link ThreadLocalRandom} + */ + public static ThreadLocalRandom getRandom() + { + return ThreadLocalRandom.current(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/xss/Xss.java b/ruoyi-common/src/main/java/com/ruoyi/common/xss/Xss.java new file mode 100644 index 0000000..7bfdf04 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/xss/Xss.java @@ -0,0 +1,27 @@ +package com.ruoyi.common.xss; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 自定义xss校验注解 + * + * @author ruoyi + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(value = { ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER }) +@Constraint(validatedBy = { XssValidator.class }) +public @interface Xss +{ + String message() + + default "不允许任何脚本运行"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssValidator.java b/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssValidator.java new file mode 100644 index 0000000..ed9ec1f --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssValidator.java @@ -0,0 +1,34 @@ +package com.ruoyi.common.xss; + +import com.ruoyi.common.utils.StringUtils; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 自定义xss校验注解实现 + * + * @author ruoyi + */ +public class XssValidator implements ConstraintValidator +{ + private static final String HTML_PATTERN = "<(\\S*?)[^>]*>.*?|<.*? />"; + + @Override + public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) + { + if (StringUtils.isBlank(value)) + { + return true; + } + return !containsHtml(value); + } + + public static boolean containsHtml(String value) + { + Pattern pattern = Pattern.compile(HTML_PATTERN); + Matcher matcher = pattern.matcher(value); + return matcher.matches(); + } +} \ No newline at end of file diff --git a/ruoyi-framework/pom.xml b/ruoyi-framework/pom.xml new file mode 100644 index 0000000..62bcfcb --- /dev/null +++ b/ruoyi-framework/pom.xml @@ -0,0 +1,76 @@ + + + + ruoyi + com.ruoyi + 3.8.4 + + 4.0.0 + + ruoyi-framework + + + framework框架核心 + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-aop + + + + + com.alibaba + druid-spring-boot-starter + + + + + pro.fessional + kaptcha + + + javax.servlet-api + javax.servlet + + + + + + + com.github.oshi + oshi-core + + + + + com.ruoyi + ruoyi-system + + + + + com.baomidou + mybatis-plus-boot-starter + + + + + org.redisson + redisson + + + + + \ No newline at end of file diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/BindDictAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/BindDictAspect.java new file mode 100644 index 0000000..04e4367 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/BindDictAspect.java @@ -0,0 +1,161 @@ +package com.ruoyi.framework.aspectj; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ReflectUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.common.annotation.BindDict; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.system.service.ISysDictDataService; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +/** + * @author ntxz + * @create 2023-02-20-14:36 + */ +@Aspect +@Component +@Slf4j +public class BindDictAspect { + + @Autowired + private ISysDictDataService sysDictDataService; + + + //切入点 com.ntxz.functional包下所有 类名是 *Controller 的类,方法参数任意个。 + @Pointcut("execution(* com.ruoyi.*.controller..*.*Controller.*(..))") + public void around() { + } + + /* + * 环绕通知 + * */ + @Around("around()") + public Object process(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { + //1.执行原方法 + Object proceed = proceedingJoinPoint.proceed(); + //2.拿到原方法的原返回值 调用parseDict进行字典转换 + this.parseDict(proceed); + return proceed; + } + + + private void parseDict(Object result) throws IllegalAccessException { + +// 1. 检测是否为统一返回(更据自身情况修改,Result是我自己编写的一个统一返回) + if (result instanceof TableDataInfo) { + //2.获取Result中的数据体 + Object metaObj = ((TableDataInfo) result).getRows(); + + if (metaObj instanceof Page) { + List list = ((Page) metaObj).getRecords(); + for (Object a : list) { + doParseDict(a); + } + } + //返回是否是列表 + if (metaObj instanceof ArrayList) { + ArrayList list = (ArrayList) metaObj; + for (Object a : list) { + doParseDict(a); + } + } + + } + if (result instanceof AjaxResult) { + //2.获取Result中的数据体 + Object metaObj = ((AjaxResult) result).get("data"); + + //返回单个对象 + if (metaObj != null && !(metaObj instanceof ArrayList)) { + doParseDict(metaObj); + } + + } + + } + + //绑定字典 + public void doParseDict(Object obj) throws IllegalAccessException { + Field[] fields = ReflectUtil.getFields(obj.getClass()); + if (fields != null && fields.length != 0) { + Iterator iterator = Arrays.stream(fields).iterator(); + while (iterator.hasNext()) { + Field field = iterator.next(); + BindDict dict = field.getAnnotation(BindDict.class); + //获取绑定了注解的字段 + if (dict != null) { + if (List.class.equals(field.getType())) { + ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType(); + Class actualTypeArgument = (Class) parameterizedType.getActualTypeArguments()[0]; + if(actualTypeArgument.getClassLoader()==null){ + continue; + } + field.setAccessible(true); + List list = (List) field.get(obj); + if(CollUtil.isNotEmpty(list)) { + for (Object object : list) { + doParseDict(object); + } + } + continue; + + } + if (field.getType().getClassLoader() != null) { + field.setAccessible(true); + Object o = field.get(obj); + if(o!=null) { + doParseDict(o); + } + continue; + } + + //设置取消字段保护 + field.setAccessible(true); + String mapping = dict.filedMapping();//字典值所在字段名 + Field mappingField = ReflectUtil.getField(obj.getClass(), mapping);//获取字典值所在字段 + mappingField.setAccessible(true); + + //查询字典表 + QueryWrapper queryWrapper = new QueryWrapper<>(); +// queryWrapper.eq("dict_type",dict.type()).eq("dict_value",mappingField.get(obj)); + String label = ""; + if (mappingField.get(obj) != null) { + if(mappingField.get(obj).toString().startsWith("[")){ + List split = JSONUtil.toList(mappingField.get(obj).toString(), String.class); + ArrayList strings = new ArrayList<>(); + for (String s : split) { + String label1 = sysDictDataService.selectDictLabel(dict.type(), s); + strings.add(label1); + } + label = JSONUtil.toJsonStr(strings).replace("\"","").replace("[","").replace("]",""); + }else { + label = sysDictDataService.selectDictLabel(dict.type(), mappingField.get(obj).toString()); + } + + } + field.set(obj, label);//设置字典 + } + } + } + } + +} + + diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java new file mode 100644 index 0000000..9ba02f4 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java @@ -0,0 +1,168 @@ +package com.ruoyi.framework.aspectj; + +import java.util.ArrayList; +import java.util.List; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.springframework.stereotype.Component; +import com.ruoyi.common.annotation.DataScope; +import com.ruoyi.common.core.domain.BaseEntity; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.security.context.PermissionContextHolder; + +/** + * 数据过滤处理 + * + * @author ruoyi + */ +@Aspect +@Component +public class DataScopeAspect +{ + /** + * 全部数据权限 + */ + public static final String DATA_SCOPE_ALL = "1"; + + /** + * 自定数据权限 + */ + public static final String DATA_SCOPE_CUSTOM = "2"; + + /** + * 部门数据权限 + */ + public static final String DATA_SCOPE_DEPT = "3"; + + /** + * 部门及以下数据权限 + */ + public static final String DATA_SCOPE_DEPT_AND_CHILD = "4"; + + /** + * 仅本人数据权限 + */ + public static final String DATA_SCOPE_SELF = "5"; + + /** + * 数据权限过滤关键字 + */ + public static final String DATA_SCOPE = "dataScope"; + + @Before("@annotation(controllerDataScope)") + public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable + { + clearDataScope(point); + handleDataScope(point, controllerDataScope); + } + + protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope) + { + // 获取当前的用户 + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNotNull(loginUser)) + { + SysUser currentUser = loginUser.getUser(); + // 如果是超级管理员,则不过滤数据 + if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) + { + String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), PermissionContextHolder.getContext()); + dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(), + controllerDataScope.userAlias(), permission); + } + } + } + + /** + * 数据范围过滤 + * + * @param joinPoint 切点 + * @param user 用户 + * @param deptAlias 部门别名 + * @param userAlias 用户别名 + * @param permission 权限字符 + */ + public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission) + { + StringBuilder sqlString = new StringBuilder(); + List conditions = new ArrayList(); + + for (SysRole role : user.getRoles()) + { + String dataScope = role.getDataScope(); + if (!DATA_SCOPE_CUSTOM.equals(dataScope) && conditions.contains(dataScope)) + { + continue; + } + if (StringUtils.isNotEmpty(permission) && StringUtils.isNotEmpty(role.getPermissions()) + && !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) + { + continue; + } + if (DATA_SCOPE_ALL.equals(dataScope)) + { + sqlString = new StringBuilder(); + break; + } + else if (DATA_SCOPE_CUSTOM.equals(dataScope)) + { + sqlString.append(StringUtils.format( + " OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, + role.getRoleId())); + } + else if (DATA_SCOPE_DEPT.equals(dataScope)) + { + sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId())); + } + else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) + { + sqlString.append(StringUtils.format( + // " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", + " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or cast({} as varchar) = any(string_to_array(ancestors,',')) )", + deptAlias, user.getDeptId(), user.getDeptId())); + } + else if (DATA_SCOPE_SELF.equals(dataScope)) + { + if (StringUtils.isNotBlank(userAlias)) + { + sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId())); + } + else + { + // 数据权限为仅本人且没有userAlias别名不查询任何数据 + sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias)); + } + } + conditions.add(dataScope); + } + + if (StringUtils.isNotBlank(sqlString.toString())) + { + Object params = joinPoint.getArgs()[0]; + if (StringUtils.isNotNull(params) && params instanceof BaseEntity) + { + BaseEntity baseEntity = (BaseEntity) params; + baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")"); + } + } + } + + /** + * 拼接权限sql前先清空params.dataScope参数防止注入 + */ + private void clearDataScope(final JoinPoint joinPoint) + { + Object params = joinPoint.getArgs()[0]; + if (StringUtils.isNotNull(params) && params instanceof BaseEntity) + { + BaseEntity baseEntity = (BaseEntity) params; + baseEntity.getParams().put(DATA_SCOPE, ""); + } + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java new file mode 100644 index 0000000..8c2c9f4 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java @@ -0,0 +1,72 @@ +package com.ruoyi.framework.aspectj; + +import java.util.Objects; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import com.ruoyi.common.annotation.DataSource; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.datasource.DynamicDataSourceContextHolder; + +/** + * 多数据源处理 + * + * @author ruoyi + */ +@Aspect +@Order(1) +@Component +public class DataSourceAspect +{ + protected Logger logger = LoggerFactory.getLogger(getClass()); + + @Pointcut("@annotation(com.ruoyi.common.annotation.DataSource)" + + "|| @within(com.ruoyi.common.annotation.DataSource)") + public void dsPointCut() + { + + } + + @Around("dsPointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable + { + DataSource dataSource = getDataSource(point); + + if (StringUtils.isNotNull(dataSource)) + { + DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name()); + } + + try + { + return point.proceed(); + } + finally + { + // 销毁数据源 在执行方法之后 + DynamicDataSourceContextHolder.clearDataSourceType(); + } + } + + /** + * 获取需要切换的数据源 + */ + public DataSource getDataSource(ProceedingJoinPoint point) + { + MethodSignature signature = (MethodSignature) point.getSignature(); + DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class); + if (Objects.nonNull(dataSource)) + { + return dataSource; + } + + return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java new file mode 100644 index 0000000..0c33f54 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java @@ -0,0 +1,227 @@ +package com.ruoyi.framework.aspectj; + +import java.util.Collection; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.validation.BindingResult; +import org.springframework.web.multipart.MultipartFile; +import com.alibaba.fastjson2.JSON; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.enums.BusinessStatus; +import com.ruoyi.common.enums.HttpMethod; +import com.ruoyi.common.filter.PropertyPreExcludeFilter; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.ip.IpUtils; +import com.ruoyi.framework.manager.AsyncManager; +import com.ruoyi.framework.manager.factory.AsyncFactory; +import com.ruoyi.system.domain.SysOperLog; + +/** + * 操作日志记录处理 + * + * @author ruoyi + */ +@Aspect +@Component +public class LogAspect +{ + private static final Logger log = LoggerFactory.getLogger(LogAspect.class); + + /** 排除敏感属性字段 */ + public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" }; + + /** + * 处理完请求后执行 + * + * @param joinPoint 切点 + */ + @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult") + public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) + { + handleLog(joinPoint, controllerLog, null, jsonResult); + } + + /** + * 拦截异常操作 + * + * @param joinPoint 切点 + * @param e 异常 + */ + @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e") + public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) + { + handleLog(joinPoint, controllerLog, e, null); + } + + protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) + { + try + { + // 获取当前的用户 + LoginUser loginUser = SecurityUtils.getLoginUser(); + + // *========数据库日志=========*// + SysOperLog operLog = new SysOperLog(); + operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); + // 请求的地址 + String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); + operLog.setOperIp(ip); + operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255)); + if (loginUser != null) + { + operLog.setOperName(loginUser.getUsername()); + } + + if (e != null) + { + operLog.setStatus(BusinessStatus.FAIL.ordinal()); + operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); + } + // 设置方法名称 + String className = joinPoint.getTarget().getClass().getName(); + String methodName = joinPoint.getSignature().getName(); + operLog.setMethod(className + "." + methodName + "()"); + // 设置请求方式 + operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); + // 处理设置注解上的参数 + getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); + // 保存数据库 + AsyncManager.me().execute(AsyncFactory.recordOper(operLog)); + } + catch (Exception exp) + { + // 记录本地异常日志 + log.error("异常信息:{}", exp.getMessage()); + exp.printStackTrace(); + } + } + + /** + * 获取注解中对方法的描述信息 用于Controller层注解 + * + * @param log 日志 + * @param operLog 操作日志 + * @throws Exception + */ + public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception + { + // 设置action动作 + operLog.setBusinessType(log.businessType().ordinal()); + // 设置标题 + operLog.setTitle(log.title()); + // 设置操作人类别 + operLog.setOperatorType(log.operatorType().ordinal()); + // 是否需要保存request,参数和值 + if (log.isSaveRequestData()) + { + // 获取参数的信息,传入到数据库中。 + setRequestValue(joinPoint, operLog); + } + // 是否需要保存response,参数和值 + if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) + { + operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000)); + } + } + + /** + * 获取请求的参数,放到log中 + * + * @param operLog 操作日志 + * @throws Exception 异常 + */ + private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception + { + String requestMethod = operLog.getRequestMethod(); + if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) + { + String params = argsArrayToString(joinPoint.getArgs()); + operLog.setOperParam(StringUtils.substring(params, 0, 2000)); + } + else + { + Map paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest()); + operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter()), 0, 2000)); + } + } + + /** + * 参数拼装 + */ + private String argsArrayToString(Object[] paramsArray) + { + String params = ""; + if (paramsArray != null && paramsArray.length > 0) + { + for (Object o : paramsArray) + { + if (StringUtils.isNotNull(o) && !isFilterObject(o)) + { + try + { + String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter()); + params += jsonObj.toString() + " "; + } + catch (Exception e) + { + } + } + } + } + return params.trim(); + } + + /** + * 忽略敏感属性 + */ + public PropertyPreExcludeFilter excludePropertyPreFilter() + { + return new PropertyPreExcludeFilter().addExcludes(EXCLUDE_PROPERTIES); + } + + /** + * 判断是否需要过滤的对象。 + * + * @param o 对象信息。 + * @return 如果是需要过滤的对象,则返回true;否则返回false。 + */ + @SuppressWarnings("rawtypes") + public boolean isFilterObject(final Object o) + { + Class clazz = o.getClass(); + if (clazz.isArray()) + { + return clazz.getComponentType().isAssignableFrom(MultipartFile.class); + } + else if (Collection.class.isAssignableFrom(clazz)) + { + Collection collection = (Collection) o; + for (Object value : collection) + { + return value instanceof MultipartFile; + } + } + else if (Map.class.isAssignableFrom(clazz)) + { + Map map = (Map) o; + for (Object value : map.entrySet()) + { + Map.Entry entry = (Map.Entry) value; + return entry.getValue() instanceof MultipartFile; + } + } + return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse + || o instanceof BindingResult; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java new file mode 100644 index 0000000..69811bc --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java @@ -0,0 +1,90 @@ +package com.ruoyi.framework.aspectj; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.List; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.script.RedisScript; +import org.springframework.stereotype.Component; +import com.ruoyi.common.annotation.RateLimiter; +import com.ruoyi.common.enums.LimitType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.ip.IpUtils; + +/** + * 限流处理 + * + * @author ruoyi + */ +@Aspect +@Component +public class RateLimiterAspect +{ + private static final Logger log = LoggerFactory.getLogger(RateLimiterAspect.class); + + private RedisTemplate redisTemplate; + + private RedisScript limitScript; + + @Autowired + public void setRedisTemplate1(RedisTemplate redisTemplate) + { + this.redisTemplate = redisTemplate; + } + + @Autowired + public void setLimitScript(RedisScript limitScript) + { + this.limitScript = limitScript; + } + + @Before("@annotation(rateLimiter)") + public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable + { + int time = rateLimiter.time(); + int count = rateLimiter.count(); + + String combineKey = getCombineKey(rateLimiter, point); + List keys = Collections.singletonList(combineKey); + try + { + Long number = redisTemplate.execute(limitScript, keys, count, time); + if (StringUtils.isNull(number) || number.intValue() > count) + { + throw new ServiceException("访问过于频繁,请稍候再试"); + } + log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), combineKey); + } + catch (ServiceException e) + { + throw e; + } + catch (Exception e) + { + throw new RuntimeException("服务器限流异常,请稍候再试"); + } + } + + public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) + { + StringBuffer stringBuffer = new StringBuffer(rateLimiter.key()); + if (rateLimiter.limitType() == LimitType.IP) + { + stringBuffer.append(IpUtils.getIpAddr(ServletUtils.getRequest())).append("-"); + } + MethodSignature signature = (MethodSignature) point.getSignature(); + Method method = signature.getMethod(); + Class targetClass = method.getDeclaringClass(); + stringBuffer.append(targetClass.getName()).append("-").append(method.getName()); + return stringBuffer.toString(); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java new file mode 100644 index 0000000..1d4dc1f --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java @@ -0,0 +1,30 @@ +package com.ruoyi.framework.config; + +import java.util.TimeZone; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + +/** + * 程序注解配置 + * + * @author ruoyi + */ +@Configuration +// 表示通过aop框架暴露该代理对象,AopContext能够访问 +@EnableAspectJAutoProxy(exposeProxy = true) +// 指定要扫描的Mapper类的包的路径 +@MapperScan("com.ruoyi.**.mapper") +public class ApplicationConfig +{ + /** + * 时区配置 + */ + @Bean + public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() + { + return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault()); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/CaptchaConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/CaptchaConfig.java new file mode 100644 index 0000000..43e78ae --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/CaptchaConfig.java @@ -0,0 +1,83 @@ +package com.ruoyi.framework.config; + +import java.util.Properties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.google.code.kaptcha.impl.DefaultKaptcha; +import com.google.code.kaptcha.util.Config; +import static com.google.code.kaptcha.Constants.*; + +/** + * 验证码配置 + * + * @author ruoyi + */ +@Configuration +public class CaptchaConfig +{ + @Bean(name = "captchaProducer") + public DefaultKaptcha getKaptchaBean() + { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + // 是否有边框 默认为true 我们可以自己设置yes,no + properties.setProperty(KAPTCHA_BORDER, "yes"); + // 验证码文本字符颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black"); + // 验证码图片宽度 默认为200 + properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); + // 验证码图片高度 默认为50 + properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); + // 验证码文本字符大小 默认为40 + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38"); + // KAPTCHA_SESSION_KEY + properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); + // 验证码文本字符长度 默认为5 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4"); + // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); + // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy + properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } + + @Bean(name = "captchaProducerMath") + public DefaultKaptcha getKaptchaBeanMath() + { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + // 是否有边框 默认为true 我们可以自己设置yes,no + properties.setProperty(KAPTCHA_BORDER, "yes"); + // 边框颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90"); + // 验证码文本字符颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue"); + // 验证码图片宽度 默认为200 + properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); + // 验证码图片高度 默认为50 + properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); + // 验证码文本字符大小 默认为40 + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35"); + // KAPTCHA_SESSION_KEY + properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath"); + // 验证码文本生成器 + properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ruoyi.framework.config.KaptchaTextCreator"); + // 验证码文本字符间距 默认为2 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3"); + // 验证码文本字符长度 默认为5 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6"); + // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); + // 验证码噪点颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_NOISE_COLOR, "white"); + // 干扰实现类 + properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise"); + // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy + properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java new file mode 100644 index 0000000..f6abac1 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java @@ -0,0 +1,126 @@ +package com.ruoyi.framework.config; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.sql.DataSource; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; +import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties; +import com.alibaba.druid.util.Utils; +import com.ruoyi.common.enums.DataSourceType; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.framework.config.properties.DruidProperties; +import com.ruoyi.framework.datasource.DynamicDataSource; + +/** + * druid 配置多数据源 + * + * @author ruoyi + */ +@Configuration +public class DruidConfig +{ + @Bean + @ConfigurationProperties("spring.datasource.druid.master") + public DataSource masterDataSource(DruidProperties druidProperties) + { + DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); + return druidProperties.dataSource(dataSource); + } + + @Bean + @ConfigurationProperties("spring.datasource.druid.slave") + @ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true") + public DataSource slaveDataSource(DruidProperties druidProperties) + { + DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); + return druidProperties.dataSource(dataSource); + } + + @Bean(name = "dynamicDataSource") + @Primary + public DynamicDataSource dataSource(DataSource masterDataSource) + { + Map targetDataSources = new HashMap<>(); + targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource); + setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource"); + return new DynamicDataSource(masterDataSource, targetDataSources); + } + + /** + * 设置数据源 + * + * @param targetDataSources 备选数据源集合 + * @param sourceName 数据源名称 + * @param beanName bean名称 + */ + public void setDataSource(Map targetDataSources, String sourceName, String beanName) + { + try + { + DataSource dataSource = SpringUtils.getBean(beanName); + targetDataSources.put(sourceName, dataSource); + } + catch (Exception e) + { + } + } + + /** + * 去除监控页面底部的广告 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true") + public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties) + { + // 获取web监控页面的参数 + DruidStatProperties.StatViewServlet config = properties.getStatViewServlet(); + // 提取common.js的配置路径 + String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*"; + String commonJsPattern = pattern.replaceAll("\\*", "js/common.js"); + final String filePath = "support/http/resources/js/common.js"; + // 创建filter进行过滤 + Filter filter = new Filter() + { + @Override + public void init(javax.servlet.FilterConfig filterConfig) throws ServletException + { + } + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException + { + chain.doFilter(request, response); + // 重置缓冲区,响应头不会被重置 + response.resetBuffer(); + // 获取common.js + String text = Utils.readFromResource(filePath); + // 正则替换banner, 除去底部的广告信息 + text = text.replaceAll("
", ""); + text = text.replaceAll("powered.*?shrek.wang", ""); + response.getWriter().write(text); + } + @Override + public void destroy() + { + } + }; + FilterRegistrationBean registrationBean = new FilterRegistrationBean(); + registrationBean.setFilter(filter); + registrationBean.addUrlPatterns(commonJsPattern); + return registrationBean; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java new file mode 100644 index 0000000..b6d6110 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java @@ -0,0 +1,48 @@ +package com.ruoyi.framework.config; + +import java.nio.charset.Charset; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.SerializationException; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONReader; +import com.alibaba.fastjson2.JSONWriter; + +/** + * Redis使用FastJson序列化 + * + * @author ruoyi + */ +public class FastJson2JsonRedisSerializer implements RedisSerializer +{ + public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + + private Class clazz; + + public FastJson2JsonRedisSerializer(Class clazz) + { + super(); + this.clazz = clazz; + } + + @Override + public byte[] serialize(T t) throws SerializationException + { + if (t == null) + { + return new byte[0]; + } + return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET); + } + + @Override + public T deserialize(byte[] bytes) throws SerializationException + { + if (bytes == null || bytes.length <= 0) + { + return null; + } + String str = new String(bytes, DEFAULT_CHARSET); + + return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java new file mode 100644 index 0000000..bb14c04 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java @@ -0,0 +1,58 @@ +package com.ruoyi.framework.config; + +import java.util.HashMap; +import java.util.Map; +import javax.servlet.DispatcherType; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.ruoyi.common.filter.RepeatableFilter; +import com.ruoyi.common.filter.XssFilter; +import com.ruoyi.common.utils.StringUtils; + +/** + * Filter配置 + * + * @author ruoyi + */ +@Configuration +public class FilterConfig +{ + @Value("${xss.excludes}") + private String excludes; + + @Value("${xss.urlPatterns}") + private String urlPatterns; + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + @ConditionalOnProperty(value = "xss.enabled", havingValue = "true") + public FilterRegistrationBean xssFilterRegistration() + { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setDispatcherTypes(DispatcherType.REQUEST); + registration.setFilter(new XssFilter()); + registration.addUrlPatterns(StringUtils.split(urlPatterns, ",")); + registration.setName("xssFilter"); + registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE); + Map initParameters = new HashMap(); + initParameters.put("excludes", excludes); + registration.setInitParameters(initParameters); + return registration; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + public FilterRegistrationBean someFilterRegistration() + { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setFilter(new RepeatableFilter()); + registration.addUrlPatterns("/*"); + registration.setName("repeatableFilter"); + registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE); + return registration; + } + +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/KaptchaTextCreator.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/KaptchaTextCreator.java new file mode 100644 index 0000000..7f8e1d5 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/KaptchaTextCreator.java @@ -0,0 +1,68 @@ +package com.ruoyi.framework.config; + +import java.util.Random; +import com.google.code.kaptcha.text.impl.DefaultTextCreator; + +/** + * 验证码文本生成器 + * + * @author ruoyi + */ +public class KaptchaTextCreator extends DefaultTextCreator +{ + private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(","); + + @Override + public String getText() + { + Integer result = 0; + Random random = new Random(); + int x = random.nextInt(10); + int y = random.nextInt(10); + StringBuilder suChinese = new StringBuilder(); + int randomoperands = random.nextInt(3); + if (randomoperands == 0) + { + result = x * y; + suChinese.append(CNUMBERS[x]); + suChinese.append("*"); + suChinese.append(CNUMBERS[y]); + } + else if (randomoperands == 1) + { + if ((x != 0) && y % x == 0) + { + result = y / x; + suChinese.append(CNUMBERS[y]); + suChinese.append("/"); + suChinese.append(CNUMBERS[x]); + } + else + { + result = x + y; + suChinese.append(CNUMBERS[x]); + suChinese.append("+"); + suChinese.append(CNUMBERS[y]); + } + } + else + { + if (x >= y) + { + result = x - y; + suChinese.append(CNUMBERS[x]); + suChinese.append("-"); + suChinese.append(CNUMBERS[y]); + } + else + { + result = y - x; + suChinese.append(CNUMBERS[y]); + suChinese.append("-"); + suChinese.append(CNUMBERS[x]); + } + } + suChinese.append("=?@" + result); + return suChinese.toString(); + } +} \ No newline at end of file diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.zip b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.zip new file mode 100644 index 0000000000000000000000000000000000000000..192cde542c36db4075c266a9eb19ec8ee191dbb6 GIT binary patch literal 1713 zcmWIWW@Zs#U|`^2@Xyu^d$>PzD?1wl!v%2$1|bFp2H#4j#FETn=ls01%yhl1#InSt z5ohy+4F&dvzp|bocOlP#FMUCWKv3h9peZaZEdfte{5EZfWWOEFv4UN|L!oiU0me@C z2IrlMEe|p?Sn?0vcpaNwKPl&MSZ~?endk5Kq#v^vzEthdCi3-$#ODdVwl)t^eB=%P zF?^3O_|PV9W^QJ_=VMD@=ex&UYoeJtiSP6-jx7z4VRw_TJ&mlG8G)exNWm~F4w)-zA`}8dWpK^{J4cF zeElC4)ePK~yKHsW@8Qpx?%Bb?Z!UK^j$^{ymo3vKo)7fYJbLZOA92C;VdAe#4qkow zEa7E?tkt|9F3Wn2lFX`hA8>!*=)yNyAtA_LY#n2xyWH}>qQ5FPeYp1B#Lc!&`Cr_I z*PM*2PBD5bPTkkyFhhOwv`aM~)?Q(|XJT=n_rZb3Iue&1rd?>z*zLux@+GyKYi_)+ z+pj6pgL_L)d3F~pO8MZcx4;6ovzjsXM!X&2cOE2}O zD(=>vdX_iDaaq;bd-7-R*{qh?|MTDXr?+pu*56$IzVH5?D?-1X8$CJSQMhDcsCQ}c z<07ppb91%C>))$9qS=)Z&K861mV|*AD-`hCj$GI7UAJLZnrH@2!g4J+Aq;JU!8 zed=@9ZjN48SZ$a$&q)9Lb(=`L+uhGZug~6ECav`LR^8g0clKY+dUrp^v~1n|PQ}mX zB~va3U#)YPxa%p~lY;iMye37LObi6%tk-c1L|@hY5i9bkvRUX~`Fq8@IMx|QldaoK zA~{^rZYce)V15!YC-}jw3*Rrkyeua3+eG4&;I5W)Ghap-rv6Mg=VI99c5?H^iz2fp zTyS`i2eR3#-3h|EIX5 zXATx=Im?MmFn!cMGj>Moyho~;(|y#Ym`D1*S8_F)nK9>`#Z57vt?InDvvYTR zxu+<$CuREdH~$Wuk|>q_nkhW#>t)@opHfHA_pFEv$(Sgk-mr`}O^4&-On6zZM`^XJKRk8n zy$Kd8rPsf>BAL13zsq@DL* znYQxJ9XFjmd@0m<{?;=;4TV$FC)x$9lUg^AOKtA;*6Zn2lV@+Sd?{hFc*$zFG=ru4 zuJ84)zGQJ redisTemplate(RedisConnectionFactory connectionFactory) + { + + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(connectionFactory); + + FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); + + // 使用StringRedisSerializer来序列化和反序列化redis的key值 + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(serializer); + + // Hash的key也采用StringRedisSerializer的序列化方式 + template.setHashKeySerializer(new StringRedisSerializer()); + template.setHashValueSerializer(serializer); + + template.afterPropertiesSet(); + return template; + } + + @Bean + RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { + + RedisMessageListenerContainer container = new RedisMessageListenerContainer(); + container.setConnectionFactory(connectionFactory); + return container; + } + + + @Bean + public DefaultRedisScript limitScript() + { + DefaultRedisScript redisScript = new DefaultRedisScript<>(); + redisScript.setScriptText(limitScriptText()); + redisScript.setResultType(Long.class); + return redisScript; + } + + /** + * 限流脚本 + */ + private String limitScriptText() + { + return "local key = KEYS[1]\n" + + "local count = tonumber(ARGV[1])\n" + + "local time = tonumber(ARGV[2])\n" + + "local current = redis.call('get', key);\n" + + "if current and tonumber(current) > count then\n" + + " return tonumber(current);\n" + + "end\n" + + "current = redis.call('incr', key)\n" + + "if tonumber(current) == 1 then\n" + + " redis.call('expire', key, time)\n" + + "end\n" + + "return tonumber(current);"; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedissonConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedissonConfig.java new file mode 100644 index 0000000..fb73c10 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedissonConfig.java @@ -0,0 +1,27 @@ +package com.ruoyi.framework.config; + +import org.redisson.Redisson; +import org.redisson.api.RedissonClient; +import org.redisson.config.Config; +import org.springframework.context.annotation.Bean; +import org.springframework.beans.factory.annotation.Value; + +public class RedissonConfig { + + @Value("${redisson.addr.singleAddr.host}") + private String host; + + @Value("${redisson.addr.singleAddr.password}") + private String password; + + @Value("${redisson.addr.singleAddr.database}") + private int database; + + @Bean + public RedissonClient redissonClient() { + Config config = new Config(); + config.useSingleServer().setAddress(host).setPassword(password).setDatabase(database); + return Redisson.create(config); + } + +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java new file mode 100644 index 0000000..68445cf --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java @@ -0,0 +1,126 @@ +package com.ruoyi.framework.config; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.deser.std.DateDeserializers; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.DateSerializer; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.format.datetime.DateFormatter; +import org.springframework.http.CacheControl; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor; + +/** + * 通用配置 + * + * @author ruoyi + */ +@Configuration +public class ResourcesConfig implements WebMvcConfigurer +{ + @Autowired + private RepeatSubmitInterceptor repeatSubmitInterceptor; + + private static final String DEFAULT_DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; + private static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd"; + private static final String DEFAULT_TIME_PATTERN = "HH:mm:ss"; + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) + { + /** 本地文件上传路径 */ + registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**") + .addResourceLocations("file:" + RuoYiConfig.getProfile() + "/"); + + /** swagger配置 */ + registry.addResourceHandler("/swagger-ui/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/") + .setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic());; + } + + /** + * 自定义拦截规则 + */ + @Override + public void addInterceptors(InterceptorRegistry registry) + { + registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**"); + } + + /** + * 跨域配置 + */ + @Bean + public CorsFilter corsFilter() + { + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + // 设置访问源地址 + config.addAllowedOriginPattern("*"); + // 设置访问源请求头 + config.addAllowedHeader("*"); + // 设置访问源请求方法 + config.addAllowedMethod("*"); + // 有效期 1800秒 + config.setMaxAge(1800L); + // 添加映射路径,拦截一切请求 + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", config); + // 返回新的CorsFilter + return new CorsFilter(source); + } + + @Bean + public MappingJackson2HttpMessageConverter toStringConverter() { + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + ObjectMapper mapper = new ObjectMapper(); + SimpleModule simpleModule = new SimpleModule(); +// simpleModule.addSerializer(Long.class, ToStringSerializer.instance); +// simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); + simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_PATTERN))); + simpleModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_PATTERN))); + simpleModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_PATTERN))); + simpleModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_PATTERN))); + simpleModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_PATTERN))); + simpleModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_PATTERN))); + mapper.registerModule(simpleModule); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + //接收前端的""反序列化为null + mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + mapper.setDateFormat(dateFormat); + converter.setObjectMapper(mapper); + + return converter; + } + +} \ No newline at end of file diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java new file mode 100644 index 0000000..85ef53b --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java @@ -0,0 +1,158 @@ +package com.ruoyi.framework.config; + +import com.ruoyi.framework.security.sms.SmsCodeAuthenticationProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.logout.LogoutFilter; +import org.springframework.web.filter.CorsFilter; +import com.ruoyi.framework.config.properties.PermitAllUrlProperties; +import com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter; +import com.ruoyi.framework.security.handle.AuthenticationEntryPointImpl; +import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl; + +/** + * spring security配置 + * + * @author ruoyi + */ +@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) +public class SecurityConfig extends WebSecurityConfigurerAdapter +{ + /** + * 自定义用户认证逻辑 + */ + @Autowired + @Qualifier("userDetailsServiceImpl") + private UserDetailsService userDetailsByUsername; + + @Autowired + @Qualifier("userDetailsByTelephoneServiceImpl") + private UserDetailsService userDetailsByPhonenumber; + + /** + * 认证失败处理类 + */ + @Autowired + private AuthenticationEntryPointImpl unauthorizedHandler; + + /** + * 退出处理类 + */ + @Autowired + private LogoutSuccessHandlerImpl logoutSuccessHandler; + + /** + * token认证过滤器 + */ + @Autowired + private JwtAuthenticationTokenFilter authenticationTokenFilter; + + /** + * 跨域过滤器 + */ + @Autowired + private CorsFilter corsFilter; + + /** + * 允许匿名访问的地址 + */ + @Autowired + private PermitAllUrlProperties permitAllUrl; + + /** + * 解决 无法直接注入 AuthenticationManager + * + * @return + * @throws Exception + */ + @Bean + @Override + public AuthenticationManager authenticationManagerBean() throws Exception + { + return super.authenticationManagerBean(); + } + + /** + * anyRequest | 匹配所有请求路径 + * access | SpringEl表达式结果为true时可以访问 + * anonymous | 匿名可以访问 + * denyAll | 用户不能访问 + * fullyAuthenticated | 用户完全认证可以访问(非remember-me下自动登录) + * hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问 + * hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问 + * hasAuthority | 如果有参数,参数表示权限,则其权限可以访问 + * hasIpAddress | 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问 + * hasRole | 如果有参数,参数表示角色,则其角色可以访问 + * permitAll | 用户可以任意访问 + * rememberMe | 允许通过remember-me登录的用户访问 + * authenticated | 用户登录后可访问 + */ + @Override + protected void configure(HttpSecurity httpSecurity) throws Exception + { + // 注解标记允许匿名访问的url + ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests(); + permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll()); + + httpSecurity + // CSRF禁用,因为不使用session + .csrf().disable() + // 禁用HTTP响应标头 + .headers().cacheControl().disable().and() + // 认证失败处理类 + .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() + // 基于token,所以不需要session + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() + // 过滤请求 + .authorizeRequests() + // 对于登录login 注册register 验证码captchaImage 允许匿名访问 + .antMatchers("/app/version/config","/ydLogin","/login","/autoLogin","/getLoginCode","/autoLogin", "/register", "/captchaImage","/eastcom_yw/notice","/eastcom_yw/daping/**").permitAll() + .antMatchers("/monitor/shutdown").access("@ss.hasRole('admin')") + // 静态资源,可匿名访问 + .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() + .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() + // 除上面外的所有请求全部需要鉴权认证 + .anyRequest().authenticated() + .and() + .headers().frameOptions().disable(); + // 添加Logout filter + httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler); + // 添加JWT filter + httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); + // 添加CORS filter + httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class); + httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class); + } + + /** + * 强散列哈希加密实现 + */ + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() + { + return new BCryptPasswordEncoder(); + } + + /** + * 身份认证接口 + */ + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception + { + auth.authenticationProvider(new SmsCodeAuthenticationProvider(userDetailsByPhonenumber)); + + auth.userDetailsService(userDetailsByUsername).passwordEncoder(bCryptPasswordEncoder()); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ServerConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ServerConfig.java new file mode 100644 index 0000000..b5b7de3 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ServerConfig.java @@ -0,0 +1,32 @@ +package com.ruoyi.framework.config; + +import javax.servlet.http.HttpServletRequest; +import org.springframework.stereotype.Component; +import com.ruoyi.common.utils.ServletUtils; + +/** + * 服务相关配置 + * + * @author ruoyi + */ +@Component +public class ServerConfig +{ + /** + * 获取完整的请求路径,包括:域名,端口,上下文访问路径 + * + * @return 服务地址 + */ + public String getUrl() + { + HttpServletRequest request = ServletUtils.getRequest(); + return getDomain(request); + } + + public static String getDomain(HttpServletRequest request) + { + StringBuffer url = request.getRequestURL(); + String contextPath = request.getServletContext().getContextPath(); + return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString(); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java new file mode 100644 index 0000000..7840141 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java @@ -0,0 +1,63 @@ +package com.ruoyi.framework.config; + +import com.ruoyi.common.utils.Threads; +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * 线程池配置 + * + * @author ruoyi + **/ +@Configuration +public class ThreadPoolConfig +{ + // 核心线程池大小 + private int corePoolSize = 50; + + // 最大可创建的线程数 + private int maxPoolSize = 200; + + // 队列最大长度 + private int queueCapacity = 1000; + + // 线程池维护线程所允许的空闲时间 + private int keepAliveSeconds = 300; + + @Bean(name = "threadPoolTaskExecutor") + public ThreadPoolTaskExecutor threadPoolTaskExecutor() + { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setMaxPoolSize(maxPoolSize); + executor.setCorePoolSize(corePoolSize); + executor.setQueueCapacity(queueCapacity); + executor.setKeepAliveSeconds(keepAliveSeconds); + // 线程池对拒绝任务(无线程可用)的处理策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + return executor; + } + + /** + * 执行周期性或定时任务 + */ + @Bean(name = "scheduledExecutorService") + protected ScheduledExecutorService scheduledExecutorService() + { + return new ScheduledThreadPoolExecutor(corePoolSize, + new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(), + new ThreadPoolExecutor.CallerRunsPolicy()) + { + @Override + protected void afterExecute(Runnable r, Throwable t) + { + super.afterExecute(r, t); + Threads.printException(r, t); + } + }; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/DruidProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/DruidProperties.java new file mode 100644 index 0000000..84f7e00 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/DruidProperties.java @@ -0,0 +1,77 @@ +package com.ruoyi.framework.config.properties; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import com.alibaba.druid.pool.DruidDataSource; + +/** + * druid 配置属性 + * + * @author ruoyi + */ +@Configuration +public class DruidProperties +{ + @Value("${spring.datasource.druid.initialSize}") + private int initialSize; + + @Value("${spring.datasource.druid.minIdle}") + private int minIdle; + + @Value("${spring.datasource.druid.maxActive}") + private int maxActive; + + @Value("${spring.datasource.druid.maxWait}") + private int maxWait; + + @Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}") + private int timeBetweenEvictionRunsMillis; + + @Value("${spring.datasource.druid.minEvictableIdleTimeMillis}") + private int minEvictableIdleTimeMillis; + + @Value("${spring.datasource.druid.maxEvictableIdleTimeMillis}") + private int maxEvictableIdleTimeMillis; + + @Value("${spring.datasource.druid.validationQuery}") + private String validationQuery; + + @Value("${spring.datasource.druid.testWhileIdle}") + private boolean testWhileIdle; + + @Value("${spring.datasource.druid.testOnBorrow}") + private boolean testOnBorrow; + + @Value("${spring.datasource.druid.testOnReturn}") + private boolean testOnReturn; + + public DruidDataSource dataSource(DruidDataSource datasource) + { + /** 配置初始化大小、最小、最大 */ + datasource.setInitialSize(initialSize); + datasource.setMaxActive(maxActive); + datasource.setMinIdle(minIdle); + + /** 配置获取连接等待超时的时间 */ + datasource.setMaxWait(maxWait); + + /** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */ + datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); + + /** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */ + datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); + datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis); + + /** + * 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。 + */ + datasource.setValidationQuery(validationQuery); + /** 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 */ + datasource.setTestWhileIdle(testWhileIdle); + /** 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */ + datasource.setTestOnBorrow(testOnBorrow); + /** 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */ + datasource.setTestOnReturn(testOnReturn); + return datasource; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/PermitAllUrlProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/PermitAllUrlProperties.java new file mode 100644 index 0000000..9632eb1 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/PermitAllUrlProperties.java @@ -0,0 +1,72 @@ +package com.ruoyi.framework.config.properties; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.regex.Pattern; +import org.apache.commons.lang3.RegExUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; +import com.ruoyi.common.annotation.Anonymous; + +/** + * 设置Anonymous注解允许匿名访问的url + * + * @author ruoyi + */ +@Configuration +public class PermitAllUrlProperties implements InitializingBean, ApplicationContextAware +{ + private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}"); + + private ApplicationContext applicationContext; + + private List urls = new ArrayList<>(); + + public String ASTERISK = "*"; + + @Override + public void afterPropertiesSet() + { + RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class); + Map map = mapping.getHandlerMethods(); + + map.keySet().forEach(info -> { + HandlerMethod handlerMethod = map.get(info); + + // 获取方法上边的注解 替代path variable 为 * + Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class); + Optional.ofNullable(method).ifPresent(anonymous -> info.getPatternsCondition().getPatterns() + .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK)))); + + // 获取类上边的注解, 替代path variable 为 * + Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class); + Optional.ofNullable(controller).ifPresent(anonymous -> info.getPatternsCondition().getPatterns() + .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK)))); + }); + } + + @Override + public void setApplicationContext(ApplicationContext context) throws BeansException + { + this.applicationContext = context; + } + + public List getUrls() + { + return urls; + } + + public void setUrls(List urls) + { + this.urls = urls; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSource.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSource.java new file mode 100644 index 0000000..e70b8cf --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSource.java @@ -0,0 +1,26 @@ +package com.ruoyi.framework.datasource; + +import java.util.Map; +import javax.sql.DataSource; +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; + +/** + * 动态数据源 + * + * @author ruoyi + */ +public class DynamicDataSource extends AbstractRoutingDataSource +{ + public DynamicDataSource(DataSource defaultTargetDataSource, Map targetDataSources) + { + super.setDefaultTargetDataSource(defaultTargetDataSource); + super.setTargetDataSources(targetDataSources); + super.afterPropertiesSet(); + } + + @Override + protected Object determineCurrentLookupKey() + { + return DynamicDataSourceContextHolder.getDataSourceType(); + } +} \ No newline at end of file diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSourceContextHolder.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSourceContextHolder.java new file mode 100644 index 0000000..3572db9 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSourceContextHolder.java @@ -0,0 +1,45 @@ +package com.ruoyi.framework.datasource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 数据源切换处理 + * + * @author ruoyi + */ +public class DynamicDataSourceContextHolder +{ + public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class); + + /** + * 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本, + * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 + */ + private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>(); + + /** + * 设置数据源的变量 + */ + public static void setDataSourceType(String dsType) + { + log.info("切换到{}数据源", dsType); + CONTEXT_HOLDER.set(dsType); + } + + /** + * 获得数据源的变量 + */ + public static String getDataSourceType() + { + return CONTEXT_HOLDER.get(); + } + + /** + * 清空数据源变量 + */ + public static void clearDataSourceType() + { + CONTEXT_HOLDER.remove(); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/MyMetaObjectHandler.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/MyMetaObjectHandler.java new file mode 100644 index 0000000..4ed5d5c --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/MyMetaObjectHandler.java @@ -0,0 +1,68 @@ +package com.ruoyi.framework.handler; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import com.ruoyi.common.utils.SecurityUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.reflection.MetaObject; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.Objects; + +/** + * 字段自动填充处理器 + * @author ** + */ +@Component +@Slf4j +public class MyMetaObjectHandler implements MetaObjectHandler { + + @Override + public void insertFill(MetaObject metaObject) { + log.debug("start insert fill ...."); + Long id = getUserId(); + String userName = getUserName(); + LocalDateTime now = LocalDateTime.now(); + this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, now); + this.strictInsertFill(metaObject, "createBy", String.class, userName); + this.strictInsertFill(metaObject, "createUserId", Long.class, id); + this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, now); + this.strictInsertFill(metaObject, "updateBy", String.class, userName); + } + + @Override + public void updateFill(MetaObject metaObject) { + log.debug("start update fill ...."); + String userName = getUserName(); + Long id = getUserId(); + this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); + this.strictInsertFill(metaObject, "updateBy", String.class, userName); + this.strictInsertFill(metaObject, "updateUserId", Long.class, id); + } + + private Long getUserId() { + + Long userId =null; + try { + userId = SecurityUtils.getUserId(); + } catch (Exception e) { + log.error(e.getMessage()); + } + long id = 1L; + if (Objects.nonNull(userId)) { + id = userId; + } + return id; + } + + private String getUserName() { + + String userName =""; + try { + userName = SecurityUtils.getLoginUser().getNickName(); + } catch (Exception e) { + log.error(e.getMessage()); + } + return userName; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java new file mode 100644 index 0000000..fa0e4b2 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java @@ -0,0 +1,72 @@ +package com.ruoyi.framework.interceptor; + +import java.lang.reflect.Method; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; +import com.alibaba.fastjson2.JSON; +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.ServletUtils; + +/** + * 防止重复提交拦截器 + * + * @author ruoyi + */ +@Component +public abstract class RepeatSubmitInterceptor implements HandlerInterceptor +{ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception + { + if (handler instanceof HandlerMethod) + { + HandlerMethod handlerMethod = (HandlerMethod) handler; + Method method = handlerMethod.getMethod(); + RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class); + if (annotation != null) + { + if(annotation.enable()) { + if (this.isRepeatSubmit(request, annotation)) { +// AjaxResult ajaxResult = AjaxResult.error(annotation.message() + request.getRequestURL()); +// ServletUtils.renderString(response, JSON.toJSONString(ajaxResult)); + return false; + } + } + } +// if (annotation == null) { +// if (this.isRepeatSubmit(request)) { +//// AjaxResult ajaxResult = AjaxResult.error("请不要重复提交"+request.getRequestURL()); +//// ServletUtils.renderString(response, JSON.toJSONString(ajaxResult)); +// return false; +// } +// } + return true; + } + else + { + + if (this.isRepeatSubmit(request)) { +// AjaxResult ajaxResult = AjaxResult.error("请不要重复提交"+ request.getRequestURL()); +// ServletUtils.renderString(response, JSON.toJSONString(ajaxResult)); + return false; + } + + return true; + } + } + + /** + * 验证是否重复提交由子类实现具体的防重复提交的规则 + * + * @param request + * @return + * @throws Exception + */ + public abstract boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation); + + public abstract boolean isRepeatSubmit(HttpServletRequest request); +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java new file mode 100644 index 0000000..89d666e --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java @@ -0,0 +1,213 @@ +package com.ruoyi.framework.interceptor.impl; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.servlet.http.HttpServletRequest; + +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.ip.IpUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import com.alibaba.fastjson2.JSON; +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.filter.RepeatedlyRequestWrapper; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.http.HttpHelper; +import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor; + +/** + * 判断请求url和数据是否和上一次相同, + * 如果和上次相同,则是重复提交表单。 有效时间为10秒内。 + * + * @author ruoyi + */ +@Component +public class SameUrlDataInterceptor extends RepeatSubmitInterceptor +{ + public final String REPEAT_PARAMS = "repeatParams"; + + public final String REPEAT_TIME = "repeatTime"; + + + public final String REPEAT_NUM = "repeatNum"; + + // 令牌自定义标识 + @Value("${token.header}") + private String header; + + @Autowired + private RedisCache redisCache; + + @SuppressWarnings("unchecked") + @Override + public boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation) + { + String nowParams = ""; + if (request instanceof RepeatedlyRequestWrapper) + { + RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request; + nowParams = HttpHelper.getBodyString(repeatedlyRequest); + } + + // body参数为空,获取Parameter的数据 + if (StringUtils.isEmpty(nowParams)) + { + nowParams = JSON.toJSONString(request.getParameterMap()); + } + Map nowDataMap = new HashMap(); + nowDataMap.put(REPEAT_PARAMS, nowParams); + nowDataMap.put(REPEAT_TIME, System.currentTimeMillis()); + + // 请求地址(作为存放cache的key值) + String url = request.getRequestURI(); + + // 唯一值(没有消息头则使用请求地址) + String submitKey = StringUtils.trimToEmpty(request.getHeader(header)); + + //ip +// String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); + + // 唯一标识(指定key + url + 消息头) + String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey; +// String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY +ip+ url; + + Integer nowRepeatNum = 1; + + Object sessionObj = redisCache.getCacheObject(cacheRepeatKey); + if (sessionObj != null) + { + Map sessionMap = (Map) sessionObj; + if (sessionMap.containsKey(url)) + { + Map preDataMap = (Map) sessionMap.get(url); + + if(!annotation.enable()) + { + nowDataMap.put(REPEAT_NUM, 1); + + if(preDataMap.containsKey(REPEAT_NUM)) + { + Integer repeatNum = (Integer) preDataMap.get(REPEAT_NUM); + + nowRepeatNum = repeatNum + 1; + + if(nowRepeatNum > annotation.num()) + { + return true; + } + + nowDataMap.put(REPEAT_NUM, nowRepeatNum); + } + } + if(annotation.enable()) { + if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap, annotation.interval())) { + return true; + } + } + } + } + System.out.println(JSONObject.toJSONString(nowDataMap)); + Map cacheMap = new HashMap(); + cacheMap.put(url, nowDataMap); + redisCache.setCacheObject(cacheRepeatKey, cacheMap, annotation.interval(), TimeUnit.MILLISECONDS); + return false; + } + + @Override + public boolean isRepeatSubmit(HttpServletRequest request) + { + String nowParams = ""; + if (request instanceof RepeatedlyRequestWrapper) + { + RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request; + nowParams = HttpHelper.getBodyString(repeatedlyRequest); + } + + // body参数为空,获取Parameter的数据 + if (StringUtils.isEmpty(nowParams)) + { + nowParams = JSON.toJSONString(request.getParameterMap()); + } + Map nowDataMap = new HashMap(); + nowDataMap.put(REPEAT_PARAMS, nowParams); + nowDataMap.put(REPEAT_TIME, System.currentTimeMillis()); + + // 请求地址(作为存放cache的key值) + String url = request.getRequestURI(); + + // 唯一值(没有消息头则使用请求地址) + String submitKey = StringUtils.trimToEmpty(request.getHeader(header)); + + //ip +// String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); + + // 唯一标识(指定key + url + 消息头) + String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey; +// String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY +ip+ url; + Integer nowRepeatNum = 1; + Object sessionObj = redisCache.getCacheObject(cacheRepeatKey); + if (sessionObj != null) + { + Map sessionMap = (Map) sessionObj; + if (sessionMap.containsKey(url)) + { + Map preDataMap = (Map) sessionMap.get(url); + + nowDataMap.put(REPEAT_NUM, nowRepeatNum); + +// 默认可以请求2次 + if(preDataMap.containsKey(REPEAT_NUM)) + { + Integer repeatNum = (Integer) preDataMap.get(REPEAT_NUM); + + nowRepeatNum = repeatNum + 1; + + if(nowRepeatNum > 1) + { + if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap, 1000)) + { + return true; + } + } + + nowDataMap.put(REPEAT_NUM, nowRepeatNum); + } + + } + } + System.out.println(JSONObject.toJSONString(nowDataMap)); + Map cacheMap = new HashMap(); + cacheMap.put(url, nowDataMap); + redisCache.setCacheObject(cacheRepeatKey, cacheMap, 1000, TimeUnit.MILLISECONDS); + return false; + } + + /** + * 判断参数是否相同 + */ + private boolean compareParams(Map nowMap, Map preMap) + { + String nowParams = (String) nowMap.get(REPEAT_PARAMS); + String preParams = (String) preMap.get(REPEAT_PARAMS); + return nowParams.equals(preParams); + } + + /** + * 判断两次间隔时间 + */ + private boolean compareTime(Map nowMap, Map preMap, int interval) + { + long time1 = (Long) nowMap.get(REPEAT_TIME); + long time2 = (Long) preMap.get(REPEAT_TIME); + if ((time1 - time2) < interval) + { + return true; + } + return false; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/RedisKeyExpirationListener.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/RedisKeyExpirationListener.java new file mode 100644 index 0000000..ebe9f79 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/RedisKeyExpirationListener.java @@ -0,0 +1,61 @@ +package com.ruoyi.framework.listener; + +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.enums.UserStatus; +import com.ruoyi.system.service.ISysUserService; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.connection.Message; +import org.springframework.data.redis.listener.KeyExpirationEventMessageListener; +import org.springframework.data.redis.listener.RedisMessageListenerContainer; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * Created by Administrator on 2019/2/26. + */ +@Component +class RedisKeyExpirationListener extends KeyExpirationEventMessageListener { + + public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) { + super(listenerContainer); + } + + @Autowired + private ISysUserService userService; + + private Logger logger = LoggerFactory.getLogger(RedisKeyExpirationListener.class); + + private final Object fanNumUpdate = new Object(); + /** + * 针对redis数据失效事件,进行数据处理 + * @param message + * @param pattern + */ + @Override + public void onMessage(Message message, byte[] pattern) { + // 用户做自己的业务处理即可,注意message.toString()可以获取失效的key + String expiredKey = message.toString(); +// logger.info("key"+expiredKey+"已过期"); + //如果用户的短信验证码错误redis过期,则更新用户的状态为正常 + if(expiredKey.contains(CacheConstants.SMS_ERR_CNT_KEY)) + { + String phone = expiredKey.split(":")[1]; + if(StringUtils.isNotEmpty(phone)) { + SysUser user = userService.selectUserByPhone(phone); + if (ObjectUtils.isNotEmpty(user)) { + user.setStatus(UserStatus.OK.getCode()); + userService.updateUserStatus(user); + } + } + } + + + } +} + diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/AsyncManager.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/AsyncManager.java new file mode 100644 index 0000000..7387a02 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/AsyncManager.java @@ -0,0 +1,55 @@ +package com.ruoyi.framework.manager; + +import java.util.TimerTask; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import com.ruoyi.common.utils.Threads; +import com.ruoyi.common.utils.spring.SpringUtils; + +/** + * 异步任务管理器 + * + * @author ruoyi + */ +public class AsyncManager +{ + /** + * 操作延迟10毫秒 + */ + private final int OPERATE_DELAY_TIME = 10; + + /** + * 异步操作任务调度线程池 + */ + private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService"); + + /** + * 单例模式 + */ + private AsyncManager(){} + + private static AsyncManager me = new AsyncManager(); + + public static AsyncManager me() + { + return me; + } + + /** + * 执行任务 + * + * @param task 任务 + */ + public void execute(TimerTask task) + { + executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS); + } + + /** + * 停止任务线程池 + */ + public void shutdown() + { + Threads.shutdownAndAwaitTermination(executor); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java new file mode 100644 index 0000000..e36ca3c --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java @@ -0,0 +1,39 @@ +package com.ruoyi.framework.manager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import javax.annotation.PreDestroy; + +/** + * 确保应用退出时能关闭后台线程 + * + * @author ruoyi + */ +@Component +public class ShutdownManager +{ + private static final Logger logger = LoggerFactory.getLogger("sys-user"); + + @PreDestroy + public void destroy() + { + shutdownAsyncManager(); + } + + /** + * 停止异步执行任务 + */ + private void shutdownAsyncManager() + { + try + { + logger.info("====关闭后台任务任务线程池===="); + AsyncManager.me().shutdown(); + } + catch (Exception e) + { + logger.error(e.getMessage(), e); + } + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java new file mode 100644 index 0000000..23d0230 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java @@ -0,0 +1,102 @@ +package com.ruoyi.framework.manager.factory; + +import java.util.TimerTask; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.utils.LogUtils; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.ip.AddressUtils; +import com.ruoyi.common.utils.ip.IpUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.system.domain.SysLogininfor; +import com.ruoyi.system.domain.SysOperLog; +import com.ruoyi.system.service.ISysLogininforService; +import com.ruoyi.system.service.ISysOperLogService; +import eu.bitwalker.useragentutils.UserAgent; + +/** + * 异步工厂(产生任务用) + * + * @author ruoyi + */ +public class AsyncFactory +{ + private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user"); + + /** + * 记录登录信息 + * + * @param username 用户名 + * @param status 状态 + * @param message 消息 + * @param args 列表 + * @return 任务task + */ + public static TimerTask recordLogininfor(final String username, final String status, final String message, + final Object... args) + { + final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); + final String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); + return new TimerTask() + { + @Override + public void run() + { + String address = AddressUtils.getRealAddressByIP(ip); + StringBuilder s = new StringBuilder(); + s.append(LogUtils.getBlock(ip)); + s.append(address); + s.append(LogUtils.getBlock(username)); + s.append(LogUtils.getBlock(status)); + s.append(LogUtils.getBlock(message)); + // 打印信息到日志 + sys_user_logger.info(s.toString(), args); + // 获取客户端操作系统 + String os = userAgent.getOperatingSystem().getName(); + // 获取客户端浏览器 + String browser = userAgent.getBrowser().getName(); + // 封装对象 + SysLogininfor logininfor = new SysLogininfor(); + logininfor.setUserName(username); + logininfor.setIpaddr(ip); + logininfor.setLoginLocation(address); + logininfor.setBrowser(browser); + logininfor.setOs(os); + logininfor.setMsg(message); + // 日志状态 + if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) + { + logininfor.setStatus(Constants.SUCCESS); + } + else if (Constants.LOGIN_FAIL.equals(status)) + { + logininfor.setStatus(Constants.FAIL); + } + // 插入数据 + SpringUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor); + } + }; + } + + /** + * 操作日志记录 + * + * @param operLog 操作日志信息 + * @return 任务task + */ + public static TimerTask recordOper(final SysOperLog operLog) + { + return new TimerTask() + { + @Override + public void run() + { + // 远程查询操作地点 + operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp())); + SpringUtils.getBean(ISysOperLogService.class).insertOperlog(operLog); + } + }; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/context/AuthenticationContextHolder.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/context/AuthenticationContextHolder.java new file mode 100644 index 0000000..6c776ce --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/context/AuthenticationContextHolder.java @@ -0,0 +1,28 @@ +package com.ruoyi.framework.security.context; + +import org.springframework.security.core.Authentication; + +/** + * 身份验证信息 + * + * @author ruoyi + */ +public class AuthenticationContextHolder +{ + private static final ThreadLocal contextHolder = new ThreadLocal<>(); + + public static Authentication getContext() + { + return contextHolder.get(); + } + + public static void setContext(Authentication context) + { + contextHolder.set(context); + } + + public static void clearContext() + { + contextHolder.remove(); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/context/PermissionContextHolder.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/context/PermissionContextHolder.java new file mode 100644 index 0000000..5472f3d --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/context/PermissionContextHolder.java @@ -0,0 +1,27 @@ +package com.ruoyi.framework.security.context; + +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import com.ruoyi.common.core.text.Convert; + +/** + * 权限信息 + * + * @author ruoyi + */ +public class PermissionContextHolder +{ + private static final String PERMISSION_CONTEXT_ATTRIBUTES = "PERMISSION_CONTEXT"; + + public static void setContext(String permission) + { + RequestContextHolder.currentRequestAttributes().setAttribute(PERMISSION_CONTEXT_ATTRIBUTES, permission, + RequestAttributes.SCOPE_REQUEST); + } + + public static String getContext() + { + return Convert.toStr(RequestContextHolder.currentRequestAttributes().getAttribute(PERMISSION_CONTEXT_ATTRIBUTES, + RequestAttributes.SCOPE_REQUEST)); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java new file mode 100644 index 0000000..3eb2495 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java @@ -0,0 +1,44 @@ +package com.ruoyi.framework.security.filter; + +import java.io.IOException; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.web.service.TokenService; + +/** + * token过滤器 验证token有效性 + * + * @author ruoyi + */ +@Component +public class JwtAuthenticationTokenFilter extends OncePerRequestFilter +{ + @Autowired + private TokenService tokenService; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) + throws ServletException, IOException + { + LoginUser loginUser = tokenService.getLoginUser(request); + if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) + { + tokenService.verifyToken(loginUser); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities()); + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + } + chain.doFilter(request, response); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java new file mode 100644 index 0000000..93b7032 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java @@ -0,0 +1,34 @@ +package com.ruoyi.framework.security.handle; + +import java.io.IOException; +import java.io.Serializable; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; +import com.alibaba.fastjson2.JSON; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; + +/** + * 认证失败处理类 返回未授权 + * + * @author ruoyi + */ +@Component +public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable +{ + private static final long serialVersionUID = -8970718410437077606L; + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) + throws IOException + { + int code = HttpStatus.UNAUTHORIZED; + String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI()); + ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, msg))); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java new file mode 100644 index 0000000..9245bbd --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java @@ -0,0 +1,58 @@ +package com.ruoyi.framework.security.handle; + +import com.alibaba.fastjson2.JSON; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.manager.AsyncManager; +import com.ruoyi.framework.manager.factory.AsyncFactory; +import com.ruoyi.framework.web.service.TokenService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 自定义退出处理类 返回成功 + * + * @author ruoyi + */ +@Configuration +public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler +{ + @Autowired + private TokenService tokenService; + + @Autowired + private RedisCache redisCache; + + /** + * 退出处理 + * + * @return + */ + @Override + public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) + throws IOException, ServletException + { + LoginUser loginUser = tokenService.getLoginUser(request); + if (StringUtils.isNotNull(loginUser)) + { + String userName = loginUser.getUsername(); + // 删除用户缓存记录 + tokenService.delLoginUser(loginUser.getToken(),loginUser.getUserId(),loginUser.getLoginType()); + + // 记录用户退出日志 + AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功")); + } + ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success("退出成功"))); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/sms/SmsCodeAuthenticationProvider.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/sms/SmsCodeAuthenticationProvider.java new file mode 100644 index 0000000..9ca1440 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/sms/SmsCodeAuthenticationProvider.java @@ -0,0 +1,52 @@ +package com.ruoyi.framework.security.sms; + +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; + +/** + * 短信登陆鉴权 Provider,要求实现 AuthenticationProvider 接口 + * + * @author gmk + */ +public class SmsCodeAuthenticationProvider implements AuthenticationProvider { + + private UserDetailsService userDetailsService; + + public SmsCodeAuthenticationProvider(UserDetailsService userDetailsService){ + setUserDetailsService(userDetailsService); + } + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + SmsCodeAuthenticationToken authenticationToken = (SmsCodeAuthenticationToken) authentication; + + String telephone = (String) authenticationToken.getPrincipal(); + + UserDetails userDetails = userDetailsService.loadUserByUsername(telephone); + + // 此时鉴权成功后,应当重新 new 一个拥有鉴权的 authenticationResult 返回 + SmsCodeAuthenticationToken authenticationResult = new SmsCodeAuthenticationToken(userDetails, userDetails.getAuthorities()); + + authenticationResult.setDetails(authenticationToken.getDetails()); + + return authenticationResult; + } + + + @Override + public boolean supports(Class authentication) { + // 判断 authentication 是不是 SmsCodeAuthenticationToken 的子类或子接口 + return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication); + } + + public UserDetailsService getUserDetailsService() { + return userDetailsService; + } + + public void setUserDetailsService(UserDetailsService userDetailsService) { + this.userDetailsService = userDetailsService; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/sms/SmsCodeAuthenticationToken.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/sms/SmsCodeAuthenticationToken.java new file mode 100644 index 0000000..e7a15db --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/sms/SmsCodeAuthenticationToken.java @@ -0,0 +1,73 @@ +package com.ruoyi.framework.security.sms; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.SpringSecurityCoreVersion; + +import java.util.Collection; + +/** + * 短信登录 AuthenticationToken,模仿 UsernamePasswordAuthenticationToken 实现 + * + * @author gmk + */ +public class SmsCodeAuthenticationToken extends AbstractAuthenticationToken { + + private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; + + /** + * 在 UsernamePasswordAuthenticationToken 中该字段代表登录的用户名, + * 在这里就代表登录的手机号码 + */ + private final Object principal; + + //短信验证码 + private Object credentials; + + /** + * 构建一个没有鉴权的 SmsCodeAuthenticationToken + */ + public SmsCodeAuthenticationToken(Object principal, Object credentials) { + super(null); + this.principal = principal; + this.credentials = credentials; + setAuthenticated(false); + } + + + /** + * 构建拥有鉴权的 SmsCodeAuthenticationToken + */ + public SmsCodeAuthenticationToken(Object principal, Collection authorities) { + super(authorities); + this.principal = principal; + // must use super, as we override + super.setAuthenticated(true); + } + + @Override + public Object getCredentials() { + return this.credentials; + } + + @Override + public Object getPrincipal() { + return this.principal; + } + + @Override + public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { + if (isAuthenticated) { + throw new IllegalArgumentException( + "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); + } + + super.setAuthenticated(false); + } + + @Override + public void eraseCredentials() { + super.eraseCredentials(); + } + +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/Server.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/Server.java new file mode 100644 index 0000000..63b03da --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/Server.java @@ -0,0 +1,240 @@ +package com.ruoyi.framework.web.domain; + +import java.net.UnknownHostException; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import com.ruoyi.common.utils.Arith; +import com.ruoyi.common.utils.ip.IpUtils; +import com.ruoyi.framework.web.domain.server.Cpu; +import com.ruoyi.framework.web.domain.server.Jvm; +import com.ruoyi.framework.web.domain.server.Mem; +import com.ruoyi.framework.web.domain.server.Sys; +import com.ruoyi.framework.web.domain.server.SysFile; +import oshi.SystemInfo; +import oshi.hardware.CentralProcessor; +import oshi.hardware.CentralProcessor.TickType; +import oshi.hardware.GlobalMemory; +import oshi.hardware.HardwareAbstractionLayer; +import oshi.software.os.FileSystem; +import oshi.software.os.OSFileStore; +import oshi.software.os.OperatingSystem; +import oshi.util.Util; + +/** + * 服务器相关信息 + * + * @author ruoyi + */ +public class Server +{ + private static final int OSHI_WAIT_SECOND = 1000; + + /** + * CPU相关信息 + */ + private Cpu cpu = new Cpu(); + + /** + * 內存相关信息 + */ + private Mem mem = new Mem(); + + /** + * JVM相关信息 + */ + private Jvm jvm = new Jvm(); + + /** + * 服务器相关信息 + */ + private Sys sys = new Sys(); + + /** + * 磁盘相关信息 + */ + private List sysFiles = new LinkedList(); + + public Cpu getCpu() + { + return cpu; + } + + public void setCpu(Cpu cpu) + { + this.cpu = cpu; + } + + public Mem getMem() + { + return mem; + } + + public void setMem(Mem mem) + { + this.mem = mem; + } + + public Jvm getJvm() + { + return jvm; + } + + public void setJvm(Jvm jvm) + { + this.jvm = jvm; + } + + public Sys getSys() + { + return sys; + } + + public void setSys(Sys sys) + { + this.sys = sys; + } + + public List getSysFiles() + { + return sysFiles; + } + + public void setSysFiles(List sysFiles) + { + this.sysFiles = sysFiles; + } + + public void copyTo() throws Exception + { + SystemInfo si = new SystemInfo(); + HardwareAbstractionLayer hal = si.getHardware(); + + setCpuInfo(hal.getProcessor()); + + setMemInfo(hal.getMemory()); + + setSysInfo(); + + setJvmInfo(); + + setSysFiles(si.getOperatingSystem()); + } + + /** + * 设置CPU信息 + */ + private void setCpuInfo(CentralProcessor processor) + { + // CPU信息 + long[] prevTicks = processor.getSystemCpuLoadTicks(); + Util.sleep(OSHI_WAIT_SECOND); + long[] ticks = processor.getSystemCpuLoadTicks(); + long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()]; + long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()]; + long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()]; + long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()]; + long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()]; + long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()]; + long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()]; + long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()]; + long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal; + cpu.setCpuNum(processor.getLogicalProcessorCount()); + cpu.setTotal(totalCpu); + cpu.setSys(cSys); + cpu.setUsed(user); + cpu.setWait(iowait); + cpu.setFree(idle); + } + + /** + * 设置内存信息 + */ + private void setMemInfo(GlobalMemory memory) + { + mem.setTotal(memory.getTotal()); + mem.setUsed(memory.getTotal() - memory.getAvailable()); + mem.setFree(memory.getAvailable()); + } + + /** + * 设置服务器信息 + */ + private void setSysInfo() + { + Properties props = System.getProperties(); + sys.setComputerName(IpUtils.getHostName()); + sys.setComputerIp(IpUtils.getHostIp()); + sys.setOsName(props.getProperty("os.name")); + sys.setOsArch(props.getProperty("os.arch")); + sys.setUserDir(props.getProperty("user.dir")); + } + + /** + * 设置Java虚拟机 + */ + private void setJvmInfo() throws UnknownHostException + { + Properties props = System.getProperties(); + jvm.setTotal(Runtime.getRuntime().totalMemory()); + jvm.setMax(Runtime.getRuntime().maxMemory()); + jvm.setFree(Runtime.getRuntime().freeMemory()); + jvm.setVersion(props.getProperty("java.version")); + jvm.setHome(props.getProperty("java.home")); + } + + /** + * 设置磁盘信息 + */ + private void setSysFiles(OperatingSystem os) + { + FileSystem fileSystem = os.getFileSystem(); + List fsArray = fileSystem.getFileStores(); + for (OSFileStore fs : fsArray) + { + long free = fs.getUsableSpace(); + long total = fs.getTotalSpace(); + long used = total - free; + SysFile sysFile = new SysFile(); + sysFile.setDirName(fs.getMount()); + sysFile.setSysTypeName(fs.getType()); + sysFile.setTypeName(fs.getName()); + sysFile.setTotal(convertFileSize(total)); + sysFile.setFree(convertFileSize(free)); + sysFile.setUsed(convertFileSize(used)); + sysFile.setUsage(Arith.mul(Arith.div(used, total, 4), 100)); + sysFiles.add(sysFile); + } + } + + /** + * 字节转换 + * + * @param size 字节大小 + * @return 转换后值 + */ + public String convertFileSize(long size) + { + long kb = 1024; + long mb = kb * 1024; + long gb = mb * 1024; + if (size >= gb) + { + return String.format("%.1f GB", (float) size / gb); + } + else if (size >= mb) + { + float f = (float) size / mb; + return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f); + } + else if (size >= kb) + { + float f = (float) size / kb; + return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f); + } + else + { + return String.format("%d B", size); + } + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/SysNoticeEntity.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/SysNoticeEntity.java new file mode 100644 index 0000000..27f7fb5 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/SysNoticeEntity.java @@ -0,0 +1,125 @@ +package com.ruoyi.framework.web.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.mybatis.JsonListLongTypeHandler; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 通知公告表 + *

+ * + * @author ck + * @since 2023-04-14 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "SysNotice对象", description = "通知公告表") +public class SysNoticeEntity { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增id") + private Integer noticeId; + + @ApiModelProperty("通知标题") + private String noticeTitle; + + @ApiModelProperty("通知类型--字典表sys_notice_type") + @TableField("notice_type") + private String noticeType; + + @ApiModelProperty("通知内容") + @TableField("notice_content") + private String noticeContent; + + @ApiModelProperty("状态 0未读 1已读") + @TableField("status") + private String status; + + @ApiModelProperty("创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty("插入时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty("更新人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty("更新时间") + @TableField("update_time") + private LocalDateTime updateTime; + + @ApiModelProperty("备注") + @TableField("remark") + private String remark; + + @ApiModelProperty("接收人") + @TableField("recive_user") + private Long reciveUser; + + @ApiModelProperty("工作流id") + @TableField("flw_processid") + private String flwProcessid; + + @ApiModelProperty("工作流任务id") + @TableField("flw_taskid") + private String flwTaskid; + + @ApiModelProperty("实际发送时间") + @TableField("send_time") + private LocalDateTime sendTime; + + @ApiModelProperty("发送是否成功,1成功 0失败") + @TableField("send_status") + private String sendStatus; + + @ApiModelProperty("接收人手机号") + @TableField("recive_user_phone") + private String reciveUserPhone; + + @ApiModelProperty("计划发送时间(同天当前时间之前立即发送)") + @TableField("exp_send_time") + private LocalDateTime expSendTime; + + @ApiModelProperty("加入定时任务标记 默认0未加入 1已加入") + @TableField("add_flag") + private String addFlag; + + @ApiModelProperty("通知对象ids数组") + @TableField(value = "notice_object_id",typeHandler = JsonListLongTypeHandler.class) + private List noticeObjectId; + + @ApiModelProperty("通知模板id") + @TableField("notice_model_id") + private Long noticeModelId; + + @ApiModelProperty("通知场景--字典yw_notice_scene (0一般告警 1重大告警 ....)") + @TableField("model_scene") + private String modelScene; + + @ApiModelProperty("对象属性--yw_notice_object(0场馆层 1分公司层 2亚运指挥层 3ITCC层)") + @TableField("object_proto") + private String objectProto; + + @ApiModelProperty("通知对象(是指具体的通知接受者,呈现方式包括场馆+群组;分公司+群组名;地市+群组名;ITCC+群组名;场馆+个人名;分公司+个人名;地市+个人名;ITCC+个人名这几种组合。具体呈现内容和对象属性、通知方式相关联)") + @TableField("notice_object") + private String noticeObject; + + @ApiModelProperty("通知类型model_suit_type 1 普通 2 手工 3简报") + @TableField("model_suit_type") + private String modelSuitType; + +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/dto/MobileOfficesDTO.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/dto/MobileOfficesDTO.java new file mode 100644 index 0000000..19462d1 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/dto/MobileOfficesDTO.java @@ -0,0 +1,47 @@ +package com.ruoyi.framework.web.domain.dto; + +import lombok.Data; + +@Data +public class MobileOfficesDTO { + + /** + * 发送移动办公群ID + * 根据省公司的参数要求,需要提供群号 + * 例如:378930703,378930703 多个群需要用英文逗号‘,’隔开输入 + * */ + private String mobileoffices; + + /** + * 移动办公群人员@ + * */ + private String mobileoffice_user; + + /** + * 发送的文件 base64 + * 文件、图片、文本必填一个,支持同时传送三个 + * file(文件),filename(文件名)一起传递 + * img(图片),imgname(图片名)一起传递 + * */ + private String file; + + /** + * 文件名称 + * */ + private String filename; + + /** + * 发送的图片 base64 + * */ + private String img; + + /** + * 图片名称 + * */ + private String imgname; + + /** + * 发送内容 + * */ + private String content; +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Cpu.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Cpu.java new file mode 100644 index 0000000..a13a66c --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Cpu.java @@ -0,0 +1,101 @@ +package com.ruoyi.framework.web.domain.server; + +import com.ruoyi.common.utils.Arith; + +/** + * CPU相关信息 + * + * @author ruoyi + */ +public class Cpu +{ + /** + * 核心数 + */ + private int cpuNum; + + /** + * CPU总的使用率 + */ + private double total; + + /** + * CPU系统使用率 + */ + private double sys; + + /** + * CPU用户使用率 + */ + private double used; + + /** + * CPU当前等待率 + */ + private double wait; + + /** + * CPU当前空闲率 + */ + private double free; + + public int getCpuNum() + { + return cpuNum; + } + + public void setCpuNum(int cpuNum) + { + this.cpuNum = cpuNum; + } + + public double getTotal() + { + return Arith.round(Arith.mul(total, 100), 2); + } + + public void setTotal(double total) + { + this.total = total; + } + + public double getSys() + { + return Arith.round(Arith.mul(sys / total, 100), 2); + } + + public void setSys(double sys) + { + this.sys = sys; + } + + public double getUsed() + { + return Arith.round(Arith.mul(used / total, 100), 2); + } + + public void setUsed(double used) + { + this.used = used; + } + + public double getWait() + { + return Arith.round(Arith.mul(wait / total, 100), 2); + } + + public void setWait(double wait) + { + this.wait = wait; + } + + public double getFree() + { + return Arith.round(Arith.mul(free / total, 100), 2); + } + + public void setFree(double free) + { + this.free = free; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java new file mode 100644 index 0000000..444b280 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java @@ -0,0 +1,130 @@ +package com.ruoyi.framework.web.domain.server; + +import java.lang.management.ManagementFactory; +import com.ruoyi.common.utils.Arith; +import com.ruoyi.common.utils.DateUtils; + +/** + * JVM相关信息 + * + * @author ruoyi + */ +public class Jvm +{ + /** + * 当前JVM占用的内存总数(M) + */ + private double total; + + /** + * JVM最大可用内存总数(M) + */ + private double max; + + /** + * JVM空闲内存(M) + */ + private double free; + + /** + * JDK版本 + */ + private String version; + + /** + * JDK路径 + */ + private String home; + + public double getTotal() + { + return Arith.div(total, (1024 * 1024), 2); + } + + public void setTotal(double total) + { + this.total = total; + } + + public double getMax() + { + return Arith.div(max, (1024 * 1024), 2); + } + + public void setMax(double max) + { + this.max = max; + } + + public double getFree() + { + return Arith.div(free, (1024 * 1024), 2); + } + + public void setFree(double free) + { + this.free = free; + } + + public double getUsed() + { + return Arith.div(total - free, (1024 * 1024), 2); + } + + public double getUsage() + { + return Arith.mul(Arith.div(total - free, total, 4), 100); + } + + /** + * 获取JDK名称 + */ + public String getName() + { + return ManagementFactory.getRuntimeMXBean().getVmName(); + } + + public String getVersion() + { + return version; + } + + public void setVersion(String version) + { + this.version = version; + } + + public String getHome() + { + return home; + } + + public void setHome(String home) + { + this.home = home; + } + + /** + * JDK启动时间 + */ + public String getStartTime() + { + return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getServerStartDate()); + } + + /** + * JDK运行时间 + */ + public String getRunTime() + { + return DateUtils.getDatePoor(DateUtils.getNowDate(), DateUtils.getServerStartDate()); + } + + /** + * 运行参数 + */ + public String getInputArgs() + { + return ManagementFactory.getRuntimeMXBean().getInputArguments().toString(); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Mem.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Mem.java new file mode 100644 index 0000000..13eec52 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Mem.java @@ -0,0 +1,61 @@ +package com.ruoyi.framework.web.domain.server; + +import com.ruoyi.common.utils.Arith; + +/** + * 內存相关信息 + * + * @author ruoyi + */ +public class Mem +{ + /** + * 内存总量 + */ + private double total; + + /** + * 已用内存 + */ + private double used; + + /** + * 剩余内存 + */ + private double free; + + public double getTotal() + { + return Arith.div(total, (1024 * 1024 * 1024), 2); + } + + public void setTotal(long total) + { + this.total = total; + } + + public double getUsed() + { + return Arith.div(used, (1024 * 1024 * 1024), 2); + } + + public void setUsed(long used) + { + this.used = used; + } + + public double getFree() + { + return Arith.div(free, (1024 * 1024 * 1024), 2); + } + + public void setFree(long free) + { + this.free = free; + } + + public double getUsage() + { + return Arith.mul(Arith.div(used, total, 4), 100); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Sys.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Sys.java new file mode 100644 index 0000000..45d64d9 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Sys.java @@ -0,0 +1,84 @@ +package com.ruoyi.framework.web.domain.server; + +/** + * 系统相关信息 + * + * @author ruoyi + */ +public class Sys +{ + /** + * 服务器名称 + */ + private String computerName; + + /** + * 服务器Ip + */ + private String computerIp; + + /** + * 项目路径 + */ + private String userDir; + + /** + * 操作系统 + */ + private String osName; + + /** + * 系统架构 + */ + private String osArch; + + public String getComputerName() + { + return computerName; + } + + public void setComputerName(String computerName) + { + this.computerName = computerName; + } + + public String getComputerIp() + { + return computerIp; + } + + public void setComputerIp(String computerIp) + { + this.computerIp = computerIp; + } + + public String getUserDir() + { + return userDir; + } + + public void setUserDir(String userDir) + { + this.userDir = userDir; + } + + public String getOsName() + { + return osName; + } + + public void setOsName(String osName) + { + this.osName = osName; + } + + public String getOsArch() + { + return osArch; + } + + public void setOsArch(String osArch) + { + this.osArch = osArch; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/SysFile.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/SysFile.java new file mode 100644 index 0000000..1320cde --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/SysFile.java @@ -0,0 +1,114 @@ +package com.ruoyi.framework.web.domain.server; + +/** + * 系统文件相关信息 + * + * @author ruoyi + */ +public class SysFile +{ + /** + * 盘符路径 + */ + private String dirName; + + /** + * 盘符类型 + */ + private String sysTypeName; + + /** + * 文件类型 + */ + private String typeName; + + /** + * 总大小 + */ + private String total; + + /** + * 剩余大小 + */ + private String free; + + /** + * 已经使用量 + */ + private String used; + + /** + * 资源的使用率 + */ + private double usage; + + public String getDirName() + { + return dirName; + } + + public void setDirName(String dirName) + { + this.dirName = dirName; + } + + public String getSysTypeName() + { + return sysTypeName; + } + + public void setSysTypeName(String sysTypeName) + { + this.sysTypeName = sysTypeName; + } + + public String getTypeName() + { + return typeName; + } + + public void setTypeName(String typeName) + { + this.typeName = typeName; + } + + public String getTotal() + { + return total; + } + + public void setTotal(String total) + { + this.total = total; + } + + public String getFree() + { + return free; + } + + public void setFree(String free) + { + this.free = free; + } + + public String getUsed() + { + return used; + } + + public void setUsed(String used) + { + this.used = used; + } + + public double getUsage() + { + return usage; + } + + public void setUsage(double usage) + { + this.usage = usage; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/ErrorInfoBuilder.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/ErrorInfoBuilder.java new file mode 100644 index 0000000..207393d --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/ErrorInfoBuilder.java @@ -0,0 +1,138 @@ +package com.ruoyi.framework.web.exception; + +import cn.hutool.core.util.StrUtil; +import com.ruoyi.common.core.domain.AjaxResult; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.web.ErrorProperties; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.util.WebUtils; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * ErrorBuilder之所以使用@Order注解和实现HandlerExceptionResolver接口是为了获取错误/异常 + * 通常情况下@ExceptionHandler并不需要这么做,因为在映射方法注入Throwable就可以获得错误/异常, + * 这是主要是为了ErrorController根据Request对象快速获取错误/异常 + */ +@Order(Ordered.HIGHEST_PRECEDENCE) +@Component +@Slf4j +public class ErrorInfoBuilder implements HandlerExceptionResolver, Ordered { + + /** + * 错误KEY + */ + private final static String ERROR_NAME = "error"; + + private ErrorProperties errorProperties; + + public ErrorInfoBuilder(ServerProperties serverProperties) { + this.errorProperties = serverProperties.getError(); + } + + public AjaxResult getErrorInfo(HttpServletRequest request) { + return getErrorInfo(request, getError(request)); + } + + public AjaxResult getErrorInfo(HttpServletRequest request, Throwable error) { + log.error(request.getRequestURI() + " error: " + error.getMessage(), error); + return AjaxResult.error("服务器异常" + error.getMessage()); + } + + public Throwable getError(HttpServletRequest request) { + //根据HandlerExceptionResolver接口方法来获取错误 + Throwable error = (Throwable) request.getAttribute(ERROR_NAME); + + if (error == null) { + error = (Throwable) request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE); + } + + //当获取错误非空,取出RootCause + if (error != null) { + while (error instanceof ServletException && error.getCause() != null) { + error = error.getCause(); + } + } else { + String message = (String) request.getAttribute(WebUtils.ERROR_MESSAGE_ATTRIBUTE); + if (StrUtil.isEmpty(message)) { + HttpStatus httpStatus = getHttpStatus(request); + message = "Unknown Exception But " + httpStatus.value() + " " + httpStatus.getReasonPhrase(); + } + + error = new Exception(message); + } + + return error; + } + + /** + * 获取通信状态 + */ + public HttpStatus getHttpStatus(HttpServletRequest request) { + Integer statusCode = (Integer) request.getAttribute(WebUtils.ERROR_STATUS_CODE_ATTRIBUTE); + try { + return statusCode != null ? HttpStatus.valueOf(statusCode) : HttpStatus.INTERNAL_SERVER_ERROR; + } catch (Exception e) { + return HttpStatus.INTERNAL_SERVER_ERROR; + } + } + + /** + * 获取堆栈轨迹(StackTrace) + */ + public String getStackTraceInfo(Throwable error, boolean flag) { +// if (!flag) { +// return "omitted"; +// } + StringWriter stackTrace = new StringWriter(); + error.printStackTrace(new PrintWriter(stackTrace)); + stackTrace.flush(); + return stackTrace.toString(); + } + + public boolean isIncludeStackTrade(HttpServletRequest request) { + // 读取配置 + ErrorProperties.IncludeAttribute includeStacktrace = errorProperties.getIncludeStacktrace(); + + if (includeStacktrace == ErrorProperties.IncludeAttribute.ALWAYS) { + return true; + } + + // 若请求参数含有trace + if (includeStacktrace == ErrorProperties.IncludeAttribute.ON_PARAM) { + String parameter = request.getParameter("trace"); + return parameter != null && !"false".equalsIgnoreCase(parameter); + } + + return false; + } + + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE; + } + + @Override + public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { + httpServletRequest.setAttribute(ERROR_NAME, e); + return null; + } + + public ErrorProperties getErrorProperties() { + return errorProperties; + } + + public void setErrorProperties(ErrorProperties errorProperties) { + this.errorProperties = errorProperties; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..ac61eee --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java @@ -0,0 +1,188 @@ +package com.ruoyi.framework.web.exception; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.apache.ibatis.exceptions.PersistenceException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.validation.BindException; +import org.springframework.validation.ObjectError; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingServletRequestParameterException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.DemoModeException; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.StringUtils; + +import java.sql.SQLIntegrityConstraintViolationException; +import java.util.List; + +/** + * 全局异常处理器 + * + * @author ruoyi + */ +@RestControllerAdvice +public class GlobalExceptionHandler +{ + private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); + + @Autowired + ErrorInfoBuilder errorInfoBuilder; + + @ExceptionHandler(value = Exception.class) + public ResponseEntity errorHandle(HttpServletRequest request, Exception e) { + e.printStackTrace(); + ResponseEntity responseEntity = null; + + if(e instanceof MissingServletRequestParameterException){ + responseEntity = new ResponseEntity(AjaxResult.error(e.getMessage()), org.springframework.http.HttpStatus.OK); + return responseEntity; + } + + if(e instanceof ServiceException){ + responseEntity = new ResponseEntity(AjaxResult.error(e.getMessage()), org.springframework.http.HttpStatus.OK); + return responseEntity; + } + + if(e instanceof DuplicateKeyException) { + log.error("数据重复" + e.getMessage(),e); + responseEntity = new ResponseEntity(AjaxResult.error("数据重复!"), org.springframework.http.HttpStatus.OK); + return responseEntity; + } + + if(e instanceof PersistenceException) { + Throwable rootCause = ExceptionUtils.getRootCause(e); + if(rootCause instanceof SQLIntegrityConstraintViolationException + && rootCause.getMessage().toLowerCase().contains("duplicate")){ + log.error("数据库处理异常" + e.getMessage(),e); + responseEntity = new ResponseEntity(AjaxResult.error("数据重复!"+e.getMessage()), org.springframework.http.HttpStatus.OK); + return responseEntity; + } + + log.error("数据库处理异常" + e.getMessage(),e); + responseEntity = new ResponseEntity(AjaxResult.error("数据库错误,请联系管理员!"+e.getMessage()), org.springframework.http.HttpStatus.OK); + return responseEntity; + } + + if (e instanceof MethodArgumentNotValidException) { + log.error(request.getRequestURI() + e.getMessage(), e); + MethodArgumentNotValidException exception = (MethodArgumentNotValidException) e; + List allErrors = exception.getBindingResult().getAllErrors(); + StringBuilder stringBuilder = new StringBuilder(); + for (ObjectError objectError : allErrors) { + stringBuilder.append(objectError.getDefaultMessage()).append(";"); + } + if (stringBuilder.length() > 0) { + stringBuilder.deleteCharAt(stringBuilder.length() - 1); + } + return new ResponseEntity(AjaxResult.error(stringBuilder.toString()), org.springframework.http.HttpStatus.OK); + } + + if(e instanceof IllegalArgumentException){ + responseEntity = new ResponseEntity(AjaxResult.error(e.getMessage()), org.springframework.http.HttpStatus.OK); + return responseEntity; + } + + AjaxResult errorInfo = errorInfoBuilder.getErrorInfo(request); + responseEntity = new ResponseEntity(errorInfo, org.springframework.http.HttpStatus.OK); + + return responseEntity; + } + + /** + * 权限校验异常 + */ + @ExceptionHandler(AccessDeniedException.class) + public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage()); + return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权"); + } + + /** + * 请求方式不支持 + */ + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, + HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); + return AjaxResult.error(e.getMessage()); + } + + /** + * 业务异常 + */ + @ExceptionHandler(ServiceException.class) + public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) + { + log.error(e.getMessage(), e); + Integer code = e.getCode(); + return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage()); + } + +// /** +// * 拦截未知的运行时异常 +// */ +// @ExceptionHandler(RuntimeException.class) +// public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) +// { +// String requestURI = request.getRequestURI(); +// log.error("请求地址'{}',发生未知异常.", requestURI, e); +// return AjaxResult.error(e.getMessage()); +// } + +// /** +// * 系统异常 +// */ +// @ExceptionHandler(Exception.class) +// public AjaxResult handleException(Exception e, HttpServletRequest request) +// { +// String requestURI = request.getRequestURI(); +// log.error("请求地址'{}',发生系统异常.", requestURI, e); +// return AjaxResult.error(e.getMessage()); +// } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(BindException.class) + public AjaxResult handleBindException(BindException e) + { + log.error(e.getMessage(), e); + String message = e.getAllErrors().get(0).getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) + { + log.error(e.getMessage(), e); + String message = e.getBindingResult().getFieldError().getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 演示模式异常 + */ + @ExceptionHandler(DemoModeException.class) + public AjaxResult handleDemoModeException(DemoModeException e) + { + return AjaxResult.error("演示模式,不允许操作"); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/mapper/SysLoginMapper.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/mapper/SysLoginMapper.java new file mode 100644 index 0000000..1d69066 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/mapper/SysLoginMapper.java @@ -0,0 +1,11 @@ +package com.ruoyi.framework.web.mapper; + +import com.ruoyi.framework.web.domain.SysNoticeEntity; +import org.apache.ibatis.annotations.Insert; + +public interface SysLoginMapper { + + @Insert("insert into sys_notice (notice_title, notice_type, status, create_by,create_time, notice_content, recive_user,recive_user_phone, exp_send_time, add_flag) VALUES " + + "(#{noticeTitle},#{noticeType},#{status},#{createBy},#{createTime},#{noticeContent},#{reciveUser},#{reciveUserPhone},#{expSendTime},#{addFlag})") + void insertNotice(SysNoticeEntity notice); +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/AppPermissionService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/AppPermissionService.java new file mode 100644 index 0000000..27a4cf6 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/AppPermissionService.java @@ -0,0 +1,169 @@ +package com.ruoyi.framework.web.service; + +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.security.context.PermissionContextHolder; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.Set; + +/** + * RuoYi首创 自定义权限实现,ss取自SpringSecurity首字母 app专用 + * + * @author ruoyi + */ +@Service("app") +public class AppPermissionService +{ + /** 所有权限标识 */ + private static final String ALL_PERMISSION = "*:*:*"; + + /** 管理员角色权限标识 */ + private static final String SUPER_ADMIN = "admin"; + + private static final String ROLE_DELIMETER = ","; + + private static final String PERMISSION_DELIMETER = ","; + + /** + * 验证用户是否具备某权限 + * + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public boolean hasPermi(String permission) + { + if (StringUtils.isEmpty(permission)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getAppPermissions())) + { + return false; + } + PermissionContextHolder.setContext(permission); + return hasPermissions(loginUser.getAppPermissions(), permission); + } + + /** + * 验证用户是否不具备某权限,与 hasPermi逻辑相反 + * + * @param permission 权限字符串 + * @return 用户是否不具备某权限 + */ + public boolean lacksPermi(String permission) + { + return hasPermi(permission) != true; + } + + /** + * 验证用户是否具有以下任意一个权限 + * + * @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表 + * @return 用户是否具有以下任意一个权限 + */ + public boolean hasAnyPermi(String permissions) + { + if (StringUtils.isEmpty(permissions)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getAppPermissions())) + { + return false; + } + PermissionContextHolder.setContext(permissions); + Set authorities = loginUser.getAppPermissions(); + for (String permission : permissions.split(PERMISSION_DELIMETER)) + { + if (permission != null && hasPermissions(authorities, permission)) + { + return true; + } + } + return false; + } + + /** + * 判断用户是否拥有某个角色 + * + * @param role 角色字符串 + * @return 用户是否具备某角色 + */ + public boolean hasRole(String role) + { + if (StringUtils.isEmpty(role)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) + { + return false; + } + for (SysRole sysRole : loginUser.getUser().getRoles()) + { + String roleKey = sysRole.getRoleKey(); + if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role))) + { + return true; + } + } + return false; + } + + /** + * 验证用户是否不具备某角色,与 isRole逻辑相反。 + * + * @param role 角色名称 + * @return 用户是否不具备某角色 + */ + public boolean lacksRole(String role) + { + return hasRole(role) != true; + } + + /** + * 验证用户是否具有以下任意一个角色 + * + * @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表 + * @return 用户是否具有以下任意一个角色 + */ + public boolean hasAnyRoles(String roles) + { + if (StringUtils.isEmpty(roles)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) + { + return false; + } + for (String role : roles.split(ROLE_DELIMETER)) + { + if (hasRole(role)) + { + return true; + } + } + return false; + } + + /** + * 判断是否包含权限 + * + * @param permissions 权限列表 + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + private boolean hasPermissions(Set permissions, String permission) + { + return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission)); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java new file mode 100644 index 0000000..c2f97a1 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java @@ -0,0 +1,168 @@ +package com.ruoyi.framework.web.service; + +import java.util.Set; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.security.context.PermissionContextHolder; + +/** + * RuoYi首创 自定义权限实现,ss取自SpringSecurity首字母 + * + * @author ruoyi + */ +@Service("ss") +public class PermissionService +{ + /** 所有权限标识 */ + private static final String ALL_PERMISSION = "*:*:*"; + + /** 管理员角色权限标识 */ + private static final String SUPER_ADMIN = "admin"; + + private static final String ROLE_DELIMETER = ","; + + private static final String PERMISSION_DELIMETER = ","; + + /** + * 验证用户是否具备某权限 + * + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public boolean hasPermi(String permission) + { + if (StringUtils.isEmpty(permission)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) + { + return false; + } + PermissionContextHolder.setContext(permission); + return hasPermissions(loginUser.getPermissions(), permission); + } + + /** + * 验证用户是否不具备某权限,与 hasPermi逻辑相反 + * + * @param permission 权限字符串 + * @return 用户是否不具备某权限 + */ + public boolean lacksPermi(String permission) + { + return hasPermi(permission) != true; + } + + /** + * 验证用户是否具有以下任意一个权限 + * + * @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表 + * @return 用户是否具有以下任意一个权限 + */ + public boolean hasAnyPermi(String permissions) + { + if (StringUtils.isEmpty(permissions)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) + { + return false; + } + PermissionContextHolder.setContext(permissions); + Set authorities = loginUser.getPermissions(); + for (String permission : permissions.split(PERMISSION_DELIMETER)) + { + if (permission != null && hasPermissions(authorities, permission)) + { + return true; + } + } + return false; + } + + /** + * 判断用户是否拥有某个角色 + * + * @param role 角色字符串 + * @return 用户是否具备某角色 + */ + public boolean hasRole(String role) + { + if (StringUtils.isEmpty(role)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) + { + return false; + } + for (SysRole sysRole : loginUser.getUser().getRoles()) + { + String roleKey = sysRole.getRoleKey(); + if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role))) + { + return true; + } + } + return false; + } + + /** + * 验证用户是否不具备某角色,与 isRole逻辑相反。 + * + * @param role 角色名称 + * @return 用户是否不具备某角色 + */ + public boolean lacksRole(String role) + { + return hasRole(role) != true; + } + + /** + * 验证用户是否具有以下任意一个角色 + * + * @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表 + * @return 用户是否具有以下任意一个角色 + */ + public boolean hasAnyRoles(String roles) + { + if (StringUtils.isEmpty(roles)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) + { + return false; + } + for (String role : roles.split(ROLE_DELIMETER)) + { + if (hasRole(role)) + { + return true; + } + } + return false; + } + + /** + * 判断是否包含权限 + * + * @param permissions 权限列表 + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + private boolean hasPermissions(Set permissions, String permission) + { + return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission)); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java new file mode 100644 index 0000000..d47f1c3 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -0,0 +1,438 @@ +package com.ruoyi.framework.web.service; + +import com.github.pagehelper.util.StringUtil; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginBody; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.enums.UserStatus; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.exception.user.CaptchaException; +import com.ruoyi.common.exception.user.CaptchaExpireException; +import com.ruoyi.common.exception.user.UserPasswordNotMatchException; +import com.ruoyi.common.utils.*; +import com.ruoyi.common.utils.ip.IpUtils; +import com.ruoyi.framework.manager.AsyncManager; +import com.ruoyi.framework.manager.factory.AsyncFactory; +import com.ruoyi.framework.security.context.AuthenticationContextHolder; +import com.ruoyi.framework.security.sms.SmsCodeAuthenticationToken; +import com.ruoyi.framework.web.service.sms.MessageService; +import com.ruoyi.framework.web.service.sms.SmsRsponseVo; +import com.ruoyi.system.service.ISysConfigService; +import com.ruoyi.system.service.ISysUserService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.binary.Base64; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import javax.crypto.*; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.concurrent.TimeUnit; + +/** + * 登录校验方法 + * + * @author ruoyi + */ +@Component +@Slf4j +public class SysLoginService { + @Autowired + private TokenService tokenService; + + @Resource + private AuthenticationManager authenticationManager; + + @Autowired + private RedisCache redisCache; + + @Autowired + private MessageService messageService; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysConfigService configService; + + @Autowired + private SysPermissionService permissionService; + + @Value("${user.sms.defaultCode}") + private boolean defaultCode; + + // 是否允许同类型端同时登录(true允许 false不允许) + @Value("${token.soloLogin}") + private boolean soloLogin; + + //密钥 前后台一致16位 + private static final String KEY = "MFwwDQYJKoZIhvcN"; + //参数分别代表 算法名称/加密模式/数据填充方式 + private static final String ALGORITHMESTR = "AES/ECB/PKCS5Padding"; + + /** + * 登录验证 + * + * @param username 用户名 + * @param password 密码 + * @param code 验证码 + * @param uuid 唯一标识 + * @return 结果 + */ + public String login(String username, String password, String code, String uuid) { + + // 密码解密 + password = aESDecodePassword(password); + + boolean captchaEnabled = configService.selectCaptchaEnabled(); + // 验证码开关 + if (captchaEnabled) { + validateCaptcha(username, code, uuid); + } + // 用户验证 + Authentication authentication = null; + try { + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password); + AuthenticationContextHolder.setContext(authenticationToken); + // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername + authentication = authenticationManager.authenticate(authenticationToken); + } catch (Exception e) { + if (e instanceof BadCredentialsException) { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } else { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage())); + throw new ServiceException(e.getMessage()); + } + } finally { + AuthenticationContextHolder.clearContext(); + } + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); + +// 从缓存中去掉原来登录的用户 +// Collection keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); +// for (String key : keys) { +// LoginUser user = redisCache.getCacheObject(key); +// +// if (user.getUsername().equals(username)) { +// redisCache.deleteObject(key); +// break; +// } +// } + + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + + if (!soloLogin) + { + // 如果用户不允许多终端同时登录,清除缓存信息 + String userIdKey = Constants.LOGIN_USERID_KEY + loginUser.getUser().getUserId()+":"+UserConstants.PC; + String userKey = redisCache.getCacheObject(userIdKey); + if (StringUtils.isNotEmpty(userKey)) + { + redisCache.deleteObject(userIdKey); + redisCache.deleteObject(userKey); + } + } + loginUser.setLoginType("pc"); + recordLoginInfo(loginUser.getUserId()); + // 生成token + return tokenService.createToken(loginUser); + } + + private String aESDecodePassword(String password) { + try { + KeyGenerator kgen = KeyGenerator.getInstance("AES"); + kgen.init(128); + //拿到秘钥,KEY是我们刚刚定义的 + SecretKeySpec key = new SecretKeySpec(KEY.getBytes(),"AES"); + //创建密码器[算法名/加密模式/数据填充模式] + Cipher cipher = Cipher.getInstance(ALGORITHMESTR); + //表示密码器要使用key进行解码 + cipher.init(Cipher.DECRYPT_MODE, key); + //根据刚刚加密得到的结果,我们需要把info.getPassword字符串通过base64编码成cipher能识别的byte数组 + byte[] result = cipher.doFinal(Base64.decodeBase64(password)); + System.out.println("decode:"+new String(result)); + return new String(result); + } catch (NoSuchPaddingException e) { + e.printStackTrace(); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (BadPaddingException e) { + e.printStackTrace(); + } catch (InvalidKeyException e) { + e.printStackTrace(); + } + return password; + } + + public AjaxResult getCode(LoginBody loginBody) throws Exception { + String phoneText = loginBody.getPhone(); + //测试阶段暂不加密 + String phone = null; + try { + phone = RsaUtils.decryptByPrivateKey(phoneText); + } catch (Exception e) { + log.info("密文解密失败:"+phoneText); + throw new ServiceException("解密失败"); + } + if (StringUtil.isEmpty(phone) || phone.length() != 11) { + throw new ServiceException("手机号码有误!"); + } + SysUser user = userService.selectUserByPhone(phone); + if (StringUtils.isNull(user)) { + log.info("登录用户的手机号码:{} 不存在.", phone); + throw new ServiceException("登录用户手机号码不存在"); + } + if (!"0".equals(user.getStatus())) { + if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { + //20230510锁定的在缓存结束后解锁 + String smsCodeKey = CacheConstants.SMS_ERR_CNT_KEY + phone; + Long expire = 1L ; + if(redisCache.hasKey(smsCodeKey)) { + //获取到的是秒 + expire = redisCache.getExpire(smsCodeKey) / 60; + if(expire<1) + { + expire = 1L; + } + log.info("登录用户的手机号码:{} 已被锁定.", phone); + throw new ServiceException("手机号码:" + phone + " 已锁定,还剩下" + expire + "分钟"); + } + else + { + //没有缓存锁定用户已经恢复,需要设置为正常 + user.setStatus(UserStatus.OK.getCode()); + userService.updateUserStatus(user); + } +// log.info("登录用户的手机号码:{} 已被锁定.", phone); +// throw new ServiceException("登录用户手机号码:" + phone + " 已锁定"); + } + if (UserStatus.SLEEP.getCode().equals(user.getStatus())) { + log.info("登录用户的手机号码:{} 已被已冻结.", phone); + throw new ServiceException("登录用户手机号码:" + phone + " 已冻结"); + } +// log.info("登录用户的帐号非正常状态,状态:"+user.getStatus()); +// throw new ServiceException("登录用户的帐号非正常状态"); + } + //从缓存获取验证码 + String code = (String) redisCache.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + phone); + + if (!StringUtils.isEmpty(code)) { + //数据库轮询发送短信 + SmsRsponseVo smsRsponseVo = messageService.senSMSCodeByUser(user.getUserId(), phone, code); + if (!smsRsponseVo.getCode().equals(0)) { + throw new ServiceException("短信发送失败!"); + } + log.info(phone + "有效期内重新发送短信验证码:" + code); + //需求即使还在有效期内也重新发送短信 + throw new ServiceException("验证码还在有效期内,短信已发送,请注意查收"); + } + + if (StringUtils.isEmpty(code)) { + if (defaultCode) { + code = "123456"; + } else { + code = PasswordUtil.createNumPassWord(6); + } + log.info(phone + "生成短信验证码:" + code); + redisCache.setCacheObject(CacheConstants.CAPTCHA_CODE_KEY + phone, code, 300, TimeUnit.SECONDS); + } + + + + //数据库轮询发送短信 + SmsRsponseVo smsRsponseVo = messageService.senSMSCodeByUser(user.getUserId(), phone, code); + if (!smsRsponseVo.getCode().equals(0)) { + throw new ServiceException("短信发送失败!"); + } + + + return AjaxResult.success(); + } + + public String loginByPhone(String phoneText, String code, String uuid,String loginType) { + + if (StringUtil.isEmpty(phoneText)) { + throw new ServiceException("手机号码不能为空"); + } + + if (StringUtil.isEmpty(code)) { + throw new ServiceException("短信验证码不能为空"); + } + + //测试阶段暂不加密 + String phone = null; + try { + phone = RsaUtils.decryptByPrivateKey(phoneText); + } catch (Exception e) { + log.info("密文解密失败:"+phoneText); + throw new ServiceException("解密失败"); + } + + // 用户验证 + Authentication authentication = null; + try { + SmsCodeAuthenticationToken authenticationToken = new SmsCodeAuthenticationToken(phone, code); + AuthenticationContextHolder.setContext(authenticationToken); + // userDetailsByTelephoneServiceImpl.loadUserByUsername + authentication = authenticationManager.authenticate(authenticationToken); + } catch (Exception e) { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(phone, Constants.LOGIN_FAIL, e.getMessage())); + throw new ServiceException(e.getMessage()); + } finally { + AuthenticationContextHolder.clearContext(); + } + + AsyncManager.me().execute(AsyncFactory.recordLogininfor(phone, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); + + SysUser user= userService.selectUserByPhone(phone); + + boolean captchaEnabled = configService.selectDistinctEnabled(); + +// if(captchaEnabled) { +// //从缓存中去除原来登录的用户 +// Collection keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); +// for (String key : keys) { +// LoginUser redisUser = redisCache.getCacheObject(key); +// if(StringUtil.isNotEmpty(redisUser.getLoginType())) { +// if (redisUser.getUsername().equals(user.getUserName()) && redisUser.getLoginType().equals(loginType)) { +// redisCache.deleteObject(key); +// break; +// } +// } +// } +// } +// String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); + String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + "/getLoginCode"; + if (redisCache.hasKey(cacheRepeatKey)) { + redisCache.deleteObject(cacheRepeatKey); + } + // + if (redisCache.hasKey(CacheConstants.CAPTCHA_CODE_KEY + phone)&&(!"15726940139".equals(phone))) { + redisCache.deleteObject(CacheConstants.CAPTCHA_CODE_KEY + phone); + } + + //假定用户有验证码错误次数,则删除 + String key = CacheConstants.SMS_ERR_CNT_KEY + phone; + if (redisCache.hasKey(key)) { + redisCache.deleteObject(key); + } + + //授权用户登录 + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + + loginUser.setLoginType(loginType); + + if (!soloLogin) + { + // 如果用户不允许多终端同时登录,清除缓存信息 + String userIdKey = Constants.LOGIN_USERID_KEY + loginUser.getUser().getUserId()+":"+loginType; + String userKey = redisCache.getCacheObject(userIdKey); + if (StringUtils.isNotEmpty(userKey)) + { + redisCache.deleteObject(userIdKey); + redisCache.deleteObject(userKey); + } + } + + recordLoginInfo(loginUser.getUserId()); + + // 生成token + return tokenService.createToken(loginUser); + + } + + /** + * 校验验证码 + * + * @param username 用户名 + * @param code 验证码 + * @param uuid 唯一标识 + * @return 结果 + */ + public void validateCaptcha(String username, String code, String uuid) { + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); + String captcha = redisCache.getCacheObject(verifyKey); + redisCache.deleteObject(verifyKey); + if (captcha == null) { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"))); + throw new CaptchaExpireException(); + } + if (!code.equalsIgnoreCase(captcha)) { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); + throw new CaptchaException(); + } + } + + /** + * 记录登录信息 + * + * @param userId 用户ID + */ + public void recordLoginInfo(Long userId) { + SysUser sysUser = new SysUser(); + sysUser.setUserId(userId); + sysUser.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest())); + sysUser.setLoginDate(DateUtils.getNowDate()); + userService.updateUserLogin(sysUser); + } + + + public static void main(String[] args) { + try { + String s = RsaUtils.decryptByPrivateKey("Ox0ruk7PvJq4Sdc95dyrMPwTz1zH2lGKdA58aEQVMREL1iPlAOADuKNb9rvMGNzB/r2xWyV97JMew8sKklxaRWxozPM+AhKuAnxGMgAvkh7xnLGybMsbMi3/nWtL5rR3O6FXUpN9lFzjRYJ9Uqbc0R03uWR2Ys02x6YX6ilYHdc="); + RsaUtils.RsaKeyPair rsaKeyPair = RsaUtils.generateKeyPair(); + System.out.println(rsaKeyPair.getPublicKey()); + System.out.println("-----------------"); + System.out.println(rsaKeyPair.getPrivateKey()); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public AjaxResult ydLoginByPhone(String phone) { + SysUser user = userService.selectUserByPhone(phone); + if(user!=null){ + if (!soloLogin) + { + // 如果用户不允许多终端同时登录,清除缓存信息 + String userIdKey = Constants.LOGIN_USERID_KEY + user.getUserId()+":"+UserConstants.APP; + String userKey = redisCache.getCacheObject(userIdKey); + if (StringUtils.isNotEmpty(userKey)) + { + redisCache.deleteObject(userIdKey); + redisCache.deleteObject(userKey); + } + } + LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user), permissionService.getAppMenuPermission(user)); + loginUser.setLoginType(UserConstants.APP); + String token = tokenService.createToken(loginUser); + AjaxResult ajaxResult = new AjaxResult(); + ajaxResult.put("success","true"); + ajaxResult.put("msg",""); + ajaxResult.put("return_str",token); + return ajaxResult; + } + AjaxResult ajaxResult = new AjaxResult(); + ajaxResult.put("success","false"); + ajaxResult.put("msg","用户不存在"); + ajaxResult.put("return_str",""); + return ajaxResult; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysPasswordService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysPasswordService.java new file mode 100644 index 0000000..6ad91b0 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysPasswordService.java @@ -0,0 +1,94 @@ +package com.ruoyi.framework.web.service; + +import java.util.concurrent.TimeUnit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.exception.user.UserPasswordNotMatchException; +import com.ruoyi.common.exception.user.UserPasswordRetryLimitExceedException; +import com.ruoyi.common.utils.MessageUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.framework.manager.AsyncManager; +import com.ruoyi.framework.manager.factory.AsyncFactory; +import com.ruoyi.framework.security.context.AuthenticationContextHolder; + +/** + * 登录密码方法 + * + * @author ruoyi + */ +@Component +public class SysPasswordService +{ + @Autowired + private RedisCache redisCache; + + @Value(value = "${user.password.maxRetryCount}") + private int maxRetryCount; + + @Value(value = "${user.password.lockTime}") + private int lockTime; + + /** + * 登录账户密码错误次数缓存键名 + * + * @param username 用户名 + * @return 缓存键key + */ + private String getCacheKey(String username) + { + return CacheConstants.PWD_ERR_CNT_KEY + username; + } + + public void validate(SysUser user) + { + Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext(); + String username = usernamePasswordAuthenticationToken.getName(); + String password = usernamePasswordAuthenticationToken.getCredentials().toString(); + + Integer retryCount = redisCache.getCacheObject(getCacheKey(username)); + + if (retryCount == null) + { + retryCount = 0; + } + + if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, + MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, lockTime))); + throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime); + } + + if (!matches(user, password)) + { + retryCount = retryCount + 1; + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, + MessageUtils.message("user.password.retry.limit.count", retryCount))); + redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES); + throw new UserPasswordNotMatchException(); + } + else + { + clearLoginRecordCache(username); + } + } + + public boolean matches(SysUser user, String rawPassword) + { + return SecurityUtils.matchesPassword(rawPassword, user.getPassword()); + } + + public void clearLoginRecordCache(String loginName) + { + if (redisCache.hasKey(getCacheKey(loginName))) + { + redisCache.deleteObject(getCacheKey(loginName)); + } + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysPermissionService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysPermissionService.java new file mode 100644 index 0000000..9a71f25 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysPermissionService.java @@ -0,0 +1,122 @@ +package com.ruoyi.framework.web.service; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.ruoyi.system.service.ISysAppMenuService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.system.service.ISysMenuService; +import com.ruoyi.system.service.ISysRoleService; + +/** + * 用户权限处理 + * + * @author ruoyi + */ +@Component +public class SysPermissionService +{ + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysMenuService menuService; + + @Autowired + private ISysAppMenuService appMenuService; + + /** + * 获取角色数据权限 + * + * @param user 用户信息 + * @return 角色权限信息 + */ + public Set getRolePermission(SysUser user) + { + Set roles = new HashSet(); + // 管理员拥有所有权限 + if (user.isAdmin()) + { + roles.add("admin"); + } + else + { + roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId())); + } + return roles; + } + + /** + * 获取菜单数据权限 + * + * @param user 用户信息 + * @return 菜单权限信息 + */ + public Set getMenuPermission(SysUser user) + { + Set perms = new HashSet(); + // 管理员拥有所有权限 + if (user.isAdmin()) + { + perms.add("*:*:*"); + } + else + { + List roles = user.getRoles(); + if (!roles.isEmpty() && roles.size() > 1) + { + // 多角色设置permissions属性,以便数据权限匹配权限 + for (SysRole role : roles) + { + Set rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId()); + role.setPermissions(rolePerms); + perms.addAll(rolePerms); + } + } + else + { + perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId())); + } + } + return perms; + } + + /** + * 获取APP菜单数据权限 + * + * @param user 用户信息 + * @return 菜单权限信息 + */ + public Set getAppMenuPermission(SysUser user) + { + Set perms = new HashSet(); + // 管理员拥有所有权限 + if (user.isAdmin()) + { + perms.add("*:*:*"); + } + else + { + List roles = user.getRoles(); + if (!roles.isEmpty() && roles.size() > 1) + { + // 多角色设置permissions属性,以便数据权限匹配权限 + for (SysRole role : roles) + { + Set rolePerms = appMenuService.selectMenuPermsByRoleId(role.getRoleId()); + role.setPermissions(rolePerms); + perms.addAll(rolePerms); + } + } + else + { + perms.addAll(appMenuService.selectMenuPermsByUserId(user.getUserId())); + } + } + return perms; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java new file mode 100644 index 0000000..974580e --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java @@ -0,0 +1,115 @@ +package com.ruoyi.framework.web.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.RegisterBody; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.exception.user.CaptchaException; +import com.ruoyi.common.exception.user.CaptchaExpireException; +import com.ruoyi.common.utils.MessageUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.manager.AsyncManager; +import com.ruoyi.framework.manager.factory.AsyncFactory; +import com.ruoyi.system.service.ISysConfigService; +import com.ruoyi.system.service.ISysUserService; + +/** + * 注册校验方法 + * + * @author ruoyi + */ +@Component +public class SysRegisterService +{ + @Autowired + private ISysUserService userService; + + @Autowired + private ISysConfigService configService; + + @Autowired + private RedisCache redisCache; + + /** + * 注册 + */ + public String register(RegisterBody registerBody) + { + String msg = "", username = registerBody.getUsername(), password = registerBody.getPassword(); + SysUser sysUser = new SysUser(); + sysUser.setUserName(username); + + // 验证码开关 + boolean captchaEnabled = configService.selectCaptchaEnabled(); + if (captchaEnabled) + { + validateCaptcha(username, registerBody.getCode(), registerBody.getUuid()); + } + + if (StringUtils.isEmpty(username)) + { + msg = "用户名不能为空"; + } + else if (StringUtils.isEmpty(password)) + { + msg = "用户密码不能为空"; + } + else if (username.length() < UserConstants.USERNAME_MIN_LENGTH + || username.length() > UserConstants.USERNAME_MAX_LENGTH) + { + msg = "账户长度必须在2到20个字符之间"; + } + else if (password.length() < UserConstants.PASSWORD_MIN_LENGTH + || password.length() > UserConstants.PASSWORD_MAX_LENGTH) + { + msg = "密码长度必须在5到20个字符之间"; + } + else if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(sysUser))) + { + msg = "保存用户'" + username + "'失败,注册账号已存在"; + } + else + { + sysUser.setNickName(username); + sysUser.setPassword(SecurityUtils.encryptPassword(password)); + boolean regFlag = userService.registerUser(sysUser); + if (!regFlag) + { + msg = "注册失败,请联系系统管理人员"; + } + else + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.register.success"))); + } + } + return msg; + } + + /** + * 校验验证码 + * + * @param username 用户名 + * @param code 验证码 + * @param uuid 唯一标识 + * @return 结果 + */ + public void validateCaptcha(String username, String code, String uuid) + { + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); + String captcha = redisCache.getCacheObject(verifyKey); + redisCache.deleteObject(verifyKey); + if (captcha == null) + { + throw new CaptchaExpireException(); + } + if (!code.equalsIgnoreCase(captcha)) + { + throw new CaptchaException(); + } + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysSmsService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysSmsService.java new file mode 100644 index 0000000..1593609 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysSmsService.java @@ -0,0 +1,119 @@ +package com.ruoyi.framework.web.service; + +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.enums.UserStatus; +import com.ruoyi.common.exception.user.*; +import com.ruoyi.common.utils.MessageUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.manager.AsyncManager; +import com.ruoyi.framework.manager.factory.AsyncFactory; +import com.ruoyi.framework.security.context.AuthenticationContextHolder; +import com.ruoyi.framework.security.sms.SmsCodeAuthenticationToken; +import com.ruoyi.system.service.ISysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + +/** + * 登录密码方法 + * + * @author ruoyi + */ +@Component +public class SysSmsService +{ + @Autowired + private RedisCache redisCache; + + @Autowired + private ISysUserService userService; + + @Value(value = "${user.sms.maxRetryCount}") + private int maxRetryCount; + + @Value(value = "${user.sms.lockTime}") + private int lockTime; + + /** + * 登录账户短信错误次数缓存键名 + * + * @param phone 手机号码 + * @return 缓存键key + */ + private String getCacheKey(String phone) + { + return CacheConstants.SMS_ERR_CNT_KEY + phone; + } + + public void validate(Long userId) + { + + Authentication smsCodeAuthenticationToken = AuthenticationContextHolder.getContext(); + + String phone = smsCodeAuthenticationToken.getName(); + String code = smsCodeAuthenticationToken.getCredentials().toString(); + + String smsCode = (String) redisCache.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + phone); + + //短信验证码是否过期 + if (StringUtils.isEmpty(smsCode)) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(phone, Constants.LOGIN_FAIL, MessageUtils.message("user.sms.expire"))); + throw new CaptchaExpireException(); + } + + Integer retryCount = redisCache.getCacheObject(getCacheKey(phone)); + + if (retryCount == null) + { + retryCount = 0; + } + + if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(phone, Constants.LOGIN_FAIL, + MessageUtils.message("user.sms.retry.limit.exceed", maxRetryCount, lockTime))); + + //设置锁定状态 + SysUser user=new SysUser(); + user.setUserId(userId); + user.setStatus(UserStatus.DISABLE.getCode()); + userService.updateUserStatus(user); + + throw new UserSmsRetryLimitExceedException(maxRetryCount, lockTime); + } + + if (!smsCode.equalsIgnoreCase(code)) + { + retryCount = retryCount + 1; + + Integer surplusCount = Integer.valueOf(maxRetryCount).intValue() - retryCount; + + AsyncManager.me().execute(AsyncFactory.recordLogininfor(phone, Constants.LOGIN_FAIL, + MessageUtils.message("user.sms.retry.limit.count", retryCount))); + + redisCache.setCacheObject(getCacheKey(phone), retryCount, lockTime, TimeUnit.MINUTES); + + throw new UserSmsNotMatchException(surplusCount); + } + else + { + clearLoginRecordCache(phone); + } + } + + public void clearLoginRecordCache(String loginName) + { + if (redisCache.hasKey(getCacheKey(loginName))) + { + redisCache.deleteObject(getCacheKey(loginName)); + } + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java new file mode 100644 index 0000000..37d825b --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java @@ -0,0 +1,289 @@ +package com.ruoyi.framework.web.service; + +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.ip.AddressUtils; +import com.ruoyi.common.utils.ip.IpUtils; +import com.ruoyi.common.utils.uuid.IdUtils; +import com.ruoyi.system.service.ISysConfigService; +import eu.bitwalker.useragentutils.UserAgent; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * token验证处理 + * + * @author ruoyi + */ +@Component +public class TokenService +{ + // 令牌自定义标识 + @Value("${token.header}") + private String header; + + // 令牌秘钥 + @Value("${token.secret}") + private String secret; + + // 令牌有效期(默认30分钟) + @Value("${token.expireTime}") + private int expireTime; + + // 是否允许同类型端同时登录(true允许 false不允许) + @Value("${token.soloLogin}") + private boolean soloLogin; + + protected static final long MILLIS_SECOND = 1000; + + protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; + + private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L; + + @Autowired + private RedisCache redisCache; + + @Autowired + private ISysConfigService configService; + + /** + * 获取用户身份信息 + * + * @return 用户信息 + */ + public LoginUser getLoginUser(HttpServletRequest request) + { + // 获取请求携带的令牌 + String token = getToken(request); + if (StringUtils.isNotEmpty(token)) + { + try + { + Claims claims = parseToken(token); + // 解析对应的权限以及用户信息 + String uuid = (String) claims.get(Constants.LOGIN_USER_KEY); + String userKey = getTokenKey(uuid); + LoginUser user = redisCache.getCacheObject(userKey); + return user; + } + catch (Exception e) + { + } + } + return null; + } + + /** + * 设置用户身份信息 + */ + public void setLoginUser(LoginUser loginUser) + { + if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) + { + refreshToken(loginUser); + } + } + + /** + * 删除用户身份信息 + */ + public void delLoginUser(String token,Long userId,String loginType) + { + if (StringUtils.isNotEmpty(token)) + { + String userKey = getTokenKey(token); + redisCache.deleteObject(userKey); + } + if (!soloLogin && StringUtils.isNotNull(userId)) + { + String userIdKey = getUserIdKey(userId,loginType); + redisCache.deleteObject(userIdKey); + } + } + + /** + * 创建令牌 + * + * @param loginUser 用户信息 + * @return 令牌 + */ + public String createToken(LoginUser loginUser) + { + String token = IdUtils.fastUUID(); + loginUser.setToken(token); + setUserAgent(loginUser); + refreshToken(loginUser); + + Map claims = new HashMap<>(); + claims.put(Constants.LOGIN_USER_KEY, token); + return createToken(claims); + } + + /** + * 验证令牌有效期,相差不足20分钟,自动刷新缓存 + * + * @param loginUser + * @return 令牌 + */ + public void verifyToken(LoginUser loginUser) + { + long expireTime = loginUser.getExpireTime(); + long currentTime = System.currentTimeMillis(); + if (expireTime - currentTime <= MILLIS_MINUTE_TEN) + { + refreshToken(loginUser); + } + } + + /** + * 刷新令牌有效期 + * + * @param loginUser 登录信息 + */ + public void refreshToken(LoginUser loginUser) + { + + + + loginUser.setLoginTime(System.currentTimeMillis()); + loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); + // 根据uuid将loginUser缓存 + String userKey = getTokenKey(loginUser.getToken()); + + //大屏用户缓存不过期 + if("bigscreen".equals(loginUser.getUser().getUserName())) + { + redisCache.setCacheObject(userKey, loginUser); + return; + } + + redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); + + if (!soloLogin) + { + // 缓存用户唯一标识,防止同一帐号,同时登录 + String userIdKey = getUserIdKey(loginUser.getUser().getUserId(),loginUser.getLoginType()); + redisCache.setCacheObject(userIdKey, userKey, expireTime, TimeUnit.MINUTES); + } + } + + /** + * 设置用户代理信息 + * + * @param loginUser 登录信息 + */ + public void setUserAgent(LoginUser loginUser) + { + UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); + String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); + loginUser.setIpaddr(ip); + loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); + loginUser.setBrowser(userAgent.getBrowser().getName()); + loginUser.setOs(userAgent.getOperatingSystem().getName()); + } + + private String getUserIdKey(Long userId,String loginType) + { + return Constants.LOGIN_USERID_KEY + userId+":"+loginType; + } + + /** + * 从数据声明生成令牌 + * + * @param claims 数据声明 + * @return 令牌 + */ + private String createToken(Map claims) + { + String token = Jwts.builder() + .setClaims(claims) + .signWith(SignatureAlgorithm.HS512, secret).compact(); + return token; + } + + /** + * 从令牌中获取数据声明 + * + * @param token 令牌 + * @return 数据声明 + */ + private Claims parseToken(String token) + { + return Jwts.parser() + .setSigningKey(secret) + .parseClaimsJws(token) + .getBody(); + } + + /** + * 从令牌中获取用户名 + * + * @param token 令牌 + * @return 用户名 + */ + public String getUsernameFromToken(String token) + { + Claims claims = parseToken(token); + return claims.getSubject(); + } + + /** + * 获取请求token + * + * @param request + * @return token + */ + private String getToken(HttpServletRequest request) + { + String token = request.getHeader(header); + if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) + { + token = token.replace(Constants.TOKEN_PREFIX, ""); + } + return token; + } + + private String getTokenKey(String uuid) + { + return CacheConstants.LOGIN_TOKEN_KEY + uuid; + } + + public Boolean isLogin(String token) throws Exception { + try + { + Claims claims = parseToken(token); + // 解析对应的权限以及用户信息 + String uuid = (String) claims.get(Constants.LOGIN_USER_KEY); + String userKey = getTokenKey(uuid); + LoginUser user = redisCache.getCacheObject(userKey); + if(ObjectUtils.isEmpty(user)) + { + return false; + } + + } + catch (Exception e) + { + throw new Exception(e.getMessage()); + } + + return true; + } + + +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsByTelephoneServiceImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsByTelephoneServiceImpl.java new file mode 100644 index 0000000..322a08d --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsByTelephoneServiceImpl.java @@ -0,0 +1,101 @@ +package com.ruoyi.framework.web.service; + +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.enums.UserStatus; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.exception.base.BaseException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.service.ISysUserService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Primary; +import org.springframework.data.redis.core.TimeoutUtils; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * 用户验证处理 + * + * @author gmk + */ +@Service("userDetailsByTelephoneServiceImpl") +public class UserDetailsByTelephoneServiceImpl implements UserDetailsService { + private static final Logger log = LoggerFactory.getLogger(UserDetailsByTelephoneServiceImpl.class); + + @Autowired + private ISysUserService userService; + + @Autowired + private SysPermissionService permissionService; + + @Autowired + private SysSmsService sysSmsService; + + @Autowired + private RedisCache redisCache; + + @Override + public UserDetails loadUserByUsername(String phone) throws UsernameNotFoundException { + + SysUser user= userService.selectUserByPhone(phone); + if (StringUtils.isNull(user)) + { + log.info("登录用户的手机号码:{} 不存在.", phone); + throw new ServiceException("登录用户手机号码:" + phone + " 不存在"); + } + else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) + { + log.info("登录用户:{} 已被删除.", user.getUserName()); + throw new ServiceException("登录用户手机号码:" + phone + " 不存在"); + } + else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) + { + String smsCodeKey = CacheConstants.SMS_ERR_CNT_KEY + phone; + Long expire = 1L ; + if(redisCache.hasKey(smsCodeKey)) { + //获取到的是秒 + expire = redisCache.getExpire(smsCodeKey) / 60; + if(expire<1) + { + expire = 1L; + } + log.info("登录用户:{} 已被锁定.",user.getUserName()); + throw new ServiceException("手机号码:" + phone + " 已锁定,还剩下" + expire + "分钟"); + } + else + { + //锁定用户假定已经恢复,需要设置为正常 + user.setStatus(UserStatus.OK.getCode()); + userService.updateUserStatus(user); + } + } + else if (UserStatus.SLEEP.getCode().equals(user.getStatus())) + { + log.info("登录用户:{} 已被冻结.",user.getUserName()); + throw new ServiceException("登录用户手机号码:" + phone + " 已冻结"); + } + + sysSmsService.validate(user.getUserId()); + + return createLoginUser(user); + } + + public UserDetails createLoginUser(SysUser user) { + return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user),permissionService.getAppMenuPermission(user)); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java new file mode 100644 index 0000000..ec39243 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java @@ -0,0 +1,65 @@ +package com.ruoyi.framework.web.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.enums.UserStatus; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.service.ISysUserService; + +/** + * 用户验证处理 + * + * @author ruoyi + */ +@Service +public class UserDetailsServiceImpl implements UserDetailsService +{ + private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class); + + @Autowired + private ISysUserService userService; + + @Autowired + private SysPasswordService passwordService; + + @Autowired + private SysPermissionService permissionService; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException + { + SysUser user = userService.selectUserByUserName(username); + + if (StringUtils.isNull(user)) { + log.info("登录用户:{} 不存在.", username); + throw new ServiceException("登录用户:" + username + " 不存在"); + } + + //20230324 管理员不用判断 + if(!user.isAdmin()) { + if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) { + log.info("登录用户:{} 已被删除.", username); + throw new ServiceException("对不起,您的账号:" + username + " 已被删除"); + } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { + log.info("登录用户:{} 已被锁定.", username); + throw new ServiceException("对不起,您的账号:" + username + " 已锁定"); + } + passwordService.validate(user); + } + + return createLoginUser(user); + } + + public UserDetails createLoginUser(SysUser user) + { + return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user),permissionService.getAppMenuPermission(user)); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/sms/MessageService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/sms/MessageService.java new file mode 100644 index 0000000..ccf1d23 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/sms/MessageService.java @@ -0,0 +1,54 @@ +package com.ruoyi.framework.web.service.sms; + +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.framework.web.domain.dto.MobileOfficesDTO; + +/** + * @author yqf + * @date 2022/8/4 + */ +public interface MessageService { + +// /** +// * 开发期间,全部返回成功。 +// * @param content +// * :发送内容 +// * @param mobile +// * :手机号 +// * 返回信息:返回信息:0-发送成功 1-业务号不能为空 2-内容不能为空 3-内容长度超出512个字符 4-手机号不能为空 5-业务号不存在 6-号码有误 7-信息机不可用 +// */ +// public SmsRsponseVo sendSM(String content, String mobile); + +// /** +// * 发送短信验证码 +// * @param mobile +// * @param code +// * @return +// */ +// public SmsRsponseVo senSMSCode(String mobile,String code); + + /** + * 发送移动办公群 + */ + public JSONObject sendMobileOffice(MobileOfficesDTO dto); + + /** + * 发送短信 + */ + public JSONObject sendSMS(String content, String mobile); + + /** + * 发送IVR + */ + public JSONObject sendIvr(String content, String mobile); + + public SmsRsponseVo senSMSCodeByUser(Long userId,String phone,String code); + + /** + * 获取系统运行环境 + * dev 测试环境 + * prod 生产环境 + * @return + */ + public String getActive(); +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/sms/MessageServiceImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/sms/MessageServiceImpl.java new file mode 100644 index 0000000..aa31988 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/sms/MessageServiceImpl.java @@ -0,0 +1,361 @@ +package com.ruoyi.framework.web.service.sms; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.asymmetric.AsymmetricAlgorithm; +import cn.hutool.crypto.asymmetric.KeyType; +import cn.hutool.crypto.asymmetric.RSA; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.framework.web.domain.SysNoticeEntity; +import com.ruoyi.framework.web.domain.dto.MobileOfficesDTO; +import com.ruoyi.framework.web.mapper.SysLoginMapper; +import com.ruoyi.system.service.ISysConfigService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.util.Date; +import java.util.HashMap; + +/** + * @author yqf + * @date 2022/8/4 + */ +@Slf4j +@Service +public class MessageServiceImpl implements MessageService { + // @Value("${system.sms.imbms.url}") + private String SMS_URL; + // @Value("${system.sms.imbms.code}") + private String CODE; + // @Value("${system.sms.imbms.username}") + private String UUSER_NAME; + + @Value("${spring.profiles.active}") + private String ACTIVE; + + @Value("${system.msg.url}") + private String url; + + @Value("${system.msg.sms_comm}") + private String sms_comm; + + @Value("${system.msg.ivr_comm}") + private String ivr_comm; + + @Value("${system.msg.mobileoffice_comm}") + private String mobileoffice_comm; + + @Value("${system.msg.applicationid}") + private String applicationid; + + @Value("${system.msg.platform_code}") + private String platform_code; + + @Value("${system.msg.publickey}") + private String publickey; + + @Autowired + private ISysConfigService sysConfigService; + + @Autowired + private SysLoginMapper sysLoginMapper; + // @Override + public SmsRsponseVo sendSM(String content, String mobile) { + // 向WebService发送的参数格式(xml) +// String strParameter = "\n" + +// "\n" + +// " \n" + +// " \n" + +// " \n" + +// " " + CODE + "\n" + +// " " + content + "\n" + +// " " + mobile + "\n" + +// " " + UUSER_NAME + "\n" + +// " \n" + +// " \n" + +// ""; +// log.info("开始发送短信",strParameter); + // 向HttpClient发送请求 +// String returnDatabase = HttpUtils.sendPost(SMS_URL, strParameter); +// JSONObject jsonObject = null; +// try { +// // 将请求结果转换成json类型 +// jsonObject = WebServiceUnit.xml2Json(returnDatabase); +// } catch (Exception e) { +// log.error("短信发送失败!",e); +// e.printStackTrace(); +// } +// log.info("短信发送结果",returnDatabase); + + SmsRsponseVo smsRsponseVo = new SmsRsponseVo(); + smsRsponseVo.setCode(0); + return smsRsponseVo; + } + + /** + * 发送移动办公群 + * + * @param dto 发送内容 + * @return code 返回代码 0/1 1成功 0失败 + * message 返回信息 成功/失败/别的提示 + * mobileoffice_id 返回id 查询发送结果的id + */ + @Override + public JSONObject sendMobileOffice(MobileOfficesDTO dto) { + + HashMap map = new HashMap<>(); + map.put("comm", mobileoffice_comm); + map.put("applicationid", applicationid); + String tokenId = createTokenId(); + map.put("tokenid", tokenId); + map.put("mobileoffices", dto.getMobileoffices()); + map.put("mobileoffice_user", dto.getMobileoffice_user()); + map.put("file", dto.getFile()); + map.put("filename", dto.getFilename()); + map.put("img", dto.getImg()); + map.put("imgname", dto.getImgname()); + map.put("content", dto.getContent()); + // 向HttpClient发送请求 + String url = sysConfigService.selectConfigByKey("sys.sms.url"); + log.info("移动办公群发送url=" + url); + url = StrUtil.isNotBlank(url) ? url : this.url; + String res = ""; + try { + res = HttpUtil.post(url, map, 5000); + } catch (Exception e) { + e.printStackTrace(); + } + JSONObject jsonObject = JSONObject.parseObject(res); + if(jsonObject!=null) { + if ("1".equals(jsonObject.getString("code"))) { + log.info("移动办公群发送成功!"); + } else { + log.error("移动办公群发送失败:" + jsonObject.getString("message")); + } + } + return jsonObject; + } + + /** + * 发送短信(适合发送内容相同的多人发送) + * + * @param content 发送内容 + * @param mobile 发送手机号码 13805711234,13805715678,13805710000 逗号隔开 + * @return code 返回代码 0/1 1成功 0失败 + * message 返回信息 成功/失败/别的提示 + * sms_id 返回id 查询发送结果的id + */ + @Override + public JSONObject sendSMS(String content, String mobile) { + + HashMap map = new HashMap<>(); + map.put("comm", sms_comm); + map.put("applicationid", applicationid); + String tokenId = createTokenId(); + map.put("tokenid", tokenId); + map.put("mobiles", mobile); + map.put("content", content); + + // 向HttpClient发送请求 + String url = sysConfigService.selectConfigByKey("sys.sms.url"); + log.info("短信发送url=" + url); + url = StrUtil.isNotBlank(url) ? url : this.url; + String res = ""; + try { + res = HttpUtil.post(url, map, 5000); + } catch (Exception e) { + log.error("调用三方失败"); + e.printStackTrace(); + } + if(StrUtil.isBlank(res)){ + log.error("调用三方失败"); + } + JSONObject jsonObject = JSONObject.parseObject(res); + if(jsonObject!=null) { + if ("1".equals(jsonObject.getString("code"))) { + log.info("短信发送成功!"); + } else { + jsonObject.put("code",0); + jsonObject.put("message","调用三方失败"); + log.error("短信发送失败:调用三方失败"); + } + } + return jsonObject; + } + + /** + * 发送IVR(适合发送内容相同的多人发送) + * + * @param content 发送内容 + * @param mobile 发送手机号码 13805711234,13805715678,13805710000 逗号隔开 + * @return code 返回代码 0/1 1成功 0失败 + * message 返回信息 成功/失败/别的提示 + * sms_id 返回id 查询发送结果的id + */ + @Override + public JSONObject sendIvr(String content, String mobile) { + + HashMap map = new HashMap<>(); + map.put("comm", ivr_comm); + map.put("applicationid", applicationid); + String tokenId = createTokenId(); + map.put("tokenid", tokenId); + //手机号码 13805711234,13805715678,13805710000 逗号隔开 + map.put("mobiles", mobile); + map.put("content", content); + //拨打方式 不必填 0:一次性全拨打 1:一个接个拨打,成功一个结束 + map.put("call_type", "0"); + //最大拨号次数 必填 + map.put("call_times", "1"); + //重拨间隔时间 必填 颗粒度:分钟 + map.put("call_interval_time", "1"); + + // 向HttpClient发送请求 + String url = sysConfigService.selectConfigByKey("sys.sms.url"); + log.info("IVR发送url=" + url); + url = StrUtil.isNotBlank(url) ? url : this.url; + String res = ""; + try { + log.info("传递参数:"+map); + res = HttpUtil.post(url, map, 5000); + } catch (Exception e) { + e.printStackTrace(); + } + JSONObject jsonObject = JSONObject.parseObject(res); + if(jsonObject!=null) { + if ("1".equals(jsonObject.getString("code"))) { + log.info("IVR发送成功!"); + } else { + log.error("IVR发送失败:" + jsonObject.getString("message")); + } + } + return jsonObject; + } + + /** + * 获取短信发送结果( 查询IVR、短信、微信、移动办公、MOA发送结果) + * + * @param type 查询类型:ivr、sms、wechat、mobileoffice、mobileoffice_zmcc、moa + * @param id 查询id ivr_id\sms_id\wechat_id\mobileoffice_id\moa_id + * @return + */ + public JSONObject getResult(String type, String id) { + HashMap map = new HashMap<>(); + map.put("comm", "get_result"); + map.put("applicationid", applicationid); + String tokenId = createTokenId(); + map.put("tokenid", tokenId); + map.put("type", type); + map.put("id", id); + + // 向HttpClient发送请求 + String res = HttpUtil.post(SMS_URL, map, 5000); + JSONObject jsonObject = JSONObject.parseObject(res); + if ("1".equals(jsonObject.getString("code"))) { + log.info("获取发送结果成功!"); + } else { + log.error("获取发送结果失败:" + jsonObject.getString("message")); + } + return jsonObject; + } + + +// @Override +// public SmsRsponseVo senSMSCode(String mobile, String code) { +// String content = "您的验证码为" + code + ",请勿向他人泄露。"; +// return sendSM(content, mobile); +// } + + //生成tokenid + public String createTokenId() { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("platform_code", platform_code); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String currenTime = dateFormat.format(new Date()); + jsonObject.put("time", currenTime); + RSA rsa = new RSA(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), null, publickey); + return rsa.encryptBase64(jsonObject.toJSONString(), KeyType.PublicKey); + } + + //生成tokenid + public static void main(String[] args) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("platform_code", "东信亚运重保"); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String currenTime = dateFormat.format(new Date()); + jsonObject.put("time", currenTime); + String s = jsonObject.toJSONString(); + System.out.println(s); + String pubilcKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhBtwcgGVE1ILMDoxU4Og77PugS2JlHDnfkmHO3Ek0s+L4ukWDbh6XvRNxUIBM9GvhvrdT7JGE7/Xq6oIYRk6QqfvYp/aHzw1DkhoEz7Bx9O0fdQKWMCHd4kl6hmyLeurmr11/h6nwtu1U/R2BqJ/blRCebUuYvMaCxVO1rr8irQIDAQAB"; + RSA rsa = new RSA(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), null, pubilcKey); + String s1 = rsa.encryptBase64(s, KeyType.PublicKey); + System.out.println(s1); + System.out.println(s1.length()); + } + + @Override + public SmsRsponseVo senSMSCodeByUser(Long userId, String phone, String code) { +// String content = "尊敬的用户,您本次登录的验证码是[" + code + "],请在5分钟内使用!"; +// SysNotice notice = new SysNotice(); +// notice.setNoticeType("3"); +// notice.setNoticeTitle("亚运保障平台登录验证码"); +// notice.setStatus("0"); +// notice.setCreateBy("sys"); +// notice.setNoticeContent(content); +// notice.setReciveUser(userId); +// notice.setReciveUserPhone(phone); +// //计划发送时间 当前时间立即发送 +// notice.setExpSendTime(LocalDateTime.now()); +// //加入定时任务标记 初始0 +// notice.setAddFlag("0"); +// //定时任务实际发送时修改 +//// notice.setSendTime(DateUtils.getNowDate()); +// try { +// sysNoticeService.saveOrUpdate(notice); +// } catch (Exception e) { +// log.error("短信发送失败!", e); +// e.printStackTrace(); +// } +// +// SmsRsponseVo smsRsponseVo = new SmsRsponseVo(); +// smsRsponseVo.setCode(0); +// return smsRsponseVo; + + + String content = "尊敬的用户,您本次登录的验证码是[" + code + "],请在5分钟内使用!"; + SysNoticeEntity notice = new SysNoticeEntity(); + notice.setNoticeType("3"); + notice.setNoticeTitle("亚运保障平台登录验证码"); + notice.setStatus("0"); + notice.setCreateBy("sys"); + notice.setCreateTime(LocalDateTime.now()); + notice.setNoticeContent(content); + notice.setReciveUser(userId); + notice.setReciveUserPhone(phone); + //计划发送时间 当前时间立即发送 + notice.setExpSendTime(LocalDateTime.now()); + //加入定时任务标记 初始0 + notice.setAddFlag("0"); + //定时任务实际发送时修改 +// notice.setSendTime(DateUtils.getNowDate()); + try { + sysLoginMapper.insertNotice(notice); + } catch (Exception e) { + log.error("短信发送失败!", e); + e.printStackTrace(); + } + + SmsRsponseVo smsRsponseVo = new SmsRsponseVo(); + smsRsponseVo.setCode(0); + return smsRsponseVo; + } + + @Override + public String getActive() { + return ACTIVE; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/sms/SmsRsponseVo.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/sms/SmsRsponseVo.java new file mode 100644 index 0000000..2c10a5d --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/sms/SmsRsponseVo.java @@ -0,0 +1,16 @@ +package com.ruoyi.framework.web.service.sms; + +import lombok.Data; + +@Data +public class SmsRsponseVo { + /** + * 发送短信响应状态码 + * 返回信息:0-发送成功 1-业务号不能为空 2-内容不能为空 3-内容长度超出512个字符 4-手机号不能为空 5-业务号不存在 6-号码有误 7-信息机不可用 + */ + private Integer code; + /** + * 发送短信返回信息 + */ + private String msg; +} diff --git a/ruoyi-generator/pom.xml b/ruoyi-generator/pom.xml new file mode 100644 index 0000000..ac2e964 --- /dev/null +++ b/ruoyi-generator/pom.xml @@ -0,0 +1,69 @@ + + + + ruoyi + com.ruoyi + 3.8.4 + + 4.0.0 + + ruoyi-generator + + + generator代码生成 + + + + + + + + + + + + org.postgresql + postgresql + + + + + org.apache.velocity + velocity-engine-core + + + + + commons-collections + commons-collections + + + + + com.ruoyi + ruoyi-common + + + + com.baomidou + mybatis-plus-boot-starter + + + + com.baomidou + mybatis-plus-generator + 3.5.3.1 + + + + org.freemarker + freemarker + 2.3.28 + compile + + + + + \ No newline at end of file diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/MyBatisPlusGenerator.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/MyBatisPlusGenerator.java new file mode 100644 index 0000000..66292fd --- /dev/null +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/MyBatisPlusGenerator.java @@ -0,0 +1,75 @@ +package com.ruoyi.generator; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.generator.FastAutoGenerator; +import com.baomidou.mybatisplus.generator.config.DataSourceConfig; +import com.baomidou.mybatisplus.generator.config.OutputFile; +import com.baomidou.mybatisplus.generator.config.converts.PostgreSqlTypeConvert; +import com.baomidou.mybatisplus.generator.config.querys.PostgreSqlQuery; +import com.baomidou.mybatisplus.generator.config.rules.DbColumnType; +import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; +import com.baomidou.mybatisplus.generator.fill.Column; +import com.baomidou.mybatisplus.generator.fill.Property; +import com.baomidou.mybatisplus.generator.keywords.PostgreSqlKeyWordsHandler; + +import java.sql.Types; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class MyBatisPlusGenerator { + + private static final DataSourceConfig.Builder DATA_SOURCE_CONFIG = new DataSourceConfig + .Builder("jdbc:postgresql://192.168.97.156:5432/hz_zxp?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true", "postgres", "eastcom") + .dbQuery(new PostgreSqlQuery()) //数据库查询 + .schema("public") //数据库schema(部分数据库适用) + .typeConvert(new PostgreSqlTypeConvert()) //数据库类型转换器 + .keyWordsHandler(new PostgreSqlKeyWordsHandler()); + + public static void main(String[] args) { + + FastAutoGenerator.create(DATA_SOURCE_CONFIG) + .globalConfig(builder -> { + builder.author("yqf") // 设置作者 + .enableSwagger() // 开启 swagger 模式 + .fileOverride() // 覆盖已生成文件 + .outputDir("D://code_gen"); // 指定输出目录 + }) + .packageConfig(builder -> { + builder.parent("com.ruoyi.web") // 设置父包名 + .moduleName("eastcom_yw") // 设置父包模块名 + .pathInfo(Collections.singletonMap(OutputFile.xml, "D://code_gen")); // 设置mapperXml生成路径 + }) + .strategyConfig(builder -> { + builder.addInclude("yw_spare_parts") // 设置需要生成的表名 + .addTablePrefix()// 设置过滤表前缀 + .serviceBuilder() + .formatServiceFileName("%sService") + .entityBuilder() + .enableLombok() + .enableTableFieldAnnotation(); +// .addSuperEntityColumns("id", "status_", "seq_no", "create_date", "create_user_id", "modify_date", "modify_user_id") +// .addTableFills(new Column("create_date", FieldFill.INSERT)) +// .addTableFills(new Column("create_user_id", FieldFill.INSERT)) +// .addTableFills(new Property("modify_date", FieldFill.UPDATE)) +// .addTableFills(new Property("modify_user_id", FieldFill.UPDATE)); + + + }) + .templateEngine(new FreemarkerTemplateEngine())// 使用Freemarker引擎模板,默认的是Velocity引擎模板 +// .templateConfig(builder -> { +// builder.("/templates/dto.java"); +// builder.entity("/templates/qo.java"); +// }) + .injectionConfig(consumer -> { + Map customFile = new HashMap<>(); + // DTO + customFile.put("DTO.java", "/templates/dto.java.ftl"); + customFile.put("QO.java", "/templates/qo.java.ftl"); + customFile.put("VO.java", "/templates/vo.java.ftl"); + customFile.put("Convert.java", "/templates/convert.java.ftl"); + consumer.customFile(customFile); + }) + .execute(); + } +} \ No newline at end of file diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/config/GenConfig.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/config/GenConfig.java new file mode 100644 index 0000000..cc4cd14 --- /dev/null +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/config/GenConfig.java @@ -0,0 +1,73 @@ +package com.ruoyi.generator.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +/** + * 读取代码生成相关配置 + * + * @author ruoyi + */ +@Component +@ConfigurationProperties(prefix = "gen") +@PropertySource(value = { "classpath:generator.yml" }) +public class GenConfig +{ + /** 作者 */ + public static String author; + + /** 生成包路径 */ + public static String packageName; + + /** 自动去除表前缀,默认是false */ + public static boolean autoRemovePre; + + /** 表前缀(类名不会包含表前缀) */ + public static String tablePrefix; + + public static String getAuthor() + { + return author; + } + + @Value("${author}") + public void setAuthor(String author) + { + GenConfig.author = author; + } + + public static String getPackageName() + { + return packageName; + } + + @Value("${packageName}") + public void setPackageName(String packageName) + { + GenConfig.packageName = packageName; + } + + public static boolean getAutoRemovePre() + { + return autoRemovePre; + } + + @Value("${autoRemovePre}") + public void setAutoRemovePre(boolean autoRemovePre) + { + GenConfig.autoRemovePre = autoRemovePre; + } + + public static String getTablePrefix() + { + return tablePrefix; + } + + @Value("${tablePrefix}") + public void setTablePrefix(String tablePrefix) + { + GenConfig.tablePrefix = tablePrefix; + } +} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java new file mode 100644 index 0000000..2aed686 --- /dev/null +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java @@ -0,0 +1,214 @@ +package com.ruoyi.generator.controller; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.generator.domain.GenTable; +import com.ruoyi.generator.domain.GenTableColumn; +import com.ruoyi.generator.service.IGenTableColumnService; +import com.ruoyi.generator.service.IGenTableService; + +/** + * 代码生成 操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/tool/gen") +public class GenController extends BaseController +{ + @Autowired + private IGenTableService genTableService; + + @Autowired + private IGenTableColumnService genTableColumnService; + + /** + * 查询代码生成列表 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @GetMapping("/list") + public TableDataInfo genList(GenTable genTable) + { + startPage(); + List list = genTableService.selectGenTableList(genTable); + return getDataTable(list); + } + + /** + * 修改代码生成业务 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:query')") + @GetMapping(value = "/{tableId}") + public AjaxResult getInfo(@PathVariable Long tableId) + { + GenTable table = genTableService.selectGenTableById(tableId); + List tables = genTableService.selectGenTableAll(); + List list = genTableColumnService.selectGenTableColumnListByTableId(tableId); + Map map = new HashMap(); + map.put("info", table); + map.put("rows", list); + map.put("tables", tables); + return success(map); + } + + /** + * 查询数据库列表 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @GetMapping("/db/list") + public TableDataInfo dataList(GenTable genTable) + { + startPage(); + List list = genTableService.selectDbTableList(genTable); + return getDataTable(list); + } + + /** + * 查询数据表字段列表 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @GetMapping(value = "/column/{tableId}") + public TableDataInfo columnList(Long tableId) + { + TableDataInfo dataInfo = new TableDataInfo(); + List list = genTableColumnService.selectGenTableColumnListByTableId(tableId); + dataInfo.setRows(list); + dataInfo.setTotal(list.size()); + return dataInfo; + } + + /** + * 导入表结构(保存) + */ + @PreAuthorize("@ss.hasPermi('tool:gen:import')") + @Log(title = "代码生成", businessType = BusinessType.IMPORT) + @PostMapping("/importTable") + public AjaxResult importTableSave(String tables) + { + String[] tableNames = Convert.toStrArray(tables); + // 查询表信息 + List tableList = genTableService.selectDbTableListByNames(tableNames); + genTableService.importGenTable(tableList); + return success(); + } + + /** + * 修改保存代码生成业务 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:edit')") + @Log(title = "代码生成", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult editSave(@Validated @RequestBody GenTable genTable) + { + genTableService.validateEdit(genTable); + genTableService.updateGenTable(genTable); + return success(); + } + + /** + * 删除代码生成 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:remove')") + @Log(title = "代码生成", businessType = BusinessType.DELETE) + @DeleteMapping("/{tableIds}") + public AjaxResult remove(@PathVariable Long[] tableIds) + { + genTableService.deleteGenTableByIds(tableIds); + return success(); + } + + /** + * 预览代码 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:preview')") + @GetMapping("/preview/{tableId}") + public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException + { + Map dataMap = genTableService.previewCode(tableId); + return success(dataMap); + } + + /** + * 生成代码(下载方式) + */ + @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/download/{tableName}") + public void download(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException + { + byte[] data = genTableService.downloadCode(tableName); + genCode(response, data); + } + + /** + * 生成代码(自定义路径) + */ + @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/genCode/{tableName}") + public AjaxResult genCode(@PathVariable("tableName") String tableName) + { + genTableService.generatorCode(tableName); + return success(); + } + + /** + * 同步数据库 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:edit')") + @Log(title = "代码生成", businessType = BusinessType.UPDATE) + @GetMapping("/synchDb/{tableName}") + public AjaxResult synchDb(@PathVariable("tableName") String tableName) + { + genTableService.synchDb(tableName); + return success(); + } + + /** + * 批量生成代码 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/batchGenCode") + public void batchGenCode(HttpServletResponse response, String tables) throws IOException + { + String[] tableNames = Convert.toStrArray(tables); + byte[] data = genTableService.downloadCode(tableNames); + genCode(response, data); + } + + /** + * 生成zip文件 + */ + private void genCode(HttpServletResponse response, byte[] data) throws IOException + { + response.reset(); + response.addHeader("Access-Control-Allow-Origin", "*"); + response.addHeader("Access-Control-Expose-Headers", "Content-Disposition"); + response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\""); + response.addHeader("Content-Length", "" + data.length); + response.setContentType("application/octet-stream; charset=UTF-8"); + IOUtils.write(data, response.getOutputStream()); + } +} \ No newline at end of file diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java new file mode 100644 index 0000000..269779c --- /dev/null +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java @@ -0,0 +1,372 @@ +package com.ruoyi.generator.domain; + +import java.util.List; +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import org.apache.commons.lang3.ArrayUtils; +import com.ruoyi.common.constant.GenConstants; +import com.ruoyi.common.core.domain.BaseEntity; +import com.ruoyi.common.utils.StringUtils; + +/** + * 业务表 gen_table + * + * @author ruoyi + */ +public class GenTable extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 编号 */ + private Long tableId; + + /** 表名称 */ + @NotBlank(message = "表名称不能为空") + private String tableName; + + /** 表描述 */ + @NotBlank(message = "表描述不能为空") + private String tableComment; + + /** 关联父表的表名 */ + private String subTableName; + + /** 本表关联父表的外键名 */ + private String subTableFkName; + + /** 实体类名称(首字母大写) */ + @NotBlank(message = "实体类名称不能为空") + private String className; + + /** 使用的模板(crud单表操作 tree树表操作 sub主子表操作) */ + private String tplCategory; + + /** 生成包路径 */ + @NotBlank(message = "生成包路径不能为空") + private String packageName; + + /** 生成模块名 */ + @NotBlank(message = "生成模块名不能为空") + private String moduleName; + + /** 生成业务名 */ + @NotBlank(message = "生成业务名不能为空") + private String businessName; + + /** 生成功能名 */ + @NotBlank(message = "生成功能名不能为空") + private String functionName; + + /** 生成作者 */ + @NotBlank(message = "作者不能为空") + private String functionAuthor; + + /** 生成代码方式(0zip压缩包 1自定义路径) */ + private String genType; + + /** 生成路径(不填默认项目路径) */ + private String genPath; + + /** 主键信息 */ + private GenTableColumn pkColumn; + + /** 子表信息 */ + private GenTable subTable; + + /** 表列信息 */ + @Valid + private List columns; + + /** 其它生成选项 */ + private String options; + + /** 树编码字段 */ + private String treeCode; + + /** 树父编码字段 */ + private String treeParentCode; + + /** 树名称字段 */ + private String treeName; + + /** 上级菜单ID字段 */ + private String parentMenuId; + + /** 上级菜单名称字段 */ + private String parentMenuName; + + public Long getTableId() + { + return tableId; + } + + public void setTableId(Long tableId) + { + this.tableId = tableId; + } + + public String getTableName() + { + return tableName; + } + + public void setTableName(String tableName) + { + this.tableName = tableName; + } + + public String getTableComment() + { + return tableComment; + } + + public void setTableComment(String tableComment) + { + this.tableComment = tableComment; + } + + public String getSubTableName() + { + return subTableName; + } + + public void setSubTableName(String subTableName) + { + this.subTableName = subTableName; + } + + public String getSubTableFkName() + { + return subTableFkName; + } + + public void setSubTableFkName(String subTableFkName) + { + this.subTableFkName = subTableFkName; + } + + public String getClassName() + { + return className; + } + + public void setClassName(String className) + { + this.className = className; + } + + public String getTplCategory() + { + return tplCategory; + } + + public void setTplCategory(String tplCategory) + { + this.tplCategory = tplCategory; + } + + public String getPackageName() + { + return packageName; + } + + public void setPackageName(String packageName) + { + this.packageName = packageName; + } + + public String getModuleName() + { + return moduleName; + } + + public void setModuleName(String moduleName) + { + this.moduleName = moduleName; + } + + public String getBusinessName() + { + return businessName; + } + + public void setBusinessName(String businessName) + { + this.businessName = businessName; + } + + public String getFunctionName() + { + return functionName; + } + + public void setFunctionName(String functionName) + { + this.functionName = functionName; + } + + public String getFunctionAuthor() + { + return functionAuthor; + } + + public void setFunctionAuthor(String functionAuthor) + { + this.functionAuthor = functionAuthor; + } + + public String getGenType() + { + return genType; + } + + public void setGenType(String genType) + { + this.genType = genType; + } + + public String getGenPath() + { + return genPath; + } + + public void setGenPath(String genPath) + { + this.genPath = genPath; + } + + public GenTableColumn getPkColumn() + { + return pkColumn; + } + + public void setPkColumn(GenTableColumn pkColumn) + { + this.pkColumn = pkColumn; + } + + public GenTable getSubTable() + { + return subTable; + } + + public void setSubTable(GenTable subTable) + { + this.subTable = subTable; + } + + public List getColumns() + { + return columns; + } + + public void setColumns(List columns) + { + this.columns = columns; + } + + public String getOptions() + { + return options; + } + + public void setOptions(String options) + { + this.options = options; + } + + public String getTreeCode() + { + return treeCode; + } + + public void setTreeCode(String treeCode) + { + this.treeCode = treeCode; + } + + public String getTreeParentCode() + { + return treeParentCode; + } + + public void setTreeParentCode(String treeParentCode) + { + this.treeParentCode = treeParentCode; + } + + public String getTreeName() + { + return treeName; + } + + public void setTreeName(String treeName) + { + this.treeName = treeName; + } + + public String getParentMenuId() + { + return parentMenuId; + } + + public void setParentMenuId(String parentMenuId) + { + this.parentMenuId = parentMenuId; + } + + public String getParentMenuName() + { + return parentMenuName; + } + + public void setParentMenuName(String parentMenuName) + { + this.parentMenuName = parentMenuName; + } + + public boolean isSub() + { + return isSub(this.tplCategory); + } + + public static boolean isSub(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_SUB, tplCategory); + } + + public boolean isTree() + { + return isTree(this.tplCategory); + } + + public static boolean isTree(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_TREE, tplCategory); + } + + public boolean isCrud() + { + return isCrud(this.tplCategory); + } + + public static boolean isCrud(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_CRUD, tplCategory); + } + + public boolean isSuperColumn(String javaField) + { + return isSuperColumn(this.tplCategory, javaField); + } + + public static boolean isSuperColumn(String tplCategory, String javaField) + { + if (isTree(tplCategory)) + { + return StringUtils.equalsAnyIgnoreCase(javaField, + ArrayUtils.addAll(GenConstants.TREE_ENTITY, GenConstants.BASE_ENTITY)); + } + return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY); + } +} \ No newline at end of file diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java new file mode 100644 index 0000000..d1733b6 --- /dev/null +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java @@ -0,0 +1,373 @@ +package com.ruoyi.generator.domain; + +import javax.validation.constraints.NotBlank; +import com.ruoyi.common.core.domain.BaseEntity; +import com.ruoyi.common.utils.StringUtils; + +/** + * 代码生成业务字段表 gen_table_column + * + * @author ruoyi + */ +public class GenTableColumn extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 编号 */ + private Long columnId; + + /** 归属表编号 */ + private Long tableId; + + /** 列名称 */ + private String columnName; + + /** 列描述 */ + private String columnComment; + + /** 列类型 */ + private String columnType; + + /** JAVA类型 */ + private String javaType; + + /** JAVA字段名 */ + @NotBlank(message = "Java属性不能为空") + private String javaField; + + /** 是否主键(1是) */ + private String isPk; + + /** 是否自增(1是) */ + private String isIncrement; + + /** 是否必填(1是) */ + private String isRequired; + + /** 是否为插入字段(1是) */ + private String isInsert; + + /** 是否编辑字段(1是) */ + private String isEdit; + + /** 是否列表字段(1是) */ + private String isList; + + /** 是否查询字段(1是) */ + private String isQuery; + + /** 查询方式(EQ等于、NE不等于、GT大于、LT小于、LIKE模糊、BETWEEN范围) */ + private String queryType; + + /** 显示类型(input文本框、textarea文本域、select下拉框、checkbox复选框、radio单选框、datetime日期控件、image图片上传控件、upload文件上传控件、editor富文本控件) */ + private String htmlType; + + /** 字典类型 */ + private String dictType; + + /** 排序 */ + private Integer sort; + + public void setColumnId(Long columnId) + { + this.columnId = columnId; + } + + public Long getColumnId() + { + return columnId; + } + + public void setTableId(Long tableId) + { + this.tableId = tableId; + } + + public Long getTableId() + { + return tableId; + } + + public void setColumnName(String columnName) + { + this.columnName = columnName; + } + + public String getColumnName() + { + return columnName; + } + + public void setColumnComment(String columnComment) + { + this.columnComment = columnComment; + } + + public String getColumnComment() + { + return columnComment; + } + + public void setColumnType(String columnType) + { + this.columnType = columnType; + } + + public String getColumnType() + { + return columnType; + } + + public void setJavaType(String javaType) + { + this.javaType = javaType; + } + + public String getJavaType() + { + return javaType; + } + + public void setJavaField(String javaField) + { + this.javaField = javaField; + } + + public String getJavaField() + { + return javaField; + } + + public String getCapJavaField() + { + return StringUtils.capitalize(javaField); + } + + public void setIsPk(String isPk) + { + this.isPk = isPk; + } + + public String getIsPk() + { + return isPk; + } + + public boolean isPk() + { + return isPk(this.isPk); + } + + public boolean isPk(String isPk) + { + return isPk != null && StringUtils.equals("1", isPk); + } + + public String getIsIncrement() + { + return isIncrement; + } + + public void setIsIncrement(String isIncrement) + { + this.isIncrement = isIncrement; + } + + public boolean isIncrement() + { + return isIncrement(this.isIncrement); + } + + public boolean isIncrement(String isIncrement) + { + return isIncrement != null && StringUtils.equals("1", isIncrement); + } + + public void setIsRequired(String isRequired) + { + this.isRequired = isRequired; + } + + public String getIsRequired() + { + return isRequired; + } + + public boolean isRequired() + { + return isRequired(this.isRequired); + } + + public boolean isRequired(String isRequired) + { + return isRequired != null && StringUtils.equals("1", isRequired); + } + + public void setIsInsert(String isInsert) + { + this.isInsert = isInsert; + } + + public String getIsInsert() + { + return isInsert; + } + + public boolean isInsert() + { + return isInsert(this.isInsert); + } + + public boolean isInsert(String isInsert) + { + return isInsert != null && StringUtils.equals("1", isInsert); + } + + public void setIsEdit(String isEdit) + { + this.isEdit = isEdit; + } + + public String getIsEdit() + { + return isEdit; + } + + public boolean isEdit() + { + return isInsert(this.isEdit); + } + + public boolean isEdit(String isEdit) + { + return isEdit != null && StringUtils.equals("1", isEdit); + } + + public void setIsList(String isList) + { + this.isList = isList; + } + + public String getIsList() + { + return isList; + } + + public boolean isList() + { + return isList(this.isList); + } + + public boolean isList(String isList) + { + return isList != null && StringUtils.equals("1", isList); + } + + public void setIsQuery(String isQuery) + { + this.isQuery = isQuery; + } + + public String getIsQuery() + { + return isQuery; + } + + public boolean isQuery() + { + return isQuery(this.isQuery); + } + + public boolean isQuery(String isQuery) + { + return isQuery != null && StringUtils.equals("1", isQuery); + } + + public void setQueryType(String queryType) + { + this.queryType = queryType; + } + + public String getQueryType() + { + return queryType; + } + + public String getHtmlType() + { + return htmlType; + } + + public void setHtmlType(String htmlType) + { + this.htmlType = htmlType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + public String getDictType() + { + return dictType; + } + + public void setSort(Integer sort) + { + this.sort = sort; + } + + public Integer getSort() + { + return sort; + } + + public boolean isSuperColumn() + { + return isSuperColumn(this.javaField); + } + + public static boolean isSuperColumn(String javaField) + { + return StringUtils.equalsAnyIgnoreCase(javaField, + // BaseEntity + "createBy", "createTime", "updateBy", "updateTime", "remark", + // TreeEntity + "parentName", "parentId", "orderNum", "ancestors"); + } + + public boolean isUsableColumn() + { + return isUsableColumn(javaField); + } + + public static boolean isUsableColumn(String javaField) + { + // isSuperColumn()中的名单用于避免生成多余Domain属性,若某些属性在生成页面时需要用到不能忽略,则放在此处白名单 + return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum", "remark"); + } + + public String readConverterExp() + { + String remarks = StringUtils.substringBetween(this.columnComment, "(", ")"); + StringBuffer sb = new StringBuffer(); + if (StringUtils.isNotEmpty(remarks)) + { + for (String value : remarks.split(" ")) + { + if (StringUtils.isNotEmpty(value)) + { + Object startStr = value.subSequence(0, 1); + String endStr = value.substring(1); + sb.append("").append(startStr).append("=").append(endStr).append(","); + } + } + return sb.deleteCharAt(sb.length() - 1).toString(); + } + else + { + return this.columnComment; + } + } +} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java new file mode 100644 index 0000000..951e166 --- /dev/null +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java @@ -0,0 +1,60 @@ +package com.ruoyi.generator.mapper; + +import java.util.List; +import com.ruoyi.generator.domain.GenTableColumn; + +/** + * 业务字段 数据层 + * + * @author ruoyi + */ +public interface GenTableColumnMapper +{ + /** + * 根据表名称查询列信息 + * + * @param tableName 表名称 + * @return 列信息 + */ + public List selectDbTableColumnsByName(String tableName); + + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + public List selectGenTableColumnListByTableId(Long tableId); + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int insertGenTableColumn(GenTableColumn genTableColumn); + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int updateGenTableColumn(GenTableColumn genTableColumn); + + /** + * 删除业务字段 + * + * @param genTableColumns 列数据 + * @return 结果 + */ + public int deleteGenTableColumns(List genTableColumns); + + /** + * 批量删除业务字段 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableColumnByIds(Long[] ids); +} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java new file mode 100644 index 0000000..9b330df --- /dev/null +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java @@ -0,0 +1,83 @@ +package com.ruoyi.generator.mapper; + +import java.util.List; +import com.ruoyi.generator.domain.GenTable; + +/** + * 业务 数据层 + * + * @author ruoyi + */ +public interface GenTableMapper +{ + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + public List selectGenTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + public List selectDbTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + public List selectDbTableListByNames(String[] tableNames); + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + public List selectGenTableAll(); + + /** + * 查询表ID业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + public GenTable selectGenTableById(Long id); + + /** + * 查询表名称业务信息 + * + * @param tableName 表名称 + * @return 业务信息 + */ + public GenTable selectGenTableByName(String tableName); + + /** + * 新增业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public int insertGenTable(GenTable genTable); + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public int updateGenTable(GenTable genTable); + + /** + * 批量删除业务 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableByIds(Long[] ids); +} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableColumnServiceImpl.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableColumnServiceImpl.java new file mode 100644 index 0000000..0679689 --- /dev/null +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableColumnServiceImpl.java @@ -0,0 +1,68 @@ +package com.ruoyi.generator.service; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.generator.domain.GenTableColumn; +import com.ruoyi.generator.mapper.GenTableColumnMapper; + +/** + * 业务字段 服务层实现 + * + * @author ruoyi + */ +@Service +public class GenTableColumnServiceImpl implements IGenTableColumnService +{ + @Autowired + private GenTableColumnMapper genTableColumnMapper; + + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + @Override + public List selectGenTableColumnListByTableId(Long tableId) + { + return genTableColumnMapper.selectGenTableColumnListByTableId(tableId); + } + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + @Override + public int insertGenTableColumn(GenTableColumn genTableColumn) + { + return genTableColumnMapper.insertGenTableColumn(genTableColumn); + } + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + @Override + public int updateGenTableColumn(GenTableColumn genTableColumn) + { + return genTableColumnMapper.updateGenTableColumn(genTableColumn); + } + + /** + * 删除业务字段对象 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteGenTableColumnByIds(String ids) + { + return genTableColumnMapper.deleteGenTableColumnByIds(Convert.toLongArray(ids)); + } +} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java new file mode 100644 index 0000000..4889f81 --- /dev/null +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java @@ -0,0 +1,521 @@ +package com.ruoyi.generator.service; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.GenConstants; +import com.ruoyi.common.core.text.CharsetKit; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.generator.domain.GenTable; +import com.ruoyi.generator.domain.GenTableColumn; +import com.ruoyi.generator.mapper.GenTableColumnMapper; +import com.ruoyi.generator.mapper.GenTableMapper; +import com.ruoyi.generator.util.GenUtils; +import com.ruoyi.generator.util.VelocityInitializer; +import com.ruoyi.generator.util.VelocityUtils; + +/** + * 业务 服务层实现 + * + * @author ruoyi + */ +@Service +public class GenTableServiceImpl implements IGenTableService +{ + private static final Logger log = LoggerFactory.getLogger(GenTableServiceImpl.class); + + @Autowired + private GenTableMapper genTableMapper; + + @Autowired + private GenTableColumnMapper genTableColumnMapper; + + /** + * 查询业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + @Override + public GenTable selectGenTableById(Long id) + { + GenTable genTable = genTableMapper.selectGenTableById(id); + setTableFromOptions(genTable); + return genTable; + } + + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + @Override + public List selectGenTableList(GenTable genTable) + { + return genTableMapper.selectGenTableList(genTable); + } + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + @Override + public List selectDbTableList(GenTable genTable) + { + return genTableMapper.selectDbTableList(genTable); + } + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + @Override + public List selectDbTableListByNames(String[] tableNames) + { + return genTableMapper.selectDbTableListByNames(tableNames); + } + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + @Override + public List selectGenTableAll() + { + return genTableMapper.selectGenTableAll(); + } + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + @Override + @Transactional + public void updateGenTable(GenTable genTable) + { + String options = JSON.toJSONString(genTable.getParams()); + genTable.setOptions(options); + int row = genTableMapper.updateGenTable(genTable); + if (row > 0) + { + for (GenTableColumn cenTableColumn : genTable.getColumns()) + { + genTableColumnMapper.updateGenTableColumn(cenTableColumn); + } + } + } + + /** + * 删除业务对象 + * + * @param tableIds 需要删除的数据ID + * @return 结果 + */ + @Override + @Transactional + public void deleteGenTableByIds(Long[] tableIds) + { + genTableMapper.deleteGenTableByIds(tableIds); + genTableColumnMapper.deleteGenTableColumnByIds(tableIds); + } + + /** + * 导入表结构 + * + * @param tableList 导入表列表 + */ + @Override + @Transactional + public void importGenTable(List tableList) + { + String operName = SecurityUtils.getUsername(); + try + { + for (GenTable table : tableList) + { + String tableName = table.getTableName(); + GenUtils.initTable(table, operName); + int row = genTableMapper.insertGenTable(table); + if (row > 0) + { + // 保存列信息 + List genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); + for (GenTableColumn column : genTableColumns) + { + GenUtils.initColumnField(column, table); + genTableColumnMapper.insertGenTableColumn(column); + } + } + } + } + catch (Exception e) + { + throw new ServiceException("导入失败:" + e.getMessage()); + } + } + + /** + * 预览代码 + * + * @param tableId 表编号 + * @return 预览数据列表 + */ + @Override + public Map previewCode(Long tableId) + { + Map dataMap = new LinkedHashMap<>(); + // 查询表信息 + GenTable table = genTableMapper.selectGenTableById(tableId); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory()); + for (String template : templates) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + dataMap.put(template, sw.toString()); + } + return dataMap; + } + + /** + * 生成代码(下载方式) + * + * @param tableName 表名称 + * @return 数据 + */ + @Override + public byte[] downloadCode(String tableName) + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + generatorCode(tableName, zip); + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + /** + * 生成代码(自定义路径) + * + * @param tableName 表名称 + */ + @Override + public void generatorCode(String tableName) + { + // 查询表信息 + GenTable table = genTableMapper.selectGenTableByName(tableName); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory()); + for (String template : templates) + { + if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm")) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + try + { + String path = getGenPath(table, template); + FileUtils.writeStringToFile(new File(path), sw.toString(), CharsetKit.UTF_8); + } + catch (IOException e) + { + throw new ServiceException("渲染模板失败,表名:" + table.getTableName()); + } + } + } + } + + /** + * 同步数据库 + * + * @param tableName 表名称 + */ + @Override + @Transactional + public void synchDb(String tableName) + { + GenTable table = genTableMapper.selectGenTableByName(tableName); + List tableColumns = table.getColumns(); + Map tableColumnMap = tableColumns.stream().collect(Collectors.toMap(GenTableColumn::getColumnName, Function.identity())); + + List dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); + if (StringUtils.isEmpty(dbTableColumns)) + { + throw new ServiceException("同步数据失败,原表结构不存在"); + } + List dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList()); + + dbTableColumns.forEach(column -> { + GenUtils.initColumnField(column, table); + if (tableColumnMap.containsKey(column.getColumnName())) + { + GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName()); + column.setColumnId(prevColumn.getColumnId()); + if (column.isList()) + { + // 如果是列表,继续保留查询方式/字典类型选项 + column.setDictType(prevColumn.getDictType()); + column.setQueryType(prevColumn.getQueryType()); + } + if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk() + && (column.isInsert() || column.isEdit()) + && ((column.isUsableColumn()) || (!column.isSuperColumn()))) + { + // 如果是(新增/修改&非主键/非忽略及父属性),继续保留必填/显示类型选项 + column.setIsRequired(prevColumn.getIsRequired()); + column.setHtmlType(prevColumn.getHtmlType()); + } + genTableColumnMapper.updateGenTableColumn(column); + } + else + { + genTableColumnMapper.insertGenTableColumn(column); + } + }); + + List delColumns = tableColumns.stream().filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList()); + if (StringUtils.isNotEmpty(delColumns)) + { + genTableColumnMapper.deleteGenTableColumns(delColumns); + } + } + + /** + * 批量生成代码(下载方式) + * + * @param tableNames 表数组 + * @return 数据 + */ + @Override + public byte[] downloadCode(String[] tableNames) + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + for (String tableName : tableNames) + { + generatorCode(tableName, zip); + } + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + /** + * 查询表信息并生成代码 + */ + private void generatorCode(String tableName, ZipOutputStream zip) + { + // 查询表信息 + GenTable table = genTableMapper.selectGenTableByName(tableName); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory()); + for (String template : templates) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + try + { + // 添加到zip + zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table))); + IOUtils.write(sw.toString(), zip, Constants.UTF8); + IOUtils.closeQuietly(sw); + zip.flush(); + zip.closeEntry(); + } + catch (IOException e) + { + log.error("渲染模板失败,表名:" + table.getTableName(), e); + } + } + } + + /** + * 修改保存参数校验 + * + * @param genTable 业务信息 + */ + @Override + public void validateEdit(GenTable genTable) + { + if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) + { + String options = JSON.toJSONString(genTable.getParams()); + JSONObject paramsObj = JSON.parseObject(options); + if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_CODE))) + { + throw new ServiceException("树编码字段不能为空"); + } + else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_PARENT_CODE))) + { + throw new ServiceException("树父编码字段不能为空"); + } + else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_NAME))) + { + throw new ServiceException("树名称字段不能为空"); + } + else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory())) + { + if (StringUtils.isEmpty(genTable.getSubTableName())) + { + throw new ServiceException("关联子表的表名不能为空"); + } + else if (StringUtils.isEmpty(genTable.getSubTableFkName())) + { + throw new ServiceException("子表关联的外键名不能为空"); + } + } + } + } + + /** + * 设置主键列信息 + * + * @param table 业务表信息 + */ + public void setPkColumn(GenTable table) + { + for (GenTableColumn column : table.getColumns()) + { + if (column.isPk()) + { + table.setPkColumn(column); + break; + } + } + if (StringUtils.isNull(table.getPkColumn())) + { + table.setPkColumn(table.getColumns().get(0)); + } + if (GenConstants.TPL_SUB.equals(table.getTplCategory())) + { + for (GenTableColumn column : table.getSubTable().getColumns()) + { + if (column.isPk()) + { + table.getSubTable().setPkColumn(column); + break; + } + } + if (StringUtils.isNull(table.getSubTable().getPkColumn())) + { + table.getSubTable().setPkColumn(table.getSubTable().getColumns().get(0)); + } + } + } + + /** + * 设置主子表信息 + * + * @param table 业务表信息 + */ + public void setSubTable(GenTable table) + { + String subTableName = table.getSubTableName(); + if (StringUtils.isNotEmpty(subTableName)) + { + table.setSubTable(genTableMapper.selectGenTableByName(subTableName)); + } + } + + /** + * 设置代码生成其他选项值 + * + * @param genTable 设置后的生成对象 + */ + public void setTableFromOptions(GenTable genTable) + { + JSONObject paramsObj = JSON.parseObject(genTable.getOptions()); + if (StringUtils.isNotNull(paramsObj)) + { + String treeCode = paramsObj.getString(GenConstants.TREE_CODE); + String treeParentCode = paramsObj.getString(GenConstants.TREE_PARENT_CODE); + String treeName = paramsObj.getString(GenConstants.TREE_NAME); + String parentMenuId = paramsObj.getString(GenConstants.PARENT_MENU_ID); + String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME); + + genTable.setTreeCode(treeCode); + genTable.setTreeParentCode(treeParentCode); + genTable.setTreeName(treeName); + genTable.setParentMenuId(parentMenuId); + genTable.setParentMenuName(parentMenuName); + } + } + + /** + * 获取代码生成地址 + * + * @param table 业务表信息 + * @param template 模板文件路径 + * @return 生成地址 + */ + public static String getGenPath(GenTable table, String template) + { + String genPath = table.getGenPath(); + if (StringUtils.equals(genPath, "/")) + { + return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table); + } + return genPath + File.separator + VelocityUtils.getFileName(template, table); + } +} \ No newline at end of file diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableColumnService.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableColumnService.java new file mode 100644 index 0000000..3037f70 --- /dev/null +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableColumnService.java @@ -0,0 +1,44 @@ +package com.ruoyi.generator.service; + +import java.util.List; +import com.ruoyi.generator.domain.GenTableColumn; + +/** + * 业务字段 服务层 + * + * @author ruoyi + */ +public interface IGenTableColumnService +{ + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + public List selectGenTableColumnListByTableId(Long tableId); + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int insertGenTableColumn(GenTableColumn genTableColumn); + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int updateGenTableColumn(GenTableColumn genTableColumn); + + /** + * 删除业务字段信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableColumnByIds(String ids); +} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java new file mode 100644 index 0000000..9d53f95 --- /dev/null +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java @@ -0,0 +1,121 @@ +package com.ruoyi.generator.service; + +import java.util.List; +import java.util.Map; +import com.ruoyi.generator.domain.GenTable; + +/** + * 业务 服务层 + * + * @author ruoyi + */ +public interface IGenTableService +{ + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + public List selectGenTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + public List selectDbTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + public List selectDbTableListByNames(String[] tableNames); + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + public List selectGenTableAll(); + + /** + * 查询业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + public GenTable selectGenTableById(Long id); + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public void updateGenTable(GenTable genTable); + + /** + * 删除业务信息 + * + * @param tableIds 需要删除的表数据ID + * @return 结果 + */ + public void deleteGenTableByIds(Long[] tableIds); + + /** + * 导入表结构 + * + * @param tableList 导入表列表 + */ + public void importGenTable(List tableList); + + /** + * 预览代码 + * + * @param tableId 表编号 + * @return 预览数据列表 + */ + public Map previewCode(Long tableId); + + /** + * 生成代码(下载方式) + * + * @param tableName 表名称 + * @return 数据 + */ + public byte[] downloadCode(String tableName); + + /** + * 生成代码(自定义路径) + * + * @param tableName 表名称 + * @return 数据 + */ + public void generatorCode(String tableName); + + /** + * 同步数据库 + * + * @param tableName 表名称 + */ + public void synchDb(String tableName); + + /** + * 批量生成代码(下载方式) + * + * @param tableNames 表数组 + * @return 数据 + */ + public byte[] downloadCode(String[] tableNames); + + /** + * 修改保存参数校验 + * + * @param genTable 业务信息 + */ + public void validateEdit(GenTable genTable); +} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java new file mode 100644 index 0000000..e7ebc20 --- /dev/null +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java @@ -0,0 +1,257 @@ +package com.ruoyi.generator.util; + +import java.util.Arrays; +import org.apache.commons.lang3.RegExUtils; +import com.ruoyi.common.constant.GenConstants; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.generator.config.GenConfig; +import com.ruoyi.generator.domain.GenTable; +import com.ruoyi.generator.domain.GenTableColumn; + +/** + * 代码生成器 工具类 + * + * @author ruoyi + */ +public class GenUtils +{ + /** + * 初始化表信息 + */ + public static void initTable(GenTable genTable, String operName) + { + genTable.setClassName(convertClassName(genTable.getTableName())); + genTable.setPackageName(GenConfig.getPackageName()); + genTable.setModuleName(getModuleName(GenConfig.getPackageName())); + genTable.setBusinessName(getBusinessName(genTable.getTableName())); + genTable.setFunctionName(replaceText(genTable.getTableComment())); + genTable.setFunctionAuthor(GenConfig.getAuthor()); + genTable.setCreateBy(operName); + } + + /** + * 初始化列属性字段 + */ + public static void initColumnField(GenTableColumn column, GenTable table) + { + String dataType = getDbType(column.getColumnType()); + String columnName = column.getColumnName(); + column.setTableId(table.getTableId()); + column.setCreateBy(table.getCreateBy()); + // 设置java字段名 + column.setJavaField(StringUtils.toCamelCase(columnName)); + // 设置默认类型 + column.setJavaType(GenConstants.TYPE_STRING); + column.setQueryType(GenConstants.QUERY_EQ); + + if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType)) + { + // 字符串长度超过500设置为文本域 + Integer columnLength = getColumnLength(column.getColumnType()); + String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT; + column.setHtmlType(htmlType); + } + else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType)) + { + column.setJavaType(GenConstants.TYPE_DATE); + column.setHtmlType(GenConstants.HTML_DATETIME); + } + else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType)) + { + column.setHtmlType(GenConstants.HTML_INPUT); + + // 如果是浮点型 统一用BigDecimal + String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ","); + if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0) + { + column.setJavaType(GenConstants.TYPE_BIGDECIMAL); + } + // 如果是整形 + else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10) + { + column.setJavaType(GenConstants.TYPE_INTEGER); + } + // 长整形 + else + { + column.setJavaType(GenConstants.TYPE_LONG); + } + } + + // 插入字段(默认所有字段都需要插入) + column.setIsInsert(GenConstants.REQUIRE); + + // 编辑字段 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName) && !column.isPk()) + { + column.setIsEdit(GenConstants.REQUIRE); + } + // 列表字段 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName) && !column.isPk()) + { + column.setIsList(GenConstants.REQUIRE); + } + // 查询字段 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk()) + { + column.setIsQuery(GenConstants.REQUIRE); + } + + // 查询字段类型 + if (StringUtils.endsWithIgnoreCase(columnName, "name")) + { + column.setQueryType(GenConstants.QUERY_LIKE); + } + // 状态字段设置单选框 + if (StringUtils.endsWithIgnoreCase(columnName, "status")) + { + column.setHtmlType(GenConstants.HTML_RADIO); + } + // 类型&性别字段设置下拉框 + else if (StringUtils.endsWithIgnoreCase(columnName, "type") + || StringUtils.endsWithIgnoreCase(columnName, "sex")) + { + column.setHtmlType(GenConstants.HTML_SELECT); + } + // 图片字段设置图片上传控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "image")) + { + column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD); + } + // 文件字段设置文件上传控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "file")) + { + column.setHtmlType(GenConstants.HTML_FILE_UPLOAD); + } + // 内容字段设置富文本控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "content")) + { + column.setHtmlType(GenConstants.HTML_EDITOR); + } + } + + /** + * 校验数组是否包含指定值 + * + * @param arr 数组 + * @param targetValue 值 + * @return 是否包含 + */ + public static boolean arraysContains(String[] arr, String targetValue) + { + return Arrays.asList(arr).contains(targetValue); + } + + /** + * 获取模块名 + * + * @param packageName 包名 + * @return 模块名 + */ + public static String getModuleName(String packageName) + { + int lastIndex = packageName.lastIndexOf("."); + int nameLength = packageName.length(); + return StringUtils.substring(packageName, lastIndex + 1, nameLength); + } + + /** + * 获取业务名 + * + * @param tableName 表名 + * @return 业务名 + */ + public static String getBusinessName(String tableName) + { + int lastIndex = tableName.lastIndexOf("_"); + int nameLength = tableName.length(); + return StringUtils.substring(tableName, lastIndex + 1, nameLength); + } + + /** + * 表名转换成Java类名 + * + * @param tableName 表名称 + * @return 类名 + */ + public static String convertClassName(String tableName) + { + boolean autoRemovePre = GenConfig.getAutoRemovePre(); + String tablePrefix = GenConfig.getTablePrefix(); + if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)) + { + String[] searchList = StringUtils.split(tablePrefix, ","); + tableName = replaceFirst(tableName, searchList); + } + return StringUtils.convertToCamelCase(tableName); + } + + /** + * 批量替换前缀 + * + * @param replacementm 替换值 + * @param searchList 替换列表 + * @return + */ + public static String replaceFirst(String replacementm, String[] searchList) + { + String text = replacementm; + for (String searchString : searchList) + { + if (replacementm.startsWith(searchString)) + { + text = replacementm.replaceFirst(searchString, ""); + break; + } + } + return text; + } + + /** + * 关键字替换 + * + * @param text 需要被替换的名字 + * @return 替换后的名字 + */ + public static String replaceText(String text) + { + return RegExUtils.replaceAll(text, "(?:表|若依)", ""); + } + + /** + * 获取数据库类型字段 + * + * @param columnType 列类型 + * @return 截取后的列类型 + */ + public static String getDbType(String columnType) + { + if (StringUtils.indexOf(columnType, "(") > 0) + { + return StringUtils.substringBefore(columnType, "("); + } + else + { + return columnType; + } + } + + /** + * 获取字段长度 + * + * @param columnType 列类型 + * @return 截取后的列类型 + */ + public static Integer getColumnLength(String columnType) + { + if (StringUtils.indexOf(columnType, "(") > 0) + { + String length = StringUtils.substringBetween(columnType, "(", ")"); + return Integer.valueOf(length); + } + else + { + return 0; + } + } +} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java new file mode 100644 index 0000000..9f69403 --- /dev/null +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java @@ -0,0 +1,34 @@ +package com.ruoyi.generator.util; + +import java.util.Properties; +import org.apache.velocity.app.Velocity; +import com.ruoyi.common.constant.Constants; + +/** + * VelocityEngine工厂 + * + * @author ruoyi + */ +public class VelocityInitializer +{ + /** + * 初始化vm方法 + */ + public static void initVelocity() + { + Properties p = new Properties(); + try + { + // 加载classpath目录下的vm文件 + p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + // 定义字符集 + p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8); + // 初始化Velocity引擎,指定配置Properties + Velocity.init(p); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } +} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java new file mode 100644 index 0000000..7ede02d --- /dev/null +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java @@ -0,0 +1,402 @@ +package com.ruoyi.generator.util; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.apache.velocity.VelocityContext; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.constant.GenConstants; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.generator.domain.GenTable; +import com.ruoyi.generator.domain.GenTableColumn; + +/** + * 模板处理工具类 + * + * @author ruoyi + */ +public class VelocityUtils +{ + /** 项目空间路径 */ + private static final String PROJECT_PATH = "main/java"; + + /** mybatis空间路径 */ + private static final String MYBATIS_PATH = "main/resources/mapper"; + + /** 默认上级菜单,系统工具 */ + private static final String DEFAULT_PARENT_MENU_ID = "3"; + + /** + * 设置模板变量信息 + * + * @return 模板列表 + */ + public static VelocityContext prepareContext(GenTable genTable) + { + String moduleName = genTable.getModuleName(); + String businessName = genTable.getBusinessName(); + String packageName = genTable.getPackageName(); + String tplCategory = genTable.getTplCategory(); + String functionName = genTable.getFunctionName(); + + VelocityContext velocityContext = new VelocityContext(); + velocityContext.put("tplCategory", genTable.getTplCategory()); + velocityContext.put("tableName", genTable.getTableName()); + velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】"); + velocityContext.put("ClassName", genTable.getClassName()); + velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName())); + velocityContext.put("moduleName", genTable.getModuleName()); + velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName())); + velocityContext.put("businessName", genTable.getBusinessName()); + velocityContext.put("basePackage", getPackagePrefix(packageName)); + velocityContext.put("packageName", packageName); + velocityContext.put("author", genTable.getFunctionAuthor()); + velocityContext.put("datetime", DateUtils.getDate()); + velocityContext.put("pkColumn", genTable.getPkColumn()); + velocityContext.put("importList", getImportList(genTable)); + velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); + velocityContext.put("columns", genTable.getColumns()); + velocityContext.put("table", genTable); + velocityContext.put("dicts", getDicts(genTable)); + setMenuVelocityContext(velocityContext, genTable); + if (GenConstants.TPL_TREE.equals(tplCategory)) + { + setTreeVelocityContext(velocityContext, genTable); + } + if (GenConstants.TPL_SUB.equals(tplCategory)) + { + setSubVelocityContext(velocityContext, genTable); + } + return velocityContext; + } + + public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String parentMenuId = getParentMenuId(paramsObj); + context.put("parentMenuId", parentMenuId); + } + + public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String treeCode = getTreecode(paramsObj); + String treeParentCode = getTreeParentCode(paramsObj); + String treeName = getTreeName(paramsObj); + + context.put("treeCode", treeCode); + context.put("treeParentCode", treeParentCode); + context.put("treeName", treeName); + context.put("expandColumn", getExpandColumn(genTable)); + if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) + { + context.put("tree_parent_code", paramsObj.getString(GenConstants.TREE_PARENT_CODE)); + } + if (paramsObj.containsKey(GenConstants.TREE_NAME)) + { + context.put("tree_name", paramsObj.getString(GenConstants.TREE_NAME)); + } + } + + public static void setSubVelocityContext(VelocityContext context, GenTable genTable) + { + GenTable subTable = genTable.getSubTable(); + String subTableName = genTable.getSubTableName(); + String subTableFkName = genTable.getSubTableFkName(); + String subClassName = genTable.getSubTable().getClassName(); + String subTableFkClassName = StringUtils.convertToCamelCase(subTableFkName); + + context.put("subTable", subTable); + context.put("subTableName", subTableName); + context.put("subTableFkName", subTableFkName); + context.put("subTableFkClassName", subTableFkClassName); + context.put("subTableFkclassName", StringUtils.uncapitalize(subTableFkClassName)); + context.put("subClassName", subClassName); + context.put("subclassName", StringUtils.uncapitalize(subClassName)); + context.put("subImportList", getImportList(genTable.getSubTable())); + } + + /** + * 获取模板信息 + * + * @return 模板列表 + */ + public static List getTemplateList(String tplCategory) + { + List templates = new ArrayList(); + templates.add("vm/java/domain.java.vm"); + templates.add("vm/java/mapper.java.vm"); + templates.add("vm/java/service.java.vm"); + templates.add("vm/java/serviceImpl.java.vm"); + templates.add("vm/java/controller.java.vm"); + templates.add("vm/xml/mapper.xml.vm"); + templates.add("vm/sql/sql.vm"); + templates.add("vm/js/api.js.vm"); + if (GenConstants.TPL_CRUD.equals(tplCategory)) + { + templates.add("vm/vue/index.vue.vm"); + } + else if (GenConstants.TPL_TREE.equals(tplCategory)) + { + templates.add("vm/vue/index-tree.vue.vm"); + } + else if (GenConstants.TPL_SUB.equals(tplCategory)) + { + templates.add("vm/vue/index.vue.vm"); + templates.add("vm/java/sub-domain.java.vm"); + } + return templates; + } + + /** + * 获取文件名 + */ + public static String getFileName(String template, GenTable genTable) + { + // 文件名称 + String fileName = ""; + // 包路径 + String packageName = genTable.getPackageName(); + // 模块名 + String moduleName = genTable.getModuleName(); + // 大写类名 + String className = genTable.getClassName(); + // 业务名称 + String businessName = genTable.getBusinessName(); + + String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/"); + String mybatisPath = MYBATIS_PATH + "/" + moduleName; + String vuePath = "vue"; + + if (template.contains("domain.java.vm")) + { + fileName = StringUtils.format("{}/domain/{}.java", javaPath, className); + } + if (template.contains("sub-domain.java.vm") && StringUtils.equals(GenConstants.TPL_SUB, genTable.getTplCategory())) + { + fileName = StringUtils.format("{}/domain/{}.java", javaPath, genTable.getSubTable().getClassName()); + } + else if (template.contains("mapper.java.vm")) + { + fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className); + } + else if (template.contains("service.java.vm")) + { + fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className); + } + else if (template.contains("serviceImpl.java.vm")) + { + fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className); + } + else if (template.contains("controller.java.vm")) + { + fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className); + } + else if (template.contains("mapper.xml.vm")) + { + fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className); + } + else if (template.contains("sql.vm")) + { + fileName = businessName + "Menu.sql"; + } + else if (template.contains("api.js.vm")) + { + fileName = StringUtils.format("{}/api/{}/{}.js", vuePath, moduleName, businessName); + } + else if (template.contains("index.vue.vm")) + { + fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); + } + else if (template.contains("index-tree.vue.vm")) + { + fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); + } + return fileName; + } + + /** + * 获取包前缀 + * + * @param packageName 包名称 + * @return 包前缀名称 + */ + public static String getPackagePrefix(String packageName) + { + int lastIndex = packageName.lastIndexOf("."); + return StringUtils.substring(packageName, 0, lastIndex); + } + + /** + * 根据列类型获取导入包 + * + * @param genTable 业务表对象 + * @return 返回需要导入的包列表 + */ + public static HashSet getImportList(GenTable genTable) + { + List columns = genTable.getColumns(); + GenTable subGenTable = genTable.getSubTable(); + HashSet importList = new HashSet(); + if (StringUtils.isNotNull(subGenTable)) + { + importList.add("java.util.List"); + } + for (GenTableColumn column : columns) + { + if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) + { + importList.add("java.util.Date"); + importList.add("com.fasterxml.jackson.annotation.JsonFormat"); + } + else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) + { + importList.add("java.math.BigDecimal"); + } + } + return importList; + } + + /** + * 根据列类型获取字典组 + * + * @param genTable 业务表对象 + * @return 返回字典组 + */ + public static String getDicts(GenTable genTable) + { + List columns = genTable.getColumns(); + Set dicts = new HashSet(); + addDicts(dicts, columns); + if (StringUtils.isNotNull(genTable.getSubTable())) + { + List subColumns = genTable.getSubTable().getColumns(); + addDicts(dicts, subColumns); + } + return StringUtils.join(dicts, ", "); + } + + /** + * 添加字典列表 + * + * @param dicts 字典列表 + * @param columns 列集合 + */ + public static void addDicts(Set dicts, List columns) + { + for (GenTableColumn column : columns) + { + if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny( + column.getHtmlType(), + new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) + { + dicts.add("'" + column.getDictType() + "'"); + } + } + } + + /** + * 获取权限前缀 + * + * @param moduleName 模块名称 + * @param businessName 业务名称 + * @return 返回权限前缀 + */ + public static String getPermissionPrefix(String moduleName, String businessName) + { + return StringUtils.format("{}:{}", moduleName, businessName); + } + + /** + * 获取上级菜单ID字段 + * + * @param paramsObj 生成其他选项 + * @return 上级菜单ID字段 + */ + public static String getParentMenuId(JSONObject paramsObj) + { + if (StringUtils.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID) + && StringUtils.isNotEmpty(paramsObj.getString(GenConstants.PARENT_MENU_ID))) + { + return paramsObj.getString(GenConstants.PARENT_MENU_ID); + } + return DEFAULT_PARENT_MENU_ID; + } + + /** + * 获取树编码 + * + * @param paramsObj 生成其他选项 + * @return 树编码 + */ + public static String getTreecode(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_CODE)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_CODE)); + } + return StringUtils.EMPTY; + } + + /** + * 获取树父编码 + * + * @param paramsObj 生成其他选项 + * @return 树父编码 + */ + public static String getTreeParentCode(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_PARENT_CODE)); + } + return StringUtils.EMPTY; + } + + /** + * 获取树名称 + * + * @param paramsObj 生成其他选项 + * @return 树名称 + */ + public static String getTreeName(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_NAME)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_NAME)); + } + return StringUtils.EMPTY; + } + + /** + * 获取需要在哪一列上面显示展开按钮 + * + * @param genTable 业务表对象 + * @return 展开按钮列序号 + */ + public static int getExpandColumn(GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String treeName = paramsObj.getString(GenConstants.TREE_NAME); + int num = 0; + for (GenTableColumn column : genTable.getColumns()) + { + if (column.isList()) + { + num++; + String columnName = column.getColumnName(); + if (columnName.equals(treeName)) + { + break; + } + } + } + return num; + } +} diff --git a/ruoyi-generator/src/main/resources/generator.yml b/ruoyi-generator/src/main/resources/generator.yml new file mode 100644 index 0000000..5bd3dd6 --- /dev/null +++ b/ruoyi-generator/src/main/resources/generator.yml @@ -0,0 +1,10 @@ +# 代码生成 +gen: + # 作者 + author: ruoyi + # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool + packageName: com.ruoyi.system + # 自动去除表前缀,默认是false + autoRemovePre: false + # 表前缀(生成类名不会包含表前缀,多个用逗号分隔) + tablePrefix: sys_ \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml b/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml new file mode 100644 index 0000000..a79398a --- /dev/null +++ b/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select column_id, table_id, column_name, column_comment, column_type, java_type, java_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time from gen_table_column + + + + + + + + insert into gen_table_column ( + table_id, + column_name, + column_comment, + column_type, + java_type, + java_field, + is_pk, + is_increment, + is_required, + is_insert, + is_edit, + is_list, + is_query, + query_type, + html_type, + dict_type, + sort, + create_by, + create_time + )values( + #{tableId}, + #{columnName}, + #{columnComment}, + #{columnType}, + #{javaType}, + #{javaField}, + #{isPk}, + #{isIncrement}, + #{isRequired}, + #{isInsert}, + #{isEdit}, + #{isList}, + #{isQuery}, + #{queryType}, + #{htmlType}, + #{dictType}, + #{sort}, + #{createBy}, + now() + ) + + + + update gen_table_column + + column_comment = #{columnComment}, + java_type = #{javaType}, + java_field = #{javaField}, + is_insert = #{isInsert}, + is_edit = #{isEdit}, + is_list = #{isList}, + is_query = #{isQuery}, + is_required = #{isRequired}, + query_type = #{queryType}, + html_type = #{htmlType}, + dict_type = #{dictType}, + sort = #{sort}, + update_by = #{updateBy}, + update_time = now() + + where column_id = #{columnId} + + + + delete from gen_table_column where table_id in + + #{tableId} + + + + + delete from gen_table_column where column_id in + + #{item.columnId} + + + + \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml b/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml new file mode 100644 index 0000000..527fdac --- /dev/null +++ b/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select table_id, table_name, table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table + + + + + + + + + + + + + + + + + + insert into gen_table ( + table_name, + table_comment, + class_name, + tpl_category, + package_name, + module_name, + business_name, + function_name, + function_author, + gen_type, + gen_path, + remark, + create_by, + create_time + )values( + #{tableName}, + #{tableComment}, + #{className}, + #{tplCategory}, + #{packageName}, + #{moduleName}, + #{businessName}, + #{functionName}, + #{functionAuthor}, + #{genType}, + #{genPath}, + #{remark}, + #{createBy}, + now() + ) + + + + update gen_table + + table_name = #{tableName}, + table_comment = #{tableComment}, + sub_table_name = #{subTableName}, + sub_table_fk_name = #{subTableFkName}, + class_name = #{className}, + function_author = #{functionAuthor}, + gen_type = #{genType}, + gen_path = #{genPath}, + tpl_category = #{tplCategory}, + package_name = #{packageName}, + module_name = #{moduleName}, + business_name = #{businessName}, + function_name = #{functionName}, + options = #{options}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = now() + + where table_id = #{tableId} + + + + delete from gen_table where table_id in + + #{tableId} + + + + \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/templates/controller.java.ftl b/ruoyi-generator/src/main/resources/templates/controller.java.ftl new file mode 100644 index 0000000..9c949dd --- /dev/null +++ b/ruoyi-generator/src/main/resources/templates/controller.java.ftl @@ -0,0 +1,137 @@ +package ${package.Controller}; + +import com.zyjc.base.annotation.log.SysLog; +import com.zyjc.base.enums.SysLogEnum; +import com.zyjc.base.web.response.ResultVO; +import ${package.Entity}.${entity}; +import ${package.Service}.${table.serviceName}; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +<#if restControllerStyle> +<#else> + import org.springframework.stereotype.Controller; + +<#if superControllerClassPackage??> + import ${superControllerClassPackage}; + + + +import javax.validation.Valid; +import java.util.List; + +/** +*

+ * ${table.comment} 前端控制器 + *

+* +* @author ${author} +* @since ${date} +*/ +@Api(tags = "${table.comment}") +@RestController +@RequestMapping("/eastcom_yw/${entity?uncap_first}") +@Slf4j +@RequiredArgsConstructor +<#if kotlin> + class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}() +<#else> + <#if superControllerClass??> +public class ${table.controllerName} extends ${superControllerClass} { + <#else> +public class ${table.controllerName} extends BaseController{ + + + private final ${entity}Service ${entity?uncap_first}Service; + + /** + * ${table.comment}列表 + */ + @ApiOperation(value = "${table.comment}列表", notes = "${table.comment}列表") + @RequestMapping(value = "list", method = RequestMethod.POST) + public TableDataInfo list(@RequestBody ${entity}QO qo) { + List<${entity}VO> list = ${entity?uncap_first}Service.getData(qo); + return getDataTable(list); + } + + + /** + * ${table.comment}分页列表 + */ + @ApiOperation(value = "${table.comment}分页列表", notes = "${table.comment}分页列表") + @RequestMapping(value = "pageList", method = RequestMethod.POST) + public TableDataInfo pageList(@RequestBody ${entity}QO qo) { + IPage<${entity}VO> page = ${entity?uncap_first}Service.getDataByPage(qo); + return getDataTable(page.getRecords(),page.getTotal()); + } + + /** + * 获取${table.comment}详情 + */ + @ApiOperation(value = "${table.comment}详情", notes = "${table.comment}详情") + @GetMapping(value = "/fetchById/{id}") + public AjaxResult fetchById(@PathVariable Long id) { + return AjaxResult.success(${entity?uncap_first}Service.fetchById(id)); + } + + /** + * 新增或修改${table.comment} + */ + @Log(title = "新增或修改${table.comment}", businessType = BusinessType.INSERT) + @ApiOperation(value = "新增或修改${table.comment}", notes = "新增或修改${table.comment}") + @PostMapping(value = "/saveOrUpdate") + public AjaxResult saveOrUpdate(@RequestBody @Validated ${entity}DTO dto) { + ${entity?uncap_first}Service.saveOrUpdate(dto); + return AjaxResult.success(); + } + + /** + * 根据id删除${table.comment} + */ + @Log(title = "根据id删除${table.comment}", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id删除${table.comment}", notes = "根据id删除${table.comment}") + @GetMapping(value = "/deleteById/{id}") + public AjaxResult deleteById(@PathVariable Long id) { + ${entity?uncap_first}Service.deleteById(id); + return AjaxResult.success(); + } + + /** + * 根据id批量删除${table.comment} + */ + @Log(title = "根据id批量删除${table.comment}", businessType = BusinessType.DELETE) + @ApiOperation(value = "根据id批量删除${table.comment}", notes = "根据id批量删除${table.comment}") + @PostMapping(value = "/deleteByIdBatch") + public AjaxResult deleteByIdBatch(@RequestBody List ids) { + ${entity?uncap_first}Service.deleteByIdBatch(ids); + return AjaxResult.success(); + } + + @Log(title = "${table.comment}导入", businessType = BusinessType.IMPORT) + @PostMapping("/import") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { + ExcelUtil<${entity}> util = new ExcelUtil<>(${entity}.class); + List<${entity}> list = util.importExcel(file.getInputStream()); + ${entity?uncap_first}Service.importData(list, updateSupport); + return AjaxResult.success(); + } + + + /** + * ${table.comment}导出 + */ + @ApiOperation(value = "${table.comment}导出") + @PostMapping(value = "/export") + public void export(@RequestBody ${entity}QO qo){ + ${entity?uncap_first}Service.export(qo); + } + +} + \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/templates/controller.java.vm b/ruoyi-generator/src/main/resources/templates/controller.java.vm new file mode 100644 index 0000000..f125d46 --- /dev/null +++ b/ruoyi-generator/src/main/resources/templates/controller.java.vm @@ -0,0 +1,44 @@ +package ${package.Controller}; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +#if(${restControllerStyle}) +import org.springframework.web.bind.annotation.RestController; +#else +import org.springframework.stereotype.Controller; +#end +#if(${superControllerClassPackage}) +import ${superControllerClassPackage}; +#end + +/** + *

+ * $!{table.comment} 前端控制器 + *

+ * + * @author ${author} + * @since ${date} + */ +#if(${restControllerStyle}) +@RestController +#else +@Controller +#end +@RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end") +#if(${kotlin}) +class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end + +#else + #if(${superControllerClass}) + public class ${table.controllerName} extends ${superControllerClass} { + #else + public class ${table.controllerName} { + #end + + } + +#end \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/templates/convert.java.ftl b/ruoyi-generator/src/main/resources/templates/convert.java.ftl new file mode 100644 index 0000000..fea3864 --- /dev/null +++ b/ruoyi-generator/src/main/resources/templates/convert.java.ftl @@ -0,0 +1,22 @@ +package ${package.Entity}; + +import com.zyjc.happy.dto.${entity}DTO; +import com.zyjc.happy.entity.${entity}; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface ${entity}Convert { + +${entity}Convert INSTANCE = Mappers.getMapper(${entity}Convert.class); + +${entity} dtoToEntity(${entity}DTO dto); + +${entity}VO entityToVo(${entity} entity); + +List<${entity}VO> entityToVoList(List<${entity}> entityList); + +${entity}DTO entityToDto(${entity} entity); + +} + diff --git a/ruoyi-generator/src/main/resources/templates/dto.java.ftl b/ruoyi-generator/src/main/resources/templates/dto.java.ftl new file mode 100644 index 0000000..bebf61d --- /dev/null +++ b/ruoyi-generator/src/main/resources/templates/dto.java.ftl @@ -0,0 +1,117 @@ +package ${package.Entity}; + +import com.zyjc.base.web.request.Page; +<#list table.importPackages as pkg> +import ${pkg}; + +<#if springdoc> +import io.swagger.v3.oas.annotations.media.Schema; +<#elseif swagger> +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +<#if entityLombokModel> +import lombok.*; + <#if chainModel> +import lombok.experimental.Accessors; + + + +/** + *

+ * ${table.comment!}DTO + *

+ * + * @author ${author} + * @since ${date} + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ${entity}DTO { + +<#if entitySerialVersionUID> + + private static final long serialVersionUID = 1L; + +<#-- ---------- BEGIN 字段循环遍历 ----------> +<#list table.fields as field> + <#if field.keyFlag> + <#assign keyPropertyName="${field.propertyName}"/> + + + <#if field.comment!?length gt 0> + <#if springdoc> + @Schema(description = "${field.comment}") + <#elseif swagger> + @ApiModelProperty("${field.comment}") + <#else> + /** + * ${field.comment} + */ + + + <#if field.keyFlag> + <#-- 主键 --> + <#if field.keyIdentityFlag> + @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO) + <#elseif idType??> + @TableId(value = "${field.annotationColumnName}", type = IdType.${idType}) + <#elseif field.convert> + @TableId("${field.annotationColumnName}") + + <#-- 普通字段 --> + <#elseif field.fill??> + <#-- ----- 存在字段填充设置 -----> + <#if field.convert> + @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill}) + <#else> + @TableField(fill = FieldFill.${field.fill}) + + <#elseif field.convert> + @TableField("${field.annotationColumnName}") + + <#-- 乐观锁注解 --> + <#if field.versionField> + @Version + + <#-- 逻辑删除注解 --> + <#if field.logicDeleteField> + @TableLogic + + private ${field.propertyType} ${field.propertyName}; + +<#------------ END 字段循环遍历 ----------> +<#if !entityLombokModel> + <#list table.fields as field> + <#if field.propertyType == "boolean"> + <#assign getprefix="is"/> + <#else> + <#assign getprefix="get"/> + + + public ${field.propertyType} ${getprefix}${field.capitalName}() { + return ${field.propertyName}; + } + + <#if chainModel> + public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + <#else> + public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + + this.${field.propertyName} = ${field.propertyName}; + <#if chainModel> + return this; + + } + + +<#if entityColumnConstant> + <#list table.fields as field> + + public static final String ${field.name?upper_case} = "${field.name}"; + + + +} diff --git a/ruoyi-generator/src/main/resources/templates/entity.java.ftl b/ruoyi-generator/src/main/resources/templates/entity.java.ftl new file mode 100644 index 0000000..83b8116 --- /dev/null +++ b/ruoyi-generator/src/main/resources/templates/entity.java.ftl @@ -0,0 +1,136 @@ +package ${package.Entity}; + +<#list table.importPackages as pkg> +import ${pkg}; + +<#if springdoc> +import io.swagger.v3.oas.annotations.media.Schema; +<#elseif swagger> +import com.zyjc.base.entity.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +<#if entityLombokModel> +import lombok.Data; +import lombok.EqualsAndHashCode; + <#if chainModel> +import lombok.experimental.Accessors; + + + +/** + *

+ * ${table.comment!} + *

+ * + * @author ${author} + * @since ${date} + */ +<#if entityLombokModel> + <#if chainModel> +@Accessors(chain = true) + + +@Data +@EqualsAndHashCode(callSuper = true) +<#if table.convert> +@TableName("${schemaName}${table.name}") + +<#if springdoc> +@Schema(name = "${entity}", description = "$!{table.comment}") +<#elseif swagger> +@ApiModel(value = "${entity}对象", description = "${table.comment!}") + +<#if superEntityClass??> +public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}> { +<#elseif activeRecord> +public class ${entity} extends Model<${entity}> { +<#elseif entitySerialVersionUID> +public class ${entity} { +<#else> +public class ${entity} { + +<#if entitySerialVersionUID> + + private static final long serialVersionUID = 1L; + +<#-- ---------- BEGIN 字段循环遍历 ----------> +<#list table.fields as field> + <#if field.keyFlag> + <#assign keyPropertyName="${field.propertyName}"/> + + + <#if field.comment!?length gt 0> + <#if springdoc> + @Schema(description = "${field.comment}") + <#elseif swagger> + @ApiModelProperty("${field.comment}") + <#else> + /** + * ${field.comment} + */ + + + <#if field.keyFlag> + <#-- 主键 --> + <#if field.keyIdentityFlag> + @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO) + <#elseif idType??> + @TableId(value = "${field.annotationColumnName}", type = IdType.${idType}) + <#elseif field.convert> + @TableId("${field.annotationColumnName}") + + <#-- 普通字段 --> + <#elseif field.fill??> + <#-- ----- 存在字段填充设置 -----> + <#if field.convert> + @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill}) + <#else> + @TableField(fill = FieldFill.${field.fill}) + + <#elseif field.convert> + @TableField("${field.annotationColumnName}") + + <#-- 乐观锁注解 --> + <#if field.versionField> + @Version + + <#-- 逻辑删除注解 --> + <#if field.logicDeleteField> + @TableLogic + + private ${field.propertyType} ${field.propertyName}; + +<#------------ END 字段循环遍历 ----------> +<#if !entityLombokModel> + <#list table.fields as field> + <#if field.propertyType == "boolean"> + <#assign getprefix="is"/> + <#else> + <#assign getprefix="get"/> + + + public ${field.propertyType} ${getprefix}${field.capitalName}() { + return ${field.propertyName}; + } + + <#if chainModel> + public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + <#else> + public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + + this.${field.propertyName} = ${field.propertyName}; + <#if chainModel> + return this; + + } + + +<#if entityColumnConstant> + <#list table.fields as field> + + public static final String ${field.name?upper_case} = "${field.name}"; + + + +} diff --git a/ruoyi-generator/src/main/resources/templates/entity.java.vm b/ruoyi-generator/src/main/resources/templates/entity.java.vm new file mode 100644 index 0000000..e2b76d7 --- /dev/null +++ b/ruoyi-generator/src/main/resources/templates/entity.java.vm @@ -0,0 +1,165 @@ +package ${package.Entity}; + +#foreach($pkg in ${table.importPackages}) +import ${pkg}; + #if(${pkg} == "java.time.LocalDateTime") + import com.fasterxml.jackson.annotation.JsonFormat; + #end +#end +#if(${swagger2}) +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +#end +#if(${entityLombokModel}) +import lombok.Data; +import lombok.EqualsAndHashCode; + #if(${chainModel}) + import lombok.experimental.Accessors; + #end +#end + +/** + *

+ * $!{table.comment} + *

+ * + * @author ${author} + * @since ${date} + */ +#if(${entityLombokModel}) +@Data + #if(${superEntityClass}) + @EqualsAndHashCode(callSuper = true) + #else + @EqualsAndHashCode(callSuper = false) + #end + #if(${chainModel}) + @Accessors(chain = true) + #end +#end +#if(${table.convert}) +@TableName("${table.name}") +#end +#if(${swagger2}) +@ApiModel(value="${entity}对象", description="$!{table.comment}") +#end +#if(${superEntityClass}) +public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end { +#elseif(${activeRecord}) +public class ${entity} extends Model<${entity}> { +#else +public class ${entity} implements Serializable { +#end + +#if(${entitySerialVersionUID}) +private static final long serialVersionUID=1L; +#end +## ---------- BEGIN 字段循环遍历 ---------- +#foreach($field in ${table.fields}) + + #if(${field.keyFlag}) + #set($keyPropertyName=${field.propertyName}) + #end + #if("$!field.comment" != "") + #if(${swagger2}) + @ApiModelProperty(value = "${field.comment}") + #else + /** + * ${field.comment} + */ + #end + #end + #if(${field.keyFlag}) + ## 主键 + #if(${field.keyIdentityFlag}) + @TableId(value = "${field.annotationColumnName}", type = IdType.ASSIGN_ID) + #elseif(!$null.isNull(${idType}) && "$!idType" != "") + @TableId(value = "${field.annotationColumnName}", type = IdType.${idType}) + #elseif(${field.convert}) + @TableId("${field.annotationColumnName}") + #end + ## 普通字段 + #elseif(${field.fill}) + ## ----- 存在字段填充设置 ----- + #if(${field.convert}) + @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill}) + #else + @TableField(fill = FieldFill.${field.fill}) + #end + #elseif(${field.convert}) + @TableField("${field.annotationColumnName}") + #end + ## 乐观锁注解 + #if(${versionFieldName}==${field.name}) + @Version + #end + ## 逻辑删除注解 + #if(${logicDeleteFieldName}==${field.name}) + @TableLogic + #end + #if(${field.propertyType} == "LocalDateTime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + #end +private ${field.propertyType} ${field.propertyName}; +#end +## ---------- END 字段循环遍历 ---------- + +#if(!${entityLombokModel}) + #foreach($field in ${table.fields}) + #if(${field.propertyType.equals("boolean")}) + #set($getprefix="is") + #else + #set($getprefix="get") + #end + + public ${field.propertyType} ${getprefix}${field.capitalName}() { + return ${field.propertyName}; + } + + #if(${chainModel}) + public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + #else + public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + #end + this.${field.propertyName} = ${field.propertyName}; + #if(${chainModel}) + return this; + #end + } + #end + ## --foreach end--- +#end +## --end of #if(!${entityLombokModel})-- + +#if(${entityColumnConstant}) + #foreach($field in ${table.fields}) + public static final String ${field.name.toUpperCase()} = "${field.name}"; + + #end +#end +#if(${activeRecord}) +@Override +protected Serializable pkVal() { + #if(${keyPropertyName}) + return this.${keyPropertyName}; + #else + return null; + #end + } + +#end +#if(!${entityLombokModel}) +@Override +public String toString() { + return "${entity}{" + + #foreach($field in ${table.fields}) + #if($!{foreach.index}==0) + "${field.propertyName}=" + ${field.propertyName} + + #else + ", ${field.propertyName}=" + ${field.propertyName} + + #end + #end + "}"; + } +#end +} \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/templates/mapper.xml.ftl b/ruoyi-generator/src/main/resources/templates/mapper.xml.ftl new file mode 100644 index 0000000..851af12 --- /dev/null +++ b/ruoyi-generator/src/main/resources/templates/mapper.xml.ftl @@ -0,0 +1,39 @@ + + + + +<#if enableCache> + + + + +<#if baseResultMap> + + +<#list table.fields as field> +<#if field.keyFlag><#--生成主键排在第一位--> + + + +<#list table.commonFields as field><#--生成公共字段 --> + + +<#list table.fields as field> +<#if !field.keyFlag><#--生成普通字段 --> + + + + + + +<#if baseColumnList> + + +<#list table.commonFields as field> + ${field.columnName}, + + ${table.fieldNames} + + + + diff --git a/ruoyi-generator/src/main/resources/templates/mapper.xml.vm b/ruoyi-generator/src/main/resources/templates/mapper.xml.vm new file mode 100644 index 0000000..d07909a --- /dev/null +++ b/ruoyi-generator/src/main/resources/templates/mapper.xml.vm @@ -0,0 +1,39 @@ + + + + + #if(${enableCache}) + + + + #end + #if(${baseResultMap}) + + + #foreach($field in ${table.fields}) + #if(${field.keyFlag})##生成主键排在第一位 + + #end + #end + #foreach($field in ${table.commonFields})##生成公共字段 + + #end + #foreach($field in ${table.fields}) + #if(!${field.keyFlag})##生成普通字段 + + #end + #end + + + #end + #if(${baseColumnList}) + + + #foreach($field in ${table.commonFields}) + ${field.columnName}, + #end + ${table.fieldNames} + + + #end + \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/templates/qo.java.ftl b/ruoyi-generator/src/main/resources/templates/qo.java.ftl new file mode 100644 index 0000000..69720a1 --- /dev/null +++ b/ruoyi-generator/src/main/resources/templates/qo.java.ftl @@ -0,0 +1,116 @@ +package ${package.Entity}; + +import com.github.pagehelper.Page; +<#list table.importPackages as pkg> +import ${pkg}; + +<#if springdoc> +import io.swagger.v3.oas.annotations.media.Schema; +<#elseif swagger> +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +<#if entityLombokModel> +import lombok.*; + <#if chainModel> +import lombok.experimental.Accessors; + + + +/** + *

+ * ${table.comment!}QO + *

+ * + * @author ${author} + * @since ${date} + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ${entity}QO extends CommonDTO { + +<#if entitySerialVersionUID> + + private static final long serialVersionUID = 1L; + +<#-- ---------- BEGIN 字段循环遍历 ----------> +<#list table.fields as field> + <#if field.keyFlag> + <#assign keyPropertyName="${field.propertyName}"/> + + + <#if field.comment!?length gt 0> + <#if springdoc> + @Schema(description = "${field.comment}") + <#elseif swagger> + @ApiModelProperty("${field.comment}") + <#else> + /** + * ${field.comment} + */ + + + <#if field.keyFlag> + <#-- 主键 --> + <#if field.keyIdentityFlag> + @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO) + <#elseif idType??> + @TableId(value = "${field.annotationColumnName}", type = IdType.${idType}) + <#elseif field.convert> + @TableId("${field.annotationColumnName}") + + <#-- 普通字段 --> + <#elseif field.fill??> + <#-- ----- 存在字段填充设置 -----> + <#if field.convert> + @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill}) + <#else> + @TableField(fill = FieldFill.${field.fill}) + + <#elseif field.convert> + @TableField("${field.annotationColumnName}") + + <#-- 乐观锁注解 --> + <#if field.versionField> + @Version + + <#-- 逻辑删除注解 --> + <#if field.logicDeleteField> + @TableLogic + + private ${field.propertyType} ${field.propertyName}; + +<#------------ END 字段循环遍历 ----------> +<#if !entityLombokModel> + <#list table.fields as field> + <#if field.propertyType == "boolean"> + <#assign getprefix="is"/> + <#else> + <#assign getprefix="get"/> + + + public ${field.propertyType} ${getprefix}${field.capitalName}() { + return ${field.propertyName}; + } + + <#if chainModel> + public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + <#else> + public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + + this.${field.propertyName} = ${field.propertyName}; + <#if chainModel> + return this; + + } + + +<#if entityColumnConstant> + <#list table.fields as field> + + public static final String ${field.name?upper_case} = "${field.name}"; + + + +} diff --git a/ruoyi-generator/src/main/resources/templates/service.java.ftl b/ruoyi-generator/src/main/resources/templates/service.java.ftl new file mode 100644 index 0000000..fb58864 --- /dev/null +++ b/ruoyi-generator/src/main/resources/templates/service.java.ftl @@ -0,0 +1,80 @@ +package ${package.Service}; + +import ${package.Entity}.${entity}; +import ${superServiceClassPackage}; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import java.util.List; + +/** +*

+ * ${table.comment!} 服务类 + *

+* +* @author ${author} +* @since ${date} +*/ +<#if kotlin> + interface ${entity}Service : ${superServiceClass}<${entity}> +<#else> +public interface ${entity}Service extends ${superServiceClass}<${entity}> { + + /** + * ${table.comment!}列表 + * @param qo 根据需要进行传值 + * @return + */ + List<${entity}VO> getData(${entity}QO qo); + + /** + * ${table.comment!}分页列表 + * @param qo 根据需要进行传值 + * @return + */ + IPage<${entity}VO> getDataByPage(${entity}QO qo); + + /** + * ${table.comment!}详情 + * @param id + * @return + */ + ${entity}VO fetchById(Long id); + + /** + * ${table.comment!}新增或修改 + * @param dto 根据需要进行传值 + * @return + */ + boolean saveOrUpdate(${entity}DTO dto); + + /** + * ${table.comment!}删除(单个条目) + * @param id + * @return + */ + boolean deleteById(Long id); + + /** + * ${table.comment!}批量删除(多个条目) + * + * @param ids + * @return + */ + boolean deleteByIdBatch(List ids); + + /** + * ${table.comment!}导出 + * @param qo + * @return + */ + void export(${entity}QO qo); + + /** + * ${table.comment!}导入 + * + * @param + * @return + */ + AjaxResult importData(List<${entity}> list, boolean updateSupport); +} + \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/templates/service.java.vm b/ruoyi-generator/src/main/resources/templates/service.java.vm new file mode 100644 index 0000000..67e0de1 --- /dev/null +++ b/ruoyi-generator/src/main/resources/templates/service.java.vm @@ -0,0 +1,20 @@ +package ${package.Service}; + +import ${package.Entity}.${entity}; +import ${superServiceClassPackage}; + +/** + *

+ * $!{table.comment} 服务类 + *

+ * + * @author ${author} + * @since ${date} + */ +#if(${kotlin}) +interface ${table.serviceName} : ${superServiceClass}<${entity}> +#else +public interface ${table.serviceName} extends ${superServiceClass}<${entity}> { + + } +#end \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/templates/serviceImpl.java.ftl b/ruoyi-generator/src/main/resources/templates/serviceImpl.java.ftl new file mode 100644 index 0000000..277fad9 --- /dev/null +++ b/ruoyi-generator/src/main/resources/templates/serviceImpl.java.ftl @@ -0,0 +1,175 @@ +package ${package.ServiceImpl}; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.zyjc.base.util.ExcelUtils; +import com.zyjc.base.web.exception.BizException; +import ${package.Entity}.${entity}; +import ${package.Mapper}.${table.mapperName}; +import ${package.Service}.${table.serviceName}; +import ${superServiceImplClassPackage}; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.xuhong.blogs.core.component.GlobalException; +import com.xuhong.blogs.core.component.RetJson; +import com.xuhong.blogs.core.enums.RetCode; +import com.xuhong.blogs.core.utils.IDGeneratorUtils; +import com.xuhong.blogs.core.utils.PageUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.RequestContextHolder; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** +*

+ * ${table.comment!} 服务实现类 + *

+* +* @author ${author} +* @since ${date} +*/ +@Service +<#if kotlin> + open class ${entity}ServiceImpl : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${entity}Service { + + } +<#else> +public class ${entity}ServiceImpl extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${entity}Service { + + @Resource + private ${entity}Mapper ${entity?uncap_first}Mapper; + + /** + * ${table.comment!}列表 + * @param qo 根据需要进行传值 + * @return + */ + @Override + public List<${entity}VO> getData(${entity}QO qo) { + LambdaQueryWrapper<${entity}> queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + <#list table.fields as field> + // ${field.comment} + <#if !entityLombokModel> + <#if field.propertyType == "Boolean"> + <#assign getprefix="is"/> + <#else> + <#assign getprefix="get"/> + + <#if field.propertyType == "String"> + .eq(StrUtil.isNotBlank(qo.${getprefix}${field.capitalName}()), ${entity}::${getprefix}${field.capitalName}, qo.${getprefix}${field.capitalName}()) + <#else> + .eq(qo.${getprefix}${field.capitalName}() != null, ${entity}::${getprefix}${field.capitalName}, qo.${getprefix}${field.capitalName}()) + + <#else> + <#if field.propertyType == "String"> + .eq(StrUtil.isNotBlank(qo.get${field.capitalName}()), ${entity}::get${field.capitalName}, qo.get${field.capitalName}()) + <#else> + .eq(qo.get${field.capitalName}() != null, ${entity}::get${field.capitalName}, qo.get${field.capitalName}()) + + + ; + List<${entity}> list = ${entity?uncap_first}Mapper.selectList(queryWrapper); + return ${entity}Convert.INSTANCE.entityToVoList(list); + } + + /** + * ${table.comment!}分页列表 + * @param qo 根据需要进行传值 + * @return + */ + @Override + public IPage<${entity}VO> getDataByPage(${entity}QO qo) { + LambdaQueryWrapper<${entity}> queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + <#list table.fields as field> + // ${field.comment} + <#if !entityLombokModel> + <#if field.propertyType == "Boolean"> + <#assign getprefix="is"/> + <#else> + <#assign getprefix="get"/> + + <#if field.propertyType == "String"> + .eq(StrUtil.isNotBlank(qo.${getprefix}${field.capitalName}()), ${entity}::${getprefix}${field.capitalName}, qo.${getprefix}${field.capitalName}()) + <#else> + .eq(qo.${getprefix}${field.capitalName}() != null, ${entity}::${getprefix}${field.capitalName}, qo.${getprefix}${field.capitalName}()) + + <#else> + <#if field.propertyType == "String"> + .eq(StrUtil.isNotBlank(qo.get${field.capitalName}()), ${entity}::get${field.capitalName}, qo.get${field.capitalName}()) + <#else> + .eq(qo.get${field.capitalName}() != null, ${entity}::get${field.capitalName}, qo.get${field.capitalName}()) + + + ; + + Page<${entity}> page = page(new Page<>(qo.getPageNum(), qo.getPageSize()), queryWrapper); + IPage<${entity}VO> voPage = page.convert(${entity}Convert.INSTANCE::entityToVo); + return voPage; + } + + @Override + public ${entity}VO fetchById(Long id) { + ${entity} entity = ${entity?uncap_first}Mapper.selectById(id); + return ${entity}Convert.INSTANCE.entityToVo(entity); + } + + @Override + public boolean saveOrUpdate(${entity}DTO dto) { + ${entity} entity = ${entity}Convert.INSTANCE.dtoToEntity(dto); + return saveOrUpdate(entity); + } + + @Override + public boolean deleteById(Long id) { + return removeById(id); + } + + @Override + public boolean deleteByIdBatch(List ids) { + return SqlHelper.retBool(${entity?uncap_first}Mapper.deleteBatchIds(ids)); + } + + @Override + public void export(${entity}QO qo) { + HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse(); + List<${entity}VO> data = this.getData(qo); + ExcelUtil<${entity}VO> util = new ExcelUtil<>(${entity}VO.class); + try { + util.exportExcel(response, data, "${table.comment!}信息"); + } catch (Exception e) { + throw new ServiceException("导出文件异常:" + e.getMessage()); + } + } + + @Override + public AjaxResult importData(List<${entity}> list, boolean updateSupport) { + // 核查模板 + if (CollUtil.isEmpty(list)) { + return AjaxResult.error("导入模板不正确。"); + } + + // 核查 + // boolean checkFlag; + // checkFlag = checkData(cs, ywSceneList); + // if (checkFlag) { + // checkFlag = checkUnique(cs); + // } + // if (!checkFlag) { + // ExcelUtil util = new ExcelUtil<>(YwSceneNetelementCs.class); + // String fileName = (String) util.exportExcel(cs, "网元传输导入结果").get(AjaxResult.MSG_TAG); + // return new AjaxResult(HttpStatus.ACCEPTED, "导入失败", fileName); + // } + // saveBatch(list); + return null; + } +} + \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/templates/serviceImpl.java.vm b/ruoyi-generator/src/main/resources/templates/serviceImpl.java.vm new file mode 100644 index 0000000..cc9432b --- /dev/null +++ b/ruoyi-generator/src/main/resources/templates/serviceImpl.java.vm @@ -0,0 +1,26 @@ +package ${package.ServiceImpl}; + +import ${package.Entity}.${entity}; +import ${package.Mapper}.${table.mapperName}; +import ${package.Service}.${table.serviceName}; +import ${superServiceImplClassPackage}; +import org.springframework.stereotype.Service; + +/** + *

+ * $!{table.comment} 服务实现类 + *

+ * + * @author ${author} + * @since ${date} + */ +@Service +#if(${kotlin}) +open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} { + + } +#else + public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} { + + } +#end \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/templates/vo.java.ftl b/ruoyi-generator/src/main/resources/templates/vo.java.ftl new file mode 100644 index 0000000..ffc2518 --- /dev/null +++ b/ruoyi-generator/src/main/resources/templates/vo.java.ftl @@ -0,0 +1,116 @@ +package ${package.Entity}; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +<#list table.importPackages as pkg> +import ${pkg}; + +<#if springdoc> +import io.swagger.v3.oas.annotations.media.Schema; +<#elseif swagger> +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +<#if entityLombokModel> +import lombok.*; + <#if chainModel> +import lombok.experimental.Accessors; + + + +/** + *

+ * ${table.comment!}VO + *

+ * + * @author ${author} + * @since ${date} + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ${entity}VO { + +<#if entitySerialVersionUID> + + private static final long serialVersionUID = 1L; + +<#-- ---------- BEGIN 字段循环遍历 ----------> +<#list table.fields as field> + <#if field.keyFlag> + <#assign keyPropertyName="${field.propertyName}"/> + + + <#if field.comment!?length gt 0> + <#if springdoc> + @Schema(description = "${field.comment}") + <#elseif swagger> + @ApiModelProperty("${field.comment}") + <#else> + /** + * ${field.comment} + */ + + + <#if field.keyFlag> + <#-- 主键 --> + <#if field.keyIdentityFlag> + @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO) + <#elseif idType??> + @TableId(value = "${field.annotationColumnName}", type = IdType.${idType}) + <#elseif field.convert> + @TableId("${field.annotationColumnName}") + + <#-- 普通字段 --> + <#elseif field.fill??> + <#-- ----- 存在字段填充设置 -----> + <#if field.convert> + @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill}) + <#else> + @TableField(fill = FieldFill.${field.fill}) + + <#elseif field.convert> + @TableField("${field.annotationColumnName}") + + <#-- 乐观锁注解 --> + <#if field.versionField> + @Version + + <#-- 逻辑删除注解 --> + <#if field.logicDeleteField> + @TableLogic + + private ${field.propertyType} ${field.propertyName}; + +<#------------ END 字段循环遍历 ----------> +<#if !entityLombokModel> + <#list table.fields as field> + <#if field.propertyType == "boolean"> + <#assign getprefix="is"/> + <#else> + <#assign getprefix="get"/> + + + public ${field.propertyType} ${getprefix}${field.capitalName}() { + return ${field.propertyName}; + } + + <#if chainModel> + public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + <#else> + public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + + this.${field.propertyName} = ${field.propertyName}; + <#if chainModel> + return this; + + } + + +<#if entityColumnConstant> + <#list table.fields as field> + + public static final String ${field.name?upper_case} = "${field.name}"; + + + +} diff --git a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm new file mode 100644 index 0000000..bf88988 --- /dev/null +++ b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm @@ -0,0 +1,115 @@ +package ${packageName}.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import ${packageName}.domain.${ClassName}; +import ${packageName}.service.I${ClassName}Service; +import com.ruoyi.common.utils.poi.ExcelUtil; +#if($table.crud || $table.sub) +import com.ruoyi.common.core.page.TableDataInfo; +#elseif($table.tree) +#end + +/** + * ${functionName}Controller + * + * @author ${author} + * @date ${datetime} + */ +@RestController +@RequestMapping("/${moduleName}/${businessName}") +public class ${ClassName}Controller extends BaseController +{ + @Autowired + private I${ClassName}Service ${className}Service; + + /** + * 查询${functionName}列表 + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')") + @GetMapping("/list") +#if($table.crud || $table.sub) + public TableDataInfo list(${ClassName} ${className}) + { + startPage(); + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + return getDataTable(list); + } +#elseif($table.tree) + public AjaxResult list(${ClassName} ${className}) + { + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + return success(list); + } +#end + + /** + * 导出${functionName}列表 + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')") + @Log(title = "${functionName}", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, ${ClassName} ${className}) + { + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class); + util.exportExcel(response, list, "${functionName}数据"); + } + + /** + * 获取${functionName}详细信息 + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:query')") + @GetMapping(value = "/{${pkColumn.javaField}}") + public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) + { + return success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField})); + } + + /** + * 新增${functionName} + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:add')") + @Log(title = "${functionName}", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody ${ClassName} ${className}) + { + return toAjax(${className}Service.insert${ClassName}(${className})); + } + + /** + * 修改${functionName} + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:edit')") + @Log(title = "${functionName}", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody ${ClassName} ${className}) + { + return toAjax(${className}Service.update${ClassName}(${className})); + } + + /** + * 删除${functionName} + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:remove')") + @Log(title = "${functionName}", businessType = BusinessType.DELETE) + @DeleteMapping("/{${pkColumn.javaField}s}") + public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) + { + return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s)); + } +} diff --git a/ruoyi-generator/src/main/resources/vm/java/domain.java.vm b/ruoyi-generator/src/main/resources/vm/java/domain.java.vm new file mode 100644 index 0000000..bd51c17 --- /dev/null +++ b/ruoyi-generator/src/main/resources/vm/java/domain.java.vm @@ -0,0 +1,105 @@ +package ${packageName}.domain; + +#foreach ($import in $importList) +import ${import}; +#end +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +#if($table.crud || $table.sub) +import com.ruoyi.common.core.domain.BaseEntity; +#elseif($table.tree) +import com.ruoyi.common.core.domain.TreeEntity; +#end + +/** + * ${functionName}对象 ${tableName} + * + * @author ${author} + * @date ${datetime} + */ +#if($table.crud || $table.sub) +#set($Entity="BaseEntity") +#elseif($table.tree) +#set($Entity="TreeEntity") +#end +public class ${ClassName} extends ${Entity} +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $columns) +#if(!$table.isSuperColumn($column.javaField)) + /** $column.columnComment */ +#if($column.list) +#set($parentheseIndex=$column.columnComment.indexOf("(")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($parentheseIndex != -1) + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") +#elseif($column.javaType == 'Date') + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") +#else + @Excel(name = "${comment}") +#end +#end + private $column.javaType $column.javaField; + +#end +#end +#if($table.sub) + /** $table.subTable.functionName信息 */ + private List<${subClassName}> ${subclassName}List; + +#end +#foreach ($column in $columns) +#if(!$table.isSuperColumn($column.javaField)) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + public void set${AttrName}($column.javaType $column.javaField) + { + this.$column.javaField = $column.javaField; + } + + public $column.javaType get${AttrName}() + { + return $column.javaField; + } +#end +#end + +#if($table.sub) + public List<${subClassName}> get${subClassName}List() + { + return ${subclassName}List; + } + + public void set${subClassName}List(List<${subClassName}> ${subclassName}List) + { + this.${subclassName}List = ${subclassName}List; + } + +#end + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) +#foreach ($column in $columns) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + .append("${column.javaField}", get${AttrName}()) +#end +#if($table.sub) + .append("${subclassName}List", get${subClassName}List()) +#end + .toString(); + } +} diff --git a/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm b/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm new file mode 100644 index 0000000..7e7d7c2 --- /dev/null +++ b/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm @@ -0,0 +1,91 @@ +package ${packageName}.mapper; + +import java.util.List; +import ${packageName}.domain.${ClassName}; +#if($table.sub) +import ${packageName}.domain.${subClassName}; +#end + +/** + * ${functionName}Mapper接口 + * + * @author ${author} + * @date ${datetime} + */ +public interface ${ClassName}Mapper +{ + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 查询${functionName}列表 + * + * @param ${className} ${functionName} + * @return ${functionName}集合 + */ + public List<${ClassName}> select${ClassName}List(${ClassName} ${className}); + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int insert${ClassName}(${ClassName} ${className}); + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int update${ClassName}(${ClassName} ${className}); + + /** + * 删除${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); +#if($table.sub) + + /** + * 批量删除${subTable.functionName} + * + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 + * @return 结果 + */ + public int delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 批量新增${subTable.functionName} + * + * @param ${subclassName}List ${subTable.functionName}列表 + * @return 结果 + */ + public int batch${subClassName}(List<${subClassName}> ${subclassName}List); + + + /** + * 通过${functionName}主键删除${subTable.functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}ID + * @return 结果 + */ + public int delete${subClassName}By${subTableFkClassName}(${pkColumn.javaType} ${pkColumn.javaField}); +#end +} diff --git a/ruoyi-generator/src/main/resources/vm/java/service.java.vm b/ruoyi-generator/src/main/resources/vm/java/service.java.vm new file mode 100644 index 0000000..264882b --- /dev/null +++ b/ruoyi-generator/src/main/resources/vm/java/service.java.vm @@ -0,0 +1,61 @@ +package ${packageName}.service; + +import java.util.List; +import ${packageName}.domain.${ClassName}; + +/** + * ${functionName}Service接口 + * + * @author ${author} + * @date ${datetime} + */ +public interface I${ClassName}Service +{ + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 查询${functionName}列表 + * + * @param ${className} ${functionName} + * @return ${functionName}集合 + */ + public List<${ClassName}> select${ClassName}List(${ClassName} ${className}); + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int insert${ClassName}(${ClassName} ${className}); + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int update${ClassName}(${ClassName} ${className}); + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的${functionName}主键集合 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 删除${functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); +} diff --git a/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm b/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm new file mode 100644 index 0000000..14746e1 --- /dev/null +++ b/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm @@ -0,0 +1,169 @@ +package ${packageName}.service.impl; + +import java.util.List; +#foreach ($column in $columns) +#if($column.javaField == 'createTime' || $column.javaField == 'updateTime') +import com.ruoyi.common.utils.DateUtils; +#break +#end +#end +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +#if($table.sub) +import java.util.ArrayList; +import com.ruoyi.common.utils.StringUtils; +import org.springframework.transaction.annotation.Transactional; +import ${packageName}.domain.${subClassName}; +#end +import ${packageName}.mapper.${ClassName}Mapper; +import ${packageName}.domain.${ClassName}; +import ${packageName}.service.I${ClassName}Service; + +/** + * ${functionName}Service业务层处理 + * + * @author ${author} + * @date ${datetime} + */ +@Service +public class ${ClassName}ServiceImpl implements I${ClassName}Service +{ + @Autowired + private ${ClassName}Mapper ${className}Mapper; + + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + @Override + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) + { + return ${className}Mapper.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); + } + + /** + * 查询${functionName}列表 + * + * @param ${className} ${functionName} + * @return ${functionName} + */ + @Override + public List<${ClassName}> select${ClassName}List(${ClassName} ${className}) + { + return ${className}Mapper.select${ClassName}List(${className}); + } + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int insert${ClassName}(${ClassName} ${className}) + { +#foreach ($column in $columns) +#if($column.javaField == 'createTime') + ${className}.setCreateTime(DateUtils.getNowDate()); +#end +#end +#if($table.sub) + int rows = ${className}Mapper.insert${ClassName}(${className}); + insert${subClassName}(${className}); + return rows; +#else + return ${className}Mapper.insert${ClassName}(${className}); +#end + } + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int update${ClassName}(${ClassName} ${className}) + { +#foreach ($column in $columns) +#if($column.javaField == 'updateTime') + ${className}.setUpdateTime(DateUtils.getNowDate()); +#end +#end +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${className}.get${pkColumn.capJavaField}()); + insert${subClassName}(${className}); +#end + return ${className}Mapper.update${ClassName}(${className}); + } + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的${functionName}主键 + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s) + { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaField}s); +#end + return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s); + } + + /** + * 删除${functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) + { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${pkColumn.javaField}); +#end + return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); + } +#if($table.sub) + + /** + * 新增${subTable.functionName}信息 + * + * @param ${className} ${functionName}对象 + */ + public void insert${subClassName}(${ClassName} ${className}) + { + List<${subClassName}> ${subclassName}List = ${className}.get${subClassName}List(); + ${pkColumn.javaType} ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}(); + if (StringUtils.isNotNull(${subclassName}List)) + { + List<${subClassName}> list = new ArrayList<${subClassName}>(); + for (${subClassName} ${subclassName} : ${subclassName}List) + { + ${subclassName}.set${subTableFkClassName}(${pkColumn.javaField}); + list.add(${subclassName}); + } + if (list.size() > 0) + { + ${className}Mapper.batch${subClassName}(list); + } + } + } +#end +} diff --git a/ruoyi-generator/src/main/resources/vm/java/sub-domain.java.vm b/ruoyi-generator/src/main/resources/vm/java/sub-domain.java.vm new file mode 100644 index 0000000..a3f53eb --- /dev/null +++ b/ruoyi-generator/src/main/resources/vm/java/sub-domain.java.vm @@ -0,0 +1,76 @@ +package ${packageName}.domain; + +#foreach ($import in $subImportList) +import ${import}; +#end +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * ${subTable.functionName}对象 ${subTableName} + * + * @author ${author} + * @date ${datetime} + */ +public class ${subClassName} extends BaseEntity +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $subTable.columns) +#if(!$table.isSuperColumn($column.javaField)) + /** $column.columnComment */ +#if($column.list) +#set($parentheseIndex=$column.columnComment.indexOf("(")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($parentheseIndex != -1) + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") +#elseif($column.javaType == 'Date') + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") +#else + @Excel(name = "${comment}") +#end +#end + private $column.javaType $column.javaField; + +#end +#end +#foreach ($column in $subTable.columns) +#if(!$table.isSuperColumn($column.javaField)) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + public void set${AttrName}($column.javaType $column.javaField) + { + this.$column.javaField = $column.javaField; + } + + public $column.javaType get${AttrName}() + { + return $column.javaField; + } +#end +#end + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) +#foreach ($column in $subTable.columns) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + .append("${column.javaField}", get${AttrName}()) +#end + .toString(); + } +} diff --git a/ruoyi-generator/src/main/resources/vm/js/api.js.vm b/ruoyi-generator/src/main/resources/vm/js/api.js.vm new file mode 100644 index 0000000..9295524 --- /dev/null +++ b/ruoyi-generator/src/main/resources/vm/js/api.js.vm @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询${functionName}列表 +export function list${BusinessName}(query) { + return request({ + url: '/${moduleName}/${businessName}/list', + method: 'get', + params: query + }) +} + +// 查询${functionName}详细 +export function get${BusinessName}(${pkColumn.javaField}) { + return request({ + url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, + method: 'get' + }) +} + +// 新增${functionName} +export function add${BusinessName}(data) { + return request({ + url: '/${moduleName}/${businessName}', + method: 'post', + data: data + }) +} + +// 修改${functionName} +export function update${BusinessName}(data) { + return request({ + url: '/${moduleName}/${businessName}', + method: 'put', + data: data + }) +} + +// 删除${functionName} +export function del${BusinessName}(${pkColumn.javaField}) { + return request({ + url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, + method: 'delete' + }) +} diff --git a/ruoyi-generator/src/main/resources/vm/sql/sql.vm b/ruoyi-generator/src/main/resources/vm/sql/sql.vm new file mode 100644 index 0000000..0575583 --- /dev/null +++ b/ruoyi-generator/src/main/resources/vm/sql/sql.vm @@ -0,0 +1,22 @@ +-- 菜单 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 'admin', sysdate(), '', null, '${functionName}菜单'); + +-- 按钮父菜单ID +SELECT @parentId := LAST_INSERT_ID(); + +-- 按钮 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:query', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:add', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:edit', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:remove', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:export', '#', 'admin', sysdate(), '', null, ''); \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm new file mode 100644 index 0000000..a4c64a0 --- /dev/null +++ b/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm @@ -0,0 +1,505 @@ + + + diff --git a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm new file mode 100644 index 0000000..6296014 --- /dev/null +++ b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm @@ -0,0 +1,602 @@ + + + diff --git a/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm new file mode 100644 index 0000000..405d7d6 --- /dev/null +++ b/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm @@ -0,0 +1,475 @@ + + + diff --git a/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm new file mode 100644 index 0000000..8b25665 --- /dev/null +++ b/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm @@ -0,0 +1,590 @@ + + + diff --git a/ruoyi-generator/src/main/resources/vm/vue/v3/readme.txt b/ruoyi-generator/src/main/resources/vm/vue/v3/readme.txt new file mode 100644 index 0000000..99239bb --- /dev/null +++ b/ruoyi-generator/src/main/resources/vm/vue/v3/readme.txt @@ -0,0 +1 @@ +ʹõRuoYi-Vue3ǰˣôҪһ´Ŀ¼ģindex.vue.vmindex-tree.vue.vmļϼvueĿ¼ \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm b/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm new file mode 100644 index 0000000..0ceb3d8 --- /dev/null +++ b/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm @@ -0,0 +1,135 @@ + + + + + +#foreach ($column in $columns) + +#end + +#if($table.sub) + + + + + + +#foreach ($column in $subTable.columns) + +#end + +#end + + + select#foreach($column in $columns) $column.columnName#if($foreach.count != $columns.size()),#end#end from ${tableName} + + + + + + + + insert into ${tableName} + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + $column.columnName, +#end +#end + + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + #{$column.javaField}, +#end +#end + + + + + update ${tableName} + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName) + $column.columnName = #{$column.javaField}, +#end +#end + + where ${pkColumn.columnName} = #{${pkColumn.javaField}} + + + + delete from ${tableName} where ${pkColumn.columnName} = #{${pkColumn.javaField}} + + + + delete from ${tableName} where ${pkColumn.columnName} in + + #{${pkColumn.javaField}} + + +#if($table.sub) + + + delete from ${subTableName} where ${subTableFkName} in + + #{${subTableFkclassName}} + + + + + delete from ${subTableName} where ${subTableFkName} = #{${subTableFkclassName}} + + + + insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($foreach.count != $subTable.columns.size()),#end#end) values + + (#foreach($column in $subTable.columns) #{item.$column.javaField}#if($foreach.count != $subTable.columns.size()),#end#end) + + +#end + \ No newline at end of file diff --git a/ruoyi-quartz/pom.xml b/ruoyi-quartz/pom.xml new file mode 100644 index 0000000..28f47a0 --- /dev/null +++ b/ruoyi-quartz/pom.xml @@ -0,0 +1,58 @@ + + + + ruoyi + com.ruoyi + 3.8.4 + + 4.0.0 + + ruoyi-quartz + + + quartz定时任务 + + + + + + + org.quartz-scheduler + quartz + + + com.mchange + c3p0 + + + + + + + com.ruoyi + ruoyi-common + + + + com.ruoyi + eastcom_yw + + + + com.ruoyi + ruoyi-system + + + com.ruoyi + ruoyi-framework + + + com.ruoyi + ruoyi-sunlm + + + + + \ No newline at end of file diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java new file mode 100644 index 0000000..a558170 --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java @@ -0,0 +1,57 @@ +//package com.ruoyi.quartz.config; +// +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.scheduling.quartz.SchedulerFactoryBean; +//import javax.sql.DataSource; +//import java.util.Properties; +// +///** +// * 定时任务配置(单机部署建议删除此类和qrtz数据库表,默认走内存会最高效) +// * +// * @author ruoyi +// */ +//@Configuration +//public class ScheduleConfig +//{ +// @Bean +// public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) +// { +// SchedulerFactoryBean factory = new SchedulerFactoryBean(); +// factory.setDataSource(dataSource); +// +// // quartz参数 +// Properties prop = new Properties(); +// prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler"); +// prop.put("org.quartz.scheduler.instanceId", "AUTO"); +// // 线程池配置 +// prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); +// prop.put("org.quartz.threadPool.threadCount", "20"); +// prop.put("org.quartz.threadPool.threadPriority", "5"); +// // JobStore配置 +// prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore"); +// // 集群配置 +// prop.put("org.quartz.jobStore.isClustered", "true"); +// prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); +// prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); +// prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true"); +// +// // sqlserver 启用 +// // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); +// prop.put("org.quartz.jobStore.misfireThreshold", "12000"); +// prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); +// factory.setQuartzProperties(prop); +// +// factory.setSchedulerName("RuoyiScheduler"); +// // 延时启动 +// factory.setStartupDelay(1); +// factory.setApplicationContextSchedulerContextKey("applicationContextKey"); +// // 可选,QuartzScheduler +// // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 +// factory.setOverwriteExistingJobs(true); +// // 设置自动启动,默认为true +// factory.setAutoStartup(true); +// +// return factory; +// } +//} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java new file mode 100644 index 0000000..139361b --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java @@ -0,0 +1,185 @@ +package com.ruoyi.quartz.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.quartz.SchedulerException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.exception.job.TaskException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.quartz.domain.SysJob; +import com.ruoyi.quartz.service.ISysJobService; +import com.ruoyi.quartz.util.CronUtils; +import com.ruoyi.quartz.util.ScheduleUtils; + +/** + * 调度任务信息操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/job") +public class SysJobController extends BaseController +{ + @Autowired + private ISysJobService jobService; + + /** + * 查询定时任务列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:list')") + @GetMapping("/list") + public TableDataInfo list(SysJob sysJob) + { + startPage(); + List list = jobService.selectJobList(sysJob); + return getDataTable(list); + } + + /** + * 导出定时任务列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:export')") + @Log(title = "定时任务", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysJob sysJob) + { + List list = jobService.selectJobList(sysJob); + ExcelUtil util = new ExcelUtil(SysJob.class); + util.exportExcel(response, list, "定时任务"); + } + + /** + * 获取定时任务详细信息 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:query')") + @GetMapping(value = "/{jobId}") + public AjaxResult getInfo(@PathVariable("jobId") Long jobId) + { + return success(jobService.selectJobById(jobId)); + } + + /** + * 新增定时任务 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:add')") + @Log(title = "定时任务", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysJob job) throws SchedulerException, TaskException + { + if (!CronUtils.isValid(job.getCronExpression())) + { + return error("新增任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + } + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串存在违规"); + } + else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); + } + job.setCreateBy(getUsername()); + return toAjax(jobService.insertJob(job)); + } + + /** + * 修改定时任务 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:edit')") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysJob job) throws SchedulerException, TaskException + { + if (!CronUtils.isValid(job.getCronExpression())) + { + return error("修改任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + } + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串存在违规"); + } + else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); + } + job.setUpdateBy(getUsername()); + return toAjax(jobService.updateJob(job)); + } + + /** + * 定时任务状态修改 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException + { + SysJob newJob = jobService.selectJobById(job.getJobId()); + newJob.setStatus(job.getStatus()); + return toAjax(jobService.changeStatus(newJob)); + } + + /** + * 定时任务立即执行一次 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping("/run") + public AjaxResult run(@RequestBody SysJob job) throws SchedulerException + { + boolean result = jobService.run(job); + return result ? success() : error("任务不存在或已过期!"); + } + + /** + * 删除定时任务 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") + @Log(title = "定时任务", businessType = BusinessType.DELETE) + @DeleteMapping("/{jobIds}") + public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException + { + jobService.deleteJobByIds(jobIds); + return success(); + } +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java new file mode 100644 index 0000000..62ecbab --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java @@ -0,0 +1,92 @@ +package com.ruoyi.quartz.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.quartz.domain.SysJobLog; +import com.ruoyi.quartz.service.ISysJobLogService; + +/** + * 调度日志操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/jobLog") +public class SysJobLogController extends BaseController +{ + @Autowired + private ISysJobLogService jobLogService; + + /** + * 查询定时任务调度日志列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:list')") + @GetMapping("/list") + public TableDataInfo list(SysJobLog sysJobLog) + { + startPage(); + List list = jobLogService.selectJobLogList(sysJobLog); + return getDataTable(list); + } + + /** + * 导出定时任务调度日志列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:export')") + @Log(title = "任务调度日志", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysJobLog sysJobLog) + { + List list = jobLogService.selectJobLogList(sysJobLog); + ExcelUtil util = new ExcelUtil(SysJobLog.class); + util.exportExcel(response, list, "调度日志"); + } + + /** + * 根据调度编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:query')") + @GetMapping(value = "/{jobLogId}") + public AjaxResult getInfo(@PathVariable Long jobLogId) + { + return success(jobLogService.selectJobLogById(jobLogId)); + } + + + /** + * 删除定时任务调度日志 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") + @Log(title = "定时任务调度日志", businessType = BusinessType.DELETE) + @DeleteMapping("/{jobLogIds}") + public AjaxResult remove(@PathVariable Long[] jobLogIds) + { + return toAjax(jobLogService.deleteJobLogByIds(jobLogIds)); + } + + /** + * 清空定时任务调度日志 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") + @Log(title = "调度日志", businessType = BusinessType.CLEAN) + @DeleteMapping("/clean") + public AjaxResult clean() + { + jobLogService.cleanJobLog(); + return success(); + } +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java new file mode 100644 index 0000000..1f49695 --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java @@ -0,0 +1,171 @@ +package com.ruoyi.quartz.domain; + +import java.util.Date; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.annotation.Excel.ColumnType; +import com.ruoyi.common.constant.ScheduleConstants; +import com.ruoyi.common.core.domain.BaseEntity; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.quartz.util.CronUtils; + +/** + * 定时任务调度表 sys_job + * + * @author ruoyi + */ +public class SysJob extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 任务ID */ + @Excel(name = "任务序号", cellType = ColumnType.NUMERIC) + private Long jobId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String jobName; + + /** 任务组名 */ + @Excel(name = "任务组名") + private String jobGroup; + + /** 调用目标字符串 */ + @Excel(name = "调用目标字符串") + private String invokeTarget; + + /** cron执行表达式 */ + @Excel(name = "执行表达式 ") + private String cronExpression; + + /** cron计划策略 */ + @Excel(name = "计划策略 ", readConverterExp = "0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行") + private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT; + + /** 是否并发执行(0允许 1禁止) */ + @Excel(name = "并发执行", readConverterExp = "0=允许,1=禁止") + private String concurrent; + + /** 任务状态(0正常 1暂停) */ + @Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停") + private String status; + + public Long getJobId() + { + return jobId; + } + + public void setJobId(Long jobId) + { + this.jobId = jobId; + } + + @NotBlank(message = "任务名称不能为空") + @Size(min = 0, max = 64, message = "任务名称不能超过64个字符") + public String getJobName() + { + return jobName; + } + + public void setJobName(String jobName) + { + this.jobName = jobName; + } + + public String getJobGroup() + { + return jobGroup; + } + + public void setJobGroup(String jobGroup) + { + this.jobGroup = jobGroup; + } + + @NotBlank(message = "调用目标字符串不能为空") + @Size(min = 0, max = 500, message = "调用目标字符串长度不能超过500个字符") + public String getInvokeTarget() + { + return invokeTarget; + } + + public void setInvokeTarget(String invokeTarget) + { + this.invokeTarget = invokeTarget; + } + + @NotBlank(message = "Cron执行表达式不能为空") + @Size(min = 0, max = 255, message = "Cron执行表达式不能超过255个字符") + public String getCronExpression() + { + return cronExpression; + } + + public void setCronExpression(String cronExpression) + { + this.cronExpression = cronExpression; + } + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + public Date getNextValidTime() + { + if (StringUtils.isNotEmpty(cronExpression)) + { + return CronUtils.getNextExecution(cronExpression); + } + return null; + } + + public String getMisfirePolicy() + { + return misfirePolicy; + } + + public void setMisfirePolicy(String misfirePolicy) + { + this.misfirePolicy = misfirePolicy; + } + + public String getConcurrent() + { + return concurrent; + } + + public void setConcurrent(String concurrent) + { + this.concurrent = concurrent; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("jobId", getJobId()) + .append("jobName", getJobName()) + .append("jobGroup", getJobGroup()) + .append("cronExpression", getCronExpression()) + .append("nextValidTime", getNextValidTime()) + .append("misfirePolicy", getMisfirePolicy()) + .append("concurrent", getConcurrent()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJobLog.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJobLog.java new file mode 100644 index 0000000..121c035 --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJobLog.java @@ -0,0 +1,155 @@ +package com.ruoyi.quartz.domain; + +import java.util.Date; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 定时任务调度日志表 sys_job_log + * + * @author ruoyi + */ +public class SysJobLog extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** ID */ + @Excel(name = "日志序号") + private Long jobLogId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String jobName; + + /** 任务组名 */ + @Excel(name = "任务组名") + private String jobGroup; + + /** 调用目标字符串 */ + @Excel(name = "调用目标字符串") + private String invokeTarget; + + /** 日志信息 */ + @Excel(name = "日志信息") + private String jobMessage; + + /** 执行状态(0正常 1失败) */ + @Excel(name = "执行状态", readConverterExp = "0=正常,1=失败") + private String status; + + /** 异常信息 */ + @Excel(name = "异常信息") + private String exceptionInfo; + + /** 开始时间 */ + private Date startTime; + + /** 停止时间 */ + private Date stopTime; + + public Long getJobLogId() + { + return jobLogId; + } + + public void setJobLogId(Long jobLogId) + { + this.jobLogId = jobLogId; + } + + public String getJobName() + { + return jobName; + } + + public void setJobName(String jobName) + { + this.jobName = jobName; + } + + public String getJobGroup() + { + return jobGroup; + } + + public void setJobGroup(String jobGroup) + { + this.jobGroup = jobGroup; + } + + public String getInvokeTarget() + { + return invokeTarget; + } + + public void setInvokeTarget(String invokeTarget) + { + this.invokeTarget = invokeTarget; + } + + public String getJobMessage() + { + return jobMessage; + } + + public void setJobMessage(String jobMessage) + { + this.jobMessage = jobMessage; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getExceptionInfo() + { + return exceptionInfo; + } + + public void setExceptionInfo(String exceptionInfo) + { + this.exceptionInfo = exceptionInfo; + } + + public Date getStartTime() + { + return startTime; + } + + public void setStartTime(Date startTime) + { + this.startTime = startTime; + } + + public Date getStopTime() + { + return stopTime; + } + + public void setStopTime(Date stopTime) + { + this.stopTime = stopTime; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("jobLogId", getJobLogId()) + .append("jobName", getJobName()) + .append("jobGroup", getJobGroup()) + .append("jobMessage", getJobMessage()) + .append("status", getStatus()) + .append("exceptionInfo", getExceptionInfo()) + .append("startTime", getStartTime()) + .append("stopTime", getStopTime()) + .toString(); + } +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java new file mode 100644 index 0000000..46d80c3 --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java @@ -0,0 +1,67 @@ +package com.ruoyi.quartz.mapper; + +import java.util.List; +import com.ruoyi.quartz.domain.SysJobLog; + +/** + * 调度任务日志信息 数据层 + * + * @author ruoyi + */ +public interface SysJobLogMapper +{ + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + public List selectJobLogList(SysJobLog jobLog); + + /** + * 查询所有调度任务日志 + * + * @return 调度任务日志列表 + */ + public List selectJobLogAll(); + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + public SysJobLog selectJobLogById(Long jobLogId); + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + * @return 结果 + */ + public int insertJobLog(SysJobLog jobLog); + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的数据ID + * @return 结果 + */ + public int deleteJobLogByIds(Long[] logIds); + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + * @return 结果 + */ + public int deleteJobLogById(Long jobId); + + + public int deleteJobLogSchedule(); + + /** + * 清空任务日志 + */ + public void cleanJobLog(); +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java new file mode 100644 index 0000000..20f45db --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java @@ -0,0 +1,67 @@ +package com.ruoyi.quartz.mapper; + +import java.util.List; +import com.ruoyi.quartz.domain.SysJob; + +/** + * 调度任务信息 数据层 + * + * @author ruoyi + */ +public interface SysJobMapper +{ + /** + * 查询调度任务日志集合 + * + * @param job 调度信息 + * @return 操作日志集合 + */ + public List selectJobList(SysJob job); + + /** + * 查询所有调度任务 + * + * @return 调度任务列表 + */ + public List selectJobAll(); + + /** + * 通过调度ID查询调度任务信息 + * + * @param jobId 调度ID + * @return 角色对象信息 + */ + public SysJob selectJobById(Long jobId); + + /** + * 通过调度ID删除调度任务信息 + * + * @param jobId 调度ID + * @return 结果 + */ + public int deleteJobById(Long jobId); + + /** + * 批量删除调度任务信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteJobByIds(Long[] ids); + + /** + * 修改调度任务信息 + * + * @param job 调度任务信息 + * @return 结果 + */ + public int updateJob(SysJob job); + + /** + * 新增调度任务信息 + * + * @param job 调度任务信息 + * @return 结果 + */ + public int insertJob(SysJob job); +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java new file mode 100644 index 0000000..8546792 --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java @@ -0,0 +1,56 @@ +package com.ruoyi.quartz.service; + +import java.util.List; +import com.ruoyi.quartz.domain.SysJobLog; + +/** + * 定时任务调度日志信息信息 服务层 + * + * @author ruoyi + */ +public interface ISysJobLogService +{ + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + public List selectJobLogList(SysJobLog jobLog); + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + public SysJobLog selectJobLogById(Long jobLogId); + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + */ + public void addJobLog(SysJobLog jobLog); + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的日志ID + * @return 结果 + */ + public int deleteJobLogByIds(Long[] logIds); + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + * @return 结果 + */ + public int deleteJobLogById(Long jobId); + + /** + * 清空任务日志 + */ + public void cleanJobLog(); +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java new file mode 100644 index 0000000..437ade8 --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java @@ -0,0 +1,102 @@ +package com.ruoyi.quartz.service; + +import java.util.List; +import org.quartz.SchedulerException; +import com.ruoyi.common.exception.job.TaskException; +import com.ruoyi.quartz.domain.SysJob; + +/** + * 定时任务调度信息信息 服务层 + * + * @author ruoyi + */ +public interface ISysJobService +{ + /** + * 获取quartz调度器的计划任务 + * + * @param job 调度信息 + * @return 调度任务集合 + */ + public List selectJobList(SysJob job); + + /** + * 通过调度任务ID查询调度信息 + * + * @param jobId 调度任务ID + * @return 调度任务对象信息 + */ + public SysJob selectJobById(Long jobId); + + /** + * 暂停任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int pauseJob(SysJob job) throws SchedulerException; + + /** + * 恢复任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int resumeJob(SysJob job) throws SchedulerException; + + /** + * 删除任务后,所对应的trigger也将被删除 + * + * @param job 调度信息 + * @return 结果 + */ + public int deleteJob(SysJob job) throws SchedulerException; + + /** + * 批量删除调度信息 + * + * @param jobIds 需要删除的任务ID + * @return 结果 + */ + public void deleteJobByIds(Long[] jobIds) throws SchedulerException; + + /** + * 任务调度状态修改 + * + * @param job 调度信息 + * @return 结果 + */ + public int changeStatus(SysJob job) throws SchedulerException; + + /** + * 立即运行任务 + * + * @param job 调度信息 + * @return 结果 + */ + public boolean run(SysJob job) throws SchedulerException; + + /** + * 新增任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int insertJob(SysJob job) throws SchedulerException, TaskException; + + /** + * 更新任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int updateJob(SysJob job) throws SchedulerException, TaskException; + + /** + * 校验cron表达式是否有效 + * + * @param cronExpression 表达式 + * @return 结果 + */ + public boolean checkCronExpressionIsValid(String cronExpression); +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java new file mode 100644 index 0000000..812eed7 --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java @@ -0,0 +1,87 @@ +package com.ruoyi.quartz.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.quartz.domain.SysJobLog; +import com.ruoyi.quartz.mapper.SysJobLogMapper; +import com.ruoyi.quartz.service.ISysJobLogService; + +/** + * 定时任务调度日志信息 服务层 + * + * @author ruoyi + */ +@Service +public class SysJobLogServiceImpl implements ISysJobLogService +{ + @Autowired + private SysJobLogMapper jobLogMapper; + + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + @Override + public List selectJobLogList(SysJobLog jobLog) + { + return jobLogMapper.selectJobLogList(jobLog); + } + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + @Override + public SysJobLog selectJobLogById(Long jobLogId) + { + return jobLogMapper.selectJobLogById(jobLogId); + } + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + */ + @Override + public void addJobLog(SysJobLog jobLog) + { + jobLogMapper.insertJobLog(jobLog); + } + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteJobLogByIds(Long[] logIds) + { + return jobLogMapper.deleteJobLogByIds(logIds); + } + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + */ + @Override + public int deleteJobLogById(Long jobId) + { + return jobLogMapper.deleteJobLogById(jobId); + } + + /** + * 清空任务日志 + */ + @Override + public void cleanJobLog() + { + jobLogMapper.cleanJobLog(); + } +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java new file mode 100644 index 0000000..55bfdae --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java @@ -0,0 +1,266 @@ +package com.ruoyi.quartz.service.impl; + +import java.util.List; +import javax.annotation.PostConstruct; +import org.quartz.JobDataMap; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.ruoyi.common.constant.ScheduleConstants; +import com.ruoyi.common.exception.job.TaskException; +import com.ruoyi.quartz.domain.SysJob; +import com.ruoyi.quartz.mapper.SysJobMapper; +import com.ruoyi.quartz.service.ISysJobService; +import com.ruoyi.quartz.util.CronUtils; +import com.ruoyi.quartz.util.ScheduleUtils; + +/** + * 定时任务调度信息 服务层 + * + * @author ruoyi + */ +@Service +public class SysJobServiceImpl implements ISysJobService +{ + @Autowired + private Scheduler scheduler; + + @Autowired + private SysJobMapper jobMapper; + + @Value("${job.enabled}") + private boolean enabled; + + /** + * 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据) + */ + @PostConstruct + public void init() throws SchedulerException, TaskException + { + if(enabled) { + scheduler.clear(); + List jobList = jobMapper.selectJobAll(); + for (SysJob job : jobList) { + ScheduleUtils.createScheduleJob(scheduler, job); + } + } + } + + /** + * 获取quartz调度器的计划任务列表 + * + * @param job 调度信息 + * @return + */ + @Override + public List selectJobList(SysJob job) + { + return jobMapper.selectJobList(job); + } + + /** + * 通过调度任务ID查询调度信息 + * + * @param jobId 调度任务ID + * @return 调度任务对象信息 + */ + @Override + public SysJob selectJobById(Long jobId) + { + return jobMapper.selectJobById(jobId); + } + + /** + * 暂停任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int pauseJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 恢复任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int resumeJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + job.setStatus(ScheduleConstants.Status.NORMAL.getValue()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 删除任务后,所对应的trigger也将被删除 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + int rows = jobMapper.deleteJobById(jobId); + if (rows > 0) + { + scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 批量删除调度信息 + * + * @param jobIds 需要删除的任务ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteJobByIds(Long[] jobIds) throws SchedulerException + { + for (Long jobId : jobIds) + { + SysJob job = jobMapper.selectJobById(jobId); + deleteJob(job); + } + } + + /** + * 任务调度状态修改 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int changeStatus(SysJob job) throws SchedulerException + { + int rows = 0; + String status = job.getStatus(); + if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) + { + rows = resumeJob(job); + } + else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) + { + rows = pauseJob(job); + } + return rows; + } + + /** + * 立即运行任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean run(SysJob job) throws SchedulerException + { + boolean result = false; + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + SysJob properties = selectJobById(job.getJobId()); + // 参数 + JobDataMap dataMap = new JobDataMap(); + dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties); + JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); + if (scheduler.checkExists(jobKey)) + { + result = true; + scheduler.triggerJob(jobKey, dataMap); + } + return result; + } + + /** + * 新增任务 + * + * @param job 调度信息 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int insertJob(SysJob job) throws SchedulerException, TaskException + { + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); + int rows = jobMapper.insertJob(job); + if (rows > 0) + { + ScheduleUtils.createScheduleJob(scheduler, job); + } + return rows; + } + + /** + * 更新任务的时间表达式 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateJob(SysJob job) throws SchedulerException, TaskException + { + SysJob properties = selectJobById(job.getJobId()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + updateSchedulerJob(job, properties.getJobGroup()); + } + return rows; + } + + /** + * 更新任务 + * + * @param job 任务对象 + * @param jobGroup 任务组名 + */ + public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException + { + Long jobId = job.getJobId(); + // 判断是否存在 + JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); + if (scheduler.checkExists(jobKey)) + { + // 防止创建时存在数据问题 先移除,然后在执行创建操作 + scheduler.deleteJob(jobKey); + } + ScheduleUtils.createScheduleJob(scheduler, job); + } + + /** + * 校验cron表达式是否有效 + * + * @param cronExpression 表达式 + * @return 结果 + */ + @Override + public boolean checkCronExpressionIsValid(String cronExpression) + { + return CronUtils.isValid(cronExpression); + } +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java new file mode 100644 index 0000000..a05d702 --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java @@ -0,0 +1,223 @@ +package com.ruoyi.quartz.task; + +import cn.hutool.core.date.LocalDateTimeUtil; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.eastcom_yw.domain.SysNotice; +import com.ruoyi.eastcom_yw.mapper.YwSignLogMapper; +import com.ruoyi.eastcom_yw.mapper.YwSignPlanMapper; +import com.ruoyi.eastcom_yw.service.*; +import com.ruoyi.quartz.mapper.SysJobLogMapper; +import com.ruoyi.sunlm.service.YwDpNewYayunService; +import com.ruoyi.sunlm.service.dpAllMyServices; +import com.ruoyi.system.mapper.SysLogininforMapper; +import com.ruoyi.system.mapper.SysOperLogMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * 定时任务调度测试 + * + * @author ruoyi + */ +@Component("ryTask") +//@Profile("other") +public class RyTask { + + @Autowired + private YwAlarmService ywAlarmService; + @Autowired + private YwAlarmViewService ywAlarmViewService; + + @Autowired + private YwRoutInspectPlanService ywRoutInspectPlanService; + + @Autowired + private yw_alarm_deal_logService alarm_deal_logService; + + @Autowired + private YwAlarmHangupLogService ywAlarmHangupLogService; + + @Autowired + private YwSignLogMapper ywSignLogMapper; + + @Autowired + private YwSignPlanMapper ywSignPlanMapper; + + @Autowired + private SysNoticeService sysNoticeService; + + @Autowired + private YwNoticeBriefingService noticeBriefingService; + + @Autowired + private YwNoticeHandworkService ywNoticeHandworkService; + + @Autowired + private YwScenePictureService ywScenePictureService; + + @Autowired + private YwSceneTestDataService ywSceneTestDataService; + + @Autowired + private YwDpNewYayunService ywDpNewYayunService; + + @Autowired + private dpAllMyServices DpAllMyServices; + + @Autowired + private SysJobLogMapper sysJobLogMapper; + + @Autowired + private SysOperLogMapper sysOperLogMapper; + + @Autowired + private SysLogininforMapper sysLogininforMapper; + + public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) { + System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i)); + } + + public void ryParams(String params) { + System.out.println("执行有参方法:" + params); + } + + public void ryNoParams() { + System.out.println("执行无参方法"); + } + + public void eastcomYwAlarmSchedule() { + + ywAlarmViewService.insert_alarm_schedule(); + + ywAlarmViewService.insert_alarmNotice_schedule(); + + //定时器实现更新LOG表的恢复时间,但是新告警不会变成重新需要处理 + alarm_deal_logService.updateEndTime(); + } + + public void eastcomYwAlarmNoticeSchedule() { + ywAlarmService.YwAlarmAutoRecover(); + } + + public void eastcomYwAlarmStatisticsSchedule() { + ywScenePictureService.generateAlarmStatisticsEvery5Minutes(); + } + + public void eastcomYwSceneTestDataSchedule() { + ywSceneTestDataService.insertTestData(); + } + + public void eastcomYwSignLogSchedule() { + ywSignLogMapper.deleteSignLogToday(); + ywSignLogMapper.AssignSignLog(); + } + + public void eastcomYwAlarmRecoverSchedule() { + ywAlarmService.YwAlarmAutoRecover(); + } + + public void eastcomYwSignRemindSchedule() { + + ywSignPlanMapper.getSignRemindList().forEach( + + ywSignRemind -> { + + SysNotice notice = new SysNotice(); + notice.setNoticeType(ywSignRemind.getNoticeType()); + notice.setStatus("0"); + notice.setCreateBy("sys"); + notice.setNoticeTitle(ywSignRemind.getNoticeTitle()); + notice.setNoticeContent(ywSignRemind.getNoticeContent()); + notice.setReciveUser(ywSignRemind.getUserId()); + notice.setCreateTime(LocalDateTimeUtil.now()); + //notice.setSendTime(ywSignRemind.getRemindTime()); + notice.setReciveUserPhone(ywSignRemind.getPhoneNumber()); + //计划发送时间 当前时间立即发送 + notice.setExpSendTime(LocalDateTimeUtil.of(ywSignRemind.getRemindTime())); + //加入定时任务标记 初始0 + notice.setAddFlag("0"); + + sysNoticeService.saveOrUpdate(notice); + + } + ); + } + + + public void eastcomYwInspectPlanSchedule() { + ywRoutInspectPlanService.insetInspectSchedule(); + } + +// public void eastcomYwSendSMSSchedule() { +// sysNoticeService.eastcomYwSendSMSSchedule(); +// } + + public void newEastcomYwSendSMSSchedule() { + sysNoticeService.newEastcomYwSendSMSSchedule(); + } + + public void eastcomYwSendBriefingSchedule() { + noticeBriefingService.eastcomYwSendBriefingSchedule(); + } + + public void eastcomYwSendAlarmBriefingSchedule() { + ywAlarmService.eastcomYwSendAlarmBriefingSchedule(); + } + + public void eastcomYwUpdateBriefingSendTypeSchedule() { + noticeBriefingService.eastcomYwUpdateBriefingSendTypeSchedule(); + } + + public void eastcomSelectPassAndAddNoticeSchedule() { + ywNoticeHandworkService.eastcomSelectPassAndAddNoticeSchedule(); + } + + public void eastcomUpdateTransAlarmsSchedule() { + ywDpNewYayunService.eastcomUpdateTransAlarmsSchedule(); + } + + public void eastcomUpdateComprehensiveManageSchedule() { + ywDpNewYayunService.eastcomUpdateComprehensiveManageSchedule(); + } + + public void eastcomUpdateNetAlarmsSchedule() { + ywDpNewYayunService.eastcomUpdateNetAlarmsSchedule(); + } + + + //---------------------------------------------sunlm 2023-07-19, 定时计算后保存到缓存 + public void AutoStatisticsforDPSchedule_1min() { + + DpAllMyServices.get_wireless_outservice(); + DpAllMyServices.get_trans_counts(); + DpAllMyServices.get_dict_counts(); + DpAllMyServices.get_agis_internet_counts(); + DpAllMyServices.get_maps_all_alarms(); + DpAllMyServices.get_maps_wireless_kpi_min(); + DpAllMyServices.get_maps_all_alarms_popup(); + DpAllMyServices.get_maps_wireless_alarms_popup(); + DpAllMyServices.get_spot_wirelessalarms_popup(); + //---------------------------------------DICT + DpAllMyServices.get_dict_monitor_project_list(); + DpAllMyServices.get_dict_monitor_alarm_list(); + DpAllMyServices.get_dict_link_alarm_list(); + DpAllMyServices.get_dict_map_alarm_list(); + } + + public void AutoStatisticsforDPSchedule_5min() { + DpAllMyServices.get_gbflow_wireless(); + DpAllMyServices.get_manage_counts(); + DpAllMyServices.get_gbflow_huanlu(); + DpAllMyServices.get_maps_wireless_kpi_cell(); + } +//------------------------------------------------------------------------------ + + public void deleteLog() + { + sysJobLogMapper.deleteJobLogSchedule(); + sysLogininforMapper.deleteLogininforSchedule(); + sysOperLogMapper.deleteOperLogSchedule(); + } + + +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java new file mode 100644 index 0000000..f11984d --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java @@ -0,0 +1,145 @@ +package com.ruoyi.quartz.util; + +import cn.hutool.core.date.LocalDateTimeUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.ScheduleConstants; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.ExceptionUtil; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.eastcom_yw.domain.SysNotice; +import com.ruoyi.eastcom_yw.service.SysNoticeService; +import com.ruoyi.quartz.domain.SysJob; +import com.ruoyi.quartz.domain.SysJobLog; +import com.ruoyi.quartz.service.ISysJobLogService; +import com.ruoyi.system.service.ISysUserService; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Date; +import java.util.List; + +/** + * 抽象quartz调用 + * + * @author ruoyi + */ +public abstract class AbstractQuartzJob implements Job +{ + private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class); + + /** + * 线程本地变量 + */ + private static ThreadLocal threadLocal = new ThreadLocal<>(); + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException + { + SysJob sysJob = new SysJob(); + BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES)); + try + { + before(context, sysJob); + if (sysJob != null) + { + doExecute(context, sysJob); + } + after(context, sysJob, null); + } + catch (Exception e) + { + log.error("任务执行异常 - :", e); + after(context, sysJob, e); + } + } + + /** + * 执行前 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void before(JobExecutionContext context, SysJob sysJob) + { + threadLocal.set(new Date()); + } + + /** + * 执行后 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void after(JobExecutionContext context, SysJob sysJob, Exception e) + { + Date startTime = threadLocal.get(); + threadLocal.remove(); + + final SysJobLog sysJobLog = new SysJobLog(); + sysJobLog.setJobName(sysJob.getJobName()); + sysJobLog.setJobGroup(sysJob.getJobGroup()); + sysJobLog.setInvokeTarget(sysJob.getInvokeTarget()); + sysJobLog.setStartTime(startTime); + sysJobLog.setStopTime(new Date()); + long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime(); + sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒"); + if (e != null) + { + sysJobLog.setStatus(Constants.FAIL); + String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000); + sysJobLog.setExceptionInfo(errorMsg); + + + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.ge(SysNotice::getCreateTime,LocalDateTimeUtil.of(DateUtils.getNowDate()).minusHours(1L)); + query.likeRight(SysNotice::getNoticeContent,sysJob.getJobName()); +// query.eq(SysNotice::getStatus,"0"); + //相同JOB异常1小时内是否已经发送过 + List list = SpringUtils.getBean(SysNoticeService.class).getBaseMapper().selectList(query); + if(list.isEmpty()) { + //发送管理员的手机号码 + SysUser user = SpringUtils.getBean(ISysUserService.class).selectUserById(1L); + if (user != null) { + //任务调度失败,发送到sys_notice提醒 + SysNotice notice = new SysNotice(); + notice.setNoticeType("3"); + notice.setStatus("0"); + notice.setCreateBy("sys"); + notice.setNoticeTitle("中小屏后端定时器监控"); + notice.setNoticeContent(sysJob.getJobName() + " 执行异常,异常原因:" + errorMsg); + notice.setReciveUser(1L); + notice.setCreateTime(LocalDateTimeUtil.now()); + notice.setReciveUserPhone(user.getPhonenumber()); + //计划发送时间 当前时间立即发送 + notice.setExpSendTime(LocalDateTimeUtil.of(DateUtils.getNowDate())); + //加入定时任务标记 初始0 + notice.setAddFlag("0"); + SpringUtils.getBean(SysNoticeService.class).saveOrUpdate(notice); + } + } + } + else + { + sysJobLog.setStatus(Constants.SUCCESS); + } + + // 写入数据库当中 + SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog); + } + + /** + * 执行方法,由子类重载 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + * @throws Exception 执行过程中的异常 + */ + protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception; +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java new file mode 100644 index 0000000..dd53839 --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java @@ -0,0 +1,63 @@ +package com.ruoyi.quartz.util; + +import java.text.ParseException; +import java.util.Date; +import org.quartz.CronExpression; + +/** + * cron表达式工具类 + * + * @author ruoyi + * + */ +public class CronUtils +{ + /** + * 返回一个布尔值代表一个给定的Cron表达式的有效性 + * + * @param cronExpression Cron表达式 + * @return boolean 表达式是否有效 + */ + public static boolean isValid(String cronExpression) + { + return CronExpression.isValidExpression(cronExpression); + } + + /** + * 返回一个字符串值,表示该消息无效Cron表达式给出有效性 + * + * @param cronExpression Cron表达式 + * @return String 无效时返回表达式错误描述,如果有效返回null + */ + public static String getInvalidMessage(String cronExpression) + { + try + { + new CronExpression(cronExpression); + return null; + } + catch (ParseException pe) + { + return pe.getMessage(); + } + } + + /** + * 返回下一个执行时间根据给定的Cron表达式 + * + * @param cronExpression Cron表达式 + * @return Date 下次Cron表达式执行时间 + */ + public static Date getNextExecution(String cronExpression) + { + try + { + CronExpression cron = new CronExpression(cronExpression); + return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis())); + } + catch (ParseException e) + { + throw new IllegalArgumentException(e.getMessage()); + } + } +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java new file mode 100644 index 0000000..3da377a --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java @@ -0,0 +1,182 @@ +package com.ruoyi.quartz.util; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.List; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.quartz.domain.SysJob; + +/** + * 任务执行工具 + * + * @author ruoyi + */ +public class JobInvokeUtil +{ + /** + * 执行方法 + * + * @param sysJob 系统任务 + */ + public static void invokeMethod(SysJob sysJob) throws Exception + { + String invokeTarget = sysJob.getInvokeTarget(); + String beanName = getBeanName(invokeTarget); + String methodName = getMethodName(invokeTarget); + List methodParams = getMethodParams(invokeTarget); + + if (!isValidClassName(beanName)) + { + Object bean = SpringUtils.getBean(beanName); + invokeMethod(bean, methodName, methodParams); + } + else + { + Object bean = Class.forName(beanName).newInstance(); + invokeMethod(bean, methodName, methodParams); + } + } + + /** + * 调用任务方法 + * + * @param bean 目标对象 + * @param methodName 方法名称 + * @param methodParams 方法参数 + */ + private static void invokeMethod(Object bean, String methodName, List methodParams) + throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, + InvocationTargetException + { + if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0) + { + Method method = bean.getClass().getMethod(methodName, getMethodParamsType(methodParams)); + method.invoke(bean, getMethodParamsValue(methodParams)); + } + else + { + Method method = bean.getClass().getMethod(methodName); + method.invoke(bean); + } + } + + /** + * 校验是否为为class包名 + * + * @param invokeTarget 名称 + * @return true是 false否 + */ + public static boolean isValidClassName(String invokeTarget) + { + return StringUtils.countMatches(invokeTarget, ".") > 1; + } + + /** + * 获取bean名称 + * + * @param invokeTarget 目标字符串 + * @return bean名称 + */ + public static String getBeanName(String invokeTarget) + { + String beanName = StringUtils.substringBefore(invokeTarget, "("); + return StringUtils.substringBeforeLast(beanName, "."); + } + + /** + * 获取bean方法 + * + * @param invokeTarget 目标字符串 + * @return method方法 + */ + public static String getMethodName(String invokeTarget) + { + String methodName = StringUtils.substringBefore(invokeTarget, "("); + return StringUtils.substringAfterLast(methodName, "."); + } + + /** + * 获取method方法参数相关列表 + * + * @param invokeTarget 目标字符串 + * @return method方法相关参数列表 + */ + public static List getMethodParams(String invokeTarget) + { + String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")"); + if (StringUtils.isEmpty(methodStr)) + { + return null; + } + String[] methodParams = methodStr.split(",(?=([^\"']*[\"'][^\"']*[\"'])*[^\"']*$)"); + List classs = new LinkedList<>(); + for (int i = 0; i < methodParams.length; i++) + { + String str = StringUtils.trimToEmpty(methodParams[i]); + // String字符串类型,以'或"开头 + if (StringUtils.startsWithAny(str, "'", "\"")) + { + classs.add(new Object[] { StringUtils.substring(str, 1, str.length() - 1), String.class }); + } + // boolean布尔类型,等于true或者false + else if ("true".equalsIgnoreCase(str) || "false".equalsIgnoreCase(str)) + { + classs.add(new Object[] { Boolean.valueOf(str), Boolean.class }); + } + // long长整形,以L结尾 + else if (StringUtils.endsWith(str, "L")) + { + classs.add(new Object[] { Long.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Long.class }); + } + // double浮点类型,以D结尾 + else if (StringUtils.endsWith(str, "D")) + { + classs.add(new Object[] { Double.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Double.class }); + } + // 其他类型归类为整形 + else + { + classs.add(new Object[] { Integer.valueOf(str), Integer.class }); + } + } + return classs; + } + + /** + * 获取参数类型 + * + * @param methodParams 参数相关列表 + * @return 参数类型列表 + */ + public static Class[] getMethodParamsType(List methodParams) + { + Class[] classs = new Class[methodParams.size()]; + int index = 0; + for (Object[] os : methodParams) + { + classs[index] = (Class) os[1]; + index++; + } + return classs; + } + + /** + * 获取参数值 + * + * @param methodParams 参数相关列表 + * @return 参数值列表 + */ + public static Object[] getMethodParamsValue(List methodParams) + { + Object[] classs = new Object[methodParams.size()]; + int index = 0; + for (Object[] os : methodParams) + { + classs[index] = (Object) os[0]; + index++; + } + return classs; + } +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java new file mode 100644 index 0000000..5e13558 --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java @@ -0,0 +1,21 @@ +package com.ruoyi.quartz.util; + +import org.quartz.DisallowConcurrentExecution; +import org.quartz.JobExecutionContext; +import com.ruoyi.quartz.domain.SysJob; + +/** + * 定时任务处理(禁止并发执行) + * + * @author ruoyi + * + */ +@DisallowConcurrentExecution +public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob +{ + @Override + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception + { + JobInvokeUtil.invokeMethod(sysJob); + } +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java new file mode 100644 index 0000000..e975326 --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java @@ -0,0 +1,19 @@ +package com.ruoyi.quartz.util; + +import org.quartz.JobExecutionContext; +import com.ruoyi.quartz.domain.SysJob; + +/** + * 定时任务处理(允许并发执行) + * + * @author ruoyi + * + */ +public class QuartzJobExecution extends AbstractQuartzJob +{ + @Override + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception + { + JobInvokeUtil.invokeMethod(sysJob); + } +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java new file mode 100644 index 0000000..f885d42 --- /dev/null +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java @@ -0,0 +1,139 @@ +package com.ruoyi.quartz.util; + +import org.quartz.CronScheduleBuilder; +import org.quartz.CronTrigger; +import org.quartz.Job; +import org.quartz.JobBuilder; +import org.quartz.JobDetail; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.TriggerBuilder; +import org.quartz.TriggerKey; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.ScheduleConstants; +import com.ruoyi.common.exception.job.TaskException; +import com.ruoyi.common.exception.job.TaskException.Code; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.quartz.domain.SysJob; + +/** + * 定时任务工具类 + * + * @author ruoyi + * + */ +public class ScheduleUtils +{ + /** + * 得到quartz任务类 + * + * @param sysJob 执行计划 + * @return 具体执行任务类 + */ + private static Class getQuartzJobClass(SysJob sysJob) + { + boolean isConcurrent = "0".equals(sysJob.getConcurrent()); + return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class; + } + + /** + * 构建任务触发对象 + */ + public static TriggerKey getTriggerKey(Long jobId, String jobGroup) + { + return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); + } + + /** + * 构建任务键对象 + */ + public static JobKey getJobKey(Long jobId, String jobGroup) + { + return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); + } + + /** + * 创建定时任务 + */ + public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException + { + Class jobClass = getQuartzJobClass(job); + // 构建job信息 + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build(); + + // 表达式调度构建器 + CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); + cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); + + // 按新的cronExpression表达式构建一个新的trigger + CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup)) + .withSchedule(cronScheduleBuilder).build(); + + // 放入参数,运行时的方法可以获取 + jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); + + // 判断是否存在 + if (scheduler.checkExists(getJobKey(jobId, jobGroup))) + { + // 防止创建时存在数据问题 先移除,然后在执行创建操作 + scheduler.deleteJob(getJobKey(jobId, jobGroup)); + } + + // 判断任务是否过期 + if (StringUtils.isNotNull(CronUtils.getNextExecution(job.getCronExpression()))) + { + // 执行调度任务 + scheduler.scheduleJob(jobDetail, trigger); + } + + // 暂停任务 + if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) + { + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + } + + /** + * 设置定时任务策略 + */ + public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) + throws TaskException + { + switch (job.getMisfirePolicy()) + { + case ScheduleConstants.MISFIRE_DEFAULT: + return cb; + case ScheduleConstants.MISFIRE_IGNORE_MISFIRES: + return cb.withMisfireHandlingInstructionIgnoreMisfires(); + case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED: + return cb.withMisfireHandlingInstructionFireAndProceed(); + case ScheduleConstants.MISFIRE_DO_NOTHING: + return cb.withMisfireHandlingInstructionDoNothing(); + default: + throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() + + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); + } + } + + /** + * 检查包名是否为白名单配置 + * + * @param invokeTarget 目标字符串 + * @return 结果 + */ + public static boolean whiteList(String invokeTarget) + { + String packageName = StringUtils.substringBefore(invokeTarget, "("); + int count = StringUtils.countMatches(packageName, "."); + if (count > 1) + { + return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR); + } + Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]); + return StringUtils.containsAnyIgnoreCase(obj.getClass().getPackage().getName(), Constants.JOB_WHITELIST_STR); + } +} diff --git a/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml b/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml new file mode 100644 index 0000000..75c1854 --- /dev/null +++ b/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + select job_log_id, job_name, job_group, invoke_target, job_message, status, exception_info, create_time + from sys_job_log + + + + + + + + + + delete from sys_job_log where job_log_id = #{jobLogId} + + + + delete from sys_job_log where job_log_id in + + #{jobLogId} + + + + + delete from sys_job_log where create_time < now() + '- 1 month' + + + + truncate table sys_job_log + + + + insert into sys_job_log( + job_log_id, + job_name, + job_group, + invoke_target, + job_message, + status, + exception_info, + create_time + )values( + #{jobLogId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{jobMessage}, + #{status}, + #{exceptionInfo}, + now() + ) + + + \ No newline at end of file diff --git a/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml b/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml new file mode 100644 index 0000000..653b5a2 --- /dev/null +++ b/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark + from sys_job + + + + + + + + + + delete from sys_job where job_id = #{jobId} + + + + delete from sys_job where job_id in + + #{jobId} + + + + + update sys_job + + job_name = #{jobName}, + job_group = #{jobGroup}, + invoke_target = #{invokeTarget}, + cron_expression = #{cronExpression}, + misfire_policy = #{misfirePolicy}, + concurrent = #{concurrent}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = now() + + where job_id = #{jobId} + + + + insert into sys_job( + job_id, + job_name, + job_group, + invoke_target, + cron_expression, + misfire_policy, + concurrent, + status, + remark, + create_by, + create_time + )values( + #{jobId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{cronExpression}, + #{misfirePolicy}, + #{concurrent}, + #{status}, + #{remark}, + #{createBy}, + now() + ) + + + \ No newline at end of file diff --git a/ruoyi-sunlm/pom.xml b/ruoyi-sunlm/pom.xml new file mode 100644 index 0000000..a5a2b01 --- /dev/null +++ b/ruoyi-sunlm/pom.xml @@ -0,0 +1,44 @@ + + + + ruoyi + com.ruoyi + 3.8.4 + + 4.0.0 + + ruoyi-sunlm + + + sunlm大屏模块 + + + + + + + com.ruoyi + ruoyi-common + + + + com.baomidou + mybatis-plus-core + 3.5.1 + + + + + com.baomidou + mybatis-plus-boot-starter + + + com.ruoyi + eastcom_yw + + + + + \ No newline at end of file diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_cache_config.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_cache_config.java new file mode 100644 index 0000000..653da6c --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_cache_config.java @@ -0,0 +1,9 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_1_cache_config { + public String kind ; + public int cachesecond; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_device_alarm_counts.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_device_alarm_counts.java new file mode 100644 index 0000000..5c8c65f --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_device_alarm_counts.java @@ -0,0 +1,9 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_1_device_alarm_counts { + public int 设备数; + public int 告警总数; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_device_alarms_counts_ext.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_device_alarms_counts_ext.java new file mode 100644 index 0000000..aa34559 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_device_alarms_counts_ext.java @@ -0,0 +1,15 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_1_device_alarms_counts_ext { + public int 设备数1; + public int 告警总数1; + public int 设备数2; + public int 告警总数2; + public int 设备数3; + public int 告警总数3; + public int 设备数4; + public int 告警总数4; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_gbflow_wireless.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_gbflow_wireless.java new file mode 100644 index 0000000..2763347 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_gbflow_wireless.java @@ -0,0 +1,47 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +/* + { +    "label": [ +        "昨天(2023年04月6日)", +        "今天(2023年04月7日)" +    ], +    "xAxis": [ +        "1时", +        "2时", +        "3时", +        "4时", +        "5时" +    ], +    "value": [ +        600, +        800, +        580, +        400, +        880, +        580, +        630 +    ] + "value2": [ +        600, +        800, +        580, +        400, +        880, +        580, +        630 +    ] +} +* */ + +@Data +public class class_dp_1_gbflow_wireless { //4/5G无线流量, 传输环路流量通用 + public List label; + public List xaxis; + public List value; //当日 + public List value2; //前日 +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_gbflow_wireless_compare.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_gbflow_wireless_compare.java new file mode 100644 index 0000000..a314154 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_gbflow_wireless_compare.java @@ -0,0 +1,10 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_1_gbflow_wireless_compare { //4/5G无线流量, 传输环路流量通用 + public String adate; + public float gb; + public int sign; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_manage_counts.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_manage_counts.java new file mode 100644 index 0000000..c6100a0 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_manage_counts.java @@ -0,0 +1,13 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_1_manage_counts { //综合管理类统计值 + public int 应签到数量; + public int 实际签到数; + public float 人员签到率; + public int 巡检任务数; + public int 已巡检任务; + public float 巡检完成率; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_maps_alarms.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_maps_alarms.java new file mode 100644 index 0000000..7fb01dc --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_maps_alarms.java @@ -0,0 +1,31 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_1_maps_alarms { //地图上显示告警图标, + public String areaname; + public String venueid; + public String venuetypeid; + public String venuetype; + public String venuename; + public int icontype; //图标类型,0,1,2,3,..... + public float longitude; + public float latitude; + public int wirelesscount; + public int powercount; + public int transcount; + public int agiscount; + public int alarmcount; + public float signRate; + public float inspectRate; + public int signResult; + public int inspectResult; + public String venuenmanager; + public String phonenumber; + public List lists; //告警列表 + public class_dp_2_kpi_spot kpi; //景区KPI,无线用 + public String sitecellinto; //基站,小区数统计 +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_outservice_wireless.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_outservice_wireless.java new file mode 100644 index 0000000..4b9d82f --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_1_outservice_wireless.java @@ -0,0 +1,11 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_1_outservice_wireless { //无线退服数统计 + public int 退服数2G; + public int 退服数4G; + public int 退服数5G; + public int 基站总数; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_bts_wireless_alarms.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_bts_wireless_alarms.java new file mode 100644 index 0000000..33ff938 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_bts_wireless_alarms.java @@ -0,0 +1,14 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_2_bts_wireless_alarms { + public String btsname ; + public float longitude; + public float latitude; + public int alarmcount; + public List lists; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_code_net_alarms.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_code_net_alarms.java new file mode 100644 index 0000000..2ece595 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_code_net_alarms.java @@ -0,0 +1,17 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +/** + * @author yqf + * @date 2023/8/15 + */ +@Data +public class class_dp_2_code_net_alarms { + public String code ; + public int alarmcount; + public List lists; + public List kpilist; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_freq_statistics.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_freq_statistics.java new file mode 100644 index 0000000..ead1664 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_freq_statistics.java @@ -0,0 +1,9 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_2_freq_statistics { + public String 小区频段 ; + public int cnt; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot.java new file mode 100644 index 0000000..3ce5b47 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot.java @@ -0,0 +1,15 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_2_kpi_spot { + public String nettype; + public String datatype; + public String kpiname; + public int score; + public String color; + public List celllist; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot_cell.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot_cell.java new file mode 100644 index 0000000..6a517ad --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot_cell.java @@ -0,0 +1,15 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_2_kpi_spot_cell { + public String netttype ; + public String 时间 ; + public String 小区名称; + public class_dp_2_kpi_spot_kpi 上行prb利用率; + public class_dp_2_kpi_spot_kpi 下行prb利用率; + public class_dp_2_kpi_spot_kpi 最大用户数; + public class_dp_2_kpi_spot_kpi 上行平均干扰; + public class_dp_2_kpi_spot_kpi 综合得分; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot_celldetail.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot_celldetail.java new file mode 100644 index 0000000..a26025e --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot_celldetail.java @@ -0,0 +1,27 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_2_kpi_spot_celldetail { + public String 时间 ; + public String 小区名称 ; + public int 景区id ; + public float maxUser ; + public float prbUp ; + public float prbDown ; + public float avgDisturb ; + + public int kpiZhsf; + public String kpiclrPrbUp ; + public String kpiclrPrbDown ; + public String kpiclrMaxUser ; + public String kpiclrAvgDisturb ; + public String kpiclrKpiZhsf ; + + public int scoreZhsf; + public int scorePrbUp; + public int scorePrbDown; + public int scoreMaxUser; + public int scoreAvgDisturb; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot_kpi.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot_kpi.java new file mode 100644 index 0000000..7bd44b3 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_kpi_spot_kpi.java @@ -0,0 +1,10 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_2_kpi_spot_kpi { + public float value; + public String color; + public int score; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_out_wireless_alarms.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_out_wireless_alarms.java new file mode 100644 index 0000000..31f77f6 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_out_wireless_alarms.java @@ -0,0 +1,15 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_2_out_wireless_alarms { //外场告警及列表 + public int sceneid ; + public String scenename ; + public float longitude; + public float latitude; + public int total ; + public List alarmlist; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_power_alarm.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_power_alarm.java new file mode 100644 index 0000000..9350266 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_power_alarm.java @@ -0,0 +1,15 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_2_power_alarm { + public String eventtime; + public String alarmname; + public String siteName; + public String owner; + public String 场馆id; + public String 区域id; + private String phonenumber; + private String 故障处理人; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_control.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_control.java new file mode 100644 index 0000000..4bc212d --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_control.java @@ -0,0 +1,17 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/4/17 + */ +@Data +public class class_dp_2_scene_control { + //----------------------------------added by sunlm , 指定场馆以1分钟或15分钟展示 + private int sceneid; + //--------------------------------- + private int mintype; + private String nettype; + private String kpiname; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_seat_detail.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_seat_detail.java new file mode 100644 index 0000000..566f577 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_seat_detail.java @@ -0,0 +1,13 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/4/17 + */ +@Data +public class class_dp_2_scene_seat_detail { + public String seatid; + public int seatnumber; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_seat_info.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_seat_info.java new file mode 100644 index 0000000..2e40754 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_seat_info.java @@ -0,0 +1,14 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/4/17 + */ +@Data +public class class_dp_2_scene_seat_info { + public Integer length; + public Integer width; + public Integer angle; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_test_data.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_test_data.java new file mode 100644 index 0000000..4fc077a --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scene_test_data.java @@ -0,0 +1,21 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.Date; +@Data +public class class_dp_2_scene_test_data { + private Long id; + private String bzname; + private String scenename; + private String deviceoid; + private Float connectdelay; + private Float dlspeed; + private Float lat; + private Float lng; + private Float pagecomplete; + private Float ulspeed; + private Date updateTime; + private String nettype; + private Integer sceneId; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scenelist.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scenelist.java new file mode 100644 index 0000000..68faab6 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_scenelist.java @@ -0,0 +1,12 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_2_scenelist { //场馆信息 + public int venueId; + public String venueName; + public float longitude; + public float latitude; + public String venueCategory; //场或馆 +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_seat_chinesename.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_seat_chinesename.java new file mode 100644 index 0000000..f10d595 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_seat_chinesename.java @@ -0,0 +1,10 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_2_seat_chinesename { + public int sceneid ; + public String seatid ; + public String chinesename ; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_seat_wireless_alarms.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_seat_wireless_alarms.java new file mode 100644 index 0000000..16ba588 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_seat_wireless_alarms.java @@ -0,0 +1,12 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_2_seat_wireless_alarms { + public String seatid ; + public int alarmcount; + public List lists; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_site_cell_info.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_site_cell_info.java new file mode 100644 index 0000000..ea17fa9 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_site_cell_info.java @@ -0,0 +1,16 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_2_site_cell_info { + public String 类型; + public int 编号; + public String 名称; + public String 基站数2g; + public String 小区数2g; + public String 基站数4g; + public String 小区数4g; + public String 基站数5g; + public String 小区数5g; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_spotdetail.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_spotdetail.java new file mode 100644 index 0000000..bcba764 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_spotdetail.java @@ -0,0 +1,15 @@ +package com.ruoyi.sunlm.daping; + +import java.util.List; + +public class class_dp_2_spotdetail { + public int spotId; + public int spotTypeid; + public String spotType; + public String spotName; + public float longitude; + public float latitude; + public String spotDetail; + public int alarmcount; + public List lists; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_spotlist.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_spotlist.java new file mode 100644 index 0000000..1a583d8 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_spotlist.java @@ -0,0 +1,11 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_2_spotlist { + public String spottype; + public List spotlist; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_top5.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_top5.java new file mode 100644 index 0000000..91abe01 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_top5.java @@ -0,0 +1,41 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +/** + * [ + *     { + *         "title": "1", + *         "name": "H517599-杭州萧山奥邸国际写字楼区电梯地下室-HLW-F601-地下室SF-1", + *         "value": 20.8 + *     }, + *     { + *         "title": "2", + *         "name": "萧山石岩老街西FDD1800_66", + *         "value": 19.15 + *     }, + *     { + *         "title": "3", + *         "name": "H518207-萧山亚运村运动员一村D区-HLH-FD18102-亚运村运动员一村D02LY-8", + *         "value": 16.517 + *     }, + *     { + *         "title": "4", + *         "name": "H417875-萧山奥体博览中心-HFX-FD18901-奥体博览中心移动小微站11LY-65", + *         "value": 13.583 + *     }, + *     { + *         "title": "5", + *         "name": "萧山宝盛大厦CRAN利二路博奥路口3DMIMO_196", + *         "value": 11.367 + *     } + * ] + * */ + +@Data +public class class_dp_2_top5 { + public int title; + public String name; + public float value; + public String color; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_top5_allspot.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_top5_allspot.java new file mode 100644 index 0000000..0bb612b --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_top5_allspot.java @@ -0,0 +1,11 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_2_top5_allspot { //右侧小屏用 + public String spotname ; + public List lists; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_top5_spot.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_top5_spot.java new file mode 100644 index 0000000..a47970d --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_top5_spot.java @@ -0,0 +1,11 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_2_top5_spot { //每个指标的TOP5 + public String kpiname; + public List top5; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_usercounts.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_usercounts.java new file mode 100644 index 0000000..5a46ee7 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_usercounts.java @@ -0,0 +1,13 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_2_usercounts { //区域用户数, 区域流量通用, 漫入漫出通用 + public List label; + public List xaxis; + public List value; + public List value2; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_usercounts_compare.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_usercounts_compare.java new file mode 100644 index 0000000..c812988 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_usercounts_compare.java @@ -0,0 +1,10 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_2_usercounts_compare { ////区域用户数, 区域流量通用,, 漫入漫出通用 + public String datetime; + public float value; + public int sign; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_wireless_alarm.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_wireless_alarm.java new file mode 100644 index 0000000..1f224fc --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_wireless_alarm.java @@ -0,0 +1,19 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_2_wireless_alarm { //无线告警清单 + public String eventtime; + public String alarmname; + public String area; + public String sitename; + public String sitetype; + public String cellname; + public String 场馆id; + public String 场馆名称; + public float longitude; + public float latitude; + public String 区域id; + public String 坐席编号 ; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_wireless_highload.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_wireless_highload.java new file mode 100644 index 0000000..15a084d --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_2_wireless_highload.java @@ -0,0 +1,17 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_2_wireless_highload { + public int title; + public String statTime; + public int sceneId; + public String venueName; + public String netName; + public String kpiname; + public float kpivalue; + public int kpiscore; + public int kpitype; + public String nettype; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_gb_top5.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_gb_top5.java new file mode 100644 index 0000000..0ac5aa1 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_gb_top5.java @@ -0,0 +1,15 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/7/11 + */ +@Data +public class class_dp_3_gb_top5 { + + private String mename; + private String portname; + private float flow; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_maps_alarms.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_maps_alarms.java new file mode 100644 index 0000000..9e4756f --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_maps_alarms.java @@ -0,0 +1,23 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_3_maps_alarms { //地图上显示告警图标, + public String areaname; + public String venueid; + public String venuetypeid; + public String venuetype; + public String venuename; + public float longitude; + public float latitude; + public int alarmcount; + public int agiscount; + public int wificount; + public int voipcount; + public List lists; + public List linklists; + public List devlists; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_net_alarm.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_net_alarm.java new file mode 100644 index 0000000..1ac4eb1 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_net_alarm.java @@ -0,0 +1,22 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_3_net_alarm { + public String eventtime; + public String recovertime; + public String alarmname; + public String netname; + public String areaname; + public String detaillocation; + public String alarmtype; + public String nettype; + public String porttype; + public String portnet; + public String port; + public String mark; + public Long sceneid; + public String scenename; + public int alarmscount; //告警数量 +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_opticalpower.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_opticalpower.java new file mode 100644 index 0000000..7a4ffdc --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_opticalpower.java @@ -0,0 +1,18 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_3_opticalpower { + public String venue; + public String mename; + public String portame; + public float inOpticalpower; + public float outOpticalpower; + public float inMinvalue; + public float outMinvalue; + public String dateTime; + public String areaname; + public String 场馆id; + public String 区域id; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_trans_alarm.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_trans_alarm.java new file mode 100644 index 0000000..1311750 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_3_trans_alarm.java @@ -0,0 +1,17 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_3_trans_alarm { + public String eventtime; + public String areaname; + public String alarmname; + public String netname; + public String alarmtype; + public String alarmlevel; + public String devicetype; + public String isportalarm; + public String 场馆id; + public String 区域id; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_4_maps_alarms.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_4_maps_alarms.java new file mode 100644 index 0000000..8d90518 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_4_maps_alarms.java @@ -0,0 +1,22 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_4_maps_alarms { //地图上显示告警图标, + public String areaname; + public String venueid; + public String venuetypeid; + public String venuetype; + public String venuename; + public float longitude; + public float latitude; + public int alarmcount; + public int loopcount; + public int devicecount; + public int hardwarecount; + public int powercount; + public List lists; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_5_scenecontacts.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_5_scenecontacts.java new file mode 100644 index 0000000..767c4c4 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_5_scenecontacts.java @@ -0,0 +1,17 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/7/17 + */ +@Data +public class class_dp_5_scenecontacts { + + public Long userid; + public String username; + public String nickname; + public String phonenumber; + public String venuename; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_5_scenesta.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_5_scenesta.java new file mode 100644 index 0000000..caa5e4d --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_5_scenesta.java @@ -0,0 +1,30 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/7/17 + */ +@Data +public class class_dp_5_scenesta { + + public int scenemanager; + public int sceneassistant; + public int faulthandle; + public int inspectuser; + public int emergencycommunicationcar; + public int emergencyelectriccar; + public int emergencyrepaircar; + public int emergencywarehouse; + public int wifispare; + public int dredgespare; + public int transspare; + public int wxuser; + public int csuser; + public int zwuser; + public int dhuser; + public int gluser; + public int bxuser; + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_alarm.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_alarm.java new file mode 100644 index 0000000..216eea7 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_alarm.java @@ -0,0 +1,13 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_6_dict_alarm { + public String addressname ; + public String alarmreason ; + public String createtime ; + public String exploreid ; + public String yyalarm ; + public String quxian ; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_alarm_monitor.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_alarm_monitor.java new file mode 100644 index 0000000..353df6e --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_alarm_monitor.java @@ -0,0 +1,11 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_6_dict_alarm_monitor { + public int total; + public List lists; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_kpi_monitor.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_kpi_monitor.java new file mode 100644 index 0000000..18acdce --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_kpi_monitor.java @@ -0,0 +1,14 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_6_dict_kpi_monitor { //监控类项目 + public int projecttotal; + public int pointtotal; + public int guzhangtotal; + public float avgonlinerate; + public List lists; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_link_alarm.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_link_alarm.java new file mode 100644 index 0000000..221470f --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_link_alarm.java @@ -0,0 +1,16 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_6_dict_link_alarm { + public String 告警时间; + public String 分公司; + public String 网元名称; + public String 端口; + public String 业务名称; + public String 专线名称; + public String 详细位置; + public String 告警名称; + public String 项目类型; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_links.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_links.java new file mode 100644 index 0000000..7fd04f9 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_links.java @@ -0,0 +1,13 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_6_dict_links { + public int zhizhengtotal ; + public int teqingtotal ; + public List zhizhenglists; + public List teqinglists; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_maps.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_maps.java new file mode 100644 index 0000000..bf17dd5 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_maps.java @@ -0,0 +1,14 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_6_dict_maps { + public String areaname ; + public float longitude ; + public float latitude ; + public int alarmcount; + public List lists; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_project.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_project.java new file mode 100644 index 0000000..d63ccf4 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_project.java @@ -0,0 +1,14 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_6_dict_project { + public String projectname ; + public int pointnumber ; + public int guzhangshuliang ; + public float onlinerate; + public String ict; + public String projectnum; + public String quxian; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_project_statis.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_project_statis.java new file mode 100644 index 0000000..92ff41b --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_6_dict_project_statis.java @@ -0,0 +1,11 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +@Data +public class class_dp_6_dict_project_statis { + public int projectnum; + public int pointnumber; + public int guzhangshuliang; + public float onlinerate; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_map_agis_dev_15mi.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_map_agis_dev_15mi.java new file mode 100644 index 0000000..e595594 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_map_agis_dev_15mi.java @@ -0,0 +1,20 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/8/15 + */ +@Data +public class class_dp_map_agis_dev_15mi { + + private Long venueid; + private String venuename; + public String statdate; + private float cpuratio; + private float ramratio; + private String code; + private String devicename; + private String devicetype; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_map_agis_link_5mi.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_map_agis_link_5mi.java new file mode 100644 index 0000000..6997f49 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_map_agis_link_5mi.java @@ -0,0 +1,21 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/8/15 + */ +@Data +public class class_dp_map_agis_link_5mi { + + private Long venueid; + public String statdate; + private float ulbandratio; + private float dlbandratio; + private float ulavg24hratio; + private float dlavg24hratio; + private String linkname; + private String linkvalue; + private String venuename; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_map_alarms.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_map_alarms.java new file mode 100644 index 0000000..218bf50 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/class_dp_map_alarms.java @@ -0,0 +1,22 @@ +package com.ruoyi.sunlm.daping; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/7/31 + */ +@Data +public class class_dp_map_alarms { + + private Long sceneid; + private String major; + private String netname; + private String alarmname; + private String eventtime; + private String handlepeople; + private String phonenumber; + //------------------------------ 保留字段 + private String reserved; + private String code; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewCommonDTO.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewCommonDTO.java new file mode 100644 index 0000000..566e4bb --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewCommonDTO.java @@ -0,0 +1,16 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import lombok.Data; + +@Data +public class NewCommonDTO { + + private Integer pageNum = 1; + + private Integer pageSize = 10; + + private NewPageDTO pageSizes; + + private NewPageDTO pageNums; + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewDpKpiMonitorQO.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewDpKpiMonitorQO.java new file mode 100644 index 0000000..1afd38c --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewDpKpiMonitorQO.java @@ -0,0 +1,59 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/17 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class NewDpKpiMonitorQO extends NewCommonDTO { + + @ApiModelProperty(value = "数据类型", required = true) + @NotBlank(message = "timetype不能为空") + private String datatype; + + @ApiModelProperty(value = "网络类型", required = true) + @NotBlank(message = "netType不能为空") + private String nettype; + + @ApiModelProperty(value = "场馆ids") + private Integer sceneid; + + @ApiModelProperty(value = "指标名称",required = true) + @NotBlank(message = "指标名称不能为空") + private String kpiname; + + + @ApiModelProperty(value = "开始时间") + @TableField("starttime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private LocalDateTime starttime; + + @ApiModelProperty(value = "结束时间") + @TableField("endtime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private LocalDateTime endtime; + + private String seatno; + + private String inorout; //added by sunlm 2023-07-18 + + @ApiModelProperty(value = "查询表方式,1-查询特定表") + private int sceneruntype; + + @ApiModelProperty(value = "最大时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + private LocalDateTime maxtime; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewDpSceneConfig.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewDpSceneConfig.java new file mode 100644 index 0000000..6143748 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewDpSceneConfig.java @@ -0,0 +1,74 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("dp_scene_config") +@ApiModel(value = "DpSceneConfig对象", description = "") +public class NewDpSceneConfig { + + private static final long serialVersionUID = 1L; + @ApiModelProperty("自增id") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("颜色等级") + @TableField("level") + private Short level; + + @ApiModelProperty("指标名称") + @TableField("name") + private String name; + + @ApiModelProperty("最小值") + @TableField("range1") + private Object range1; + + @ApiModelProperty("最大值") + @TableField("range2") + private Object range2; + + @ApiModelProperty("颜色") + @TableField("color") + private String color; + + @ApiModelProperty("备注") + @TableField("content") + private String content; + + @ApiModelProperty("指标等级:cell、scene") + @TableField("type") + private String type; + + @ApiModelProperty("网络类型") + @TableField("nettype") + private String nettype; + + @ApiModelProperty("小区设备") + @TableField("celltype") + private String celltype; + + @ApiModelProperty("颜色分值") + @TableField("colorscore") + private Double colorscore; + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewDpSceneConfigQO.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewDpSceneConfigQO.java new file mode 100644 index 0000000..ffb8018 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewDpSceneConfigQO.java @@ -0,0 +1,80 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.github.pagehelper.Page; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; + +import com.ruoyi.sunlm.daping.dp3d.*; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +/** + *

+ * QO + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class NewDpSceneConfigQO extends NewCommonDTO { + + + private static final long serialVersionUID = 1L; + @ApiModelProperty("自增id") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + + @ApiModelProperty("颜色等级") + @TableField("level") + private Short level; + + @ApiModelProperty("指标名称") + @TableField("name") + private String name; + + @ApiModelProperty("最小值") + @TableField("range1") + private Double range1; + + @ApiModelProperty("最大值") + @TableField("range2") + private Double range2; + + @ApiModelProperty("颜色") + @TableField("color") + private String color; + + @ApiModelProperty("备注") + @TableField("content") + private String content; + + + @ApiModelProperty("指标等级:cell、scene") + @TableField("type") + private String type; + + @ApiModelProperty("网络类型") + @TableField("nettype") + private String nettype; + + @ApiModelProperty("设备类型") + @TableField("celltype") + private String celltype; + + @ApiModelProperty("颜色分值") + @TableField("colorscore") + private Double colorscore; + + private BigDecimal value; + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewKpiConstants.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewKpiConstants.java new file mode 100644 index 0000000..a8d32d3 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewKpiConstants.java @@ -0,0 +1,45 @@ +package com.ruoyi.sunlm.daping.dp3d; + +/** + * @author yqf + * @date 2023/4/12 + */ +public class NewKpiConstants { + + public static final String YW_KPI_COLOR_DEFAULT = "#000000"; + + public static final String YW_NETTYPE_4G = "4G"; + + public static final String YW_FIELD_RPB_UP = "上行Prb利用率"; + public static final String YW_FIELD_RPB_DOWN = "下行Prb利用率"; + public static final String YW_FIELD_MAX_USER = "最大用户数"; + public static final String YW_FIELD_AVG_DIS = "平均干扰值"; + public static final String YW_FIELD_ALL = "综合算法"; + + public static final String YW_QUERY_ALL = "综合得分"; + + + public static final String YW_SORT_DESC = "desc"; + + public static final String YW_DATATYPE_15 = "15分钟"; + public static final String YW_DATATYPE_1 = "1分钟"; + + public static final int YW_MINTYPE_1 = 1; + + public static final String QUERYSEAT = "P"; + + public static final String FIELD_4G_GB = "上行流量mb"; + public static final String FIELD_4G_DISTURB = "上行平均干扰"; + public static final String FIELD_4G_MAXUSER = "最大用户数"; + public static final String FIELD_4G_PRBUP = "上行prb利用率"; + public static final String FIELD_4G_PRBDOWN = "下行prb利用率"; + + public static final String FIELD_5G_GB = "上行5g流量"; + public static final String FIELD_5G_DISTURB = "上行干扰值"; + public static final String FIELD_5G_MAXUSER = "最大用户数"; + public static final String FIELD_5G_PRBUP = "上行prb利用率"; + public static final String FIELD_5G_PRBDOWN = "下行prb利用率"; + + public static final String ORDER_DESC = "DESC"; + public static final String ORDER_ASC = "ASC"; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewMonitorCellVo.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewMonitorCellVo.java new file mode 100644 index 0000000..98e9256 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewMonitorCellVo.java @@ -0,0 +1,79 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author yqf + * @date 2023/4/13 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("MonitorCellVo实体类") //坐席 +public class NewMonitorCellVo { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "排序") + private Integer orderid; + + @ApiModelProperty(value = "数据类型") + private String datatype; + + @ApiModelProperty(value = "网络类型") + private String nettype; + + @TableField("venue_id") + private Integer venueid; + + @ApiModelProperty(value = "场馆名称") + @TableField("venue_name") + private String venuename; + + @ApiModelProperty(value = "坐席编号") + private String seatid; + + //---------------------------------------------added sunlm 2023-09-04 + @ApiModelProperty(value = "坐席中文名") + private String seatname; + + @ApiModelProperty(value = "一键优化") + private int onekey; + //------------------------------------------------------------------- + + @ApiModelProperty(value = "坐席颜色") + private String color; + + @ApiModelProperty(value = "坐席得分") + private Float score; + + @ApiModelProperty(value = "指标名") + private String kpiname; + + @ApiModelProperty(value = "小区类型") + private String celltype; + + @ApiModelProperty(value = "基站编号") + private Long stationno; + + @ApiModelProperty(value = "基站全称") + private String pointname; + + @ApiModelProperty(value = "坐席编号") + private String pointid; + + @ApiModelProperty(value = "经度") + private Double longitude; + + @ApiModelProperty(value = "纬度") + private Double latitude; + + private List celllist; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPageDTO.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPageDTO.java new file mode 100644 index 0000000..75229f1 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPageDTO.java @@ -0,0 +1,16 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import lombok.Data; + +@Data +public class NewPageDTO { + + private Integer cs; + + private Integer dh; + + private Integer agis; + + private Integer wx; + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi15CellMonitorVO.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi15CellMonitorVO.java new file mode 100644 index 0000000..2a9b829 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi15CellMonitorVO.java @@ -0,0 +1,109 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("PmKpi15CellMonitorVO实体类") //坐席的小区 +public class NewPmKpi15CellMonitorVO { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "网络类型") + private String nettype; + + @TableField("venue_id") + private Integer venueid; + + @Excel(name = "场馆名称",width = 20) + @ApiModelProperty(value = "场馆名称") + @TableField("venue_name") + private String venuename; + + @Excel(name = "坐席编号",width = 20) + @ApiModelProperty(value = "坐席编号") + private String 坐席编号; + + @TableField("cellcodeci") + private String cellcodeci; + + @Excel(name = "开始时间",width = 20,dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField("starttime") + private LocalDateTime starttime; + + @Excel(name = "场馆名称",width = 20) + @TableField("小区名称") + @ApiModelProperty(value = "小区名称") + private String 小区名称; + + @Excel(name = "最大用户数",width = 20) + @ApiModelProperty(value = "最大用户数") + @TableField("最大用户数") + private NewPmKpiVO 最大用户数; + + @Excel(name = "上行prb利用率",width = 20) + @ApiModelProperty(value = "上行prb利用率") + @TableField("上行prb利用率") + private NewPmKpiVO 上行prb利用率; + + @Excel(name = "下行prb利用率",width = 20) + @ApiModelProperty(value = "下行prb利用率") + @TableField("下行prb利用率") + private NewPmKpiVO 下行prb利用率; + + @Excel(name = "上行平均干扰",width = 20) + @ApiModelProperty(value = "上行平均干扰") + @TableField("上行平均干扰") + private NewPmKpiVO 上行平均干扰; + + @Excel(name = "结束时间",width = 20,dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "结束时间") + @TableField("endtime") + private LocalDateTime endtime; + + @ApiModelProperty(value = "综合得分") + private NewPmKpiVO 综合得分; + + + + @ApiModelProperty(value = "基站编号") + private Long stationno; + + @ApiModelProperty(value = "基站全称") + private String pointname; + + @ApiModelProperty(value = "坐席编号") + private String pointid; + + @ApiModelProperty(value = "经度") + private Double longitude; + + @ApiModelProperty(value = "纬度") + private Double latitude; + + @ApiModelProperty(value = "小区频段") + private String 小区频段; + + @ApiModelProperty(value = "设备类型") + private String 设备类型; + + @ApiModelProperty(value = "带宽") + private Long 带宽; + + @ApiModelProperty(value = "方位角") + private Long 方位角; + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi4gCell.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi4gCell.java new file mode 100644 index 0000000..2d0757b --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi4gCell.java @@ -0,0 +1,200 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 场馆4G小区级15分钟指标 + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("pm_kpi4g_cell") +@ApiModel(value = "PmKpi4gCell对象", description = "场馆4G小区级15分钟指标") +public class NewPmKpi4gCell { + + private static final long serialVersionUID = 1L; +// @ApiModelProperty("id") +// @TableField("id") +// private Long id; + + @TableField("venue_id") + private Integer venueId; + + @TableField("venue_name") + private String venueName; + + @TableField("cellcodeci") + private String cellcodeci; + + @TableField("starttime") + private LocalDateTime starttime; + + @TableField("input_datetime") + private LocalDateTime inputDatetime; + + @TableField("小区名称") + private String 小区名称; + + @TableField("上行流量mb") + private BigDecimal 上行流量mb; + + @TableField("下行流量mb") + private BigDecimal 下行流量mb; + + @TableField("有效rrc连接平均数") + private BigDecimal 有效rrc连接平均数; + + @TableField("有效rrc连接最大数") + private BigDecimal 有效rrc连接最大数; + + @TableField("平均用户数") + private BigDecimal 平均用户数; + + @TableField("最大用户数") + private BigDecimal 最大用户数; + + @TableField("volte话务量") + private BigDecimal volte话务量; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率; + + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率; + + @TableField("上行平均干扰") + private BigDecimal 上行平均干扰; + + @TableField("rrc建立成功率") + private BigDecimal rrc建立成功率; + + @TableField("e_rab建立成功率") + private BigDecimal eRab建立成功率; + + @TableField("qci为1的e_rab建立成功率") + private BigDecimal qci为1的eRab建立成功率; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率; + + @TableField("掉线次数") + private BigDecimal 掉线次数; + + @TableField("切换成功率") + private BigDecimal 切换成功率; + + @TableField("esrvcc切换成功率") + private BigDecimal esrvcc切换成功率; + + @TableField("esrvcc切换请求次数") + private BigDecimal esrvcc切换请求次数; + + @TableField("rrc重建成功率") + private BigDecimal rrc重建成功率; + + @TableField("rrc重建次数") + private BigDecimal rrc重建次数; + + @TableField("volte掉话率") + private BigDecimal volte掉话率; + + @TableField("volte掉话次数") + private BigDecimal volte掉话次数; + + @TableField("rru_puschprbassn") + private BigDecimal rruPuschprbassn; + + @TableField("rru_puschprbtot") + private BigDecimal rruPuschprbtot; + + @TableField("rru_pdschprbassn") + private BigDecimal rruPdschprbassn; + + @TableField("rru_pdschprbtot") + private BigDecimal rruPdschprbtot; + + @TableField("rrc_succconnestab") + private BigDecimal rrcSuccconnestab; + + @TableField("rrc_attconnestab") + private BigDecimal rrcAttconnestab; + + @TableField("erab_nbrsuccestab_1") + private BigDecimal erabNbrsuccestab1; + + @TableField("erab_nbrattestab") + private BigDecimal erabNbrattestab; + + @TableField("erab_nbrattestab_1") + private BigDecimal erabNbrattestab1; + + @TableField("切换成功率_分母") + private BigDecimal 切换成功率分母; + + @TableField("切换成功率_分子") + private BigDecimal 切换成功率分子; + + @TableField("掉线率_分母") + private BigDecimal 掉线率分母; + + @TableField("iratho_succoutgeran") + private BigDecimal irathoSuccoutgeran; + + @TableField("rrc_attconnreestab") + private BigDecimal rrcAttconnreestab; + + @TableField("volte掉话率_分母") + private BigDecimal volte掉话率分母; + + @TableField("erab_nbrsuccestab") + private BigDecimal erabNbrsuccestab; + + @TableField("omcname") + private String omcname; + + @TableField("无线接通率") + private BigDecimal 无线接通率; + + @TableField("rrc_failconnestab") + private BigDecimal rrcFailconnestab; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("groupid") + private Long groupid; + + @TableField("endtime") + private LocalDateTime endtime; + + ///////////////////////////////// + @TableField(exist = false) + private Integer orderId; + + @TableField(exist = false) + private String 坐席编号; + + @TableField(exist = false) + private String 小区频段; + + @TableField(exist = false) + private String 设备类型; + + @TableField(exist = false) + private Long 带宽; + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi4gMin.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi4gMin.java new file mode 100644 index 0000000..58386c0 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi4gMin.java @@ -0,0 +1,126 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 场馆4G小区级1分钟指标 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("pm_kpi4g_min") +@ApiModel(value = "PmKpi4gMin对象", description = "场馆4G小区级1分钟指标") +public class NewPmKpi4gMin { + + private static final long serialVersionUID = 1L; + + @TableField("groupid") + private Integer groupid; + + @TableField("时间") + private LocalDateTime 时间; + + @TableField("小区名称") + private String 小区名称; + + @TableField("地市区号") + private String 地市区号; + + @TableField("厂商id") + private String 厂商id; + + @TableField("avg_user") + private BigDecimal avgUser; + + @TableField("max_user") + private Integer maxUser; + + @TableField("prb_up") + private BigDecimal prbUp; + + @TableField("prb_down") + private BigDecimal prbDown; + + @TableField("avg_disturb") + private Integer avgDisturb; + + @TableField("speed_up") + private BigDecimal speedUp; + + @TableField("speed_down") + private BigDecimal speedDown; + + @TableField("call_succ_rate") + private BigDecimal callSuccRate; + + @TableField("call_drop_rate") + private BigDecimal callDropRate; + + @TableField("act_avg_user") + private BigDecimal actAvgUser; + + @TableField("act_max_user") + private Integer actMaxUser; + + @TableField("volte") + private BigDecimal volte; + + @TableField("volte_succ_rate") + private BigDecimal volteSuccRate; + + @TableField("volte_drop_rate") + private BigDecimal volteDropRate; + + @TableField("data_up") + private BigDecimal dataUp; + + @TableField("data_down") + private BigDecimal dataDown; + + @TableField("v1_max") + private BigDecimal v1Max; + + @TableField("v1_avg") + private String v1Avg; + + @TableField("update_time") + private LocalDateTime updateTime; + + ///////////////////////////////// + @TableField(exist = false) + private Integer orderId; + + @TableField(exist = false) + private String venueName; + + @TableField(exist = false) + private String venueId; + + @TableField(exist = false) + private String cellcodeci; + + @TableField(exist = false) + private String 小区频段; + + @TableField(exist = false) + private String 设备类型; + + @TableField(exist = false) + private Long 带宽; + + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi5gCell.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi5gCell.java new file mode 100644 index 0000000..0cc725d --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi5gCell.java @@ -0,0 +1,183 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 场馆5G小区级15分钟指标 + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("pm_kpi5g_cell") +@ApiModel(value = "PmKpi5gCell对象", description = "场馆5G小区级15分钟指标") +public class NewPmKpi5gCell { + + private static final long serialVersionUID = 1L; +// @ApiModelProperty("id") +// @TableField("id") +// private Long id; + + @TableField("venue_id") + private Integer venueId; + + @TableField("venue_name") + private String venueName; + + @TableField("ci") + private String ci; + + @TableField("starttime") + private LocalDateTime starttime; + + @TableField("小区名称") + private String 小区名称; + + @TableField("nr流量") + private BigDecimal nr流量; + + @TableField("上行5g流量") + private BigDecimal 上行5g流量; + + @TableField("下行5g流量") + private BigDecimal 下行5g流量; + + @TableField("小区rlc层下行丢包率") + private BigDecimal 小区rlc层下行丢包率; + + @TableField("小区级rlc层sdu下行空口丢包数") + private BigDecimal 小区级rlc层sdu下行空口丢包数; + + @TableField("小区rlc层收到的下行sdu包数") + private BigDecimal 小区rlc层收到的下行sdu包数; + + @TableField("平均用户数") + private BigDecimal 平均用户数; + + @TableField("最大用户数") + private BigDecimal 最大用户数; + + @TableField("sn异常释放率") + private BigDecimal sn异常释放率; + + @TableField("sgnb释放总次数") + private BigDecimal sgnb释放总次数; + + @TableField("sgnb触发sgnb异常释放总次数") + private BigDecimal sgnb触发sgnb异常释放总次数; + + @TableField("nsa_sgnb添加成功率") + private BigDecimal nsaSgnb添加成功率; + + @TableField("dc场景下发送sgnb增加成功的次数") + private BigDecimal dc场景下发送sgnb增加成功的次数; + + @TableField("dc场景下收到sgnb增加尝试的次数") + private BigDecimal dc场景下收到sgnb增加尝试的次数; + + @TableField("无线接通率") + private BigDecimal 无线接通率; + + @TableField("rrc建立成功次数") + private BigDecimal rrc建立成功次数; + + @TableField("rrc建立请求消息次数") + private BigDecimal rrc建立请求消息次数; + + @TableField("小区中qos_flow建立成功次数") + private BigDecimal 小区中qosFlow建立成功次数; + + @TableField("小区中qos_flow建立尝试次数") + private BigDecimal 小区中qosFlow建立尝试次数; + + @TableField("小区中ng信令连接建立成功次数") + private BigDecimal 小区中ng信令连接建立成功次数; + + @TableField("小区中ng信令连接建立尝试次数") + private BigDecimal 小区中ng信令连接建立尝试次数; + + @TableField("无线掉线率") + private BigDecimal 无线掉线率; + + @TableField("小区中ue上下文异常释放的次数") + private BigDecimal 小区中ue上下文异常释放的次数; + + @TableField("小区中ue上下文正常释放的次数") + private BigDecimal 小区中ue上下文正常释放的次数; + + @TableField("无线掉线率分母") + private BigDecimal 无线掉线率分母; + + @TableField("切换成功率") + private BigDecimal 切换成功率; + + @TableField("切换成功率分子") + private BigDecimal 切换成功率分子; + + @TableField("切换成功率分母") + private BigDecimal 切换成功率分母; + + @TableField("下行平均使用的prb个数") + private BigDecimal 下行平均使用的prb个数; + + @TableField("下行平均可用prb个数") + private BigDecimal 下行平均可用prb个数; + + @TableField("上行平均使用的prb个数") + private BigDecimal 上行平均使用的prb个数; + + @TableField("上行平均可用prb个数") + private BigDecimal 上行平均可用prb个数; + + @TableField("上行prb利用率") + private BigDecimal 上行prb利用率; + + @TableField("下行prb利用率") + private BigDecimal 下行prb利用率; + + @TableField("input_datetime") + private LocalDateTime inputDatetime; + + @TableField("cell_name") + private String cellName; + + @TableField("pmsid") + private Long pmsid; + + @TableField("上行干扰值") + private Double 上行干扰值; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableField("endtime") + private LocalDateTime endtime; + + + ///////////////////////////////// + @TableField(exist = false) + private Integer orderId; + + @TableField(exist = false) + private String 小区频段; + + @TableField(exist = false) + private String 设备类型; + + @TableField(exist = false) + private Long 带宽; + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi5gMin.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi5gMin.java new file mode 100644 index 0000000..f82a19b --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpi5gMin.java @@ -0,0 +1,109 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 场馆5G小区级1分钟指标 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("pm_kpi5g_min") +@ApiModel(value = "PmKpi5gMin对象", description = "场馆5G小区级1分钟指标") +public class NewPmKpi5gMin { + + private static final long serialVersionUID = 1L; + + @TableField("groupid") + private Integer groupid; + + @TableField("时间") + private LocalDateTime 时间; + + @TableField("小区名称") + private String 小区名称; + + @TableField("地市区号") + private String 地市区号; + + @TableField("厂商id") + private String 厂商id; + + @TableField("prb_up") + private Double prbUp; + + @TableField("prb_down") + private Double prbDown; + + @TableField("up_disturb") + private Integer upDisturb; + + @TableField("speed_up") + private Double speedUp; + + @TableField("speed_down") + private Double speedDown; + + @TableField("act_max_user") + private Integer actMaxUser; + + @TableField("act_avg_user") + private Double actAvgUser; + + @TableField("rrc_avg_user") + private BigDecimal rrcAvgUser; + + @TableField("rrc_max_user") + private Integer rrcMaxUser; + + @TableField("call_succ_rate") + private BigDecimal callSuccRate; + + @TableField("drop_call_rate") + private BigDecimal dropCallRate; + + @TableField("data_down") + private BigDecimal dataDown; + + @TableField("data_up") + private BigDecimal dataUp; + + @TableField("update_time") + private LocalDateTime updateTime; + + ///////////////////////////////// + @TableField(exist = false) + private Integer orderId; + + @TableField(exist = false) + private String venueName; + + @TableField(exist = false) + private String venueId; + + @TableField(exist = false) + private String cellcodeci; + + @TableField(exist = false) + private String 小区频段; + + @TableField(exist = false) + private String 设备类型; + + @TableField(exist = false) + private Long 带宽; + + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiCellMonitorQO.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiCellMonitorQO.java new file mode 100644 index 0000000..7f81412 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiCellMonitorQO.java @@ -0,0 +1,92 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.sunlm.daping.dp3d.*; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class NewPmKpiCellMonitorQO extends NewCommonDTO { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "数据类型", required = true) + @NotBlank(message = "timetype不能为空") + private String datatype; + + @ApiModelProperty(value = "网络类型", required = true) + @NotBlank(message = "netType不能为空") + private String nettype; + + @ApiModelProperty(value = "区县id") + private String regionid; + + @ApiModelProperty(value = "区县id") + private String regionIdv; + + @ApiModelProperty(value = "场馆ids") + private Integer[] sceneids; + + @ApiModelProperty(value = "场馆id") + private Integer sceneid; + + @ApiModelProperty(value = "小区id(多选)") + @TableField("小区id") + private String[] villageids; + + @ApiModelProperty(value = "小区名称(多选)") + @TableField("小区名称") + private String[] villagenames; + + @ApiModelProperty(value = "开始时间", required = true) + @TableField("starttime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @NotNull(message = "starttime不能为空") + private LocalDateTime starttime; + + @ApiModelProperty(value = "结束时间", required = true) + @TableField("endtime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @NotNull(message = "endtime不能为空") + private LocalDateTime endtime; + + @ApiModelProperty(value = "排序字段名") + @NotBlank(message = "排序字段名不能为空") + private String sortcol; + + @ApiModelProperty(value = "排序") + @NotBlank(message = "排序不能为空") + private String sort; + + @ApiModelProperty(value = "坐席区(多选)") + private String[] seat; + + @ApiModelProperty(value = "坐席区颜色") + private String seatcolor; + + @ApiModelProperty(value = "指标名称") + @NotBlank(message = "指标名称不能为空") + private String kpiname; + + @ApiModelProperty(value = "是否为缓存查询(是:true)",required = true) + @NotNull(message = "isCache参数不能为空") + private Boolean iscache; + + private String seatno; + + private String inorout; ///add by sunlm 2023-07-18 + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiCellQO.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiCellQO.java new file mode 100644 index 0000000..303bdc6 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiCellQO.java @@ -0,0 +1,82 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.baomidou.mybatisplus.annotation.TableField; + +import java.time.LocalDateTime; + +import com.ruoyi.sunlm.daping.dp3d.*; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; +import reactor.util.annotation.NonNull; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + *

+ * 场馆4G小区级15分钟指标QO + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class NewPmKpiCellQO extends NewCommonDTO { + + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "网络类型:0-4G,1-5G", required = true) + @NotBlank(message = "netType不能为空") + private String netType; + + @ApiModelProperty(value = "区县id") + private String regionId; + + @ApiModelProperty(value = "区县id") + private String regionIdv; + + @ApiModelProperty(value = "场馆ids") + private Integer[] venueIds; + + @ApiModelProperty(value = "场馆id") + private Integer venueid; + + + @ApiModelProperty(value = "小区id(多选)") + @TableField("小区id") + private String[] villageIds; + + @ApiModelProperty(value = "小区名称(多选)") + @TableField("小区名称") + private String[] villageNames; + + @ApiModelProperty(value = "开始时间", required = true) + @TableField("starttime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @NotNull(message = "starttime不能为空") + private LocalDateTime starttime; + + @ApiModelProperty(value = "结束时间", required = true) + @TableField("endtime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @NotNull(message = "endtime不能为空") + private LocalDateTime endtime; + + @ApiModelProperty(value = "排序字段名") + @NotBlank(message = "排序字段名不能为空") + private String sortcol; + + @ApiModelProperty(value = "排序") + @NotBlank(message = "排序不能为空") + private String sort; + + private LocalDateTime querystarttime; + + private Integer queryvenueid; + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiColorQo.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiColorQo.java new file mode 100644 index 0000000..68857fa --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiColorQo.java @@ -0,0 +1,44 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * @author yqf + * @date 2023/4/26 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class NewPmKpiColorQo { + + + @ApiModelProperty(value = "网络类型") + private String nettype; + + @ApiModelProperty("最大用户数值") + private BigDecimal maxuservalue; + + @ApiModelProperty("上行prb利用率值") + private BigDecimal prbupvalue; + + @ApiModelProperty("下行prb利用率值") + private BigDecimal prbdownvalue; + + @ApiModelProperty("上行平均干扰值") + private BigDecimal avgdisvalue; + + @ApiModelProperty("小区频段") + private String freqtype; + + @ApiModelProperty("设备类型") + private String devicetype; + + @ApiModelProperty("带宽") + private Long bandwidth; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiMinQO.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiMinQO.java new file mode 100644 index 0000000..0c53d89 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiMinQO.java @@ -0,0 +1,70 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.sunlm.daping.dp3d.*; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class NewPmKpiMinQO extends NewCommonDTO { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "网络类型:0-4G,1-5G", required = true) + @NotBlank(message = "netType不能为空") + private String netType; + + @ApiModelProperty(value = "区县id") + private String regionId; + + @ApiModelProperty(value = "区县id") + private String regionIdv; + + @ApiModelProperty(value = "场馆ids") + private Integer[] venueIds; + + @ApiModelProperty(value = "场馆id") + private Integer venueid; + + @ApiModelProperty(value = "小区id(多选)") + @TableField("小区id") + private String[] villageIds; + + @ApiModelProperty(value = "小区名称(多选)") + @TableField("小区名称") + private String[] villageNames; + + @ApiModelProperty(value = "开始时间", required = true) + @TableField("starttime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @NotNull(message = "starttime不能为空") + private LocalDateTime starttime; + + @ApiModelProperty(value = "结束时间", required = true) + @TableField("endtime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @NotNull(message = "endtime不能为空") + private LocalDateTime endtime; + + @ApiModelProperty(value = "排序字段名") + @NotBlank(message = "排序字段名不能为空") + private String sortcol; + + @ApiModelProperty(value = "排序") + @NotBlank(message = "排序不能为空") + private String sort; + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiMonitorEntity.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiMonitorEntity.java new file mode 100644 index 0000000..8a05ab1 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiMonitorEntity.java @@ -0,0 +1,81 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/17 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "PmKpiMonitorEntity对象", description = "场馆4G小区级1分钟指标") +public class NewPmKpiMonitorEntity { + + private static final long serialVersionUID = 1L; + private Long id; + + private Integer venueid; + + private String venuename; + + private String cellcodeci; + + private LocalDateTime starttime; + + private String 小区名称; + + private BigDecimal 平均用户数; + + private BigDecimal 最大用户数; + + private BigDecimal 上行prb利用率; + + private BigDecimal 下行prb利用率; + + private BigDecimal 上行平均干扰; + + private BigDecimal 无线掉线率; + + private BigDecimal 无线接通率; + + private LocalDateTime endtime; + + private Integer orderId; + + private String 坐席编号; + + private LocalDateTime 时间; + + private Long stationno; + private String pointname; + private String pointid; + private Double longitude; + private Double latitude; + + private String maxuserColor; + private String prbupColor; + private String prbdownColor; + private String avgdisColor; + private Integer maxuserScore; + private Integer prbupScore; + private Integer prbdownScore; + private Integer avgdisScore; + + //----------------------------added by sunlm 2023 .07-25 + private Integer 综合得分值; //后续用于保存 value = maxuserScore+prbupScore+prbdownScore, 目前用于保存 score + private Integer 综合得分score; //后续增加这个字段,保存score + private String 综合得分颜色; + //------------------------------------------------------ + + private String 小区频段; + private String 设备类型; + private Long 带宽; + private Long 方位角; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiVO.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiVO.java new file mode 100644 index 0000000..c8600e4 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewPmKpiVO.java @@ -0,0 +1,52 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.List; + +/** + * @author yqf + * @date 2023/4/11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class NewPmKpiVO { + + @ApiModelProperty(value = "数值") + private BigDecimal value; + + @ApiModelProperty(value = "最大数值") + private BigDecimal maxvalue; + + @ApiModelProperty(value = "颜色") + private String color; + + @ApiModelProperty(value = "分数") + private float score; + + @ApiModelProperty(value = "data") + private List data; + + public NewPmKpiVO(BigDecimal maxvalue, String color) { + this.maxvalue = maxvalue; + this.color = color; + } + + public NewPmKpiVO(BigDecimal value, BigDecimal maxvalue, String color) { + this.value = value; + this.maxvalue = maxvalue; + this.color = color; + } + + public NewPmKpiVO(String color) { + this.color = color; + } + + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewRecordVo.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewRecordVo.java new file mode 100644 index 0000000..bbf6d84 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/daping/dp3d/NewRecordVo.java @@ -0,0 +1,27 @@ +package com.ruoyi.sunlm.daping.dp3d; + +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * @author yqf + * @date 2023/4/11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class NewRecordVo { + + private LocalDateTime time; + + private BigDecimal prbupcount; + private BigDecimal prbdowncount; + private BigDecimal maxusercount; + private BigDecimal avgdisturbcount; + private BigDecimal gbcount; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_btsinfo.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_btsinfo.java new file mode 100644 index 0000000..a2c1946 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_btsinfo.java @@ -0,0 +1,36 @@ +package com.ruoyi.sunlm.domain; + +import lombok.Data; + + + +/* { + "CI": "201692524", + "NAME": "H11665755-萧山奥体游泳馆-H5X", + "NAME2": "H417816-萧山奥体游泳馆-HFX-D902-奥体游泳馆体育馆移动小微站2LY-108CA68", + "TYPE": null, + "LONGTITUDE": "30.236615", + "LATITUDE": "120.228811", + "DIRECTION": "340", + "GD_LONG": "120.233309", + "GD_LAT": "30.234167", + "VALUE": "8" } +* */ +@Data +public class class_dp_btsinfo { + public String ci; + public String name; + public String name2; + public String type; + public String longitude; + public String latitude; + public String direction; + public String gdLong; + public String gdLat; + public String algoValue; + public String avgUsrValue; + public String uplnkPrbvalue; + public String downlnkPrbvalue; + public String level; + public String cellType; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_compare.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_compare.java new file mode 100644 index 0000000..69b2cc2 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_compare.java @@ -0,0 +1,10 @@ +package com.ruoyi.sunlm.domain; + +import lombok.Data; + +@Data +public class class_dp_compare { + public String datetime; + public float value; + public int sign; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_left_1.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_left_1.java new file mode 100644 index 0000000..87b98e4 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_left_1.java @@ -0,0 +1,47 @@ +package com.ruoyi.sunlm.domain; + +import lombok.Data; + +import java.util.List; + +/* + { +    "label": [ +        "昨天(2023年04月6日)", +        "今天(2023年04月7日)" +    ], +    "xAxis": [ +        "1时", +        "2时", +        "3时", +        "4时", +        "5时" +    ], +    "value": [ +        600, +        800, +        580, +        400, +        880, +        580, +        630 +    ], +    "value2": [ +        420, +        405, +        780, +        630, +        600, +        900, +        570 +    ] +} +* */ +@Data +public class class_dp_left_1 { //大屏左侧1 + public List label; + public List xaxis; + public List value; + public List value2; +} + diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_left_2.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_left_2.java new file mode 100644 index 0000000..ca38d96 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_left_2.java @@ -0,0 +1,45 @@ +package com.ruoyi.sunlm.domain; + +import lombok.Data; + +import java.util.List; +/* + { +    "label": [ +        "昨天(2023年04月6日)", +        "今天(2023年04月7日)" +    ], +    "xAxis": [ +        "1时", +        "2时", +        "3时", +        "4时", +        "5时" +    ], +    "value": [ +        600, +        800, +        580, +        400, +        880, +        580, +        630 +    ], +    "value2": [ +        420, +        405, +        780, +        630, +        600, +        900, +        570 +    ] +} +* */ +@Data +public class class_dp_left_2 { + public List label; + public List xaxis; + public List value; + public List value2; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_maps.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_maps.java new file mode 100644 index 0000000..122a83e --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_maps.java @@ -0,0 +1,34 @@ +package com.ruoyi.sunlm.domain; + +import lombok.Data; + +import java.util.List; + +@Data + +/* +* { + "name":'杭州奥体中心', + “center”: “120,30” + "data":[ + { + "CI": "201692524", + "NAME": "H11665755-萧山奥体游泳馆-H5X", + "NAME2": "H417816-萧山奥体游泳馆-HFX-D902-奥体游泳馆体育馆移动小微站2LY-108CA68", + "TYPE": null, + "LONGTITUDE": "30.236615", + "LATITUDE": "120.228811", + "DIRECTION": "340", + "GD_LONG": "120.233309", + "GD_LAT": "30.234167", + "VALUE": "8" + }, + ...... + } +* */ + +public class class_dp_maps { + public String name; + public String center; + public List data; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_maps_topinfo.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_maps_topinfo.java new file mode 100644 index 0000000..8a2db46 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_maps_topinfo.java @@ -0,0 +1,71 @@ +package com.ruoyi.sunlm.domain; + +/* +* { +    "red": 123, +    "orange": 123, +    "yellow": 123, +    "green": 123 +} +* */ + +/* +* { + "name":'杭州奥体中心', + “center”: “120,30” + "data":[ + { + "CI": "201692524", + "NAME": "H11665755-萧山奥体游泳馆-H5X", + "NAME2": "H417816-萧山奥体游泳馆-HFX-D902-奥体游泳馆体育馆移动小微站2LY-108CA68", + "TYPE": null, + "LONGTITUDE": "30.236615", + "LATITUDE": "120.228811", + "DIRECTION": "340", + "GD_LONG": "120.233309", + "GD_LAT": "30.234167", + "VALUE": "8" + }, + ...... + } +* */ + +//------------------------------合二为一 +/* +{ + "red": 123, +    "orange": 123, +    "yellow": 123, +    "green": 123, + "name":'杭州奥体中心', + “center”: “120,30” + "data":[ + { + "CI": "201692524", + "NAME": "H11665755-萧山奥体游泳馆-H5X", + "NAME2": "H417816-萧山奥体游泳馆-HFX-D902-奥体游泳馆体育馆移动小微站2LY-108CA68", + "TYPE": null, + "LONGTITUDE": "30.236615", + "LATITUDE": "120.228811", + "DIRECTION": "340", + "GD_LONG": "120.233309", + "GD_LAT": "30.234167", + "VALUE": "8" + }, + ...... + } +*/ + + +import lombok.Data; + +import java.util.List; + +@Data +public class class_dp_maps_topinfo { + public class_dp_topinfo total; + public String name; + public String center; + public List data; + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scene_control.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scene_control.java new file mode 100644 index 0000000..e200b19 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scene_control.java @@ -0,0 +1,14 @@ +package com.ruoyi.sunlm.domain; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/4/17 + */ +@Data +public class class_dp_scene_control { + private int mintype; + private String nettype; + private String kpiname; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scene_seat_detail.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scene_seat_detail.java new file mode 100644 index 0000000..e10d587 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scene_seat_detail.java @@ -0,0 +1,13 @@ +package com.ruoyi.sunlm.domain; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/4/17 + */ +@Data +public class class_dp_scene_seat_detail { + public String seatid; + public int seatnumber; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scene_seat_info.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scene_seat_info.java new file mode 100644 index 0000000..5a55bd6 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scene_seat_info.java @@ -0,0 +1,14 @@ +package com.ruoyi.sunlm.domain; + +import lombok.Data; + +/** + * @author yqf + * @date 2023/4/17 + */ +@Data +public class class_dp_scene_seat_info { + public Integer length; + public Integer width; + public Integer angle; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scenelist.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scenelist.java new file mode 100644 index 0000000..9a6aa9c --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_scenelist.java @@ -0,0 +1,9 @@ +package com.ruoyi.sunlm.domain; + +import lombok.Data; + +@Data +public class class_dp_scenelist { + public int venueId; + public String venueName; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_top5.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_top5.java new file mode 100644 index 0000000..5333b57 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_top5.java @@ -0,0 +1,41 @@ +package com.ruoyi.sunlm.domain; + +import lombok.Data; + +/** + * [ + *     { + *         "title": "1", + *         "name": "H517599-杭州萧山奥邸国际写字楼区电梯地下室-HLW-F601-地下室SF-1", + *         "value": 20.8 + *     }, + *     { + *         "title": "2", + *         "name": "萧山石岩老街西FDD1800_66", + *         "value": 19.15 + *     }, + *     { + *         "title": "3", + *         "name": "H518207-萧山亚运村运动员一村D区-HLH-FD18102-亚运村运动员一村D02LY-8", + *         "value": 16.517 + *     }, + *     { + *         "title": "4", + *         "name": "H417875-萧山奥体博览中心-HFX-FD18901-奥体博览中心移动小微站11LY-65", + *         "value": 13.583 + *     }, + *     { + *         "title": "5", + *         "name": "萧山宝盛大厦CRAN利二路博奥路口3DMIMO_196", + *         "value": 11.367 + *     } + * ] + * */ + +@Data +public class class_dp_top5 { + public int title; + public String name; + public Float value; + public String color; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_topinfo.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_topinfo.java new file mode 100644 index 0000000..2d89880 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_dp_topinfo.java @@ -0,0 +1,19 @@ +package com.ruoyi.sunlm.domain; + +import lombok.Data; + +/* +* { +    "red": 123, +    "orange": 123, +    "yellow": 123, +    "green": 123 +} +* */ +@Data +public class class_dp_topinfo { + public int red; + public int orange; + public int yellow; + public int green; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_medal_stand.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_medal_stand.java new file mode 100644 index 0000000..1e9f31c --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_medal_stand.java @@ -0,0 +1,43 @@ +package com.ruoyi.sunlm.domain; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +@Data +public class class_medal_stand { + public int id; + + @Excel(name = "国家或地区", cellType = Excel.ColumnType.STRING, prompt = "国家或地区") + public String areaName; + + @Excel(name = "金牌", cellType = Excel.ColumnType.STRING, prompt = "金牌数") + public int goldCount; + + @Excel(name = "银牌", cellType = Excel.ColumnType.STRING, prompt = "银牌数") + public int silverCount; + + @Excel(name = "铜牌", cellType = Excel.ColumnType.STRING, prompt = "铜牌数") + public int bronzeCount; + + @Excel(name = "奖牌数", cellType = Excel.ColumnType.STRING) + public int medalsCount; + + //@Excel(name = "更新人", cellType = Excel.ColumnType.STRING, prompt = "更新人") + public String updateBy; + + @Excel(name = "更新人", cellType = Excel.ColumnType.STRING) + public String updateByName; + + @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Excel.Type.EXPORT, prompt = "更新时间") + public Date updateTime; + + public int medalSort; + + public int sceneBigId; + + @Excel(name = "场景", cellType = Excel.ColumnType.STRING, prompt = "场景") + public String sceneBigName; + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_public_news.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_public_news.java new file mode 100644 index 0000000..cbbe3e8 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_public_news.java @@ -0,0 +1,33 @@ +package com.ruoyi.sunlm.domain; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +@Data +public class class_public_news { + public int id; + + @Excel(name = "标题", cellType = Excel.ColumnType.STRING,sort=1) + public String title; + + @Excel(name = "内容链接", cellType = Excel.ColumnType.STRING,sort=3) + public String contentUrl; + + @Excel(name = "内容", cellType = Excel.ColumnType.STRING,sort=2) + public String content; + + //@Excel(name = "更新人", cellType = Excel.ColumnType.STRING, prompt = "更新人") + public String updateBy; + + @Excel(name = "更新人", cellType = Excel.ColumnType.STRING,sort=4) + public String updateByName; + + @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Excel.Type.EXPORT,sort=5) + public Date updateTime; + + //@Excel(name = "场景", cellType = Excel.ColumnType.STRING, prompt = "场景") + public int sceneBigId; + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_big_config.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_big_config.java new file mode 100644 index 0000000..5d1e738 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_big_config.java @@ -0,0 +1,41 @@ +package com.ruoyi.sunlm.domain; + + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; //可以省去写类的GET和Set方法 + +import java.util.Date; +import java.util.List; + +@Data +//----------------------------大场馆 +//20230312 jkj 根据需求改 +//场景配置导出 +// 缺:ID、是否默认; +// 删除:备注、修改人、修改时间、创建人 +public class class_scene_big_config { + + @Excel(name = "ID") + public int id; + + @Excel(name = "主场景名称", cellType = Excel.ColumnType.STRING, prompt = "主场景名称") + public String name; + + @Excel(name = "状态", cellType = Excel.ColumnType.STRING, prompt = "状态", readConverterExp = "0=启用,1=停用,2=当前") + public String status; + +// @Excel(name = "创建人", cellType = Excel.ColumnType.STRING, prompt = "创建人") + public String createBy; + + @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Excel.Type.EXPORT, prompt = "创建时间") + public Date createTime; + +// @Excel(name = "修改人", cellType = Excel.ColumnType.STRING, prompt = "修改人") + public String updateBy; + +// @Excel(name = "修改时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Excel.Type.EXPORT, prompt = "修改时间") + public Date updateTime; + +// @Excel(name = "备注", cellType = Excel.ColumnType.STRING, prompt = "备注") + public String remark; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_calendar.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_calendar.java new file mode 100644 index 0000000..07b1009 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_calendar.java @@ -0,0 +1,44 @@ +package com.ruoyi.sunlm.domain; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +import java.sql.Time; +import java.util.Date; + +@Data +public class class_scene_calendar { //赛事 + + @Excel(name = "编号", cellType = Excel.ColumnType.STRING, sort = 1) + public int id; + + public int sceneId; + + @Excel(name = "比赛类型", cellType = Excel.ColumnType.STRING, sort = 3) + public String matchType; + + @Excel(name = "比赛名称", cellType = Excel.ColumnType.STRING, sort = 4) + public String matchName; + + @Excel(name = "备注", cellType = Excel.ColumnType.STRING, sort = 10) + public String matchRemark; + + @Excel(name = "开始时间", dateFormat = "HH:mm:ss", type = Excel.Type.EXPORT, sort = 6) + public Time beginTime; + + @Excel(name = "结束时间", dateFormat = "HH:mm:ss", type = Excel.Type.EXPORT, sort = 7) + public Time endTime; + + @Excel(name = "比赛日期", dateFormat = "yyyy-MM-dd", type = Excel.Type.EXPORT, sort = 5) + public Date matchDate; + + @Excel(name = "状态", cellType = Excel.ColumnType.STRING, sort = 8) + public String status; + + //----20230523 新增字段 + @Excel(name = "夺金点", cellType = Excel.ColumnType.STRING, readConverterExp = "0=否,1=是", sort = 9) + public String goldPoint; + + @Excel(name = "场馆", cellType = Excel.ColumnType.STRING, sort = 2) + public String venueName; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_match.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_match.java new file mode 100644 index 0000000..4f07437 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_match.java @@ -0,0 +1,44 @@ +package com.ruoyi.sunlm.domain; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +import java.sql.Time; +import java.util.Date; + +@Data +public class class_scene_match { //赛程 + + @Excel(name = "编号", cellType = Excel.ColumnType.STRING, sort = 1) + public int id; + + public int sceneId; + + @Excel(name = "场馆名称", cellType = Excel.ColumnType.STRING, sort = 2) + public String venueName; + + @Excel(name = "赛程名称", cellType = Excel.ColumnType.STRING, sort = 4) + public String taskName; + + @Excel(name = "赛程状态", cellType = Excel.ColumnType.STRING, readConverterExp = "0=启用,1=停用", sort = 7) + public String taskStatus; + + @Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Excel.Type.EXPORT, sort = 5) + public Date beginTime; + + @Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Excel.Type.EXPORT, sort = 6) + public Date endTime; + + @Excel(name = "赛程类型", width = 30, type = Excel.Type.EXPORT, sort = 3) + public String taskType; + + public String createBy; + + public Date createTime; + + public String updateBy; + + public Date updateTime; + + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_team.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_team.java new file mode 100644 index 0000000..13dfb9e --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_team.java @@ -0,0 +1,51 @@ +package com.ruoyi.sunlm.domain; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +import java.sql.Time; +import java.util.Date; +import java.util.List; + +@Data +public class class_scene_team { //施工队 + public int id; + + public String specialty; + + @Excel(name = "专业", cellType = Excel.ColumnType.STRING,sort=4) + public String specialtyname; + + public int sceneBigId; + + //@Excel(name = "场景名称", cellType = Excel.ColumnType.STRING, prompt = "场景名称") + public String sceneBigName; + + @Excel(name = "施工单位", cellType = Excel.ColumnType.STRING,sort=1) + public String venderName; + + @Excel(name = "状态", cellType = Excel.ColumnType.STRING,readConverterExp = "0=启用,1=停用",sort=7) + public String status; + + public String county; + + @Excel(name = "区县", cellType = Excel.ColumnType.STRING,sort=3) + public String countyname; + + public String city; + + @Excel(name = "地市", cellType = Excel.ColumnType.STRING,sort=2) + public String cityname; + + @Excel(name = "备注", cellType = Excel.ColumnType.STRING,sort=6) + public String remark; + + // @Excel(name = "施工队人员", cellType = Excel.ColumnType.STRING, prompt = "施工队人员") + public List user; + + // @Excel(name = "负责场馆", cellType = Excel.ColumnType.STRING) + public List dutyScene; + + @Excel(name = "负责场馆", cellType = Excel.ColumnType.STRING,sort=5) + public String dutySceneNames; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_team_scene.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_team_scene.java new file mode 100644 index 0000000..8fa6c1d --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_team_scene.java @@ -0,0 +1,11 @@ +package com.ruoyi.sunlm.domain; + +import lombok.Data; + +@Data +public class class_scene_team_scene { //施工队的场馆 + public int id; + public int construcTeamId; + public int dutySceneId; + public String venueName; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_team_user.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_team_user.java new file mode 100644 index 0000000..b328b5e --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/domain/class_scene_team_user.java @@ -0,0 +1,11 @@ +package com.ruoyi.sunlm.domain; + +import lombok.Data; + +@Data +public class class_scene_team_user { //施工队人员 + public int id; + public int construcTeamId; + public int userId; + public String userName; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_medal_stand_list.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_medal_stand_list.java new file mode 100644 index 0000000..e14f117 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_medal_stand_list.java @@ -0,0 +1,9 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +@Data +public class class_medal_stand_list extends publicEntity { // 查询用, 支持分页 + public String sceneBigId; + public String areaName; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_medal_stand_new.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_medal_stand_new.java new file mode 100644 index 0000000..7e12fc4 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_medal_stand_new.java @@ -0,0 +1,14 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +@Data +public class class_medal_stand_new { + public String sceneBigId; + public String areaName; + public String goldCount; + public String silverCount; + public String bronzeCount; + public String medalsCount; + public String updateBy; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_medal_stand_upt.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_medal_stand_upt.java new file mode 100644 index 0000000..3d2c874 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_medal_stand_upt.java @@ -0,0 +1,15 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +@Data +public class class_medal_stand_upt { + public int id; + public String sceneBigId; + public String areaName; + public String goldCount; + public String silverCount; + public String bronzeCount; + public String medalsCount; + public String updateBy; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_public_news_list.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_public_news_list.java new file mode 100644 index 0000000..540a38a --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_public_news_list.java @@ -0,0 +1,12 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_public_news_list extends publicEntity { // 查询用, 支持分页 + public String sceneBigId; + public String title; + public String content; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_public_news_new.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_public_news_new.java new file mode 100644 index 0000000..4fe20e2 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_public_news_new.java @@ -0,0 +1,14 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_public_news_new { + public String sceneBigId; + public String title; + public String contentUrl; + public String content; + public String updateBy; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_public_news_upt.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_public_news_upt.java new file mode 100644 index 0000000..1f7c519 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_public_news_upt.java @@ -0,0 +1,13 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +@Data +public class class_public_news_upt { + public int id; + public String sceneBigId; + public String title; + public String contentUrl; + public String content; + public String updateBy; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_scene_team_list.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_scene_team_list.java new file mode 100644 index 0000000..1219bd8 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_scene_team_list.java @@ -0,0 +1,16 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_scene_team_list extends publicEntity { //施工队,查询用, 支持分页 + public String sceneBigId; + public String specialty; + public String venderName; + public String county; + public String city; + public String status; + public List sceneIds; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_scene_team_new.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_scene_team_new.java new file mode 100644 index 0000000..310d224 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_scene_team_new.java @@ -0,0 +1,18 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_scene_team_new { + public int sceneBigId; + public String specialty; + public String venderName; + public String county; + public String city; + public String status; + public String remark; + public List dutySceneIds; + // public List userIds; //不需要了 +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_scene_team_upt.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_scene_team_upt.java new file mode 100644 index 0000000..9c3edc7 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/class_scene_team_upt.java @@ -0,0 +1,19 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +import java.util.List; + +@Data +public class class_scene_team_upt { + public int id; + public int sceneBigId; + public String specialty; + public String venderName; + public String county; + public String city; + public String status; + public String remark; + public List dutySceneIds; + // public List userIds; //不需要了 +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/publicEntity.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/publicEntity.java new file mode 100644 index 0000000..72e96d5 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/publicEntity.java @@ -0,0 +1,13 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +@Data +public class publicEntity { + public Integer pageNum; + public Integer pageSize; +} + + + + diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_big_entity_list.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_big_entity_list.java new file mode 100644 index 0000000..6f2a300 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_big_entity_list.java @@ -0,0 +1,15 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +import java.util.List; + +@Data +public class scene_big_entity_list extends publicEntity { //场景,查询用, 支持分页 + public String name; + public List status; + public String remark; +} + + + diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_big_entity_new.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_big_entity_new.java new file mode 100644 index 0000000..8526a14 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_big_entity_new.java @@ -0,0 +1,13 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +import java.util.Date; + +@Data +public class scene_big_entity_new { //用于新增 + public String name; + public String status; + public String createBy; + public String remark; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_big_entity_upt.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_big_entity_upt.java new file mode 100644 index 0000000..19cfbe4 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_big_entity_upt.java @@ -0,0 +1,13 @@ +package com.ruoyi.sunlm.entity; + + +import lombok.Data; + +@Data +public class scene_big_entity_upt { + public int id; + public String name; + public String updateBy; + public String status; + public String remark; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_calendar_entity_list.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_calendar_entity_list.java new file mode 100644 index 0000000..fd42656 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_calendar_entity_list.java @@ -0,0 +1,17 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +import java.util.List; + +@Data +public class scene_calendar_entity_list extends publicEntity { //赛事,查询用, 支持分页 + public String sceneBigId; + public List sceneIds; + public String matchType; + public String matchName; + public String matchRemark; + public String status; + public String matchDate; + public String goldPoint; +} \ No newline at end of file diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_calendar_entity_new.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_calendar_entity_new.java new file mode 100644 index 0000000..665fc58 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_calendar_entity_new.java @@ -0,0 +1,17 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + + +@Data +public class scene_calendar_entity_new { //用于新增 + public int sceneId; + public String matchType; + public String matchName; + public String matchRemark; + public String status; + public String beginTime; + public String endTime; + public String matchDate; + public String goldPoint; +} \ No newline at end of file diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_calendar_entity_upt.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_calendar_entity_upt.java new file mode 100644 index 0000000..bcaef94 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_calendar_entity_upt.java @@ -0,0 +1,17 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +@Data +public class scene_calendar_entity_upt { + public int id; + public int sceneId; + public String matchType; + public String matchName; + public String matchRemark; + public String status; + public String beginTime; + public String endTime; + public String matchDate; + public String goldPoint; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_match_entity_list.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_match_entity_list.java new file mode 100644 index 0000000..42d59dc --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_match_entity_list.java @@ -0,0 +1,19 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +import java.util.List; + +@Data +public class scene_match_entity_list extends publicEntity { //赛程,查询用, 支持分页 + public String sceneBigId; + public List sceneIds; + public String taskName; + public String taskStatus; + public String taskType; + public String taskDate; +} + + + + diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_match_entity_new.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_match_entity_new.java new file mode 100644 index 0000000..d1c3782 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_match_entity_new.java @@ -0,0 +1,15 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +@Data +public class scene_match_entity_new { + public int sceneId; + public String taskName; + public String taskStatus; + public String taskType; + public String beginTime; + public String endTime; + public String createBy; + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_match_entity_upt.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_match_entity_upt.java new file mode 100644 index 0000000..8f037a3 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/entity/scene_match_entity_upt.java @@ -0,0 +1,15 @@ +package com.ruoyi.sunlm.entity; + +import lombok.Data; + +@Data +public class scene_match_entity_upt { + public int id; + public int sceneId; + public String taskName; + public String taskStatus; + public String taskType; + public String beginTime; + public String endTime; + public String updateBy; +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/DpApiMapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/DpApiMapper.java new file mode 100644 index 0000000..e64af2d --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/DpApiMapper.java @@ -0,0 +1,65 @@ +package com.ruoyi.sunlm.mapper; + +import com.ruoyi.sunlm.domain.class_dp_scene_control; +import com.ruoyi.sunlm.domain.class_dp_scene_seat_detail; +import com.ruoyi.sunlm.domain.class_dp_scene_seat_info; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.SelectProvider; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +/** + * @author yqf + * @date 2023/4/18 + */ +@Mapper +@Component +public interface DpApiMapper { + + //region------------------------------------------------------------------------------------获取席座数据 + + class class_get_seat_data + { + public String get_scene_seat_info_SQL(@Param("sceneid") int sceneid) + { + String SQL="SELECT length,width,angle FROM dp_scene_seat_info where scene_id = "+sceneid; + return SQL; + } + public String get_seat_detail_SQL(@Param("sceneid") int sceneid) + { + String SQL="SELECT seat_id seatid,seat_number FROM dp_scene_seat_detail where scene_id = "+sceneid; + return SQL; + } + public String get_scene_control_SQL(@Param("sceneid") int sceneid) + { + String SQL="SELECT seat_id seatid,seat_number FROM dp_scene_seat_detail where scene_id = "+sceneid; + return SQL; + } + + + } + @SelectProvider(type = class_get_seat_data.class,method = "get_scene_seat_info_SQL") + class_dp_scene_seat_info get_scene_seat_info(@Param("sceneid") int sceneid); + + @SelectProvider(type = class_get_seat_data.class,method = "get_seat_detail_SQL") + List get_seat_detail(@Param("sceneid") int sceneid); + + @Select("SELECT mintype,nettype,kpiname FROM dp_scene_control limit 1") + class_dp_scene_control get_scene_control(); + + @Select("select starttime,endtime from pm_kpi4g_cell ORDER BY starttime desc limit 1") + Map getLastTime(); + + @Select("SELECT runtype FROM dp_scene_runtype limit 1") + Integer getsceneruntype(); + + @Select("SELECT maxtime FROM dp_scene_currtime limit 1") + LocalDateTime getmaxtime(); + + //endregion +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewDpApiMapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewDpApiMapper.java new file mode 100644 index 0000000..a82b466 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewDpApiMapper.java @@ -0,0 +1,68 @@ +package com.ruoyi.sunlm.mapper; + +import com.ruoyi.sunlm.daping.*; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.SelectProvider; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +/** + * @author yqf + * @date 2023/4/18 + */ +@Mapper +@Component +public interface NewDpApiMapper { + + //region------------------------------------------------------------------------------------获取席座数据 + + class class_get_seat_data + { + public String get_scene_seat_info_SQL(@Param("sceneid") int sceneid) + { + String SQL="SELECT length,width,angle FROM dp_scene_seat_info where scene_id = "+sceneid; + return SQL; + } + public String get_seat_detail_SQL(@Param("sceneid") int sceneid) + { + String SQL="SELECT seat_id seatid,seat_number FROM dp_scene_seat_detail where scene_id = "+sceneid; + return SQL; + } + public String get_scene_control_SQL(@Param("sceneid") int sceneid) + { + String SQL="SELECT seat_id seatid,seat_number FROM dp_scene_seat_detail where scene_id = "+sceneid; + return SQL; + } + + + } + @SelectProvider(type = class_get_seat_data.class,method = "get_scene_seat_info_SQL") + class_dp_2_scene_seat_info get_scene_seat_info(@Param("sceneid") int sceneid); + + @SelectProvider(type = class_get_seat_data.class,method = "get_seat_detail_SQL") + List get_seat_detail(@Param("sceneid") int sceneid); + + //@Select("SELECT mintype,nettype,kpiname FROM dp_scene_control limit 1") + //class_dp_2_scene_control get_scene_control(); + + //-------------------update by sunlm , 指定场馆展示1分钟或15分钟 + @Select("SELECT sceneid,mintype,'' nettype,'' kpiname FROM dp_2_scene_control where sceneid=#{sceneid} limit 1") + class_dp_2_scene_control get_scene_control(@Param("sceneid") int sceneid); + //---------------------------------------------------------- + + @Select("select starttime,endtime from pm_kpi4g_cell ORDER BY starttime desc limit 1") + Map getLastTime(); + + @Select("SELECT runtype FROM dp_scene_runtype limit 1") + Integer getsceneruntype(); + + @Select("SELECT maxtime FROM dp_scene_currtime limit 1") + LocalDateTime getmaxtime(); + + //endregion +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewDpSceneConfigMapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewDpSceneConfigMapper.java new file mode 100644 index 0000000..6cceea9 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewDpSceneConfigMapper.java @@ -0,0 +1,56 @@ +package com.ruoyi.sunlm.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.sunlm.daping.dp3d.*; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + *

+ * Mapper 接口 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Mapper +public interface NewDpSceneConfigMapper extends BaseMapper { + + String getColorByQo(NewDpSceneConfigQO qo); + + Map getFourKpiColor(NewPmKpiColorQo qo); + + Map getkpiColorAndScore(@Param("kpiname") String kpiname, + @Param("kpivalue") Double kpivalue, + @Param("nettype") String nettype, + @Param("freqtype") String freqtype, + @Param("devicetype") String devicetype, + @Param("bandwidth") Long bandwidth); + + String getkpicolor(@Param("kpiname") String kpiname, + @Param("kpivalue") Double kpivalue, + @Param("nettype") String nettype, + @Param("freqtype") String freqtype, + @Param("devicetype") String devicetype, + @Param("bandwidth") Long bandwidth); + + Map getColor(List ids); + + int getkpicolorscore(@Param("kpiname") String kpiname, + @Param("kpivalue") Double kpivalue, + @Param("nettype") String nettype, + @Param("freqtype") String freqtype, + @Param("devicetype") String devicetype, + @Param("bandwidth") Long bandwidth); + + List listColor(); + + List listKpiName(); + + List getList(NewDpSceneConfigQO qo); + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi4gCellMapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi4gCellMapper.java new file mode 100644 index 0000000..5a0a8d9 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi4gCellMapper.java @@ -0,0 +1,28 @@ +package com.ruoyi.sunlm.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.sunlm.daping.dp3d.*; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +/** + *

+ * 场馆4G小区级15分钟指标 Mapper 接口 + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Mapper +public interface NewPmKpi4gCellMapper extends BaseMapper { + + List getKpiList(NewPmKpiCellMonitorQO qo); + + Map getLastTime(@Param("sceneid") Integer sceneid,@Param("seatno") String seatno,@Param("inorout") String inorout); + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi4gMinMapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi4gMinMapper.java new file mode 100644 index 0000000..d199c62 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi4gMinMapper.java @@ -0,0 +1,28 @@ +package com.ruoyi.sunlm.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.sunlm.daping.dp3d.*; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + *

+ * 场馆4G小区级1分钟指标 Mapper 接口 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +@Mapper +public interface NewPmKpi4gMinMapper extends BaseMapper +{ + + List getKpiList(NewPmKpiCellMonitorQO qo); + + Map getLastTime(@Param("sceneid") Integer sceneid,@Param("seatno") String seatno,@Param("inorout") String inorout); + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi5gCellMapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi5gCellMapper.java new file mode 100644 index 0000000..534b2e2 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi5gCellMapper.java @@ -0,0 +1,27 @@ +package com.ruoyi.sunlm.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.sunlm.daping.dp3d.*; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +/** + *

+ * 场馆5G小区级15分钟指标 Mapper 接口 + *

+ * + * @author yqf + * @since 2023-04-11 + */ +@Mapper +public interface NewPmKpi5gCellMapper extends BaseMapper { + + List getKpiList(NewPmKpiCellMonitorQO qo); + + Map getLastTime(@Param("sceneid") Integer sceneid,@Param("seatno") String seatno,@Param("inorout") String inorout); + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi5gMinMapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi5gMinMapper.java new file mode 100644 index 0000000..1cb2f61 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/NewPmKpi5gMinMapper.java @@ -0,0 +1,26 @@ +package com.ruoyi.sunlm.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.sunlm.daping.dp3d.*; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + *

+ * 场馆5G小区级1分钟指标 Mapper 接口 + *

+ * + * @author yqf + * @since 2023-04-12 + */ +public interface NewPmKpi5gMinMapper extends BaseMapper +{ + + List getKpiList(NewPmKpiCellMonitorQO qo); + + Map getLastTime(@Param("sceneid") Integer sceneid, @Param("seatno") String seatno,@Param("inorout") String inorout); + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpConfigMapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpConfigMapper.java new file mode 100644 index 0000000..7b22b90 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpConfigMapper.java @@ -0,0 +1,1031 @@ +package com.ruoyi.sunlm.mapper; + +import java.util.List; +import com.ruoyi.sunlm.domain.*; +import org.apache.ibatis.annotations.*; +import org.springframework.stereotype.Component; + +/** + * 参数配置 数据层 + * + * @author ruoyi + */ +@Mapper +@Component +public interface dpConfigMapper +{ + //region --------------------------------------------------------------------------------------------场景增删改查接口 + //------------------------获取场景列表 + @Select("select * from yw_scene_big_config where id=#{id} order by id") + class_scene_big_config getscenebig(@Param("id") int id); + + class classscenebiglists + { + public String getscenebiglistsSQL(@Param("name") String name, + @Param("status") List status, + @Param("remark") String remark, + @Param("pagenumber") int pagenumber, + @Param("pagesize") int pagesize) + { + String swhere="where 1=1 "; + if (!name.equals("")) { + swhere+=" and name like concat('%', #{name}, '%') "; + } + if (!remark.equals("")) { + swhere+=" and remark like concat('%', #{remark}, '%') "; + } + if (!status.isEmpty()) { + swhere+=" and status::integer in (" + status.toString().replace('[',' ').replace(']',' ') +")" ; + } + String SQL=" select * from ( select * from yw_scene_big_config "+swhere+" and status='2' "+ + " union all"+ + " (select * from yw_scene_big_config "+swhere+" and status<>'2' "+ + " order by id desc)) as atable limit "+ String.valueOf(pagesize)+" offset "+String.valueOf((pagenumber-1)*pagesize); + return SQL; + } + + public String getscenebiglistsCnt(@Param("name") String name, + @Param("status") List status, + @Param("remark") String remark) + { + String swhere="where 1=1 "; + if (!name.equals("")) { + swhere+=" and name like concat('%', #{name}, '%') "; + } + if (!remark.equals("")) { + swhere+=" and remark like concat('%', #{remark}, '%') "; + } + if (!status.isEmpty()) { + swhere+=" and status::integer in (" + status.toString().replace('[',' ').replace(']',' ') +")" ; + } + String SQL=" select count(*) from ( select * from yw_scene_big_config "+swhere+" and status='2' "+ + " union all"+ + " (select * from yw_scene_big_config "+swhere+" and status<>'2' "+ + " order by id desc)) as atable "; + return SQL; + } + } + + @SelectProvider(type = classscenebiglists.class,method = "getscenebiglistsCnt") + Long getscenebiglistscnt(@Param("name") String name, + @Param("status") List status, + @Param("remark") String remark); + + @SelectProvider(type = classscenebiglists.class,method = "getscenebiglistsSQL") + List getscenebiglists(@Param("name") String name, + @Param("status") List status, + @Param("remark") String remark, + @Param("pagenumber") int pagenumber, + @Param("pagesize") int pagesize); + + //------------------------获取某个名称的场景数量 + @Select("select count(*) from yw_scene_big_config where name=#{name}") + int getscenebigbyName(@Param("name") String name); + + @Select("select count(*) from yw_scene_big_config where name=#{name} and id<>#{id}") + int getscenebigbyNameForUpdate(@Param("name") String name,@Param("id") int id); + + //------------------------新增大场馆 + class classInsertscenebig + { + public String InsertscenebigSQL(@Param("name") String name, + @Param("status") String status, + @Param("username") String username, + @Param("remark") String remark) + { + String SQL=""; + if (status.equals("2")) + { + SQL+="update yw_scene_big_config set status='0',update_by=#{username},update_time=LOCALTIMESTAMP(0) where status='2';"; + SQL+="insert into yw_scene_big_config(name,status,create_by,create_time,remark) values (#{name},#{status},#{username},LOCALTIMESTAMP(0),#{remark})"; + } + else + { + SQL+="insert into yw_scene_big_config(name,status,create_by,create_time,remark) values (#{name},#{status},#{username},LOCALTIMESTAMP(0),#{remark})"; + } + return SQL; + } + } + + @SelectProvider(type = classInsertscenebig.class,method = "InsertscenebigSQL") + void NewSceneBig(@Param("name") String name,@Param("status") String status,@Param("username") String username,@Param("remark") String remark); + + //------------------------修改大场馆状态 + class classupdatescenebig + { + public String updatescenebigSQL(@Param("id") int id, + @Param("name") String name, + @Param("status") String status, + @Param("username") String username, + @Param("remark") String remark) + { + String SQL=""; + if (status.equals("2")) + { + SQL+="update yw_scene_big_config set status='0',update_by=#{username},update_time=LOCALTIMESTAMP(0) where id!=#{id} and status='2';"; + SQL+="update yw_scene_big_config set name=#{name},status=#{status},update_by=#{username},update_time=LOCALTIMESTAMP(0),remark=#{remark} where id=#{id}"; + } + else + { + SQL+="update yw_scene_big_config set name=#{name},status=#{status},update_by=#{username},update_time=LOCALTIMESTAMP(0),remark=#{remark} where id=#{id}"; + } + return SQL; + } + } + + @SelectProvider(type = classupdatescenebig.class,method = "updatescenebigSQL") + void UpdateSceneBig(@Param("id") int id,@Param("name") String name,@Param("status") String status,@Param("username") String username,@Param("remark") String remark); + + //------------------------删除大场馆 + @Delete({"delete from yw_scene_big_config where id=#{id}"}) + void DeleteSceneBig(@Param("id") int id); + + //endregion + + //region-------------------------------------------------------------------------------------------赛事增删改查接口 + //------------------------获取场景列表 + @Select("select a.*,b.venue_name from yw_scene_calendar a left join yw_scene b on a.scene_id=b.id where a.id=#{matchid} order by a.id") + class_scene_calendar getscenecalendar(@Param("matchid") int matchid); + + class classscenecalendarlists + { + public String getscenecalendarlistsSQL(@Param("scenebigid") String scenebigid, + @Param("sceneid") List sceneids, + @Param("matchtype") String matchtype, + @Param("matchname") String matchname, + @Param("status") String status, + @Param("matchremark") String matchremark, + @Param("pagenumber") int pagenumber, + @Param("pagesize") int pagesize, + @Param("matchdate") String matchdate, + @Param("goldpoint") String goldpoint) + { + String swhere="where 1=1 "; + + if (!scenebigid.equals("")) { + swhere+=" and scene_id in (select id from yw_scene where scene_big_id =" + scenebigid +") " ; + } + if (!sceneids.isEmpty()) { + swhere+=" and scene_id in (" + sceneids.toString().replace('[',' ').replace(']',' ')+")" ; + } + if (!matchtype.equals("")) { + swhere+=" and match_type =" + matchtype ; + } + if (!matchname.equals("")) { + swhere+=" and match_name like concat('%', #{matchname}, '%') "; + } + if (!status.equals("")) { + swhere+=" and a.status ='" + status + "'"; + } + if (!matchremark.equals("")) { + swhere+=" and match_remark like concat('%', #{matchremark}, '%') "; + } + if (!matchdate.equals("")) { + swhere+=" and to_char(match_date,'yyyy-mm-dd') = '" + matchdate + "' "; + } + if (!goldpoint.equals("")) { + swhere+=" and gold_point ='" + goldpoint + "'"; + } + + String SQL="select a.*,b.venue_name from yw_scene_calendar a left join yw_scene b on a.scene_id=b.id "+swhere+ + " order by match_date desc,begin_time limit "+ String.valueOf(pagesize)+" offset "+String.valueOf((pagenumber-1)*pagesize); + return SQL; + } + + public String getscenecalendarlistsCnt(@Param("scenebigid") String scenebigid, + @Param("sceneid") List sceneids, + @Param("matchtype") String matchtype, + @Param("matchname") String matchname, + @Param("status") String status, + @Param("matchremark") String matchremark, + @Param("matchdate") String matchdate, + @Param("goldpoint") String goldpoint) + { + String swhere="where 1=1 "; + if (!scenebigid.equals("")) { + swhere+=" and scene_id in (select id from yw_scene where scene_big_id =" + scenebigid +") "; + } + if (!sceneids.isEmpty()) { + swhere+=" and scene_id in (" + sceneids.toString().replace('[',' ').replace(']',' ')+")" ; + } + if (!matchtype.equals("")) { + swhere+=" and match_type =" + matchtype ; + } + if (!matchname.equals("")) { + swhere+=" and match_name like concat('%', #{matchname}, '%') "; + } + if (!status.equals("")) { + swhere+=" and status ='" + status + "'"; + } + if (!matchremark.equals("")) { + swhere+=" and match_remark like concat('%', #{matchremark}, '%') "; + } + if (!matchdate.equals("")) { + swhere+=" and to_char(match_date,'yyyy-mm-dd') = '" + matchdate + "' "; + } + if (!goldpoint.equals("")) { + swhere+=" and gold_point ='" + goldpoint + "'"; + } + + String SQL=" select count(*) from yw_scene_calendar "+swhere; + return SQL; + } + } + + @SelectProvider(type = classscenecalendarlists.class,method = "getscenecalendarlistsCnt") + Long getscenecalendarlistscnt(@Param("scenebigid") String scenebigid, + @Param("sceneid") List sceneids, + @Param("matchtype") String matchtype, + @Param("matchname") String matchname, + @Param("status") String status, + @Param("matchremark") String matchremark, + @Param("matchdate") String matchdate, + @Param("goldpoint") String goldpoint); + + @SelectProvider(type = classscenecalendarlists.class,method = "getscenecalendarlistsSQL") + List getscenecalendarlists(@Param("scenebigid") String scenebigid, + @Param("sceneid") List sceneids, + @Param("matchtype") String matchtype, + @Param("matchname") String matchname, + @Param("status") String status, + @Param("matchremark") String matchremark, + @Param("pagenumber") int pagenumber, + @Param("pagesize") int pagesize, + @Param("matchdate") String matchdate, + @Param("goldpoint") String goldpoint); + + //------------------------获取某个名称的赛事数量 + @Select("select count(*) from yw_scene_calendar where match_name=#{matchname}") + int getscenecalendarbyName(@Param("sceneid") int sceneid,@Param("matchname") String matchname); + + @Select("select count(*) from yw_scene_calendar where match_name=#{matchname} and id <>#{id}") + int getscenecalendarbyNameForUpdate(@Param("sceneid") int sceneid,@Param("matchname") String matchname,@Param("id") int id ); + + + //------------------------新增赛事 + class classInsertscenecalendar + { + public String InsertscenecalendarSQL(@Param("sceneid") int sceneid, + @Param("matchtype") String matchtype, + @Param("matchname") String matchname, + @Param("status") String status, + @Param("matchremark") String matchremark, + @Param("beginTime") String beginTime, + @Param("endTime") String endTime, + @Param("matchDate") String matchDate, + @Param("goldpoint") String goldpoint + ) + { + String SQL="insert into yw_scene_calendar(scene_id,match_type,match_name,match_remark,begin_time,end_time,match_date,status,gold_point) "+ + "values (#{sceneid},#{matchtype},#{matchname},#{matchremark},to_timestamp(#{beginTime},'HH24:MI'),to_timestamp(#{endTime},'HH24:MI'),"+ + "to_date(#{matchDate},'yyyy-mm-dd'),#{status},#{goldpoint})"; + return SQL; + } + } + + @SelectProvider(type = classInsertscenecalendar.class,method = "InsertscenecalendarSQL") + void NewScenecalendar(@Param("sceneid") int sceneid, + @Param("matchtype") String matchtype, + @Param("matchname") String matchname, + @Param("status") String status, + @Param("matchremark") String matchremark, + @Param("beginTime") String beginTime, + @Param("endTime") String endTime, + @Param("matchDate") String matchDate, + @Param("goldpoint") String goldpoint); + + //------------------------修改赛事信息 + class classupdatescenecalendar + { + public String updatescenecalendarSQL(@Param("id") int id, + @Param("sceneid") int sceneid, + @Param("matchtype") String matchtype, + @Param("matchname") String matchname, + @Param("status") String status, + @Param("matchremark") String matchremark, + @Param("beginTime") String beginTime, + @Param("endTime") String endTime, + @Param("matchDate") String matchDate, + @Param("goldpoint") String goldpoint) + { + String SQL="update yw_scene_calendar set "+ + "scene_id=#{sceneid},match_type=#{matchtype},"+ + "match_name=#{matchname},match_remark=#{matchremark},"+ + "begin_time=to_timestamp(#{beginTime},'HH24:MI'),end_time=to_timestamp(#{endTime},'HH24:MI'),"+ + "match_date=to_date(#{matchDate},'yyyy-mm-dd'),status=#{status} ," + + "gold_point=#{goldpoint} " + + " where id=#{id}"; + return SQL; + } + } + + @SelectProvider(type = classupdatescenecalendar.class,method = "updatescenecalendarSQL") + void UpdateScenecalendar(@Param("id") int id, + @Param("sceneid") int sceneid, + @Param("matchtype") String matchtype, + @Param("matchname") String matchname, + @Param("status") String status, + @Param("matchremark") String matchremark, + @Param("beginTime") String beginTime, + @Param("endTime") String endTime, + @Param("matchDate") String matchDate, + @Param("goldpoint") String goldpoint); + + //------------------------删除赛事 + @Delete({"delete from yw_scene_calendar where id=#{id}"}) + void DeleteScenecalendar(@Param("id") int id); + //endregion + + //region-------------------------------------------------------------------------------------------施工队增删改查接口 + //region------------------------获取施工单位列表 + class classsceneteamidlists + { + public String getsceneteamSQL(@Param("teamid") int teamid) + { + String SQL="select a.*,b.name scene_big_name from yw_construc_team a left join yw_scene_big_config b on a.scene_big_id=b.id where a.id=#{teamid} "; + return SQL; + } + + public String getsceneteam_userSQL(@Param("teamid") int teamid) + { + String SQL="select a.*,b.nick_name userName from yw_construc_team_user a left join sys_user b on a.user_id=b.user_id where b.del_flag='0' and a.construc_team_id=#{teamid} "; + return SQL; + } + + public String getsceneteam_dutysceneSQL(@Param("teamid") int teamid) + { + String SQL="select a.*,b.venue_name from yw_construc_team_dutyscene a left join yw_scene b on a.duty_scene_id=b.id where a.construc_team_id=#{teamid} "; + return SQL; + } + + public String getsceneteamlistsSQL(@Param("scenebigid") String scenebigid, + @Param("specialty") String specialty, + @Param("venderName") String venderName, + @Param("status") String status, + @Param("county") String county, + @Param("city") String city, + @Param("sceneIds") List sceneIds, + @Param("pagenumber") int pagenumber, + @Param("pagesize") int pagesize + ) + { + String swhere="where 1=1 "; + if (!scenebigid.equals("")) { + swhere+=" and scene_big_id =" + scenebigid ; + } + if (!specialty.equals("")) { + swhere+=" and specialty =" + specialty ; + } + if (!venderName.equals("")) { + swhere+=" and vender_Name like concat('%', #{venderName}, '%') "; + } + if (!status.equals("")) { + swhere+=" and a.status ='" + status + "'"; + } + if (!county.equals("")) { + swhere+=" and county like concat('%', #{county}, '%') "; + } + if (!city.equals("")) { + swhere+=" and city like concat('%', #{city}, '%') "; + } + + if (sceneIds.size()>0) { + swhere+=" and a.id in (select distinct construc_team_id from yw_construc_team_dutyscene where duty_scene_id in ( "+ + sceneIds.toString().replace('[',' ').replace(']',' ') +" )) "; + } + + String SQL="select a.*,b.name scene_big_name,c.dict_label specialtyname, d.dict_label countyname ,e.dict_label cityname " + + " from yw_construc_team a left join yw_scene_big_config b on a.scene_big_id=b.id " + + " left join sys_dict_data c on c.dict_value=a.specialty and c.dict_type='yw_specialty' " + + " left join sys_dict_data d on d.dict_value=a.county and d.dict_type='yw_county' " + + " left join sys_dict_data e on e.dict_value=a.city and e.dict_type='yw_city' " + + " " + + swhere+ + " order by a.id desc limit "+ String.valueOf(pagesize)+" offset "+String.valueOf((pagenumber-1)*pagesize); + return SQL; + } + + public String getsceneteamlistsCnt(@Param("scenebigid") String scenebigid, + @Param("specialty") String specialty, + @Param("venderName") String venderName, + @Param("status") String status, + @Param("county") String county, + @Param("city") String city, + @Param("sceneIds") List sceneIds) + { + String swhere="where 1=1 "; + if (!scenebigid.equals("")) { + swhere+=" and scene_big_id =" + scenebigid ; + } + if (!specialty.equals("")) { + swhere+=" and specialty =" + specialty ; + } + if (!venderName.equals("")) { + swhere+=" and vender_Name like concat('%', #{venderName}, '%') "; + } + if (!status.equals("")) { + swhere+=" and status ='" + status + "'"; + } + if (!county.equals("")) { + swhere+=" and county like concat('%', #{county}, '%') "; + } + if (!city.equals("")) { + swhere+=" and city like concat('%', #{city}, '%') "; + } + if (sceneIds.size()>0) { + swhere+=" and id in (select distinct construc_team_id from yw_construc_team_dutyscene where duty_scene_id in ( "+ + sceneIds.toString().replace('[',' ').replace(']',' ') +" )) "; + } + + String SQL=" select count(*) from yw_construc_team "+swhere; + return SQL; + } + } + + @SelectProvider(type = classsceneteamidlists.class,method = "getsceneteamSQL") + class_scene_team getsceneteam(@Param("teamid") int teamid); + + @SelectProvider(type = classsceneteamidlists.class,method = "getsceneteam_userSQL") //获取某个TEAM的人员列表 + List getsceneteam_user(@Param("teamid") int teamid); + + @SelectProvider(type = classsceneteamidlists.class,method = "getsceneteam_dutysceneSQL") ////获取某个TEAM的场馆列表 + List getsceneteam_dutyscene(@Param("teamid") int teamid); + + @SelectProvider(type = classsceneteamidlists.class,method = "getsceneteamlistsCnt") + Long getsceneteamlistscnt(@Param("scenebigid") String scenebigid, + @Param("specialty") String specialty, + @Param("venderName") String venderName, + @Param("status") String status, + @Param("county") String county, + @Param("city") String city, + @Param("sceneIds") List sceneIds); + + @SelectProvider(type = classsceneteamidlists.class,method = "getsceneteamlistsSQL") + List getsceneteamlists(@Param("scenebigid") String scenebigid, + @Param("specialty") String specialty, + @Param("venderName") String venderName, + @Param("status") String status, + @Param("county") String county, + @Param("city") String city, + @Param("sceneIds") List sceneIds, + @Param("pagenumber") int pagenumber, + @Param("pagesize") int pagesize); + + //endregion + + //region----------------新增施工队 + //---------------------获取某个名称的施工队数量 + @Select("select count(*) from yw_construc_team where vender_name=#{vendername}") + int getsceneteambyName(@Param("vendername") String vendername); + + @Select("select id from yw_scene_big_config where status='2'") + String getSceneBigIs2(); + + //------------------------新增施工单位 //@Param("userIds") List userIds + class classInsertsceneteam + { + public String InsertsceneteamSQL(@Param("scenebigid") int scenebigid, + @Param("specialty") String specialty, + @Param("venderName") String venderName, + @Param("status") String status, + @Param("county") String county, + @Param("city") String city, + @Param("remark") String remark, + @Param("dutySceneIds") List dutySceneIds + ) + { + String SQL="insert into yw_construc_team(scene_big_id,specialty,vender_name,status,county,city,remark) "+ + "values (#{scenebigid},#{specialty},#{venderName},#{status},#{county},#{city},#{remark});"; + //-----------------------user + String ssql=""; + /* //用户不需要了 + for (int i=0;i0) + { + for (int i = 0; i < dutySceneIds.size(); i++) { + ssql += " (currval('yw_construc_team_id_seq'::regclass)," + dutySceneIds.get(i).replace('[', ' ').replace(']', ' ') + ") ,"; + } + if (ssql.substring(ssql.length() - 1).equals(",")) { + ssql = ssql.substring(0, ssql.length() - 1) + ";"; // 去掉最后一个逗号 + } + SQL += " insert into yw_construc_team_dutyscene(construc_team_id,duty_scene_id) values " + ssql; + } + + return SQL; + } + } + + // @Param("userIds") List userIds + @SelectProvider(type = classInsertsceneteam.class,method = "InsertsceneteamSQL") + void NewSceneteam(@Param("scenebigid") int scenebigid, + @Param("specialty") String specialty, + @Param("venderName") String venderName, + @Param("status") String status, + @Param("county") String county, + @Param("city") String city, + @Param("remark") String remark, + @Param("dutySceneIds") List dutySceneIds + ); + + //endregion + //region------------------------修改施工单位信息 //@Param("userIds") List userIds + class classupdatesceneteam + { + public String updatesceneteamSQL(@Param("id") int id, + @Param("scenebigid") int scenebigid, + @Param("specialty") String specialty, + @Param("venderName") String venderName, + @Param("status") String status, + @Param("county") String county, + @Param("city") String city, + @Param("remark") String remark, + @Param("dutySceneIds") List dutySceneIds + ) + { + String SQL="update yw_construc_team set "+ //scene_big_id,specialty,vender_name,status,county,remark + "scene_big_id=#{scenebigid},specialty=#{specialty},"+ + "vender_name=#{venderName},status=#{status},"+ + "county=#{county},city=#{city},remark=#{remark} where id=#{id};"; + //-----------------------user + + String ssql=""; + /* //不需要了 + for (int i=0;i0) { + for (int i = 0; i < dutySceneIds.size(); i++) { + ssql += " (" + String.valueOf(id) + "," + dutySceneIds.get(i).replace('[', ' ').replace(']', ' ') + ") ,"; + } + if (ssql.substring(ssql.length() - 1).equals(",")) { + ssql = ssql.substring(0, ssql.length() - 1) + ";"; // 去掉最后一个逗号 + } + + SQL += "delete from yw_construc_team_dutyscene where construc_team_id=" + String.valueOf(id) + ";"; + SQL += " insert into yw_construc_team_dutyscene(construc_team_id,duty_scene_id) values " + ssql; + } + else + { + SQL += "delete from yw_construc_team_dutyscene where construc_team_id=" + String.valueOf(id) + ";"; + } + + return SQL; + } + + } + + @Select("select count(*) from yw_construc_team where vender_name=#{vendername} and id<>#{id}") + int getsceneteambyNameForUpdate(@Param("vendername") String vendername,@Param("id") int id); + + //@Param("userIds") List userIds + @SelectProvider(type = classupdatesceneteam.class,method = "updatesceneteamSQL") + void UpdateSceneteam(@Param("id") int id, + @Param("scenebigid") int scenebigid, + @Param("specialty") String specialty, + @Param("venderName") String venderName, + @Param("status") String status, + @Param("county") String county, + @Param("city") String city, + @Param("remark") String remark, + @Param("dutySceneIds") List dutySceneIds + ); + + //endregion + //region------------------------删除施工单位 + @Delete({"delete from yw_construc_team where id=#{id};"+ + //"delete from yw_construc_team_user where construc_team_id=#{id};"+ + "delete from yw_construc_team_dutyscene where construc_team_id=#{id};"}) + void DeleteSceneteam(@Param("id") int id); + //endregion + + //endregion + + //region --------------------------------------------------------------------------------------------公众新闻增删改查接口 + //------------------------获取公众新闻列表 + @Select("select * from fm_public_inform_news where id=#{newsid} order by id") + class_public_news getpublicnews(@Param("newsid") int newsid); + + class classpublicnewslists + { + public String getpublicnewslistsSQL(@Param("sceneBigId") String sceneBigId, + @Param("title") String title, + @Param("content") String content, + @Param("pagenumber") int pagenumber, + @Param("pagesize") int pagesize) + { + String swhere="where b.del_flag='0'"; + if (!sceneBigId.equals("")) { + swhere+=" and a.scene_big_id = " + sceneBigId ; + } + if (!title.equals("")) { + swhere+=" and title like concat('%', #{title}, '%') "; + } + if (!content.equals("")) { + swhere+=" and content like concat('%', #{content}, '%') "; + } + + String SQL=" select a.*,b.nick_name updatebyname from fm_public_inform_news a "+ + " left join sys_user b on a.update_by=b.user_name "+ + swhere+ + " order by update_time desc "+ + " limit "+ String.valueOf(pagesize)+" offset "+String.valueOf((pagenumber-1)*pagesize); + return SQL; + } + + public String getpublicnewslistsCnt(@Param("sceneBigId") String sceneBigId, + @Param("title") String title, + @Param("content") String content) + { + String swhere="where 1=1 "; + if (!sceneBigId.equals("")) { + swhere+=" and scene_big_id = " + sceneBigId ; + } + if (!title.equals("")) { + swhere+=" and title like concat('%', #{title}, '%') "; + } + if (!content.equals("")) { + swhere+=" and content like concat('%', #{content}, '%') "; + } + + String SQL=" select count(*) from fm_public_inform_news "+swhere; + return SQL; + } + } + + @SelectProvider(type = classpublicnewslists.class,method = "getpublicnewslistsCnt") + Long getpublicnewslistscnt(@Param("sceneBigId") String sceneBigId, + @Param("title") String title, + @Param("content") String content); + + @SelectProvider(type = classpublicnewslists.class,method = "getpublicnewslistsSQL") + List getpublicnewslists(@Param("sceneBigId") String sceneBigId, + @Param("title") String title, + @Param("content") String content, + @Param("pagenumber") int pagenumber, + @Param("pagesize") int pagesize); + + //------------------------获取某个名称的数量 + @Select("select count(*) from fm_public_inform_news where scene_big_id=#{sceneBigId} and title=#{title}") + int getpublicnewsbyName(@Param("sceneBigId") int sceneBigId,@Param("title") String title); + + //------------------------新增大场馆 + class classInsertpublicnews + { + public String InsertpublicnewsSQL(@Param("sceneBigId") int sceneBigId, + @Param("title") String title, + @Param("contentUrl") String contentUrl, + @Param("content") String content, + @Param("username") String username) + { + String SQL=""; + SQL+="insert into fm_public_inform_news(scene_big_id,title,content_url,content,update_by,update_time) "+ + "values (#{sceneBigId},#{title},#{contentUrl},#{content},#{username},LOCALTIMESTAMP(0))"; + return SQL; + } + } + + @SelectProvider(type = classInsertpublicnews.class,method = "InsertpublicnewsSQL") + void Newpublicnews(@Param("sceneBigId") int sceneBigId, + @Param("title") String title, + @Param("contentUrl") String contentUrl, + @Param("content") String content, + @Param("username") String username); + + //------------------------修改 + @Select("select count(*) from fm_public_inform_news where scene_big_id=#{sceneBigId} and title=#{title} and id<>#{id}") + int getpublicnewsbyNameForUpdate(@Param("sceneBigId") int sceneBigId,@Param("title") String title,@Param("id") int id); + + class classupdatepublicnews + { + public String updatepublicnewsSQL(@Param("id") int id, + @Param("sceneBigId") int sceneBigId, + @Param("title") String title, + @Param("contentUrl") String contentUrl, + @Param("content") String content, + @Param("username") String username) + { + String SQL=""; + SQL+= "update fm_public_inform_news set scene_big_id=#{sceneBigId},title=#{title}," + + "content_url=#{contentUrl},update_by=#{username}," + + "update_time=LOCALTIMESTAMP(0),content=#{content} where id=#{id}"; + return SQL; + } + } + + @SelectProvider(type = classupdatepublicnews.class,method = "updatepublicnewsSQL") + void UpdatePublicNews(@Param("id") int id, + @Param("sceneBigId") int sceneBigId, + @Param("title") String title, + @Param("contentUrl") String contentUrl, + @Param("content") String content, + @Param("username") String username); + + //------------------------删除大场馆 + @Delete({"delete from fm_public_inform_news where id=#{id}"}) + void DeletePublicNews(@Param("id") int id); + + //endregion + + //region --------------------------------------------------------------------------------------------奖牌榜增删改查接口 + //------------------------获取奖牌榜列表 + @Select("select t1.*,t2.name scene_big_name from fm_medal_stand t1 left join yw_scene_big_config t2 on t1.scene_big_id=t2.id where t1.id=#{medalid} order by t1.id") + class_medal_stand getmedalstand(@Param("medalid") int medalid); + + class classmedalstandlists + { + public String getmedalstandlistsSQL(@Param("sceneBigId") String sceneBigId, + @Param("areaname") String areaname, + @Param("pagenumber") int pagenumber, + @Param("pagesize") int pagesize) + { + String swhere="where t3.del_flag = '0'"; + if (!sceneBigId.equals("")) { + swhere+=" and t1.scene_big_id = " + sceneBigId ; + } + if (!areaname.equals("")) { + swhere+=" and t1.area_name like concat('%', #{areaname}, '%') "; + } + + String SQL=" select t1.*,t2.name scene_big_name, gold_count*3+silver_count*2+bronze_count as acount ,t3.nick_name updatebyname from fm_medal_stand t1 " + + " left join yw_scene_big_config t2 on t1.scene_big_id=t2.id "+ + " left join sys_user t3 on t1.update_by=t3.user_name "+ + swhere+ + " order by acount desc "+ + " limit "+ String.valueOf(pagesize)+" offset "+String.valueOf((pagenumber-1)*pagesize); + return SQL; + } + + public String getmedalstandlistsCnt(@Param("sceneBigId") String sceneBigId, + @Param("areaname") String areaname) + { + String swhere="where 1=1 "; + if (!sceneBigId.equals("")) { + swhere+=" and scene_big_id = " + sceneBigId ; + } + if (!areaname.equals("")) { + swhere+=" and area_name like concat('%', #{areaname}, '%') "; + } + + String SQL=" select count(*) from fm_medal_stand "+swhere; + return SQL; + } + } + + @SelectProvider(type = classmedalstandlists.class,method = "getmedalstandlistsCnt") + Long getmedalstandlistscnt(@Param("sceneBigId") String sceneBigId, + @Param("areaname") String areaname); + + @SelectProvider(type = classmedalstandlists.class,method = "getmedalstandlistsSQL") + List getmedalstandlists(@Param("sceneBigId") String sceneBigId, + @Param("areaname") String areaname, + @Param("pagenumber") int pagenumber, + @Param("pagesize") int pagesize); + + //------------------------获取某个名称的数量 + @Select("select count(*) from fm_medal_stand where scene_big_id=#{scenebigid} and area_name=#{areaName}") + int getmedalstandbyName(@Param("scenebigid") int scenebigid,@Param("areaName") String areaName); + + @Select("select count(*) from fm_medal_stand where scene_big_id=#{scenebigid} and area_name=#{areaName} and id <>#{id}") + int getmedalstandbyNameForUpdate(@Param("scenebigid") int scenebigid,@Param("areaName") String areaName,@Param("id") int id); + + //------------------------新增大场馆 + class classInsertmedalstand + { + public String InsertmedalstandSQL(@Param("sceneBigId") int sceneBigId, + @Param("areaName") String areaName, + @Param("goldCount") int goldCount, + @Param("silverCount") int silverCount, + @Param("bronzeCount") int bronzeCount, + @Param("medalsCount") int medalsCount, + @Param("username") String username) + { + String SQL=""; + SQL+="insert into fm_medal_stand(scene_big_id,area_name,gold_count,silver_count,bronze_count,medals_count,update_time,update_by) "+ + "values (#{sceneBigId},#{areaName},#{goldCount},#{silverCount},#{bronzeCount},#{medalsCount},LOCALTIMESTAMP(0),#{username})"; + return SQL; + } + } + + @SelectProvider(type = classInsertmedalstand.class,method = "InsertmedalstandSQL") + void Newmedalstand(@Param("sceneBigId") int sceneBigId, + @Param("areaName") String areaName, + @Param("goldCount") int goldCount, + @Param("silverCount") int silverCount, + @Param("bronzeCount") int bronzeCount, + @Param("medalsCount") int medalsCount, + @Param("username") String username); + + //------------------------修改 + class classupdatemedalstand + { + public String updatemedalstandSQL(@Param("id") int id, + @Param("sceneBigId") int sceneBigId, + @Param("areaName") String areaName, + @Param("goldCount") int goldCount, + @Param("silverCount") int silverCount, + @Param("bronzeCount") int bronzeCount, + @Param("medalsCount") int medalsCount, + @Param("username") String username) + { + String SQL=""; + SQL+= "update fm_medal_stand set area_name=#{areaName},scene_big_id=#{sceneBigId}," + + "gold_count=#{goldCount},silver_count=#{silverCount}," + + "bronze_count=#{bronzeCount},medals_count=#{medalsCount}," + + "update_by=#{username},update_time=LOCALTIMESTAMP(0) where id=#{id}"; + return SQL; + } + } + + @SelectProvider(type = classupdatemedalstand.class,method = "updatemedalstandSQL") + void Updatemedalstand(@Param("id") int id, + @Param("sceneBigId") int sceneBigId, + @Param("areaName") String areaName, + @Param("goldCount") int goldCount, + @Param("silverCount") int silverCount, + @Param("bronzeCount") int bronzeCount, + @Param("medalsCount") int medalsCount, + @Param("username") String username); + + //------------------------删除大场馆 + @Delete({"delete from fm_medal_stand where id = #{id}"}) + void Deletemedalstand(@Param("id") int id); + + //endregion + + //region-------------------------------------------------------------------------------------------赛程增删改查接口 + //------------------------获取列表 + @Select("select a.*,b.venue_name from yw_scene_match a left join yw_scene b on a.scene_id=b.id where a.id=#{matchid} order by a.id") + class_scene_match getscenematch(@Param("matchid") int matchid); + + @Select("select a.*,b.venue_name from yw_scene_match a left join yw_scene b on a.scene_id=b.id where a.task_name=#{taskname} and a.scene_id = #{sceneid} order by a.id") + class_scene_match getscenematch2(@Param("taskname") String taskname,@Param("sceneid") Long sceneid); + + class classscenematchlists + { + public String getscenematchlistsSQL(@Param("scenebigid") String scenebigid, + @Param("sceneid") List sceneids, + @Param("taskname") String taskname, + @Param("taskstatus") String taskstatus, + @Param("taskdate") String taskdate, + @Param("tasktype") String tasktype, + @Param("pagenumber") int pagenumber, + @Param("pagesize") int pagesize) + { + String swhere="where 1=1 "; + + if (!scenebigid.equals("")) { + swhere+=" and scene_id in (select id from yw_scene where scene_big_id =" + scenebigid +") " ; + } + if (!sceneids.isEmpty()) { + swhere+=" and scene_id in (" + sceneids.toString().replace('[',' ').replace(']',' ')+")" ; + } + if (!taskname.equals("")) { + swhere+=" and task_name like concat('%', #{taskname}, '%') "; + } + if (!taskstatus.equals("")) { + swhere+=" and a.task_status ='" + taskstatus + "'"; + } + if (!tasktype.equals("")) { + swhere+=" and task_type like concat('%', #{tasktype}, '%') "; + } + if (!taskdate.equals("")) { + swhere+=" and to_char(a.begin_time,'yyyy-mm-dd') ='" + taskdate + "'"; + } + + String SQL="select a.*,b.venue_name from yw_scene_match a left join yw_scene b on a.scene_id=b.id "+swhere+ + " order by scene_id,begin_time limit "+ String.valueOf(pagesize)+" offset "+String.valueOf((pagenumber-1)*pagesize); + return SQL; + } + + public String getscenematchlistsCnt(@Param("scenebigid") String scenebigid, + @Param("sceneid") List sceneids, + @Param("taskname") String taskname, + @Param("taskstatus") String taskstatus, + @Param("taskdate") String taskdate, + @Param("tasktype") String tasktype) + { + String swhere="where 1=1 "; + if (!scenebigid.equals("")) { + swhere+=" and scene_id in (select id from yw_scene where scene_big_id =" + scenebigid +") " ; + } + if (!sceneids.isEmpty()) { + swhere+=" and scene_id in (" + sceneids.toString().replace('[',' ').replace(']',' ')+")" ; + } + if (!taskname.equals("")) { + swhere+=" and task_name like concat('%', #{taskname}, '%') "; + } + if (!taskstatus.equals("")) { + swhere+=" and task_status ='" + taskstatus + "'"; + } + if (!tasktype.equals("")) { + swhere+=" and task_type like concat('%', #{tasktype}, '%') "; + } + if (!taskdate.equals("")) { + swhere+=" and to_char(begin_time,'yyyy-mm-dd') ='" + taskdate + "'"; + } + String SQL=" select count(*) from yw_scene_match "+swhere; + return SQL; + } + } + + @SelectProvider(type = classscenematchlists.class,method = "getscenematchlistsCnt") + Long getscenematchlistscnt(@Param("scenebigid") String scenebigid, + @Param("sceneid") List sceneids, + @Param("taskname") String taskname, + @Param("taskstatus") String taskstatus, + @Param("taskdate") String taskdate, + @Param("tasktype") String tasktype); + + @SelectProvider(type = classscenematchlists.class,method = "getscenematchlistsSQL") + List getscenematchlists(@Param("scenebigid") String scenebigid, + @Param("sceneid") List sceneids, + @Param("taskname") String taskname, + @Param("taskstatus") String taskstatus, + @Param("taskdate") String taskdate, + @Param("tasktype") String tasktype, + @Param("pagenumber") int pagenumber, + @Param("pagesize") int pagesize); + + //------------------------获取某个名称的赛事数量 + @Select("select count(*) from yw_scene_match where task_name=#{matchname} and scene_id=#{sceneid}") + int getscenematchbyName(@Param("sceneid") int sceneid,@Param("matchname") String matchname); + + @Select("select count(*) from yw_scene_match where task_name=#{matchname} and scene_id=#{sceneid} and id <>#{id}") + int getscenematchbyNameForUpdate(@Param("sceneid") int sceneid,@Param("matchname") String matchname,@Param("id") int id); + + //------------------------新增赛程 + class classInsertscenematch + { + public String InsertscenematchSQL(@Param("sceneid") int sceneid, + @Param("taskname") String taskname, + @Param("taskstatus") String taskstatus, + @Param("tasktype") String tasktype, + @Param("beginTime") String beginTime, + @Param("endTime") String endTime, + @Param("createby") String createby + ) + { + String SQL="insert into yw_scene_match(scene_id,task_name,task_status,begin_time,end_time,create_by,create_time,task_type) "+ + "values (#{sceneid},#{taskname},#{taskstatus},to_timestamp(#{beginTime},'yyyy-mm-dd hh24:mi:ss'),to_timestamp(#{endTime},'yyyy-mm-dd hh24:mi:ss'),"+ + "#{createby},LOCALTIMESTAMP(0),#{tasktype})"; + return SQL; + } + } + + @SelectProvider(type = classInsertscenematch.class,method = "InsertscenematchSQL") + void NewScenematch(@Param("sceneid") int sceneid, + @Param("taskname") String taskname, + @Param("taskstatus") String taskstatus, + @Param("tasktype") String tasktype, + @Param("beginTime") String beginTime, + @Param("endTime") String endTime, + @Param("createby") String createby); + + //------------------------修改赛程信息 + class classupdatescenematch + { + public String updatescenematchSQL(@Param("id") int id, + @Param("sceneid") int sceneid, + @Param("taskname") String taskname, + @Param("taskstatus") String taskstatus, + @Param("tasktype") String tasktype, + @Param("beginTime") String beginTime, + @Param("endTime") String endTime, + @Param("updateby") String updateby) + { + String SQL="update yw_scene_match set "+ + "scene_id=#{sceneid},task_name=#{taskname},"+ + "task_status=#{taskstatus},task_type=#{tasktype},"+ + "begin_time=to_timestamp(#{beginTime},'yyyy-mm-dd hh24:mi:ss'),end_time=to_timestamp(#{endTime},'yyyy-mm-dd hh24:mi:ss'),"+ + "update_by=#{updateby} ,update_time=LOCALTIMESTAMP(0) where id=#{id}"; + return SQL; + } + } + + @SelectProvider(type = classupdatescenematch.class,method = "updatescenematchSQL") + void UpdateScenematch(@Param("id") int id, + @Param("sceneid") int sceneid, + @Param("taskname") String taskname, + @Param("taskstatus") String taskstatus, + @Param("tasktype") String tasktype, + @Param("beginTime") String beginTime, + @Param("endTime") String endTime, + @Param("updateby") String updateby); + + //------------------------删除赛程 + @Delete({"delete from yw_scene_match where id=#{id}"}) + void DeleteScenematch(@Param("id") int id); + //endregion +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_ChuanDong_Mapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_ChuanDong_Mapper.java new file mode 100644 index 0000000..45429b5 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_ChuanDong_Mapper.java @@ -0,0 +1,172 @@ +package com.ruoyi.sunlm.mapper; + +import java.util.List; + +import com.ruoyi.sunlm.daping.*; +import org.apache.ibatis.annotations.*; +import org.springframework.stereotype.Component; + +/** + * 数据层 + * + * @author ruoyi + */ +@Mapper +@Component +public interface dpNewYayun_ChuanDong_Mapper ////2023。5.10,新版大屏的接口 +{ + + //region------------------------------------------------------------------------------------传输告警接口 + class class_get_trans_alarms + { + public String get_trans_alarms_SQL(@Param("level") int level, + @Param("sceneid") int sceneid, + @Param("alarmtype") String alarmtype) + { + String SQL=" "; + if ((level==1) || (level==2)) //全域或城区的场馆的传输告警 + { + SQL = " select 告警时间 eventtime, " + + " 告警名称 alarmname, " + + " 场馆id ," + + " 区域id," + + " 网元名称 netname, " + + " 分公司 areaname, " + + " 告警类型 alarmtype, " + + " 告警等级 alarmlevel, " + + " 设备类型 devicetype, " + + " 是否端口告警 isportalarm from dp_2_view_trans_alarms " + + " where 恢复时间 is null " + + " and 告警类型 = #{alarmtype} order by 告警时间 desc limit 20"; + } + + return SQL; + } + + public String get_trans_alarms_all_SQL() + { + String SQL= " select 告警时间 eventtime, 告警名称 alarmname,场馆id ,区域id,网元名称 netname,分公司 areaname, " + + " 告警类型 alarmtype, 告警等级 alarmlevel,设备类型 devicetype,是否端口告警 isportalarm from dp_2_view_trans_alarms " + + " where 恢复时间 is null " + + " order by 告警时间 desc"; + return SQL; + } + + public String get_maps_all_alarms_SQL(){ + String SQL = "select 告警类型 major,告警时间 eventtime, 告警名称 alarmname, 网元名称 netname,场馆id sceneid,场馆名称 scenename,故障处理人 handlepeople,phonenumber " + + "from dp_2_view_trans_alarms where 恢复时间 is null order by 告警时间 desc"; + return SQL; + } + } + + + + @SelectProvider(type = dpNewYayun_ChuanDong_Mapper.class_get_trans_alarms.class,method = "get_trans_alarms_SQL") + List get_trans_alarms_list(@Param("level") int level, + @Param("sceneid") int sceneid, + @Param("alarmtype") String alarmtype); + + @SelectProvider(type = dpNewYayun_ChuanDong_Mapper.class_get_trans_alarms.class,method = "get_trans_alarms_all_SQL") + List get_trans_alarms_all_list(); + + @SelectProvider(type = dpNewYayun_ChuanDong_Mapper.class_get_trans_alarms.class,method = "get_maps_all_alarms_SQL") + List get_maps_alarms_all_alarms(); + //endregion + + + + + + //region------------------------------------------------------------------------------------机房环境告警清单 + class class_get_machineroom_alarms_list + { + public String get_machineroom_alarms_list_all_SQL() + { + return "select * from dp_2_view_power_alarm " + + "where 场馆id is not null order by eventtime desc limit 20 "; + } + } + + + + @SelectProvider(type = dpNewYayun_ChuanDong_Mapper.class_get_machineroom_alarms_list.class,method = "get_machineroom_alarms_list_all_SQL") + List get_machineroom_alarms_all_list(); + //endregion + + //region------------------------------------------------------------------------------------环路流量TOP5 + class class_get_huanlu_top5 + { + public String get_huanlu_top5_all_SQL() + { + return "select mename,portname,round(max(flow)::numeric, 2) flow from dp_2_view_view_flow " + + "GROUP BY mename,portname order by max(flow) desc limit 5"; + } + } + + @SelectProvider(type = dpNewYayun_ChuanDong_Mapper.class_get_huanlu_top5.class,method = "get_huanlu_top5_all_SQL") + List get_huanlu_top5_all(); + //endregion + + //region------------------------------------------------------------------------------------ 光功率清单 + class class_get_opticalpower_list + { + public String get_opticalpower_list_all_SQL() + { + // return " SELECT distinct on (mename) * FROM dp_2_view_view_opticalpower limit 20 "; // Mybatis 会报语法错误 + String sql=" select t.* from "+ + " ( "+ + " select *,row_number() OVER (PARTITION BY mename ORDER BY date_time DESC) rn FROM dp_2_view_view_opticalpower "+ + " ) t where t.rn =1 "; + return sql; + } + } + + @SelectProvider(type = dpNewYayun_ChuanDong_Mapper.class_get_opticalpower_list.class,method = "get_opticalpower_list_all_SQL") + List get_opticalpower_all_list(); + //endregion + + + //region------------------------------------------------------------------------------------中间地图告警显示接口 + class class_get_maps_all_trans_alarms + { + public String get_maps_all_alarms_SQL() + { + String SQL=" "; + String areanames= " ('上城','拱墅','西湖','滨江','萧山','余杭','临平','钱塘','富阳','临安','桐庐','淳安','建德') "; + SQL = " with t1 as " + + " ( select id venueid,'' venuetypeid,'' venuetype, " + + " case" + + " when length(COALESCE(maintain_type,''))=0 then venue_name " + + " else venue_name || '(' || maintain_type || ')' " + + " end venuename, " + + " longitude_dp longitude,latitude_dp latitude," + + "b.dict_label areaname from yw_scene a , sys_dict_data b where scene_big_id in " + + " (select id from yw_scene_big_config where status='2') and longitude<>0 and a.area_county_id=b.dict_value " + + " and a.venue_type ='比赛场馆' " + + " and b.dict_type= 'yw_county' and id not in (10000,10500,20000,20100,20200,20300,20400) and b.dict_label in " + areanames + " )," + + " t2 as " + + " ( select 场馆id,count(*) alarmcount from dp_2_view_trans_alarms group by 场馆id ) , " + + " t3 as " + + " ( select 场馆id,count(*) loopcount from dp_2_view_trans_alarms where 告警类型 = '开环类' group by 场馆id ) ," + + " t4 as " + + " ( select 场馆id,count(*) devicecount from dp_2_view_trans_alarms where 告警类型 = '设备托管' group by 场馆id ) ," + + " t5 as " + + " ( select 场馆id,count(*) hardwarecount from dp_2_view_trans_alarms where 告警类型 = '硬件故障' group by 场馆id ) " + + " select t1.*,COALESCE(t2.alarmcount,0) alarmcount,COALESCE(t3.loopcount,0) loopcount,COALESCE(t4.devicecount,0) devicecount," + + "COALESCE(t5.hardwarecount,0) hardwarecount" + + " from t1 " + + " left join t2 on t1.venueid=t2.场馆id" + + " left join t3 on t1.venueid=t3.场馆id" + + " left join t4 on t1.venueid=t4.场馆id" + + " left join t5 on t1.venueid=t5.场馆id"; + return SQL; + } + } + @SelectProvider(type = dpNewYayun_ChuanDong_Mapper.class_get_maps_all_trans_alarms.class,method = "get_maps_all_alarms_SQL") + List get_maps_all_alarms(); + //endregion + + + + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_Dict_Mapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_Dict_Mapper.java new file mode 100644 index 0000000..80b65d7 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_Dict_Mapper.java @@ -0,0 +1,99 @@ +package com.ruoyi.sunlm.mapper; + +import java.util.List; + +import com.ruoyi.sunlm.daping.*; +import org.apache.ibatis.annotations.*; +import org.springframework.stereotype.Component; + +/** + * 数据层 + * + * @author ruoyi + */ +@Mapper +@Component +public interface dpNewYayun_Dict_Mapper ////2023。5.10,新版大屏的接口 +{ + + //region------------------------------------------------------------------------------------DICT:区县列表 + @Select("select * from dp_2_dict_config order by id ") + List get_dict_list(); + //endregion + + //region------------------------------------------------------------------------------------DICT:地图告警列表 + @Select(" (select '监控' major , projectname netname, " + + " '在线率低 ('|| onlinerate ||'%)' alarmname,LOCALTIMESTAMP(0)::text eventtime,null handlepeople,null phonenumber,quxian code from dp_2_dict_project "+ + " where onlinerate::float8<98 order by onlinerate asc)"+ + " union all "+ + " (select '制证' , 网元名称 , " + + " 告警名称 ,告警时间::text ,null,null,分公司 from dp_2_view_dict_link_alarm where 项目类型='制证验证' order by 告警时间 desc) "+ + " union all "+ + " (select '特勤' , 网元名称 , " + + " 告警名称 ,告警时间::text ,null,null,分公司 from dp_2_view_dict_link_alarm where 项目类型='TQ安保' order by 告警时间 desc) " + ) + List get_map_alarm_list(); + //endregion + + + //region------------------------------------------------------------------------------------DICT:监控类项目统计 + @Select("select * from dp_2_dict_project_stat where batchid=(select max(batchid) from dp_2_dict_project_stat) ") + class_dp_6_dict_project_statis get_dict_monitor_project_stat(); + //endregion + + //region------------------------------------------------------------------------------------DICT:监控类项目 + @Select("select * from dp_2_dict_project where batchid=(select max(batchid) from dp_2_dict_project) ") + List get_dict_monitor_project_list(); + //endregion + + //region------------------------------------------------------------------------------------DICT:监控类告警 + @Select("select * from dp_2_view_dict_alarm where batchid=(select max(batchid) from dp_2_view_dict_alarm) order by createtime desc limit 20 ") + List get_dict_monitor_alarm_list(); + //endregion + + //region------------------------------------------------------------------------------------DICT:链路类告警 + @Select("select * from dp_2_view_dict_link_alarm where batchid=(select max(batchid) from dp_2_view_dict_link_alarm) order by 告警时间 desc limit 20 ") + List get_dict_link_alarm_list(); + //endregion + + //region------------------------------------------------------------------------------------DICT:终端接入统计 + class class_get_dict_clientcount // X轴0-24点,15分钟一个间隔,昨日今日对比, + { + public String get_dict_clientcount_SQL() + { + String SQL= " select * from dp_2_dict_wbc_hisclientcountday_statis where batchid=(select max(batchid) from dp_2_dict_wbc_hisclientcountday_statis)"+ + " order by adate "; + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Dict_Mapper.class_get_dict_clientcount.class,method = "get_dict_clientcount_SQL") + List get_dict_clientcount(); + //endregion + + //region------------------------------------------------------------------------------------DICT:终端流量统计 + class class_get_dict_clientstream // X轴0-24点,15分钟一个间隔,昨日今日对比, + { + public String get_dict_clientstream_SQL() + { + String SQL= " select * from dp_2_dict_wbc_hisclientsteamday_statis where batchid=(select max(batchid) from dp_2_dict_wbc_hisclientsteamday_statis)"+ + " order by adate "; + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Dict_Mapper.class_get_dict_clientstream .class,method = "get_dict_clientstream_SQL") + List get_dict_clientstream (); + //endregion + + //region------------------------------------------------------------------------------------DICT: AP在线数和总数统计 + @Select(" select sum(设备数1) 设备数1,sum(设备数2) 设备数2 from " + + " (" + + " (select online_num 设备数1 , total_num 设备数2 from dp_2_dict_wifi_online order by eventtime desc limit 1) " + + " union all " + + " (select online 设备数1 , total 设备数2 from dp_2_dict_wbc_currentapcount order by inserttime desc limit 1) " + + " ) as x ") + List get_dict_ap_count(); + //endregion + + + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_Gailan_Mapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_Gailan_Mapper.java new file mode 100644 index 0000000..3665baa --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_Gailan_Mapper.java @@ -0,0 +1,260 @@ +package com.ruoyi.sunlm.mapper; + +import java.util.List; + +import com.ruoyi.sunlm.daping.*; +import org.apache.ibatis.annotations.*; +import org.springframework.stereotype.Component; + +/** + * 数据层 + * + * @author ruoyi + */ +@Mapper +@Component +public interface dpNewYayun_Gailan_Mapper ////2023。5.10,新版大屏的接口 +{ + + //region------------------------------------------------------------------------------------获取缓存配置 + @Select(" select * from dp_2_cache_config") + class_dp_1_cache_config get_cache_config(); + //endregion + + //region------------------------------------------------------------------------------------获取概览:无线退服统计 + ///@Select(" select * from dp_2_wireless_alarm_statistics where batchid=(select max(batchid) from dp_2_wireless_alarm_statistics) ") + //------------------为了保证和故障清单显示同步,改成直接取,从统计中取可能会有1分钟时间差。 + @Select(" with t1 as " + + " ( select 1 sign,count(*) 退服数2G from dp_2_view_wireless_alarm where sitetype like '2G%' " + + //" and to_char(eventtime,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') " + + " and (场馆id is not null or 区域id is not null ) ), " + + " t2 as " + + " (select 1 sign,count(*) 退服数4G from dp_2_view_wireless_alarm where sitetype like '4G%' " + + //" and to_char(eventtime,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') " + + " and (场馆id is not null or 区域id is not null)), " + + " t3 as " + + " (select 1 sign,count(*) 退服数5G from dp_2_view_wireless_alarm where sitetype like '5G%' " + + //" and to_char(eventtime,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') " + + " and (场馆id is not null or 区域id is not null)), " + + " t4 as " + + " (select 1 sign , (select count(distinct 基站全称) from dp_2_scene_spot_allcells)+" + + " (select count(distinct 基站全称) from dp_2_scene_spot_gsmcells) 基站总数 " + + " ) " + + " select t1.退服数2G,t2.退服数4G,t3.退服数5G,t4.基站总数,2 batchid from t1 " + + " left join t2 on t1.sign=t2.sign " + + " left join t3 on t1.sign=t3.sign " + + " left join t4 on t1.sign=t4.sign ") + List get_wireless_outservice(); + //endregion + + //region------------------------------------------------------------------------------------概览:4/5G无线流量 + class class_get_gbflow_wireless // X轴0-24点,15分钟一个间隔,昨日今日对比 + { + public String get_gbflow_wireless_SQL( + @Param("typeid") int typeid) + { + String SQL=" "; + if (typeid==1) //4G + { + SQL= " select * from dp_2_gbflow_4g_statistics where batchid=(select max(batchid) from dp_2_gbflow_4g_statistics) " + + " order by adate "; + + } + else //5G //(select max(结束时间) from pm_kpi5g_venue) + { + SQL= " select * from dp_2_gbflow_5g_statistics where batchid=(select max(batchid) from dp_2_gbflow_5g_statistics) "+ + " order by adate "; + + } + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Gailan_Mapper.class_get_gbflow_wireless.class,method = "get_gbflow_wireless_SQL") + List get_gbflow_wireless(@Param("typeid") int typeid); + //endregion + + //region------------------------------------------------------------------------------------概览:综合管理统计 + //20230822 签到和巡检做个过滤,只要杭州的,修改了日期为当天当前时间之前 + //inspect_date::Date=current_date + @Select(" with t1 as " + + " (select 1 sign, count(*) 应签到数量 from v_yw_sign_log where " + + //" sign_date::Date=current_date " + + " begin_time between CURRENT_DATE::TIMESTAMP and now() "+ + " and city='杭州' )," + + " t2 as " + + " (select 1 sign,count(*) 实际签到数 from v_yw_sign_log " + + "where begin_time between CURRENT_DATE::TIMESTAMP and now() " + + "and sign_in_time is not null and city = '杭州'), " + + " t3 as " + + " (select 1 sign ,count(*) 巡检任务数 from v_yw_rout_inspect_log y where " + + " begin_time between CURRENT_DATE::TIMESTAMP and now() +'-2 hour' and city = '杭州'), " + + " t4 as " + + " (select 1 sign ,count(*) 已巡检任务 from v_yw_rout_inspect_log where feed_back_time is not null and " + + // " inspect_date::Date=current_date " + + " begin_time between CURRENT_DATE::TIMESTAMP and now() +'-2 hour' "+ + " and city='杭州') " + + + " select t1.应签到数量,t2.实际签到数 ," + + " case " + + " when t1.应签到数量::numeric=0 then 0" + + " else round(t2.实际签到数/t1.应签到数量::numeric*100,2) " + + " end 人员签到率," + + " t3.巡检任务数,t4.已巡检任务, " + + " case " + + " when t3.巡检任务数::numeric=0 then 0" + + " else round(t4.已巡检任务/t3.巡检任务数::numeric*100,2) " + + " end 巡检完成率 " + + " from t1 " + + " left join t2 on t1.sign=t2.sign " + + " left join t3 on t1.sign=t3.sign " + + " left join t4 on t1.sign=t4.sign " + ) + List get_manage_counts(); + //endregion + + //region------------------------------------------------------------------------------------概览:DICT统计 + @Select(" with t1 as" + + " (select dict_equip_num 设备数,1 sign from yw_scene_noticeinfo where id=1), "+ + " t2 as " + + " (select count(*) 告警总数,1 sign from dp_2_dict_link_alarm ), "+ + " t3 as " + + " (select count(*) 告警总数,1 sign from dp_2_dict_alarm ) "+ + " select COALESCE(t1.设备数,0) 设备数, COALESCE(t2.告警总数,0)+COALESCE(t3.告警总数,0) 告警总数 from "+ + " t1 " + + " left join t2 on t1.sign=t2.sign "+ + " left join t3 on t1.sign=t3.sign " + ) + List get_dict_counts(); + //endregion + + //region------------------------------------------------------------------------------------概览:动力传输统计 + @Select(" with t1 as " + + " (select 1 sign,COALESCE(public_transport_equip_num+private_transport_equip_num,0) 设备数1 from yw_scene_noticeinfo where id =1)," + + " t2 as " + + " (select 1 sign , COALESCE(dh_net_num,0) 设备数2 from yw_scene_noticeinfo where id=1 )," + + " t3 as " + + " (select 1 sign,count(*) 告警总数1 from dp_2_view_trans_alarms " + + //" where to_char(告警时间,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') " + + " where 1=1 " + + " and 场馆id is not null) ," + + " t4 as " + + " (select 1 sign,count(*) 告警总数2 from dp_2_view_power_alarm " + + //" where to_char(eventtime,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') " + + " where 1=1 " + + //" and (场馆id is not null or 区域id is not null) ) " + //只显示场馆的 + " and (场馆id is not null ) ) " + + " select t1.设备数1,t2.设备数2 ,t3.告警总数1,t4.告警总数2 " + + " from t1 " + + " left join t2 on t1.sign=t2.sign " + + " left join t3 on t1.sign=t3.sign " + + " left join t4 on t1.sign=t4.sign " //传输只有场馆告警 + ) + List get_trans_counts(); + //endregion + + //region------------------------------------------------------------------------------------概览:全网保障传输环路流量 + class class_get_gbflow_huanlu // X轴0-24点,15分钟一个间隔,昨日今日对比, + { + public String get_gbflow_huanlu_SQL() + { + String SQL= " select * from dp_2_view_flow_statistics where batchid=(select max(batchid) from dp_2_view_flow_statistics)"+ + " order by adate "; + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Gailan_Mapper.class_get_gbflow_huanlu.class,method = "get_gbflow_huanlu_SQL") + List get_gbflow_huanlu(); + //endregion + + //region------------------------------------------------------------------------------------概览:AGIS和互联网统计接口 + class class_get_agis_internet_counts // X轴0-24点,15分钟一个间隔,昨日今日对比, + { + public String get_agis_internet_counts_SQL() + { + String SQL = " with t1 as " + + " (select 1 sign,COALESCE(agis_num,0) 设备数1 from yw_scene_noticeinfo where id=1 )," + + " t2 as " + + " (select 1 sign ,COALESCE(wifi_net_num,0) 设备数2 from yw_scene_noticeinfo where id=1)," + + " t3 as " + + " (select 1 sign , count(*) 告警总数1 from dp_2_view_agis_alarms_combine " + + //" where to_char(告警时间,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') " + + " where 1=1 " + + " and 专业='AGIS') ," + + " t4 as " + + " (select 1 sign ,count(*) 告警总数2 from dp_2_view_agis_alarms_combine " + + //" where to_char(告警时间,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') " + + " where 1=1 " + + " and 专业='WIFI') " + + " select t1.设备数1,t2.设备数2 ,t3.告警总数1,t4.告警总数2 " + + " from t1 " + + " left join t2 on t1.sign=t2.sign " + + " left join t3 on t1.sign=t3.sign " + + " left join t4 on t1.sign=t4.sign "; + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Gailan_Mapper.class_get_agis_internet_counts.class,method = "get_agis_internet_counts_SQL") + List get_agis_internet_counts(); + //endregion + + //region------------------------------------------------------------------------------------概览:中间地图告警显示接口 + class class_get_maps_all_alarms + { + public String get_maps_all_alarms_SQL(@Param("level") int level) + { + String SQL=" "; + String areanames=" "; + if (level==0) //所有,不会用 + { + areanames = " ('上城','拱墅','西湖','滨江','萧山','余杭','临平','钱塘','富阳','临安','桐庐','淳安','建德') "; + } + else if (level==1) //1 : 全域(除了 上城区 、拱墅区、西湖区、滨江区 ,'萧山','钱塘'之外的区域), + { + //areanames = " ('余杭','临平','富阳','临安','桐庐','淳安','建德') "; + areanames = " ('上城','拱墅','西湖','滨江','萧山','余杭','临平','钱塘','富阳','临安','桐庐','淳安','建德') "; + } + else if (level==2) { //城区 上城区 、拱墅区、西湖区、滨江区,'萧山','钱塘' + areanames = " ('上城','拱墅','西湖','滨江','萧山','钱塘') "; + } + SQL =" select * from dp_2_maps_allalarms_statistics where batchid=(select max(batchid) from dp_2_maps_allalarms_statistics) " + + " and areaname in " +areanames; + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Gailan_Mapper.class_get_maps_all_alarms.class,method = "get_maps_all_alarms_SQL") + List get_maps_all_alarms(@Param("level") int level); + //endregion + + //region------------------------------------------------------------------------------------概览:中间地图告警弹出列表 + class class_get_maps_all_alarms_popup + { + public String get_maps_all_alarms_popup_SQL() + { + String SQL=" "; + /* + SQL =" select '无线' major , case when cell_name is null then site_name else cell_name end netname, " + + " alarmname alarmname,eventtime eventtime,故障处理人 handlepeople,phonenumber,场馆id sceneid from dp_2_view_wireless_alarm where 场馆id is not null "+ + " and to_char(eventtime,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') "+ + " union all "+ + " select '动环' , site_name , " + + " alarmname ,eventtime ,故障处理人,phonenumber,场馆id sceneid from dp_2_view_power_alarm where 场馆id is not null "+ + " and to_char(eventtime,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') "+ + " union all "+ + " select '传输' , 网元名称 , " + + " 告警名称, 告警时间,故障处理人,phonenumber ,场馆id sceneid from dp_2_view_trans_alarms where 场馆id is not null "+ + " and to_char(告警时间,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') "+ + " union all "+ + " select '专网' , 网元名称 , " + + " 告警名称, 告警时间,故障处理人,phonenumber ,场馆id sceneid from dp_2_view_agis_alarms where 场馆id is not null "+ + " and to_char(告警时间,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') ";*/ + SQL =" select * from dp_2_maps_allalarms_list where batchid=(select max(batchid) from dp_2_maps_allalarms_list) "; + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Gailan_Mapper.class_get_maps_all_alarms_popup.class,method = "get_maps_all_alarms_popup_SQL") + List get_maps_all_alarms_popup(); + //endregion + + + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_Wuxian_Mapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_Wuxian_Mapper.java new file mode 100644 index 0000000..dff3d0a --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_Wuxian_Mapper.java @@ -0,0 +1,1394 @@ +package com.ruoyi.sunlm.mapper; + +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DateTime; +import com.github.pagehelper.PageInfo; +import com.ruoyi.sunlm.daping.*; + +import org.apache.ibatis.annotations.*; +import org.springframework.stereotype.Component; + +/** + * 数据层 + * + * @author ruoyi + */ +@Mapper +@Component +public interface dpNewYayun_Wuxian_Mapper ////2023。5.10,新版大屏的接口 +{ + //region--------------------------------------------------------------------------------------公共方法 + class class_getmincontroltype { + public String getmincontroltype_SQL(@Param("areaid") int areaid, + @Param("sceneid") int sceneid + ) + { + String swhere = " where 1=2 "; + if (areaid>0) swhere =" where areaid=#{areaid} "; + else if (sceneid>0) swhere =" where sceneid=#{sceneid} "; + String SQL=" select COALESCE((select mintype from dp_2_scene_control "+swhere+" limit 1),15) "; //没有配置的,都以15分钟展示 + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_getmincontroltype.class,method = "getmincontroltype_SQL") + int getmincontroltype(@Param("areaid") int areaid, + @Param("sceneid") int sceneid); + //endregion + + //region------------------------------------------------------------------------------------获取场馆列表 + @Select("select * from dp_2_view_otherscene") + List getvenuelists(); + //endregion + + //region------------------------------------------------------------------------------------获取某个场馆的信息 + @Select(" select id venueId,venue_name venueName , longitude,latitude from yw_scene " + + " where id=#{sceneid} order by id") + class_dp_2_scenelist getonevenue(@Param("sceneid") int sceneid); + //endregion + + //region------------------------------------------------------------------------------------获取某个场馆的坐席中文名 + @Select(" select * from dp_2_seat_chinesename") + List get_seat_chinesename(); + //endregion + + //region------------------------------------------------------------------------------------获取景区列表,是否有告警 + @Select(" select distinct 景区大类 from dp_2_spot_config ") + List getspottypes(); + + class class_spot_wirelessalarms_lists + { + public String get_spot_wirelessalarms_lists_SQL(@Param("spottypeid") int spottypeid) + { + String swhere=""; + if (spottypeid!=0) swhere=" where 景区大类id=#{spottypeid} "; + String SQL="with t1 as " + + "( select 景区id spotId,景区大类id spotTypeid,景区大类 spotType,景区名称 spotName,中心经度 longitude,中心纬度 latitude ,景区介绍 spotDetail " + + " from dp_2_spot_config "+swhere+" )," + + "t2 as " + + "(" + + " select count(*) cnt,区域id from dp_2_view_wireless_alarm " + + //" where to_char(eventtime,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') " + + " where 1=1 " + + " and 区域id is not null group by 区域id " + + ")" + + "select t1.*,COALESCE(t2.cnt,0) alarmcount from t1 left join t2 on t1.spotId=t2.区域id "; + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_spot_wirelessalarms_lists.class,method = "get_spot_wirelessalarms_lists_SQL") + List getspotlist(@Param("spottypeid") int spottypeid); + //endregion + + //region------------------------------------------------------------------------------------景区无线告警清单 + class class_spot_wirelessalarms_popup + { + public String get_spot_wirelessalarms_popup_SQL() + { + //String swhere="where to_char(eventtime,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') and 区域id is not null "; //今天的告警 + /* + String swhere="where 区域id is not null "; + String SQL =" select '无线' major , case when cell_name is null then site_name else cell_name end netname, " + + " alarmname alarmname,eventtime eventtime,'' handlepeople,区域id sceneid from dp_2_view_wireless_alarm "+swhere;*/ + String SQL =" select * from dp_2_maps_spotalarms_list where batchid=(select max(batchid) from dp_2_maps_spotalarms_list) "; + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_spot_wirelessalarms_popup.class,method = "get_spot_wirelessalarms_popup_SQL") + List get_spot_wirelessalarms_popup(); + //endregion + + //region------------------------------------------------------------------------------------无线告警清单 + class classwirelessalarmslists + { + public String getwirelessalarmslistsSQL(@Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid + ) + { + //String swhere="where to_char(eventtime,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') "; //今天的告警 + String swhere="where 1=1 "; + if (level==1) //全域 场馆+景点 + { + swhere+=" and (区域id is not null or 场馆id is not null) "; + } + else if (level==2 ) { //区域(场馆+景点)+景区 + if (areaid!=0) + swhere+=" and 区域id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; //传入的是大类 + else + swhere+= " and (区域id is not null or 场馆id is not null) "; + } + else if (level==3 ) { // 场馆 + if (sceneid!=0) { + swhere+=" and 场馆id = #{sceneid} " ; + } + } + String SQL="select * from dp_2_view_wireless_alarm " + swhere + " order by eventtime desc limit 20 "; + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.classwirelessalarmslists.class,method = "getwirelessalarmslistsSQL") + List get_wireless_alarms_list(@Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid); + //endregion + + //region------------------------------------------------------------------------------------动环告警清单 + class classpoweralarmslists + { + public String getpoweralarmslistsSQL(@Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid + ) + { + //String swhere="where to_char(eventtime,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') "; //看今天的? + String swhere="where 1=1 "; + if (level==1) //全域 + { + swhere+= " and (区域id is not null or 场馆id is not null) " ; + } + else if (level==2) { //区域 + if (areaid!=0) //景点 + swhere+=" and 区域id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; //传入的是大类 + else + swhere+=" and (区域id is not null or 场馆id is not null) "; + } + else if (level==3 ) { // 场馆 + if (sceneid!=0) { + swhere+=" and 场馆id= #{sceneid} " ; + } + } + String SQL="select * from dp_2_view_power_alarm " + swhere + " order by eventtime desc limit 20 "; + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.classpoweralarmslists.class,method = "getpoweralarmslistsSQL") + List get_power_alarms_list(@Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid); + //endregion + + //region------------------------------------------------------------------------------------国际漫入漫出统计 + class class_get_roam_national + { + public String get_roam_national_SQL( + @Param("typeid") int typeid) + { + String SQL=" "; + String skind=" "; + if (typeid == 1) //漫入 + { + skind = "国际漫入"; + } + else { + skind = "国际漫出"; //待定 + } + String sTime = " (select max(stat_time) from dp_2_roams_statistics where position('"+skind+"' in kind)>0 ) "; + String swhere = " where position('"+skind+"' in kind)>0 "; + SQL = " select row_number() over(order by usercount::numeric desc) title,from_area name,usercount value " + + " from dp_2_roams_statistics "+ swhere+" and stat_time="+sTime+ + " order by usercount::numeric desc limit 5 "; + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_get_roam_national.class,method = "get_roam_national_SQL") + List get_roam_national(@Param("typeid") int typeid); + //endregion + + //region------------------------------------------------------------------------------------省内漫入漫出统计 + class class_get_roam_inner + { + public String get_roam_inner_SQL( + @Param("typeid") int typeid) + { + String SQL=" "; + String skind=" "; + if (typeid == 1) //漫入 + { + skind = "国内漫入"; + } + else { + skind = "国内漫出"; //待定 + } + String sTime = " (select max(stat_time) from dp_2_roams_statistics where position('"+skind+"' in kind)>0 ) "; + String swhere = " where position('"+skind+"' in kind)>0 "; + SQL = " select row_number() over(order by usercount::numeric desc) title,from_area name,usercount value " + + " from dp_2_roams_statistics "+ swhere+" and stat_time="+sTime+ + " order by usercount::numeric desc limit 5 "; + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_get_roam_inner.class,method = "get_roam_inner_SQL") + List get_roam_inner(@Param("typeid") int typeid); + //endregion + + //region ------------------------------------------------------------------------------------区域用户数 + class class_get_area_usercounts // 区域用户数,15分钟,X轴0-24点,15分钟一个间隔,昨日今日对比 + { + public String get_area_usercounts_SQL( + @Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid, + @Param("typeid") int typeid) + { + String SQL=" "; + + if (typeid==1) //4G //(select max(结束时间) from pm_kpi4g_venue) + { + if ((level==1) || (level==2) ) //区域,默认为全域,AREAID>0 时,景区 + { + String sTime = " LOCALTIMESTAMP(0) "; + String swhere=" where 1=1 "; + if ((areaid!=0) && (level==2)) swhere=" where 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), (select max(结束时间) from pm_kpi4g_spot "+swhere+" ), '15 min' ) AS b " + //where 景区id=#{areaid} + " group by time ORDER BY time ASC )," + + /* + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,sum(round(最大用户数::numeric, 2)) value , 1 sign from pm_kpi4g_spot " + swhere + + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd') group by datetime" + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,sum(round(最大用户数::numeric, 2)) value , 2 sign from pm_kpi4g_spot " +swhere + + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') group by datetime" + + " ) " + + */ + + " t2 as " + + " (select datetime, sum(value1) value , sign from dp_2_kpi4g_allspots_statistics " +swhere+ + " and sign=1 and batchid=(select max(batchid) from dp_2_kpi4g_allspots_statistics) group by sign,datetime " + + " )," + + + " t3 as " + + " (select datetime, sum(value1) value, sign from dp_2_kpi4g_allspots_statistics " +swhere+ + " and sign=2 and batchid=(select max(batchid) from dp_2_kpi4g_allspots_statistics) group by sign,datetime " + + " ) " + + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + } + else if (level==3) //场馆 + { + String sTime = " LOCALTIMESTAMP(0) "; + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), (select max(结束时间) from pm_kpi4g_venue where 场馆id =#{sceneid}), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + /* + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 1 sign from pm_kpi4g_venue where 场馆id=#{sceneid}" + + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd')" + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 2 sign from pm_kpi4g_venue where 场馆id=#{sceneid} " + + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') " + + " ) " + + */ + + " t2 as " + + " (select datetime, value1 value , sign from dp_2_kpi4g_allvenue_statistics where 场馆id=#{sceneid} " + + " and sign=1 and batchid=(select max(batchid) from dp_2_kpi4g_allvenue_statistics) " + + " )," + + + " t3 as " + + " (select datetime, value1 value , sign from dp_2_kpi4g_allvenue_statistics where 场馆id=#{sceneid} " + + " and sign=2 and batchid=(select max(batchid) from dp_2_kpi4g_allvenue_statistics) " + + " ) " + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + } + } + else //5G //(select max(结束时间) from pm_kpi5g_venue) + { + if ((level==2) || (level==1)) //区域,默认为全域,AREAID>0 时,景区 + { + String sTime = " LOCALTIMESTAMP(0) "; + String swhere=" where 1=1 "; + if ((areaid!=0) && (level==2)) swhere=" where 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), (select max(结束时间) from pm_kpi5g_spot "+swhere+"), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + /* + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,sum(round(最大用户数::numeric, 2)) value , 1 sign from pm_kpi5g_spot " +swhere+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd') group by datetime " + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,sum(round(最大用户数::numeric, 2)) value , 2 sign from pm_kpi5g_spot " +swhere+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') group by datetime " + + " ) " + + */ + " t2 as " + + " (select datetime, sum(value1) value, sign from dp_2_kpi5g_allspots_statistics " +swhere+ ////where 景区id=#{areaid} + " and sign=1 and batchid=(select max(batchid) from dp_2_kpi5g_allspots_statistics) group by sign,datetime " + + " )," + + + " t3 as " + + " (select datetime, sum(value1) value, sign from dp_2_kpi5g_allspots_statistics " +swhere+ ////where 景区id=#{areaid} + " and sign=2 and batchid=(select max(batchid) from dp_2_kpi5g_allspots_statistics) group by sign,datetime " + + " ) " + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + } + else if (level==3) //场馆 + { + String sTime = " LOCALTIMESTAMP(0) "; + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), (select max(结束时间) from pm_kpi5g_venue where 场馆id =#{sceneid}), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + /* + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 1 sign from pm_kpi5g_venue where 场馆id=#{sceneid}" + + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd')" + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 2 sign from pm_kpi5g_venue where 场馆id=#{sceneid} " + + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') " + + " ) " + + */ + " t2 as " + + " (select datetime, value1 value , sign from dp_2_kpi5g_allvenue_statistics where 场馆id=#{sceneid} " + + " and sign=1 and batchid=(select max(batchid) from dp_2_kpi5g_allvenue_statistics) " + + " )," + + + " t3 as " + + " (select datetime, value1 value, sign from dp_2_kpi5g_allvenue_statistics where 场馆id=#{sceneid} " + + " and sign=2 and batchid=(select max(batchid) from dp_2_kpi5g_allvenue_statistics) " + + " ) " + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + } + } + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_get_area_usercounts.class,method = "get_area_usercounts_SQL") + List get_area_usercounts(@Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid, + @Param("typeid") int typeid); + //endregion + + //region -----------------------------------------------------------------------------------区域流量 + class class_get_area_gbflow // 区域流量,15分钟,,X轴0-24点,15分钟一个间隔,昨日今日对比 + { + public String get_area_gbflow_SQL( + @Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid, + @Param("typeid") int typeid) + { + String SQL=" "; + if (typeid==1) //4G//(select max(结束时间) from pm_kpi4g_venue) + { + if ((level==1) || (level==2)) //区域,景区 + { + String sTime = " LOCALTIMESTAMP(0) "; + String swhere=" where 1=1 "; + if ((areaid!=0) && (level==2)) swhere=" where 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), (select max(结束时间) from pm_kpi4g_spot "+swhere+" ), '15 min' ) AS b " + //where 景区id=#{areaid} + " group by time ORDER BY time ASC )," + + /* + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,sum(round(\"流量GB\"::numeric, 2)) value , 1 sign from pm_kpi4g_spot " +swhere+ ////where 景区id=#{areaid} + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd') group by datetime" + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,sum(round(\"流量GB\"::numeric, 2)) value , 2 sign from pm_kpi4g_spot " +swhere + //where 景区id=#{areaid} + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') group by datetime" + + " ) " + + */ + + " t2 as " + + " (select datetime, sum(value2) value, sign from dp_2_kpi4g_allspots_statistics " +swhere+ ////where 景区id=#{areaid} + " and sign=1 and batchid=(select max(batchid) from dp_2_kpi4g_allspots_statistics) group by sign,datetime " + + " )," + + + " t3 as " + + " (select datetime, sum(value2) value, sign from dp_2_kpi4g_allspots_statistics " +swhere+ ////where 景区id=#{areaid} + " and sign=2 and batchid=(select max(batchid) from dp_2_kpi4g_allspots_statistics) group by sign,datetime " + + " ) " + + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + } + else if (level==3) //场馆 + { + String sTime = " LOCALTIMESTAMP(0) "; + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), (select max(结束时间) from pm_kpi4g_venue where 场馆id =#{sceneid}), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + /* + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 1 sign from pm_kpi4g_venue where 场馆id=#{sceneid}" + + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd')" + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 2 sign from pm_kpi4g_venue where 场馆id=#{sceneid} " + + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') " + + " ) " + + */ + " t2 as " + + " (select datetime, value2 value, sign from dp_2_kpi4g_allvenue_statistics where 场馆id=#{sceneid} " + + " and sign=1 and batchid=(select max(batchid) from dp_2_kpi4g_allvenue_statistics) " + + " )," + + + " t3 as " + + " (select datetime, value2 value, sign from dp_2_kpi4g_allvenue_statistics where 场馆id=#{sceneid} " + + " and sign=2 and batchid=(select max(batchid) from dp_2_kpi4g_allvenue_statistics) " + + " ) " + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + } + } + else //5G /(select max(结束时间) from pm_kpi4g_venue) + { + if ((level==1) || (level==2)) //区域 + { + String sTime = " LOCALTIMESTAMP(0) "; + String swhere=" where 1=1 "; + if ((areaid!=0) && (level==2)) swhere=" where 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), (select max(结束时间) from pm_kpi5g_spot "+swhere+"), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + /* + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,sum(round(\"流量GB\"::numeric, 2)) value , 1 sign from pm_kpi5g_spot " +swhere+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd') group by datetime " + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,sum(round(\"流量GB\"::numeric, 2)) value , 2 sign from pm_kpi5g_spot " +swhere+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') group by datetime " + + " ) " + + */ + + " t2 as " + + " (select datetime, sum(value2) value, sign from dp_2_kpi5g_allspots_statistics " +swhere+ ////where 景区id=#{areaid} + " and sign=1 and batchid=(select max(batchid) from dp_2_kpi5g_allspots_statistics) group by sign,datetime " + + " )," + + + " t3 as " + + " (select datetime, sum(value2) value, sign from dp_2_kpi5g_allspots_statistics " +swhere+ ////where 景区id=#{areaid} + " and sign=2 and batchid=(select max(batchid) from dp_2_kpi5g_allspots_statistics) group by sign,datetime " + + " ) " + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + } + else if (level==3) //场馆 + { + String sTime = " LOCALTIMESTAMP(0) "; + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), (select max(结束时间) from pm_kpi5g_venue where 场馆id =#{sceneid}), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + /* + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 1 sign from pm_kpi5g_venue where 场馆id=#{sceneid}" + + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd')" + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 2 sign from pm_kpi5g_venue where 场馆id=#{sceneid} " + + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') " + + " ) " + + */ + + " t2 as " + + " (select datetime, value2 value, sign from dp_2_kpi5g_allvenue_statistics where 场馆id=#{sceneid} " + + " and sign=1 and batchid=(select max(batchid) from dp_2_kpi5g_allvenue_statistics) " + + " )," + + + " t3 as " + + " (select datetime, value2 value, sign from dp_2_kpi5g_allvenue_statistics where 场馆id=#{sceneid} " + + " and sign=2 and batchid=(select max(batchid) from dp_2_kpi5g_allvenue_statistics) " + + " ) " + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + } + } + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_get_area_gbflow.class,method = "get_area_gbflow_SQL") + List get_area_gbflow( + @Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid, + @Param("typeid") int typeid); + //endregion + + //region --------------------------------------------------------------------------------------上行Prb利用率 + class class_get_prb_uplink // 上行Prb利用率TOP5,15分钟/1分钟(中台控制),最终值TOP5降序排列,文本白色,指标值彩色(叠加颜色指示) + { + public String get_prb_uplink_SQL( + @Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid, + @Param("typeid") int typeid, + @Param("mintype") int mintype, + @Param("inorout") int inorout) + { + String SQL=" "; + String sTable=" "; + String swhere = " "; + String swhere2=" "; + if ((level==1) || (level==2) ) //全域,区域显示一致 + { + if (mintype == 1) { //1分钟 // 一分钟的数据需要OMC控制输出,为全量的。 + if (typeid == 1) //4G //(select max(时间) from pm_kpi4g_min) + { + sTable=" dp_2_kpi4g_min_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } else //5G //(select max(时间) from pm_kpi5g_min) + { + sTable=" dp_2_kpi5g_min_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } + } else //15分钟 // 15分钟的数据需要为全量输送, 采集帅选出景区的小区的数据。//待定 + { + if (typeid == 1) //4G //(select max(endtime) from pm_kpi4g_cell_fordp) + { + sTable=" dp_2_kpi4g_cell_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } else //5G //(select max(endtime) from pm_kpi5g_cell_fordp) + { + sTable=" dp_2_kpi5g_cell_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } + } + } + else if (level==3) //场馆 + { + if (mintype == 1) { //1分钟 + if (typeid == 1) //4G //(select max(时间) from pm_kpi4g_min) + { + sTable=" dp_2_kpi4g_min_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + } else //5G //(select max(时间) from pm_kpi5g_min) + { + sTable=" dp_2_kpi5g_min_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + } + } else //15分钟 + { + if (typeid == 1) //4G //(select max(endtime) from pm_kpi4g_cell_fordp) + { + sTable=" dp_2_kpi4g_cell_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + + } else //5G //(select max(endtime) from pm_kpi5g_cell_fordp) + { + sTable=" dp_2_kpi5g_cell_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + + } + } + } + String subTable=" (select distinct 小区名称,prb_up,kpiclr_prb_up from "+sTable+" where 1=1 " +swhere2+swhere+ + " and batchid=(select max(batchid) from "+sTable+" ) ) as a "; + SQL =" select row_number() over(order by prb_up desc) title,小区名称 name,round(prb_up::numeric, 2) value, " + + " kpiclr_prb_up color from "+subTable+" where prb_up is not null "+ + " order by prb_up desc limit 5"; + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_get_prb_uplink.class,method = "get_prb_uplink_SQL") + List get_prb_uplink( + @Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid, + @Param("typeid") int typeid, + @Param("mintype") int mintype, + @Param("inorout") int inorout); + //endregion + + //region -----------------------------------------------------------------------------------下行Prb利用率 + class class_get_prb_downlink // 下行Prb利用率TOP5,15分钟/1分钟(中台控制),最终值TOP5降序排列,文本白色,指标值彩色(叠加颜色指示) + { + public String get_prb_downlink_SQL( + @Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid, + @Param("typeid") int typeid, + @Param("mintype") int mintype, + @Param("inorout") int inorout) + { + String SQL=" "; + String sTable=" "; + String swhere = " "; + String swhere2=" "; + if ((level==1) || (level==2)) //全域,区域显示一致 + { + if (mintype == 1) { //1分钟 // 一分钟的数据需要OMC控制输出,为全量的。 + if (typeid == 1) //4G //(select max(时间) from pm_kpi4g_min) + { + sTable=" dp_2_kpi4g_min_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } else //5G //(select max(时间) from pm_kpi5g_min) + { + sTable=" dp_2_kpi5g_min_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } + } else //15分钟 // 15分钟的数据需要为全量输送, 采集帅选出景区的小区的数据。//待定 + { + if (typeid == 1) //4G //(select max(endtime) from pm_kpi4g_cell_fordp) + { + sTable=" dp_2_kpi4g_cell_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } else //5G //(select max(endtime) from pm_kpi5g_cell_fordp) + { + sTable=" dp_2_kpi5g_cell_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } + } + } + else if (level==3) //场馆 + { + if (mintype == 1) { //1分钟 + if (typeid == 1) //4G //(select max(时间) from pm_kpi4g_min) + { + sTable=" dp_2_kpi4g_min_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + } else //5G //(select max(时间) from pm_kpi5g_min) + { + sTable=" dp_2_kpi5g_min_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + } + } else //15分钟 + { + if (typeid == 1) //4G //(select max(endtime) from pm_kpi4g_cell_fordp) + { + sTable=" dp_2_kpi4g_cell_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + + } else //5G //(select max(endtime) from pm_kpi5g_cell_fordp) + { + sTable=" dp_2_kpi5g_cell_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + + } + } + } + String subTable=" (select distinct 小区名称,prb_down,kpiclr_prb_down from "+sTable+" where 1=1 " +swhere2+swhere+ + " and batchid=(select max(batchid) from "+sTable+" ) ) as a "; + SQL =" select row_number() over(order by prb_down desc) title,小区名称 name,round(prb_down::numeric, 2) value, " + + " kpiclr_prb_down color from "+subTable+" where prb_down is not null "+ + " order by prb_down desc limit 5"; + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_get_prb_downlink.class,method = "get_prb_downlink_SQL") + List get_prb_downlink (@Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid, + @Param("typeid") int typeid, + @Param("mintype") int mintype, + @Param("inorout") int inorout); + //endregion + + //region ---------------------------------------------------------------------------------------平均干扰 + class class_get_avg_disturb // 最大干扰值TOP5,15分钟/1分钟(中台控制),最终值TOP5降序排列,文本白色,指标值彩色(叠加颜色指示) + { + public String get_avg_disturb_SQL( + @Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid, + @Param("typeid") int typeid, + @Param("mintype") int mintype, + @Param("inorout") int inorout) + { + String SQL=" "; + String sTable=" "; + String swhere = " "; + String swhere2=" "; + if ((level==1) || (level==2)) //全域,区域显示一致 + { + if (mintype == 1) { //1分钟 // 一分钟的数据需要OMC控制输出,为全量的。 + if (typeid == 1) //4G //(select max(时间) from pm_kpi4g_min) + { + sTable=" dp_2_kpi4g_min_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } else //5G //(select max(时间) from pm_kpi5g_min) + { + sTable=" dp_2_kpi5g_min_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } + } else //15分钟 // 15分钟的数据需要为全量输送, 采集帅选出景区的小区的数据。//待定 + { + if (typeid == 1) //4G //(select max(endtime) from pm_kpi4g_cell_fordp) + { + sTable=" dp_2_kpi4g_cell_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } else //5G //(select max(endtime) from pm_kpi5g_cell_fordp) + { + sTable=" dp_2_kpi5g_cell_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } + } + } + else if (level==3) //场馆 + { + if (mintype == 1) { //1分钟 + if (typeid == 1) //4G //(select max(时间) from pm_kpi4g_min) + { + sTable=" dp_2_kpi4g_min_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + } else //5G //(select max(时间) from pm_kpi5g_min) + { + sTable=" dp_2_kpi5g_min_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + } + } else //15分钟 + { + if (typeid == 1) //4G //(select max(endtime) from pm_kpi4g_cell_fordp) + { + sTable=" dp_2_kpi4g_cell_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + + } else //5G //(select max(endtime) from pm_kpi5g_cell_fordp) + { + sTable=" dp_2_kpi5g_cell_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + + } + } + } + String subTable=" (select distinct 小区名称,avg_disturb,kpiclr_avg_disturb from "+sTable+" where 1=1 " +swhere2+swhere+ + " and batchid=(select max(batchid) from "+sTable+" ) ) as a "; + SQL =" select row_number() over(order by avg_disturb desc) title,小区名称 name,round(avg_disturb::numeric, 2) value, " + + " kpiclr_avg_disturb color from "+subTable+" where avg_disturb is not null "+ + " order by avg_disturb desc limit 5"; + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_get_avg_disturb.class,method = "get_avg_disturb_SQL") + List get_avg_disturb (@Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid, + @Param("typeid") int typeid, + @Param("mintype") int mintype, + @Param("inorout") int inorout); + //endregion + + //region ---------------------------------------------------------------------------------------最大用户数 + class class_get_user_data // 最大用户数TOP5,15分钟/1分钟(中台控制),最终值TOP5降序排列,文本白色,指标值彩色(叠加颜色指示) + { + public String get_user_data_SQL( + @Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid, + @Param("typeid") int typeid, + @Param("mintype") int mintype, + @Param("inorout") int inorout) + { + String SQL=" "; + String sTable=" "; + String swhere = " "; + String swhere2=" "; + if ((level==1) || (level==2)) //全域,区域显示一致 + { + if (mintype == 1) { //1分钟 // 一分钟的数据需要OMC控制输出,为全量的。 + if (typeid == 1) //4G //(select max(时间) from pm_kpi4g_min) + { + sTable=" dp_2_kpi4g_min_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } else //5G //(select max(时间) from pm_kpi5g_min) + { + sTable=" dp_2_kpi5g_min_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } + } else //15分钟 // 15分钟的数据需要为全量输送, 采集帅选出景区的小区的数据。//待定 + { + if (typeid == 1) //4G //(select max(endtime) from pm_kpi4g_cell_fordp) + { + sTable=" dp_2_kpi4g_cell_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } else //5G //(select max(endtime) from pm_kpi5g_cell_fordp) + { + sTable=" dp_2_kpi5g_cell_statistics "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } + } + } + else if (level==3) //场馆 + { + if (mintype == 1) { //1分钟 + if (typeid == 1) //4G //(select max(时间) from pm_kpi4g_min) + { + sTable=" dp_2_kpi4g_min_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + } else //5G //(select max(时间) from pm_kpi5g_min) + { + sTable=" dp_2_kpi5g_min_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + } + } else //15分钟 + { + if (typeid == 1) //4G //(select max(endtime) from pm_kpi4g_cell_fordp) + { + sTable=" dp_2_kpi4g_cell_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + + } else //5G //(select max(endtime) from pm_kpi5g_cell_fordp) + { + sTable=" dp_2_kpi5g_cell_statistics "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + if (inorout > 0) swhere = " and 场内场外='" + inorout + "' "; //1:场内,2:场外,0:默认全部 + + } + } + } + String subTable=" (select distinct 小区名称,max_user,kpiclr_max_user from "+sTable+" where 1=1 " +swhere2+swhere+ + " and batchid=(select max(batchid) from "+sTable+" ) ) as a "; + SQL =" select row_number() over(order by x.colorscore desc,max_user desc) title,小区名称 name,round(max_user::numeric, 2) value, " + + " kpiclr_max_user color from "+subTable+ + " left join (select distinct upper(color) color,colorscore from dp_scene_config) x on upper(a.kpiclr_max_user)=x.color "+ + " where max_user is not null "+ + " order by x.colorscore desc,max_user desc limit 5"; + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_get_user_data.class,method = "get_user_data_SQL") + List get_user_data(@Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid, + @Param("typeid") int typeid, + @Param("mintype") int mintype, + @Param("inorout") int inorout); + //endregion + + //region------------------------------------------------------------------------------------3D大屏外场保障(牌子显示) + class class_scene_test_data + { + public String get_scene_test_dataSQL(@Param("sceneid") int sceneid, + @Param("typeid") int typeid + ) + { + String swhere=" where 1=1 "; + if (sceneid!=0) { + swhere+=" and scene_id = #{sceneid} " ; //外场的小区 + } + if (typeid!=0) { + String nettype=""; + if (typeid==1) nettype="4G" ; else nettype="5G"; + swhere+=" and nettype ='"+nettype+"' " ; //外场的小区 + } + String SQL=" select * from yw_scene_test_data " + swhere ; + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_scene_test_data.class,method = "get_scene_test_dataSQL") + List get_test_data(@Param("sceneid") int sceneid, + @Param("typeid") int typeid); + //endregion + + //region------------------------------------------------------------------------------------外场基站无线告警清单 + class class_bts_wirelessalarmslists + { + public String get_bts_wirelessalarmslistsSQL(@Param("sceneid") int sceneid) + { + String sTable=" dp_2_view_wireless_alarm "; //dp_2_view_wireless_alarm_debug + String SQL=" select site_name btsname ,longitude,latitude,count(*) alarmcount from " +sTable+ + //" where to_char(eventtime,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') " + + " where 1=1 " + + " and 场馆id = #{sceneid} and 场内场外='2' group by site_name,longitude,latitude "; + return SQL; + } + + public String get_alarmslist_by_site_SQL(@Param("sceneid") int sceneid) + { + String sTable=" dp_2_view_wireless_alarm "; //dp_2_view_wireless_alarm_debug + String SQL=" select 场馆id sceneid,'无线' major,site_name reserved," + + " case when cell_name is null then site_name else cell_name end netname, " + + " alarmname,eventtime,故障处理人 handlepeople,phonenumber "+ + " from "+sTable+ + //" where to_char(eventtime,'YYYY-MM-DD')=to_char(now() ,'YYYY-MM-DD') "+ + " where 1=1 "+ + " and 场馆id = #{sceneid} and 场内场外='2' " + + " order by eventtime desc "; + return SQL; + } + + } + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_bts_wirelessalarmslists.class,method = "get_bts_wirelessalarmslistsSQL") + List get_bts_wireless_alarms_list(@Param("sceneid") int sceneid); + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_bts_wirelessalarmslists.class,method = "get_alarmslist_by_site_SQL") + List get_wireless_alarms_by_site(@Param("sceneid") int sceneid); + //endregion + + //region------------------------------------------------------------------------------------内外场坐席无线告警清单 + class class_seat_wirelessalarmslists + { + public String get_seat_wirelessalarmslistsSQL(@Param("sceneid") int sceneid, + @Param("inorout") int inorout + ) + { + String swhere=""; + String sTable=" dp_2_view_wireless_alarm "; // dp_2_view_wireless_alarm_debug + if (inorout>0) swhere =" and 场内场外='"+inorout+ "' "; + String SQL=" select unnest(string_to_array(坐席编号::text, '/'::text)) as seatid, count(*) alarmcount " + + " from " +sTable+ + //" where to_char(eventtime,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') " + + " where 1=1 " + + " and 场馆id = #{sceneid} "+ swhere+" group by seatid "; + return SQL; + } + + public String get_alarmslist_by_seat_SQL(@Param("sceneid") int sceneid) + { + String sTable=" dp_2_view_wireless_alarm "; // dp_2_view_wireless_alarm_debug + String SQL=" select id, 场馆id sceneid,'无线' major,unnest(string_to_array(坐席编号::text, '/'::text)) reserved , " + + " case when cell_name is null then site_name else cell_name end netname, " + + " alarmname,eventtime,故障处理人 handlepeople,phonenumber "+ + " from "+sTable+ + //" where to_char(eventtime,'YYYY-MM-DD')=to_char(now() ,'YYYY-MM-DD') "+ + " where 1=1 "+ + " and 场馆id = #{sceneid} order by eventtime desc "; + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_seat_wirelessalarmslists.class,method = "get_seat_wirelessalarmslistsSQL") + List get_seat_wireless_alarms_list(@Param("sceneid") int sceneid, + @Param("inorout") int inorout); + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_seat_wirelessalarmslists.class,method = "get_alarmslist_by_seat_SQL") + List get_wireless_alarms_by_seat(@Param("sceneid") int sceneid); + //endregion + + //region------------------------------------------------------------------------------------中间地图告警显示接口 + class class_get_maps_wireless_alarms + { + public String get_maps_wireless_alarms_SQL( + @Param("level") int level, + @Param("areaid") int areaid) + { + String SQL=" "; + String areanames=" "; + if (level==0) //不会用到,场馆小区级告警统计,测试用 + { + areanames = " ('上城','拱墅','西湖','滨江','萧山','余杭','临平','钱塘','富阳','临安','桐庐','淳安','建德') "; + } + else if (level==1) //1 : 全域 (除了 上城区 、拱墅区、西湖区、滨江区 ,'萧山','钱塘'之外的区域),场馆小区级告警统计 + { + //areanames = " ('余杭','临平','富阳','临安','桐庐','淳安','建德') "; + areanames = " ('上城','拱墅','西湖','滨江','萧山','余杭','临平','钱塘','富阳','临安','桐庐','淳安','建德') "; + } + else if (level==2) //2: 区域 '上城','拱墅','西湖','滨江','萧山','钱塘',场馆小区级告警统计 + { + areanames = " ('上城','拱墅','西湖','滨江','萧山','钱塘') "; + } + //------------------------------------ + if ((level==0) || (level==1) || ((level==2) && (areaid==0)) ) //城区,未指定区域, 显示的是场馆的数据 + { + SQL =" select venueid,venuetypeid,venuetype,venuename,longitude,latitude,areaname,wirelesscount,0,0,0,wirelesscount alarmcount " + + " from dp_2_maps_allalarms_statistics where batchid=(select max(batchid) from dp_2_maps_allalarms_statistics) " + + " and areaname in " +areanames; + } + else if ((level==2) && (areaid>0)) { // 景区, 只有逻辑站退服告警和整站退服, 需要单独处理 + String swhere1=" "; + String swhere2=" "; + if (areaid!=0) { + //swhere1 = " where 景区大类id=#{areaid} "; //传入的是大类 + //swhere2 = " and 区域id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; //传入的是大类 + swhere2 = " and venueid in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; //传入的是大类 + } + /* + SQL = " with t1 as" + + " (" + + " select 景区id venueid,景区大类id venuetypeid, 景区大类 venuetype, 景区介绍 icontype ,景区名称 venuename ,中心经度 longitude,中心纬度 latitude,行政区域 areaname " + + " from dp_2_spot_config " + + swhere1+ + " ), " + + " t2 as" + + " (" + + " select 区域id,count(*) cnt from dp_2_view_wireless_alarm " + + //" where to_char(eventtime,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') " + + " where 1=1 " + + swhere2+ + " group by 区域id "+ + " ) " + + + " select t1.*,COALESCE(t2.cnt,0) wirelesscount,0,0,0,COALESCE(t2.cnt,0) alarmcount from t1 " + + " left join t2 on t1.venueid=t2.区域id " ; */ + SQL =" select * from dp_2_maps_spotalarms_statistics where batchid=(select max(batchid) from dp_2_maps_spotalarms_statistics) " + swhere2; + } + + + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_get_maps_wireless_alarms.class,method = "get_maps_wireless_alarms_SQL") + List get_maps_wireless_alarms(@Param("level") int level, + @Param("areaid") int areaid); + //endregion + + //region------------------------------------------------------------------------------------中间地图性能数据,所有景区的取取到缓存 + class class_get_maps_wireless_kpi_cells + { + public String get_maps_wireless_kpi_cells_SQL( + @Param("nettype") String nettype, + @Param("datatype") int datatype) + { + String sTable =""; + if (nettype.equals("4G") && (datatype==1)) //1分钟4G + sTable=" dp_2_kpi4g_min_statistics "; + else if (nettype.equals("5G") && (datatype==1)) //1分钟5G + sTable=" dp_2_kpi5g_min_statistics "; + else if (nettype.equals("4G") && (datatype==15)) //15分钟4G + sTable=" dp_2_kpi4g_cell_statistics "; + else if (nettype.equals("5G") && (datatype==15)) //15分钟5G + sTable=" dp_2_kpi5g_cell_statistics "; + //------------------------------------------------------ + String SQL=" select * from " +sTable+" where 景区id is not null order by 景区id "; + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_get_maps_wireless_kpi_cells.class,method = "get_maps_wireless_kpi_cells_SQL") + List get_maps_wireless_kpi_cells(@Param("nettype") String nettype, + @Param("datatype") int datatype); + //endregion + + //region------------------------------------------------------------------------------------中间地图告警弹出列表 + class class_get_maps_wireless_alarms_popup //场馆的 + { + public String get_maps_wireless_alarms_popup_SQL() + { + String SQL=" "; + /* + SQL =" select '无线' major , case when cell_name is null then site_name else cell_name end netname, " + + " alarmname alarmname,eventtime eventtime,故障处理人 handlepeople,场馆id sceneid from dp_2_view_wireless_alarm where 场馆id is not null "+ + " and to_char(eventtime,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD') ";*/ + SQL =" select * from dp_2_maps_allalarms_list where batchid=(select max(batchid) from dp_2_maps_allalarms_list) " + + " and major='无线' "; + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_get_maps_wireless_alarms_popup.class,method = "get_maps_wireless_alarms_popup_SQL") + List get_maps_wireless_alarms_popup(); + //endregion + + //region --------------------------------------------------------------------------------------西湖十景TOP5 + + + class class_get_all_spot_top5 // 四个指标同时输出 + { + public String get_all_spot_top5_SQL( + @Param("spotid") int spotid, + @Param("kpiname") String kpiname, + @Param("typeid") int typeid, + @Param("mintype") int mintype) + { + String SQL=" "; + String nettype=" "; + String timetype=" "; + if (mintype == 1) { //1分钟 // 一分钟的数据需要OMC控制输出,为全量的。 + if (typeid == 1) //4G + { + nettype="4G"; + timetype="1min"; + } else //5G + { + nettype="5G"; + timetype="1min"; + } + } else //15分钟 + { + if (typeid == 1) //4G //(select max(endtime) from pm_kpi4g_cell_fordp) + { + nettype="4G"; + timetype="15min"; + } else //5G + { + nettype="5G"; + timetype="15min"; + } + } + String batchid = " (select min(batchid) from dp_2_kpi_spot_statistics) "; + SQL = " select row_number() over(order by kpicolor desc,kpivalue::numeric desc) title, " + + " cellname name, round(kpivalue::numeric, 2) value,kpicolor color from dp_2_kpi_spot_statistics "+ + " where batchid="+batchid+" and nettype='"+nettype+"' and timetype='"+timetype+"' and spotid=#{spotid} and kpiname=#{kpiname} " + + " order by kpicolor desc , kpivalue desc "; + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_get_all_spot_top5.class,method = "get_all_spot_top5_SQL") + List get_all_spot_top5( + @Param("spotid") int spotid, + @Param("kpiname") String kpiname, + @Param("typeid") int typeid, + @Param("mintype") int mintype); + //endregion + + //region------------------------------------------------------------------------------------记录下降功率指令 + + class class_mml_info + { + public String insert_mml_info_SQL(@Param("cellname") String cellname, + @Param("prbup") float prbup, + @Param("prbdown") float prbdown, + @Param("maxuser") float maxuser, + @Param("zhscore") float zhscore, + @Param("avgdisturb") float avgdisturb, + @Param("batchno") int batchno, + @Param("sceneid") int sceneid, + @Param("stattime") String stattime, + @Param("seatid") String seatid, + @Param("nettype") String nettype) + { + String SQL=" select dp_2_insert_mml_info(#{cellname},#{prbup},#{prbdown},#{maxuser},#{zhscore}," + + " #{avgdisturb},#{batchno},#{sceneid},#{stattime},#{seatid},#{nettype})"; + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_mml_info.class,method = "insert_mml_info_SQL") + String insert_mml_info(@Param("cellname") String cellname, + @Param("prbup") float prbup, + @Param("prbdown") float prbdown, + @Param("maxuser") float maxuser, + @Param("zhscore") float zhscore, + @Param("avgdisturb") float avgdisturb, + @Param("batchno") int batchno, + @Param("sceneid") int sceneid, + @Param("stattime") String stattime, + @Param("seatid") String seatid, + @Param("nettype") String nettype ); + //endregion + + //region------------------------------------------------------------------------------------获取基站小区信息 + class class_get_site_cell_info + { + public String get_get_site_cell_info_SQL() + { + String swhere=""; + String SQL=""; + SQL="select * from dp_2_site_cell_statistics "; + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_get_site_cell_info.class,method = "get_get_site_cell_info_SQL") + List getsitecellinfo(); + //endregion + + //region------------------------------------------------------------------------------------高负荷小区TOP5 + class class_get_wireless_highload + { + public String get_get_wireless_highload_SQL( + @Param("typeid") int typeid) + { + String SQL=" "; + String stable=" "; + if (typeid == 1) + { + stable = "dp_2_wireless_highload_4g"; + } + else { + stable = "dp_2_wireless_highload_5g"; + } + SQL = " select * from "+stable + " where batchid= (select max(batchid) from "+stable+" ) "; + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_get_wireless_highload.class,method = "get_get_wireless_highload_SQL") + List get_wireless_highload(@Param("typeid") int typeid); + //endregion + + //region------------------------------------------------------------------------------------获取频段统计 + class class_get_freq_cnt + { + public String get_freq_cnt_SQL(@Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid, + @Param("typeid") int typeid, + @Param("mintype") int mintype) + { + String SQL=" "; + String sTable=" "; + String swhere2=" "; + if ((level==1) || (level==2) ) //全域,区域显示一致 + { + if (mintype == 1) { //1 min + if (typeid == 1) //4g + { + sTable=" dp_2_view_freq_statistics_min_4g "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } else //5G + { + sTable=" dp_2_view_freq_statistics_min_5g "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } + } else //15分钟 + { + if (typeid == 1) //4G + { + sTable=" dp_2_view_freq_statistics_cell_4g "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } else //5G + { + sTable=" dp_2_view_freq_statistics_cell_5g "; + if ((areaid!=0) && (level==2)) swhere2=" and 景区id in (select 景区id from dp_2_spot_config where 景区大类id=#{areaid}) "; + } + } + } + else if (level==3) //场馆 + { + if (mintype == 1) { //1分钟 + if (typeid == 1) //4G + { + sTable=" dp_2_view_freq_statistics_min_4g "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + } else //5G + { + sTable=" dp_2_view_freq_statistics_min_5g "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + } + } else //15分钟 + { + if (typeid == 1) //4G + { + sTable=" dp_2_view_freq_statistics_cell_4g "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + + } else //5G + { + sTable=" dp_2_view_freq_statistics_cell_5g "; + if (sceneid!=0) swhere2=" and 场馆id=#{sceneid} "; + + } + } + } + SQL=" select 小区频段 , sum(cnt) cnt from "+sTable+" where 1=1 " + swhere2 +" group by 小区频段"; + return SQL; + } + } + @SelectProvider(type = dpNewYayun_Wuxian_Mapper.class_get_freq_cnt.class,method = "get_freq_cnt_SQL") + List get_freq_cnt(@Param("level") int level, + @Param("areaid") int areaid, + @Param("sceneid") int sceneid, + @Param("typeid") int typeid, + @Param("mintype") int mintype); + //endregion + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_ZhuanWang_Mapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_ZhuanWang_Mapper.java new file mode 100644 index 0000000..d6c7f07 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_ZhuanWang_Mapper.java @@ -0,0 +1,358 @@ +package com.ruoyi.sunlm.mapper; + +import com.ruoyi.sunlm.daping.*; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.SelectProvider; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @author yqf + * @date 2023/7/13 + */ +@Mapper +@Component +public interface dpNewYayun_ZhuanWang_Mapper { + + + + //region------------------------------------------------------------------------------------专网告警接口 + class class_get_net_alarms + { + /* + public String get_net_alarms_SQL(@Param("level") int level, + @Param("sceneid") int sceneid, + @Param("alarmtype") String alarmtype) + { + String SQL=" "; + if ((level==1) || (level==2)) //全域或城区的场馆的传输告警 + { + SQL = " select 告警时间 eventtime, " + + " 告警名称 alarmname, " + + " 场馆id ," + + " 区域id," + + " 网元名称 netname, " + + " 分公司 areaname, " + + " 告警类型 alarmtype, " + + " 告警等级 alarmlevel, " + + " 设备类型 devicetype, " + + " 是否端口告警 isportalarm from dp_2_view_trans_alarms " + + " where 恢复时间 is null " + + " and 告警类型 = #{alarmtype} order by 告警时间 desc"; + } + else if (level==3) { ////具体某个场馆的传输告警, 地图上的展示形式和本接口待定 + SQL = " select 告警时间 eventtime, " + + " 告警名称 alarmname, " + + " 场馆id ," + + " 区域id," + + " 网元名称 netname, " + + " 分公司 areaname, " + + " 告警类型 alarmtype, " + + " 告警等级 alarmlevel, " + + " 设备类型 devicetype, " + + " 是否端口告警 isportalarm from dp_2_view_trans_alarms " + + " and 场馆id = #{sceneid} and 告警类型 = #{alarmtype} order by 告警时间 desc limit 20"; + } + + return SQL; + } */ + + public String get_net_alarms_all_SQL() + { + /* + String SQL= " select 告警时间 eventtime, 告警名称 alarmname,恢复时间 recovertime,场馆id sceneid,场馆名称 scenename," + + " 网元名称 netname, 分公司 areaname,详细位置 detaillocation, 专业 alarmtype,网元属性 nettype, 端口类型 porttype, 对端网元 portnet, " + + " 对端网元端口 port, mark from dp_2_view_agis_alarms where 恢复时间 is null " + + " order by 告警时间 desc "; */ + //----------------------------------------------要求对告警5分钟内相同告警进行合并,20230916 sunlm + String SQL= " select 告警时间 eventtime, 告警名称 alarmname,场馆id sceneid,场馆名称 scenename," + + " 网元名称 netname, 分公司 areaname, 专业 alarmtype ,告警数量 alarmscount from dp_2_view_agis_alarms_combine " + + " order by 告警时间 desc "; + return SQL; + } + + public String get_map_alarms_all_SQL() + { + String SQL= "select 专业 major,告警时间 eventtime, 告警名称 alarmname, 网元名称 netname,场馆id sceneid,故障处理人 handlepeople,phonenumber from dp_2_view_agis_alarms " + + "where 恢复时间 is null order by 告警时间 desc "; + return SQL; + } + + public String get_code_alarms_all_SQL(){ + String SQL ="select 专业 major,告警时间 eventtime, 告警名称 alarmname, 网元名称 netname,场馆id sceneid,故障处理人 handlepeople,phonenumber,编码 code\n" + + "from dp_2_view_agis_alarms where 编码 is not null and 专业 in ('WIFI','AGIS') and 场馆id = 2"; + return SQL; + } + + } + + + /* + @SelectProvider(type = dpNewYayun_ZhuanWang_Mapper.class_get_net_alarms.class,method = "get_net_alarms_SQL") + List get_net_alarms_list(@Param("level") int level, + @Param("sceneid") int sceneid, + @Param("alarmtype") String alarmtype);*/ + + @SelectProvider(type = dpNewYayun_ZhuanWang_Mapper.class_get_net_alarms.class,method = "get_net_alarms_all_SQL") + List get_net_alarms_all_list(); + + @SelectProvider(type = dpNewYayun_ZhuanWang_Mapper.class_get_net_alarms.class,method = "get_map_alarms_all_SQL") + List get_map_alarms_all_list(); + + @Select("select stat_date,venueid,场馆名称 venuename,链路名称 linkname,链路属性 linkvalue,上行带宽利用率 ulbandratio," + + "下行带宽利用率 dlbandratio,上行链路利用率 ulavg24hratio,下行链路利用率 dlavg24hratio " + + "from dp_2_view_agis_link_5mi order by stat_date desc ") + List get_map_agis_link_all_list(); + + @Select("select stat_date,venueid,场馆名称,设备名称 devicename,设备类型 devicetype,cpu利用率 cpuratio,内存利用率 ramratio,编码 code " + + "from dp_2_view_agis_dev_15mi order by stat_date desc ") + List get_map_agis_dev_all_list(); + + + @Select("select 编码 code from dp_2_agis_config") + List get_code_all_list(); + + + @SelectProvider(type = dpNewYayun_ZhuanWang_Mapper.class_get_net_alarms.class,method = "get_code_alarms_all_SQL") + List get_code_alarms_all_list(); + + @Select("select stat_date,venueid,场馆名称 venuename,设备名称 devicename,设备类型 devicetype,cpu利用率 cpuratio," + + "内存利用率 ramratio,编码 code from dp_2_view_agis_dev_15mi where 编码 is not null") + List get_code_agis_dev_all_list(); + + //endregion + + + + //region------------------------------------------------------------------------------------中间地图告警显示接口 + class class_get_maps_all_net_alarms + { + public String get_maps_all_alarms_SQL() + { + + String SQL=" "; + String areanames= " ('上城','拱墅','西湖','滨江','萧山','余杭','临平','钱塘','富阳','临安','桐庐','淳安','建德') "; + SQL = " with t1 as \n" + + " ( select id venueid,'' venuetypeid,'' venuetype, " + + " case" + + " when length(COALESCE(maintain_type,''))=0 then venue_name " + + " else venue_name || '(' || maintain_type || ')' " + + " end venuename, " + + " longitude_dp longitude,latitude_dp latitude," + + " b.dict_label areaname from yw_scene a , sys_dict_data b where scene_big_id in " + + " (select id from yw_scene_big_config where status='2') and longitude<>0 and a.area_county_id=b.dict_value " + + " and a.venue_type ='比赛场馆' " + + " and b.dict_type= 'yw_county' and id not in (10000,10500,20000,20100,20300,20400,20200) and b.dict_label in " + areanames + " )," + + " t2 as \n" + + " ( select 场馆id,count(*) alarmcount from dp_2_view_agis_alarms group by 场馆id ) , \n" + + " t3 as \n" + + " ( select 场馆id,count(*) agiscount from dp_2_view_agis_alarms where 专业 = 'AGIS' group by 场馆id ) ,\n" + + " t4 as \n" + + " ( select 场馆id,count(*) wificount from dp_2_view_agis_alarms where 专业 = 'WIFI' group by 场馆id ) ,\n" + + " t5 as \n" + + " ( select 场馆id,count(*) voipcount from dp_2_view_agis_alarms where 专业 = 'VOIP' group by 场馆id ) \n" + + " select t1.*,COALESCE(t2.alarmcount,0) alarmcount,COALESCE(t3.agiscount,0) agiscount,COALESCE(t4.wificount,0) wificount," + + "COALESCE(t5.voipcount,0) voipcount\n" + + " from t1 \n" + + " left join t2 on t1.venueid=t2.场馆id\n" + + " left join t3 on t1.venueid=t3.场馆id\n" + + " left join t4 on t1.venueid=t4.场馆id\n" + + " left join t5 on t1.venueid=t5.场馆id "; + return SQL; + } + } + @SelectProvider(type = dpNewYayun_ZhuanWang_Mapper.class_get_maps_all_net_alarms.class,method = "get_maps_all_alarms_SQL") + List get_maps_all_alarms(); + //endregion + + //region --------------------------------------------------------------------------------------AGIS交换机TOP5 + class class_get_agis_switch + { + public String get_get_agis_switch_SQL( + @Param("level") int level, + @Param("typeid") int typeid, + @Param("sceneid") int sceneid) + { + String SQL=" "; + String sTable=" "; + String sKpi="" ; + String swhere = " "; + if ((level==1) || (level==2) ) //全域,区域显示一致 + { + if (typeid==1) { //cpu + sTable=" dp_2_view_agis_dev_15mi "; + sKpi=" cpu利用率 "; + swhere=" "; + } + else //ram + { + sTable=" dp_2_view_agis_dev_15mi "; + sKpi=" 内存利用率 "; + swhere=" "; + } + } + else if (level==3) //场馆 + { + if (typeid==1) { //cpu + sTable=" dp_2_view_agis_dev_15mi "; + sKpi=" cpu利用率 "; + swhere=" where venueid=#{sceneid} "; + } + else + { + sTable=" dp_2_view_agis_dev_15mi "; + sKpi=" 内存利用率 "; + swhere=" where venueid=#{sceneid} "; + } + } + + SQL = " select row_number() over(order by "+sKpi+" desc) title,设备名称 || '[' || substring(设备类型,1,2) || ']' name,round("+sKpi+"::numeric, 2) value, " + + " '' color from "+sTable + swhere+ + " order by "+sKpi+" desc limit 5"; + + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_ZhuanWang_Mapper.class_get_agis_switch.class,method = "get_get_agis_switch_SQL") + List get_agis_switch( + @Param("level") int level, + @Param("typeid") int typeid, + @Param("sceneid") int sceneid); + //endregion + + //region --------------------------------------------------------------------------------------AGIS带宽利用率TOP5 + class class_get_agis_bandwidth + { + public String get_get_agis_bandwidth_SQL( + @Param("level") int level, + @Param("typeid") int typeid, + @Param("sceneid") int sceneid) + { + String SQL=" "; + String sTable=" "; + String sKpi="" ; + String swhere = " "; + if ((level==1) || (level==2) ) //全域,区域显示一致 + { + if (typeid==1) { //cpu + sTable=" dp_2_view_agis_link_5mi "; + sKpi=" 上行带宽利用率 "; + swhere=" "; + } + else //ram + { + sTable=" dp_2_view_agis_link_5mi "; + sKpi=" 下行带宽利用率 "; + swhere=" "; + } + } + else if (level==3) //场馆 + { + if (typeid==1) { //cpu + sTable=" dp_2_view_agis_link_5mi "; + sKpi=" 上行带宽利用率 "; + swhere=" where venueid=#{sceneid} "; + } + else + { + sTable=" dp_2_view_agis_link_5mi "; + sKpi=" 下行带宽利用率 "; + swhere=" where venueid=#{sceneid} "; + } + } + + SQL = " select row_number() over(order by "+sKpi+" desc) title,链路名称 name,round("+sKpi+"::numeric, 2) value, " + + " '' color from "+sTable + swhere+ + " order by "+sKpi+" desc limit 5"; + + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_ZhuanWang_Mapper.class_get_agis_bandwidth.class,method = "get_get_agis_bandwidth_SQL") + List get_agis_bandwidth( + @Param("level") int level, + @Param("typeid") int typeid, + @Param("sceneid") int sceneid); + //endregion + + //region --------------------------------------------------------------------------------------AGIS带宽利用率TOP5 + class class_get_agis_link + { + public String get_get_agis_link_SQL( + @Param("level") int level, + @Param("typeid") int typeid, + @Param("sceneid") int sceneid) + { + String SQL=" "; + String sTable=" "; + String sKpi="" ; + String swhere = " "; + if ((level==1) || (level==2) ) //全域,区域显示一致 + { + if (typeid==1) { //cpu + sTable=" dp_2_view_agis_link_5mi "; + sKpi=" 上行链路利用率 "; + swhere=" "; + } + else //ram + { + sTable=" dp_2_view_agis_link_5mi "; + sKpi=" 下行链路利用率 "; + swhere=" "; + } + } + else if (level==3) //场馆 + { + if (typeid==1) { //cpu + sTable=" dp_2_view_agis_link_5mi "; + sKpi=" 上行链路利用率 "; + swhere=" where venueid=#{sceneid} "; + } + else + { + sTable=" dp_2_view_agis_link_5mi "; + sKpi=" 下行链路利用率 "; + swhere=" where venueid=#{sceneid} "; + } + } + + SQL = " select row_number() over(order by "+sKpi+" desc) title,链路名称 name,round("+sKpi+"::numeric, 2) value, " + + " '' color from "+sTable + swhere+ + " order by "+sKpi+" desc limit 5"; + + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_ZhuanWang_Mapper.class_get_agis_link.class,method = "get_get_agis_link_SQL") + List get_agis_link( + @Param("level") int level, + @Param("typeid") int typeid, + @Param("sceneid") int sceneid); + //endregion + + //region --------------------------------------------------------------------------------------互联网用户数TOP5 + class class_get_internet_usercount + { + public String get_get_internet_usercount_SQL( + @Param("level") int level) + { + String SQL = " select row_number() over(order by 在线用户数 desc) title ,场馆名称 name,round(在线用户数::numeric, 2) value, " + + " '' color from dp_2_view_ph_net_venue_5mi " + + " order by 在线用户数 desc limit 5"; + + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_ZhuanWang_Mapper.class_get_internet_usercount.class,method = "get_get_internet_usercount_SQL") + List get_internet_usercount( + @Param("level") int level); + //endregion + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_ZongHe_Mapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_ZongHe_Mapper.java new file mode 100644 index 0000000..65a626a --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpNewYayun_ZongHe_Mapper.java @@ -0,0 +1,79 @@ +package com.ruoyi.sunlm.mapper; + +import com.ruoyi.eastcom_yw.domain.dto.YwInspectStatDTO; +import com.ruoyi.eastcom_yw.domain.vo.YwSignLogStaticVo; +import com.ruoyi.sunlm.daping.class_dp_3_maps_alarms; +import com.ruoyi.sunlm.daping.class_dp_3_net_alarm; +import com.ruoyi.sunlm.daping.class_dp_5_scenecontacts; +import com.ruoyi.sunlm.daping.class_dp_5_scenesta; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.SelectProvider; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @author yqf + * @date 2023/7/14 + */ +@Mapper +@Component +public interface dpNewYayun_ZongHe_Mapper { + + class class_get_statistics + { + public String get_scene_sta_SQL(){ + String addSql = "(select id FROM yw_scene where venue_type='比赛场馆' and match_type is not null and area_county_id like '0571%')"; + + return "with t1 as (select count(*) wxuser FROM sys_user a join yw_scene_user b on a.user_id = b.user_id where a.user_type = 'wx' and b.scene_id in " + addSql + " ),\n" + + " t2 as (select count(*) csuser FROM sys_user a join yw_scene_user b on a.user_id = b.user_id where a.user_type = 'cs' and b.scene_id in " + addSql + " ),\n" + + " t3 as (select count(*) zwuser FROM sys_user a join yw_scene_user b on a.user_id = b.user_id where a.user_type = 'zw' and b.scene_id in " + addSql + " ),\n" + + " t4 as (select count(*) dhuser FROM sys_user a join yw_scene_user b on a.user_id = b.user_id where a.user_type = 'dh' and b.scene_id in " + addSql + " ),\n" + + " t5 as (select count(*) gluser FROM sys_user a join yw_scene_user b on a.user_id = b.user_id where a.user_type = 'gl' and b.scene_id in " + addSql + " ),\n" + + " t6 as (select count(*) bxuser FROM sys_user a join yw_scene_user b on a.user_id = b.user_id where a.user_type = 'bx' and b.scene_id in " + addSql + " ),\n" + + " t7 as (select emergency_warehouse emergencywarehouse,emergency_communication_car emergencycommunicationcar,emergency_electric_car emergencyelectriccar," + + "emergency_repair_car emergencyrepaircar ,wifi_spare wifispare,dredge_spare dredgespare,trans_spare transspare from yw_scene_noticeinfo where id = 1)\n" + + "select wxuser,csuser,zwuser,dhuser,gluser,bxuser,emergencywarehouse,emergencycommunicationcar,emergencyelectriccar,emergencyrepaircar,wifispare,dredgespare,transspare" + + " from t1,t2,t3,t4,t5,t6,t7"; + + } + public String get_scene_contacts_SQL(){ + return "select a.user_id userid,a.user_name username,a.nick_name nickname,phonenumber,e.venue_name venuename\n" + + "from sys_user a \n" + + "join sys_user_role b on a.user_id = b.user_id\n" + + "join sys_role c on b.role_id = c.role_id\n" + + "join yw_scene_user d on a.user_id = d.user_id\n" + + "join yw_scene e on d.scene_id = e.id\n" + + "where c.role_name = '场馆经理' and e.venue_type='比赛场馆' and e.match_type is not null and e.area_county_id like '0571%' "; + + } + + public String get_sign_top5_SQL(){ + String SQL = " select venueid sceneId,venuename venueName,sign_rate finishRate,sign_rate||'%' strFinishRate " + + " from dp_2_maps_allalarms_statistics " + + " where batchid=(select max(batchid) from dp_2_maps_allalarms_statistics) and sign_rate<200 "+ + " ORDER BY sign_rate limit 5"; + return SQL; + } + public String get_inspect_top5_SQL(){ + String SQL = "select venueid sceneId,venuename venueName,inspect_rate rate,inspect_rate||'%' rateStr " + + " from dp_2_maps_allalarms_statistics " + + " where batchid=(select max(batchid) from dp_2_maps_allalarms_statistics) and inspect_rate<200 "+ + " ORDER BY inspect_rate limit 5"; + return SQL; + } + } + + @SelectProvider(type = dpNewYayun_ZongHe_Mapper.class_get_statistics.class,method = "get_scene_sta_SQL") + class_dp_5_scenesta get_scene_sta(); + + @SelectProvider(type = dpNewYayun_ZongHe_Mapper.class_get_statistics.class,method = "get_scene_contacts_SQL") + List get_scene_contacts_list(); + + @SelectProvider(type = dpNewYayun_ZongHe_Mapper.class_get_statistics.class,method = "get_sign_top5_SQL") + List get_sign_top5(); + + @SelectProvider(type = dpNewYayun_ZongHe_Mapper.class_get_statistics.class,method = "get_inspect_top5_SQL") + List get_inspect_top5(); +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpYayunMapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpYayunMapper.java new file mode 100644 index 0000000..c362297 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpYayunMapper.java @@ -0,0 +1,1089 @@ +package com.ruoyi.sunlm.mapper; + +import java.util.List; +import com.ruoyi.sunlm.domain.*; +import org.apache.ibatis.annotations.*; +import org.springframework.stereotype.Component; + +/** + * 参数配置 数据层 + * + * @author ruoyi + */ +@Mapper +@Component +public interface dpYayunMapper +{ + @Select("select runtype from dp_scene_runtype") //1:正式, 0:演示 + int getruntype(); + + //region------------------------------------------------------------------------------------调用存储过程测试 + @Select("select getkpivalue(300,98,99,-115,'4G','FDD-1800','',20)") + String calldbfunction(); + //endregion + + //region------------------------------------------------------------------------------------获取场馆列表 + @Select("select id venueId,venue_name venueName from yw_scene where scene_big_id in (select id from yw_scene_big_config where status='2') order by id") + List getvenuelists(); + //endregion + + //region --------------------------------------------------------------------------------------------左侧列表1 + class class_get_left_1_data // 区域用户数,15分钟,X轴0-24点,15分钟一个间隔,昨日今日对比 + { + public String get_left_1_data_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("jobtype") String jobtype) + { + String SQL=" "; + if (typeid==1) //4G //(select max(结束时间) from pm_kpi4g_venue) + { + String sTime=" (select max(结束时间) from pm_kpi4g_venue where 场馆id=#{sceneid}) +'-10 min' "; //TEST + if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) "; + /* + SQL=" select distinct * from ((select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 1 sign from pm_kpi4g_venue where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+",'yyyy-mm-dd') order by 结束时间)"+ + " union all " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 2 sign from pm_kpi4g_venue where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') order by 结束时间)) a"; */ + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), (select max(结束时间) from pm_kpi4g_venue where 场馆id =#{sceneid}), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 1 sign from pm_kpi4g_venue where 场馆id=#{sceneid}" + + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd')" + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 2 sign from pm_kpi4g_venue where 场馆id=#{sceneid} " + + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') " + + " ) " + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + + } + else //5G //(select max(结束时间) from pm_kpi5g_venue) + { + String sTime=" (select max(结束时间) from pm_kpi5g_venue where 场馆id =#{sceneid}) +'-10 min' "; + if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) "; + /* + SQL=" select distinct * from ((select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 1 sign from pm_kpi5g_venue where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+",'yyyy-mm-dd') order by 结束时间)"+ + " union all " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 2 sign from pm_kpi5g_venue where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') order by 结束时间)) a"; */ + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), (select max(结束时间) from pm_kpi5g_venue where 场馆id =#{sceneid}), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 1 sign from pm_kpi5g_venue where 场馆id=#{sceneid}" + + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd')" + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 2 sign from pm_kpi5g_venue where 场馆id=#{sceneid} " + + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') " + + " ) " + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + } + return SQL; + } + } + @SelectProvider(type = class_get_left_1_data.class,method = "get_left_1_data_SQL") + List get_left_1_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("jobtype") String jobtype); + //endregion + + //region --------------------------------------------------------------------------------------------左侧列表2 + class class_get_left_2_data // 区域流量,15分钟,,X轴0-24点,15分钟一个间隔,昨日今日对比 + { + public String get_left_2_data_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("jobtype") String jobtype) + { + String SQL=" "; + if (typeid==1) //4G//(select max(结束时间) from pm_kpi4g_venue) + { + String sTime=" (select max(结束时间) from pm_kpi4g_venue where 场馆id=#{sceneid}) +'-10 min' "; + if (jobtype.equals("WORK")) sTime= " LOCALTIMESTAMP(0) "; + /* + SQL="select distinct * from ((select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 1 sign from pm_kpi4g_venue where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+",'yyyy-mm-dd') order by 结束时间)"+ + " union all " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 2 sign from pm_kpi4g_venue where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') order by 结束时间)) a"; */ + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), (select max(结束时间) from pm_kpi4g_venue where 场馆id =#{sceneid}), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 1 sign from pm_kpi4g_venue where 场馆id=#{sceneid}" + + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd')" + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 2 sign from pm_kpi4g_venue where 场馆id=#{sceneid} " + + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') " + + " ) " + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + } + else //5G /(select max(结束时间) from pm_kpi4g_venue) + { + String sTime=" (select max(结束时间) from pm_kpi5g_venue where 场馆id=#{sceneid}) +'-10 min' "; + if (jobtype.equals("WORK")) sTime= " LOCALTIMESTAMP(0) "; + /* + SQL=" select distinct * from ((select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 1 sign from pm_kpi5g_venue where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+",'yyyy-mm-dd') order by 结束时间)"+ + " union all " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 2 sign from pm_kpi5g_venue where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') order by 结束时间)) a ";*/ + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), (select max(结束时间) from pm_kpi5g_venue where 场馆id =#{sceneid}), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 1 sign from pm_kpi5g_venue where 场馆id=#{sceneid}" + + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd')" + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 2 sign from pm_kpi5g_venue where 场馆id=#{sceneid} " + + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') " + + " ) " + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + } + return SQL; + } + } + + @SelectProvider(type = class_get_left_2_data.class,method = "get_left_2_data_SQL") + List get_left_2_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("jobtype") String jobtype); + //endregion + + //region --------------------------------------------------------------------------------------------左侧TOP5 + @Select("select mintype from dp_scene_control") + int getmincontroltype(); + + class class_get_left_3_data // 最大用户数TOP5,15分钟/1分钟(中台控制),最终值TOP5降序排列,文本白色,指标值彩色(叠加颜色指示) + { + public String get_left_3_data_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype) + { + String SQL=" "; + if (mintype==1) { //1分钟 + if (typeid == 1) //4G //(select max(时间) from pm_kpi4g_min) + { + //String sTime=" (select max(时间) from pm_kpi4g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell)) +'-10 min' " ; + String sTable=" (SELECT * " + + " FROM ( SELECT *, " + + " row_number() OVER (PARTITION BY t.小区名称) AS group_idx " + + " FROM ( SELECT * from pm_kpi4g_min " + + " WHERE 时间 >LOCALTIMESTAMP(0)+'-10 min' order by 小区名称, 时间 desc ) t) s " + + " WHERE s.group_idx = 1 and max_user is not null order by max_user desc) "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) + '-3 min' "; + //if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi4g_min') " ; + // sTime=" (select max(时间) from pm_kpi4g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell where 场馆id = #{sceneid})) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by level ) title,name,value,color,level from (" + + " select row_number() over(order by max_user desc) title,t.小区名称 name,round(max_user::numeric,2) value," + + " getkpicolor('最大用户数', max_user,'4G',t2.小区频段,t2.设备类型,t2.带宽) color, " + + " getkpilevel('最大用户数', max_user,'4G',t2.小区频段,t2.设备类型,t2.带宽) level " + + //" from pm_kpi4g_min t" + " from "+sTable+" t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 " + + " where max_user is not null " + + //" and 时间>="+sTime+ + " and t2.场馆id=" +sceneid+swhere+ + " order by level asc,t.max_user desc limit 5) a "; + } + else //5G //(select max(时间) from pm_kpi5g_min) + { + //String sTime=" (select max(时间) from pm_kpi5g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell)) +'-10 min' " ; + String sTable=" (SELECT * " + + " FROM ( SELECT *, " + + " row_number() OVER (PARTITION BY t.小区名称) AS group_idx " + + " FROM ( SELECT * from pm_kpi5g_min " + + " WHERE 时间 >LOCALTIMESTAMP(0)+'-10 min' order by 小区名称, 时间 desc ) t) s " + + " WHERE s.group_idx = 1 and rrc_max_user is not null order by rrc_max_user desc) "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) + '-3 min' " ; + //if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi5g_min') " ; + // sTime=" (select max(时间) from pm_kpi5g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell where 场馆id = #{sceneid})) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by level ) title,name,value,color,level from (" + + " select row_number() over(order by rrc_max_user desc) title,t.小区名称 name,round(rrc_max_user::numeric,2) value," + + " getkpicolor('最大用户数', rrc_max_user,'5G',t2.小区频段,t2.设备类型,t2.带宽) color ," + + " getkpilevel('最大用户数', rrc_max_user,'5G',t2.小区频段,t2.设备类型,t2.带宽) level " + + //" from pm_kpi5g_min t " + + " from "+sTable+" t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 where rrc_max_user is not null " + + //" and 时间>="+sTime+ + " and t2.场馆id=" +sceneid+swhere + + " order by level asc,t.rrc_max_user desc limit 5 ) a "; + } + } + else //15分钟 + { + if (typeid == 1) //4G//(select max(endtime) from pm_kpi4g_cell) + { + String sTime=" (select max(endtime) from pm_kpi4g_cell where venue_id=#{sceneid}) +'-10 min' "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-60 min' "; + //if (jobtype.equals("WORK")) sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi4g_cell' ) " ; + if (jobtype.equals("WORK")) sTime=" (select max(endtime) from pm_kpi4g_cell where venue_id = #{sceneid}) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by level ) title,name,value,color,level from (" + + " select row_number() over(order by 最大用户数 desc) title,t.小区名称 name,最大用户数 value," + + " getkpicolor('最大用户数', 最大用户数,'4G',t2.小区频段,t2.设备类型,t2.带宽) color, " + + " getkpilevel('最大用户数', 最大用户数,'4G',t2.小区频段,t2.设备类型,t2.带宽) level " + + " from pm_kpi4g_cell t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 最大用户数 is not null " + + " and endtime>="+sTime+" and venue_id="+sceneid +swhere + + " order by level asc,t.最大用户数 desc limit 5) a "; + } + else //5G //(select max(endtime) from pm_kpi5g_cell) + { + String sTime=" (select max(endtime) from pm_kpi5g_cell where venue_id =#{sceneid}) +'-10 min' " ; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-60 min' "; + //if (jobtype.equals("WORK")) sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi5g_cell') " ; + if (jobtype.equals("WORK")) sTime=" (select max(endtime) from pm_kpi5g_cell where venue_id = #{sceneid}) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by level ) title,name,value,color,level from (" + + " select row_number() over(order by 最大用户数 desc) title,t.小区名称 name,最大用户数 value," + + " getkpicolor('最大用户数', 最大用户数,'5G',t2.小区频段,t2.设备类型,t2.带宽) color ," + + " getkpilevel('最大用户数', 最大用户数,'5G',t2.小区频段,t2.设备类型,t2.带宽) level " + + " from pm_kpi5g_cell t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 最大用户数 is not null " + + " and endtime>="+sTime+" and venue_id="+sceneid +swhere+ + " order by level asc ,t.最大用户数 desc limit 5) a "; + } + } + return SQL; + } + } + + @SelectProvider(type = class_get_left_3_data.class,method = "get_left_3_data_SQL") + List get_left_3_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype); + //endregion + + //region --------------------------------------------------------------------------------------------右侧TOP5图表1 + class class_get_right_1_data // 上行Prb利用率TOP5,15分钟/1分钟(中台控制),最终值TOP5降序排列,文本白色,指标值彩色(叠加颜色指示) + { + public String get_right_1_data_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype) + { + String SQL=" "; + if (mintype==1) { //1分钟 + if (typeid == 1) //4G //(select max(时间) from pm_kpi4g_min) + { + //String sTime=" (select max(时间) from pm_kpi4g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell)) +'-10 min' "; + String sTable=" (SELECT * " + + " FROM ( SELECT *, " + + " row_number() OVER (PARTITION BY t.小区名称) AS group_idx " + + " FROM ( SELECT * from pm_kpi4g_min " + + " WHERE 时间 >LOCALTIMESTAMP(0)+'-10 min' order by 小区名称, 时间 desc ) t) s " + + " WHERE s.group_idx = 1 and prb_up is not null order by prb_up desc) "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-3 min' "; + //if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi4g_min') " ; + // sTime=" (select max(时间) from pm_kpi4g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell where 场馆id = #{sceneid})) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by prb_up desc) title,t.小区名称 name,round(prb_up::numeric, 2) value," + + " getkpicolor('上行Prb利用率', prb_up,'4G',t2.小区频段,t2.设备类型,t2.带宽) color " + + //" from pm_kpi4g_min t " + + " from "+sTable+" t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 where prb_up is not null " + + //" and 时间>="+sTime + + " and t2.场馆id=" +sceneid+swhere+ + " order by t.prb_up desc limit 5 "; + } + else //5G //(select max(时间) from pm_kpi5g_min) + { + //String sTime=" (select max(时间) from pm_kpi5g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell)) +'-10 min' "; + String sTable=" (SELECT * " + + " FROM ( SELECT *, " + + " row_number() OVER (PARTITION BY t.小区名称) AS group_idx " + + " FROM ( SELECT * from pm_kpi5g_min " + + " WHERE 时间 >LOCALTIMESTAMP(0)+'-10 min' order by 小区名称, 时间 desc ) t) s " + + " WHERE s.group_idx = 1 and prb_up is not null order by prb_up desc) "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-3 min' "; + //if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi5g_min') " ; + // sTime=" (select max(时间) from pm_kpi5g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell where 场馆id = #{sceneid})) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by prb_up desc) title,t.小区名称 name,round(prb_up::numeric, 2) value," + + " getkpicolor('上行Prb利用率', prb_up,'5G',t2.小区频段,t2.设备类型,t2.带宽) color " + + //" from pm_kpi5g_min t " + + " from "+sTable+" t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 where prb_up is not null " + + //" and 时间>="+sTime + + " and t2.场馆id=" +sceneid+swhere+ + " order by t.prb_up desc limit 5 "; + } + } + else //15分钟 + { + if (typeid == 1) //4G //(select max(endtime) from pm_kpi4g_cell) + { + String sTime=" (select max(endtime) from pm_kpi4g_cell where venue_id=#{sceneid}) +'-10 min' "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-60 min' "; + //if (jobtype.equals("WORK")) sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi4g_cell') " ; + if (jobtype.equals("WORK")) sTime=" (select max(endtime) from pm_kpi4g_cell where venue_id = #{sceneid}) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by 上行Prb利用率 desc) title,t.小区名称 name,上行Prb利用率 value," + + " getkpicolor('上行Prb利用率', 上行Prb利用率,'4G','','',20) color from pm_kpi4g_cell t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 上行Prb利用率 is not null " + + " and endtime>="+sTime+" and venue_id="+sceneid +swhere+ + " order by t.上行Prb利用率 desc limit 5 "; + } + else //5G //(select max(endtime) from pm_kpi5g_cell) + { + String sTime=" (select max(endtime) from pm_kpi5g_cell where venue_id =#{sceneid}) +'-10 min' "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-60 min' "; + //if (jobtype.equals("WORK")) sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi5g_cell') " ; + if (jobtype.equals("WORK")) sTime=" (select max(endtime) from pm_kpi5g_cell where venue_id = #{sceneid}) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by 上行Prb利用率 desc) title,t.小区名称 name,上行Prb利用率 value ," + + " getkpicolor('上行Prb利用率', 上行Prb利用率,'5G','','',20) color from pm_kpi5g_cell t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 上行Prb利用率 is not null " + + " and endtime>="+sTime+" and venue_id="+sceneid +swhere+ + " order by t.上行Prb利用率 desc limit 5 "; + } + } + return SQL; + } + } + + @SelectProvider(type = class_get_right_1_data.class,method = "get_right_1_data_SQL") + List get_right_1_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype); + //endregion + + //region --------------------------------------------------------------------------------------------右侧TOP5图表2 + class class_get_right_2_data // 下行Prb利用率TOP5,15分钟/1分钟(中台控制),最终值TOP5降序排列,文本白色,指标值彩色(叠加颜色指示) + { + public String get_right_2_data_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype) + { + String SQL=" "; + if (mintype==1) { //1分钟 + if (typeid == 1) //4G //(select max(时间) from pm_kpi4g_min) + { + //String sTime=" (select max(时间) from pm_kpi4g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell)) +'-10 min' "; + String sTable=" (SELECT * " + + " FROM ( SELECT *, " + + " row_number() OVER (PARTITION BY t.小区名称) AS group_idx " + + " FROM ( SELECT * from pm_kpi4g_min " + + " WHERE 时间 >LOCALTIMESTAMP(0)+'-10 min' order by 小区名称, 时间 desc ) t) s " + + " WHERE s.group_idx = 1 and prb_down is not null order by prb_down desc) "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) + '-3 min' "; + //if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi4g_min') " ; + // sTime=" (select max(时间) from pm_kpi4g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell where 场馆id = #{sceneid})) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by prb_down desc) title,t.小区名称 name,round(prb_down::numeric, 2) value," + + " getkpicolor('下行Prb利用率', prb_down,'4G',t2.小区频段,t2.设备类型,t2.带宽) color " + + //" from pm_kpi4g_min t " + + " from "+sTable+" t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 where prb_down is not null " + + //" and 时间>="+sTime + + " and t2.场馆id=" +sceneid+swhere+ + " order by t.prb_down desc limit 5 "; + } + else //5G //(select max(时间) from pm_kpi5g_min) + { + //String sTime= " (select max(时间) from pm_kpi5g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell)) +'-10 min' "; + String sTable=" (SELECT * " + + " FROM ( SELECT *, " + + " row_number() OVER (PARTITION BY t.小区名称) AS group_idx " + + " FROM ( SELECT * from pm_kpi5g_min " + + " WHERE 时间 >LOCALTIMESTAMP(0)+'-10 min' order by 小区名称, 时间 desc ) t) s " + + " WHERE s.group_idx = 1 and prb_down is not null order by prb_down desc) "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) + '-3 min' "; + //if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi5g_min') " ; + // sTime=" (select max(时间) from pm_kpi5g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell where 场馆id = #{sceneid})) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by prb_down desc) title,t.小区名称 name,round(prb_down::numeric, 2) value," + + " getkpicolor('下行Prb利用率', prb_down,'5G',t2.小区频段,t2.设备类型,t2.带宽) color " + + //" from pm_kpi5g_min t " + + " from "+sTable+" t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 where prb_down is not null " + + //" and 时间>="+sTime+ + " and t2.场馆id=" +sceneid+swhere+ + " order by t.prb_down desc limit 5 "; + } + } + else //15分钟 + { + if (typeid == 1) //4G //(select max(endtime) from pm_kpi4g_cell) + { + String sTime=" (select max(endtime) from pm_kpi4g_cell where venue_id=#{sceneid}) +'-10 min' "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-60 min' "; + //if (jobtype.equals("WORK")) sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi4g_cell' ) " ; + if (jobtype.equals("WORK")) sTime=" (select max(endtime) from pm_kpi4g_cell where venue_id = #{sceneid}) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by 下行Prb利用率 desc) title,t.小区名称 name,下行Prb利用率 value," + + " getkpicolor('下行Prb利用率', 下行Prb利用率,'4G','','',20) color from pm_kpi4g_cell t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 下行Prb利用率 is not null " + + " and endtime>="+sTime+" and venue_id="+sceneid +swhere+ + " order by t.下行Prb利用率 desc limit 5 "; + } + else //5G //(select max(endtime) from pm_kpi5g_cell) + { + String sTime=" (select max(endtime) from pm_kpi5g_cell where venue_id=#{sceneid}) +'-10 min' "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-60 min' "; + //if (jobtype.equals("WORK")) sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi5g_cell' ) " ; + if (jobtype.equals("WORK")) sTime=" (select max(endtime) from pm_kpi5g_cell where venue_id = #{sceneid}) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by 下行Prb利用率 desc) title,t.小区名称 name,下行Prb利用率 value," + + " getkpicolor('下行Prb利用率', 下行Prb利用率,'5G','','',20) color from pm_kpi5g_cell t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 下行Prb利用率 is not null " + + " and endtime>="+sTime+" and venue_id="+sceneid +swhere+ + " order by t.下行Prb利用率 desc limit 5 "; + } + } + return SQL; + } + } + + @SelectProvider(type = class_get_right_2_data.class,method = "get_right_2_data_SQL") + List get_right_2_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype); + //endregion + + //region --------------------------------------------------------------------------------------------右侧TOP5图表3 + class class_get_right_3_data // 最大干扰值TOP5,15分钟/1分钟(中台控制),最终值TOP5降序排列,文本白色,指标值彩色(叠加颜色指示) + { + public String get_right_3_data_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype) + { + String SQL=" "; + if (mintype==1) { //1分钟 + if (typeid == 1) //4G //(select max(时间) from pm_kpi4g_min) + { + //String sTime=" (select max(时间) from pm_kpi4g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell)) +'-10 min' "; + String sTable=" (SELECT * " + + " FROM ( SELECT *, " + + " row_number() OVER (PARTITION BY t.小区名称) AS group_idx " + + " FROM ( SELECT * from pm_kpi4g_min " + + " WHERE 时间 >LOCALTIMESTAMP(0)+'-10 min' order by 小区名称, 时间 desc ) t) s " + + " WHERE s.group_idx = 1 and avg_disturb is not null order by avg_disturb desc) "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) + '-3 min' "; + //if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi4g_min') " ; + // sTime=" (select max(时间) from pm_kpi4g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell where 场馆id = #{sceneid})) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by avg_disturb desc) title,t.小区名称 name,round(avg_disturb::numeric, 2) value," + + " getkpicolor('平均干扰值', avg_disturb,'4G',t2.小区频段,t2.设备类型,t2.带宽) color " + + //" from pm_kpi4g_min t " + + " from "+sTable+" t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 where avg_disturb is not null " + + //" and 时间>="+sTime + + " and t2.场馆id=" +sceneid+swhere+ + " order by t.avg_disturb desc limit 5 "; + } + else //5G //(select max(时间) from pm_kpi5g_min) + { + //String sTime=" (select max(时间) from pm_kpi5g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell)) +'-10 min' "; + String sTable=" (SELECT * " + + " FROM ( SELECT *, " + + " row_number() OVER (PARTITION BY t.小区名称) AS group_idx " + + " FROM ( SELECT * from pm_kpi5g_min " + + " WHERE 时间 >LOCALTIMESTAMP(0)+'-10 min' order by 小区名称, 时间 desc ) t) s " + + " WHERE s.group_idx = 1 and up_disturb is not null order by up_disturb desc) "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) + '-3 min' "; + //if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi5g_min') " ; + // sTime=" (select max(时间) from pm_kpi5g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell where 场馆id = #{sceneid})) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by up_disturb desc) title,t.小区名称 name,round(up_disturb::numeric, 2) value," + + " getkpicolor('平均干扰值', up_disturb,'5G',t2.小区频段,t2.设备类型,t2.带宽) color " + + //" from pm_kpi5g_min t " + + " from "+sTable+" t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 where up_disturb is not null " + + //" and 时间>="+sTime + + " and t2.场馆id=" +sceneid+swhere+ + " order by t.up_disturb desc limit 5 "; + } + } + else //15分钟 + { + if (typeid == 1) //4G //(select max(endtime) from pm_kpi4g_cell) + { + String sTime=" (select max(endtime) from pm_kpi4g_cell where venue_id =#{sceneid}) +'-10 min' "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-60 min' "; + //if (jobtype.equals("WORK")) sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi4g_cell' ) " ; + if (jobtype.equals("WORK")) sTime=" (select max(endtime) from pm_kpi4g_cell where venue_id = #{sceneid}) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by 上行平均干扰 desc) title,t.小区名称 name,上行平均干扰 value," + + " getkpicolor('平均干扰值', 上行平均干扰,'4G','','',20) color from pm_kpi4g_cell t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 上行平均干扰 is not null " + + " and endtime>="+sTime+" and venue_id="+sceneid +swhere+ + " order by t.上行平均干扰 desc limit 5 "; + } + else //5G //(select max(endtime) from pm_kpi5g_cell) + { + String sTime=" (select max(endtime) from pm_kpi5g_cell where venue_id=#{sceneid}) +'-10 min' "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-60 min' "; + //if (jobtype.equals("WORK")) sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi5g_cell' ) " ; + if (jobtype.equals("WORK")) sTime=" (select max(endtime) from pm_kpi5g_cell where venue_id = #{sceneid}) " ; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by 上行干扰值 desc) title,t.小区名称 name,上行干扰值 value," + + " getkpicolor('平均干扰值', 上行干扰值,'5G','','',20) color from pm_kpi5g_cell t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 上行干扰值 is not null " + + " and endtime>="+sTime+" and venue_id="+sceneid +swhere+ + " order by t.上行干扰值 desc limit 5 "; + } + } + return SQL; + } + } + + @SelectProvider(type = class_get_right_3_data.class,method = "get_right_3_data_SQL") + List get_right_3_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype); + //endregion + + //region -------------------------------------------------------------------------------------------地图, 用新接口替换 + class class_get_maps_data + { + public String get_maps_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid) + { + String SQL=" select venue_name name," + + " cast(wgs84togcj02(longitude::numeric,latitude::numeric,'lng') as VARCHAR)||','||" + + " cast(wgs84togcj02(longitude::numeric,latitude::numeric,'lat') as VARCHAR) center" + + " from yw_scene where id= "+sceneid; + return SQL; + } + + public String get_bts_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid, + @Param("kpiname") String kpiname,@Param("mintype") int mintype,@Param("jobtype") String jobtype) + { + StringBuilder SQL = new StringBuilder(); + if (mintype==1) { //1分钟 + if (typeid == 1) //4G //(select max(时间) from pm_kpi4g_min) + { + //String sTime = " (select max(时间) from pm_kpi4g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell)) +'-10 min' "; + String sTable=" (SELECT * " + + " FROM ( SELECT *, " + + " row_number() OVER (PARTITION BY t.小区名称) AS group_idx " + + " FROM ( SELECT * from pm_kpi4g_min " + + " WHERE 时间 >LOCALTIMESTAMP(0)+'-10 min' order by 小区名称, 时间 desc ) t) s " + + " WHERE s.group_idx = 1 ) "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-3 min' "; + //if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi4g_min') " ; + // sTime = " (select max(时间) from pm_kpi4g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell where 场馆id = #{sceneid})) "; + SQL.append("select ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.max_user,b.prb_up,b.prb_down,b.avg_disturb,'4G',小区频段,设备类型,带宽) algoValue," + + " b.max_user avgUsrValue," + + " b.prb_up uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.prb_down downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.max_user,b.prb_up,b.prb_down,b.avg_disturb,'4G',小区频段,设备类型,带宽)) ,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.max_user,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.prb_up,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.prb_down,'4G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a" + + //" left join pm_kpi4g_min b " + + " left join "+sTable+" b " + + " on a.小区名称=b.小区名称 " + + //" and b.时间>=" + sTime + + " where 网络='LTE' and 场馆id=" + sceneid + " order by level desc"); + } + else if (typeid == 2) //5G ////(select max(时间) from pm_kpi5g_min) + { + //String sTime = " (select max(时间) from pm_kpi5g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell)) +'-10 min' "; + String sTable=" (SELECT * " + + " FROM ( SELECT *, " + + " row_number() OVER (PARTITION BY t.小区名称) AS group_idx " + + " FROM ( SELECT * from pm_kpi5g_min " + + " WHERE 时间 >LOCALTIMESTAMP(0)+'-10 min' order by 小区名称, 时间 desc ) t) s " + + " WHERE s.group_idx = 1 ) "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-3 min' "; + //if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi5g_min') " ; + // sTime = " (select max(时间) from pm_kpi5g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell where 场馆id = #{sceneid})) "; + SQL.append(" select ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.rrc_max_user,b.prb_up,b.prb_down,b.up_disturb,'5G',小区频段,设备类型,带宽) algoValue," + + " b.rrc_max_user avgUsrValue," + + " b.prb_up uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.prb_down downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.rrc_max_user,b.prb_up,b.prb_down,b.up_disturb,'5G',小区频段,设备类型,带宽)),'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.rrc_max_user,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.prb_up,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.prb_down,'5G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a " + + //" left join pm_kpi5g_min b " + + " left join "+sTable+" b " + + " on a.小区名称=b.小区名称 " + + //" and b.时间>=" + sTime + + " where 网络='NR' and 场馆id=" + sceneid + " order by level desc"); + } + } + else //15分钟 + { + if (typeid == 1) //4G + { + String sTime = " (select max(endtime) from pm_kpi4g_cell where venue_id in (select distinct 场馆id from dp_scene_cell)) +'-10 min' "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-3 min' "; + if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi4g_min') " ; + sTime=" (select max(endtime) from pm_kpi4g_cell where venue_id = #{sceneid}) " ; + SQL.append("select ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.最大用户数,b.上行prb利用率,b.上行prb利用率,b.上行平均干扰,'4G',小区频段,设备类型,带宽) algoValue," + + " b.最大用户数 avgUsrValue," + + " b.上行prb利用率 uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.下行prb利用率 downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行平均干扰,'4G',小区频段,设备类型,带宽)) ,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.最大用户数,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.上行prb利用率,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.下行prb利用率,'4G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a" + + " left join pm_kpi4g_cell b on a.小区名称=b.小区名称 and venue_id = #{sceneid} and b.endtime>=" + sTime + + " where 网络='LTE' and 场馆id=" + sceneid + " order by level desc"); + } + else if (typeid == 2) //5G + { + String sTime = " (select max(endtime) from pm_kpi5g_cell where venue_id in (select distinct 场馆id from dp_scene_cell)) +'-10 min' "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-3 min' "; + if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi5g_min') " ; + sTime=" (select max(endtime) from pm_kpi5g_cell where venue_id = #{sceneid}) " ; + SQL.append("select a.ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行干扰值,'5G',小区频段,设备类型,带宽) algoValue," + + " b.最大用户数 avgUsrValue," + + " b.上行prb利用率 uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.下行prb利用率 downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行干扰值,'5G',小区频段,设备类型,带宽)),'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.最大用户数,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.上行prb利用率,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.下行prb利用率,'5G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a " + + " left join pm_kpi5g_cell b on a.小区名称=b.小区名称 and venue_id = #{sceneid} and b.endtime>=" + sTime + + " where 网络='NR' and 场馆id=" + sceneid + " order by level desc"); + } + } + return SQL.toString(); + } + } + + @SelectProvider(type = class_get_maps_data.class,method = "get_maps_SQL") + class_dp_maps get_maps_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid); + + @SelectProvider(type = class_get_maps_data.class,method = "get_bts_SQL") + List get_bts_data(@Param("sceneid") int sceneid, @Param("typeid") int typeid, @Param("kpiname") String kpiname, + @Param("mintype") int mintype,@Param("jobtype") String jobtype); + //endregion + + //region --------------------------------------------------------------------------------------------顶部统计值,用新接口替换 + class class_get_top_data + { + public String get_top_data_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("kpiname") String kpiname, + @Param("mintype") int mintype,@Param("jobtype") String jobtype) + { + StringBuilder SQL = new StringBuilder(); + if (mintype==1) { //1分钟 + if (typeid == 1) //4G //(select max(时间) from pm_kpi4g_min) + { + //String sTime = " (select max(时间) from pm_kpi4g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell)) +'-10 min' "; + String sTable=" (SELECT * " + + " FROM ( SELECT *, " + + " row_number() OVER (PARTITION BY t.小区名称) AS group_idx " + + " FROM ( SELECT * from pm_kpi4g_min " + + " WHERE 时间 >LOCALTIMESTAMP(0)+'-10 min' order by 小区名称, 时间 desc ) t) s " + + " WHERE s.group_idx = 1 ) "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-3 min' "; + //if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi4g_min') " ; + // sTime = " (select max(时间) from pm_kpi4g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell where 场馆id = #{sceneid})) "; + SQL.append("select ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.max_user,b.prb_up,b.prb_down,b.avg_disturb,'4G',小区频段,设备类型,带宽) algoValue," + //综合算法 + " b.max_user avgUsrValue," + + " b.prb_up uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.prb_down downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.max_user,b.prb_up,b.prb_down,b.avg_disturb,'4G',小区频段,设备类型,带宽)),'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.max_user,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.prb_up,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.prb_down,'4G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a" + + //" left join pm_kpi4g_min b " + + " left join "+sTable+" b " + + " on a.小区名称=b.小区名称 " + + //" and b.时间>=" + sTime + + " where 网络='LTE' and 场馆id=" + sceneid + " order by level desc"); + } + else if (typeid == 2) //5G ////(select max(时间) from pm_kpi5g_min) + { + //String sTime = " (select max(时间) from pm_kpi5g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell)) +'-10 min' "; + String sTable=" (SELECT * " + + " FROM ( SELECT *, " + + " row_number() OVER (PARTITION BY t.小区名称) AS group_idx " + + " FROM ( SELECT * from pm_kpi5g_min " + + " WHERE 时间 >LOCALTIMESTAMP(0)+'-10 min' order by 小区名称, 时间 desc ) t) s " + + " WHERE s.group_idx = 1 ) "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-3 min' "; + //if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi5g_min') " ; + // sTime = " (select max(时间) from pm_kpi5g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell where 场馆id = #{sceneid})) "; + SQL.append("select ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.rrc_max_user,b.prb_up,b.prb_down,b.up_disturb,'5G',小区频段,设备类型,带宽) algoValue," + + " b.rrc_max_user avgUsrValue," + + " b.prb_up uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.prb_down downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.rrc_max_user,b.prb_up,b.prb_down,b.up_disturb,'5G',小区频段,设备类型,带宽)),'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.rrc_max_user,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.prb_up,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.prb_down,'5G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a " + + //" left join pm_kpi5g_min b " + + " left join "+sTable+" b " + + " on a.小区名称=b.小区名称 " + + //" and b.时间>=" + sTime + + " where 网络='NR' and 场馆id=" + sceneid + " order by level desc"); + } + } + else //15分钟 + { + if (typeid == 1) //4G + { + String sTime = " (select max(endtime) from pm_kpi4g_cell where venue_id in (select distinct 场馆id from dp_scene_cell)) +'-10 min' "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-3 min' "; + if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi4g_min') " ; + sTime=" (select max(endtime) from pm_kpi4g_cell where venue_id = #{sceneid}) " ; + SQL.append("select ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行平均干扰,'4G',小区频段,设备类型,带宽) algoValue," + + " b.最大用户数 avgUsrValue," + + " b.上行prb利用率 uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.下行prb利用率 downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行平均干扰,'4G',小区频段,设备类型,带宽)) ,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.最大用户数,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.上行prb利用率,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.下行prb利用率,'4G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a" + + " left join pm_kpi4g_cell b on a.小区名称=b.小区名称 and venue_id = #{sceneid} and b.endtime>=" + sTime + + " where 网络='LTE' and 场馆id=" + sceneid + " order by level desc"); + } + else if (typeid == 2) //5G + { + String sTime = " (select max(endtime) from pm_kpi5g_cell where venue_id in (select distinct 场馆id from dp_scene_cell)) +'-10 min' "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-3 min' "; + if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi5g_min') " ; + sTime=" (select max(endtime) from pm_kpi5g_cell where venue_id = #{sceneid}) " ; + SQL.append("select a.ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行干扰值,'5G',小区频段,设备类型,带宽) algoValue," + + " b.最大用户数 avgUsrValue," + + " b.上行prb利用率 uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.下行prb利用率 downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行干扰值,'5G',小区频段,设备类型,带宽)),'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.最大用户数,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.上行prb利用率,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.下行prb利用率,'5G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a " + + " left join pm_kpi5g_cell b on a.小区名称=b.小区名称 and venue_id = #{sceneid} and b.endtime>=" + sTime + + " where 网络='NR' and 场馆id=" + sceneid + " order by level desc"); + } + } + return SQL.toString(); + } + } + + @SelectProvider(type = class_get_top_data.class,method = "get_top_data_SQL") + List get_top_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("kpiname") String kpiname, + @Param("mintype") int mintype,@Param("jobtype") String jobtype); + //endregion + + //region -------------------------------------------------------------------------------------------地图和统计值统一接口 + class class_get_maps_top_data + { + public String get_maps_top_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid) + { + String SQL=" select venue_name name," + + " cast(wgs84togcj02(longitude::numeric,latitude::numeric,'lng') as VARCHAR)||','||" + + " cast(wgs84togcj02(longitude::numeric,latitude::numeric,'lat') as VARCHAR) center" + + " from yw_scene where id= "+sceneid; + return SQL; + } + + public String get_bts_1to2_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid, + @Param("kpiname") String kpiname,@Param("mintype") int mintype,@Param("jobtype") String jobtype) + { + StringBuilder SQL = new StringBuilder(); + if (mintype==1) { //1分钟 + if (typeid == 1) //4G //(select max(时间) from pm_kpi4g_min) + { + //String sTime = " (select max(时间) from pm_kpi4g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell)) +'-10 min' "; + String sTable=" (SELECT * " + + " FROM ( SELECT *, " + + " row_number() OVER (PARTITION BY t.小区名称) AS group_idx " + + " FROM ( SELECT * from pm_kpi4g_min " + + " WHERE 时间 >LOCALTIMESTAMP(0)+'-10 min' order by 小区名称, 时间 desc ) t) s " + + " WHERE s.group_idx = 1 ) "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-3 min' "; + //if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi4g_min') " ; + // sTime = " (select max(时间) from pm_kpi4g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell where 场馆id = #{sceneid})) "; + SQL.append("select ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.max_user,b.prb_up,b.prb_down,b.avg_disturb,'4G',小区频段,设备类型,带宽) algoValue," + + " b.max_user avgUsrValue," + + " b.prb_up uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.prb_down downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.max_user,b.prb_up,b.prb_down,b.avg_disturb,'4G',小区频段,设备类型,带宽)) ,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.max_user,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.prb_up,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.prb_down,'4G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a" + + //" left join pm_kpi4g_min b " + + " left join "+sTable+" b " + + " on a.小区名称=b.小区名称 " + + //" and b.时间>=" + sTime + + " where 网络='LTE' and 场馆id=" + sceneid + " order by level desc"); + } + else if (typeid == 2) //5G ////(select max(时间) from pm_kpi5g_min) + { + //String sTime = " (select max(时间) from pm_kpi5g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell)) +'-10 min' "; + String sTable=" (SELECT * " + + " FROM ( SELECT *, " + + " row_number() OVER (PARTITION BY t.小区名称) AS group_idx " + + " FROM ( SELECT * from pm_kpi5g_min " + + " WHERE 时间 >LOCALTIMESTAMP(0)+'-10 min' order by 小区名称, 时间 desc ) t) s " + + " WHERE s.group_idx = 1 ) "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-3 min' "; + //if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi5g_min') " ; + // sTime = " (select max(时间) from pm_kpi5g_min where 小区名称 in (select distinct 小区名称 from dp_scene_cell where 场馆id = #{sceneid})) "; + SQL.append("select ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.rrc_max_user,b.prb_up,b.prb_down,b.up_disturb,'5G',小区频段,设备类型,带宽) algoValue," + + " b.rrc_max_user avgUsrValue," + + " b.prb_up uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.prb_down downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.rrc_max_user,b.prb_up,b.prb_down,b.up_disturb,'5G',小区频段,设备类型,带宽)),'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.rrc_max_user,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.prb_up,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.prb_down,'5G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a " + + //" left join pm_kpi5g_min b " + + " left join "+sTable+" b " + + " on a.小区名称=b.小区名称 " + + //" and b.时间>=" + sTime + + " where 网络='NR' and 场馆id=" + sceneid + " order by level desc"); + } + } + else //15分钟 + { + if (typeid == 1) //4G + { + String sTime = " (select max(endtime) from pm_kpi4g_cell where venue_id in (select distinct 场馆id from dp_scene_cell)) +'-10 min' "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-3 min' "; + if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi4g_min') " ; + sTime=" (select max(endtime) from pm_kpi4g_cell where venue_id = #{sceneid}) " ; + SQL.append("select ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.最大用户数,b.上行prb利用率,b.上行prb利用率,b.上行平均干扰,'4G',小区频段,设备类型,带宽) algoValue," + + " b.最大用户数 avgUsrValue," + + " b.上行prb利用率 uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.下行prb利用率 downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行平均干扰,'4G',小区频段,设备类型,带宽)) ,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.最大用户数,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.上行prb利用率,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.下行prb利用率,'4G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a" + + " left join pm_kpi4g_cell b on a.小区名称=b.小区名称 and venue_id = #{sceneid} and b.endtime>=" + sTime + + " where 网络='LTE' and 场馆id=" + sceneid + " order by level desc"); + } + else if (typeid == 2) //5G + { + String sTime = " (select max(endtime) from pm_kpi5g_cell where venue_id in (select distinct 场馆id from dp_scene_cell)) +'-10 min' "; + //if (jobtype.equals("WORK")) sTime=" LOCALTIMESTAMP(0) +'-3 min' "; + if (jobtype.equals("WORK")) + //sTime=" (select maxtime from dp_scene_maxtime where tablename = 'pm_kpi5g_min') " ; + sTime=" (select max(endtime) from pm_kpi5g_cell where venue_id = #{sceneid}) " ; + SQL.append("select a.ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行干扰值,'5G',小区频段,设备类型,带宽) algoValue," + + " b.最大用户数 avgUsrValue," + + " b.上行prb利用率 uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.下行prb利用率 downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行干扰值,'5G',小区频段,设备类型,带宽)),'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.最大用户数,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.上行prb利用率,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.下行prb利用率,'5G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a " + + " left join pm_kpi5g_cell b on a.小区名称=b.小区名称 and venue_id = #{sceneid} and b.endtime>=" + sTime + + " where 网络='NR' and 场馆id=" + sceneid + " order by level desc"); + } + } + return SQL.toString(); + } + } + + @SelectProvider(type = class_get_maps_top_data.class,method = "get_maps_top_SQL") + class_dp_maps_topinfo get_maps_top_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid); + + @SelectProvider(type = class_get_maps_top_data.class,method = "get_bts_1to2_SQL") + List get_bts_1to2_data(@Param("sceneid") int sceneid, @Param("typeid") int typeid, @Param("kpiname") String kpiname, + @Param("mintype") int mintype,@Param("jobtype") String jobtype); + //endregion + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpYayunReplayMapper.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpYayunReplayMapper.java new file mode 100644 index 0000000..ab016ab --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/mapper/dpYayunReplayMapper.java @@ -0,0 +1,618 @@ +package com.ruoyi.sunlm.mapper; + +import java.util.List; +import com.ruoyi.sunlm.domain.*; +import org.apache.ibatis.annotations.*; +import org.springframework.stereotype.Component; + +/** + * 参数配置 数据层 + * + * @author ruoyi + */ +@Mapper +@Component +public interface dpYayunReplayMapper +{ + + //region------------------------------------------------------------------------------------回放复位控制 + @Update({"update dp_scene_currtime set maxtime=inittime,\"reset\"='1' where tablename='all' "}) //Mybatis 不允许全表 UPDATE + void resetreplay(); + //endregion + + //region --------------------------------------------------------------------------------------------左侧列表1 + class class_get_left_1_data // 区域用户数,15分钟,X轴0-24点,15分钟一个间隔,昨日今日对比 + { + public String get_left_1_data_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("jobtype") String jobtype) + { + String SQL=" "; + if (typeid==1) //4G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + /* + SQL=" select distinct * from ((select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 1 sign from pm_kpi4g_venue_replay where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+",'yyyy-mm-dd') and 结束时间<="+sTime+" order by 结束时间)"+ + " union all " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 2 sign from pm_kpi4g_venue_replay where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') order by 结束时间)) a";*/ + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), "+sTime+"), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 1 sign from pm_kpi4g_venue_replay where 场馆id=#{sceneid}" + + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd') and 结束时间<="+sTime + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 2 sign from pm_kpi4g_venue_replay where 场馆id=#{sceneid} " + + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') " + + " ) " + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + } + else //5G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + /* + SQL=" select distinct * from ((select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 1 sign from pm_kpi5g_venue_replay where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+",'yyyy-mm-dd') and 结束时间<="+sTime+" order by 结束时间)"+ + " union all " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 2 sign from pm_kpi5g_venue_replay where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') order by 结束时间)) a";*/ + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), "+sTime+"), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 1 sign from pm_kpi5g_venue_replay where 场馆id=#{sceneid}" + + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd') and 结束时间<="+sTime + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(最大用户数::numeric, 2) value , 2 sign from pm_kpi5g_venue_replay where 场馆id=#{sceneid} " + + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') " + + " ) " + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + } + return SQL; + } + } + @SelectProvider(type = class_get_left_1_data.class,method = "get_left_1_data_SQL") + List get_left_1_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("jobtype") String jobtype); + //endregion + + //region --------------------------------------------------------------------------------------------左侧列表2 + class class_get_left_2_data // 区域流量,15分钟,,X轴0-24点,15分钟一个间隔,昨日今日对比 + { + public String get_left_2_data_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("jobtype") String jobtype) + { + String SQL=" "; + if (typeid==1) //4G/ + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime= " ( select maxtime from dp_scene_currtime ) "; + /* + SQL="select distinct * from ((select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 1 sign from pm_kpi4g_venue_replay where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+",'yyyy-mm-dd') and 结束时间<="+sTime+" order by 结束时间)"+ + " union all " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 2 sign from pm_kpi4g_venue_replay where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') order by 结束时间)) a";*/ + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), "+sTime+"), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 1 sign from pm_kpi4g_venue_replay where 场馆id=#{sceneid}" + + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd') and 结束时间<="+sTime + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 2 sign from pm_kpi4g_venue_replay where 场馆id=#{sceneid} " + + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') " + + " ) " + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + } + else //5G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime= " ( select maxtime from dp_scene_currtime ) "; + /* + SQL=" select distinct * from ((select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 1 sign from pm_kpi5g_venue_replay where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+",'yyyy-mm-dd') and 结束时间<="+sTime+" order by 结束时间)"+ + " union all " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 2 sign from pm_kpi5g_venue_replay where 场馆id="+sceneid+ + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') order by 结束时间)) a ";*/ + SQL= " with t1 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), to_timestamp ( to_char(now(),'yyyy-mm-dd') ||' 23:59:59', 'YYYY-MM-DD hh24:mi:ss' ), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t4 as " + + " ( SELECT to_char ( b, 'hh24:mi' ) AS time FROM " + + " generate_series ( to_timestamp (to_char(now(),'yyyy-mm-dd') ||' 00:00:00', 'YYYY-MM-DD hh24:mi:ss' ), "+sTime+"), '15 min' ) AS b " + + " group by time ORDER BY time ASC )," + + + " t2 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 1 sign from pm_kpi5g_venue_replay where 场馆id=#{sceneid}" + + " and to_char(结束时间,'yyyy-mm-dd')=to_char( "+sTime+",'yyyy-mm-dd') and 结束时间<="+sTime + + " )," + + + " t3 as " + + " (select to_char(结束时间,'hh24:mi') datetime,round(\"流量GB\"::numeric, 2) value , 2 sign from pm_kpi5g_venue_replay where 场馆id=#{sceneid} " + + " and to_char(结束时间,'yyyy-mm-dd')=to_char("+sTime+"+ '-1 day','yyyy-mm-dd') " + + " ) " + + + " select * from " + + " (select t4.time datetime,COALESCE(t2.value,-1) value,COALESCE(t2.sign,1) sign from t4 left join t2 on t4.time = t2 .datetime " + + " union all" + + " select t1.time datetime,COALESCE(t3.value,-1) value,COALESCE(t3.sign,2) sign from t1 left join t3 on t1.time = t3 .datetime " + + " ) t ORDER BY t.datetime ASC"; + } + return SQL; + } + } + + @SelectProvider(type = class_get_left_2_data.class,method = "get_left_2_data_SQL") + List get_left_2_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("jobtype") String jobtype); + //endregion + + //region --------------------------------------------------------------------------------------------左侧TOP5 + class class_get_left_3_data // 最大用户数TOP5,15分钟/1分钟(中台控制),最终值TOP5降序排列,文本白色,指标值彩色(叠加颜色指示) + { + public String get_left_3_data_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype) + { + String SQL=" "; + + if (1==1) //15分钟 + { + if (typeid == 1) //4G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by level ) title,name,value,color,level from (" + + " select row_number() over(order by 最大用户数 desc) title,t.小区名称 name,最大用户数 value," + + " getkpicolor('最大用户数', 最大用户数,'4G',t2.小区频段,t2.设备类型,t2.带宽) color, " + + " getkpilevel('最大用户数', 最大用户数,'4G',t2.小区频段,t2.设备类型,t2.带宽) level " + + " from pm_kpi4g_cell_replay t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 最大用户数 is not null " + + " and endtime="+sTime+" and venue_id="+sceneid +swhere+ + " order by level asc,t.最大用户数 desc limit 5) a "; + } + else //5G / + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by level ) title,name,value,color,level from (" + + " select row_number() over(order by 最大用户数 desc) title,t.小区名称 name,最大用户数 value," + + " getkpicolor('最大用户数', 最大用户数,'5G',t2.小区频段,t2.设备类型,t2.带宽) color ," + + " getkpilevel('最大用户数', 最大用户数,'5G',t2.小区频段,t2.设备类型,t2.带宽) level " + + " from pm_kpi5g_cell_replay t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 最大用户数 is not null " + + " and endtime="+sTime+" and venue_id="+sceneid +swhere+ + " order by level asc ,t.最大用户数 desc limit 5) a "; + } + } + return SQL; + } + } + + @SelectProvider(type = class_get_left_3_data.class,method = "get_left_3_data_SQL") + List get_left_3_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype); + //endregion + + //region --------------------------------------------------------------------------------------------右侧TOP5图表1 + class class_get_right_1_data // 上行Prb利用率TOP5,15分钟/1分钟(中台控制),最终值TOP5降序排列,文本白色,指标值彩色(叠加颜色指示) + { + public String get_right_1_data_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype) + { + String SQL=" "; + + if(1==1) //15分钟 + { + if (typeid == 1) //4G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by 上行Prb利用率 desc) title,t.小区名称 name,上行Prb利用率 value," + + " getkpicolor('上行Prb利用率', 上行Prb利用率,'4G','','',20) color from pm_kpi4g_cell_replay t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 上行Prb利用率 is not null " + + " and endtime="+sTime+" and venue_id="+sceneid +swhere+ + " order by t.上行Prb利用率 desc limit 5 "; + } + else //5G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by 上行Prb利用率 desc) title,t.小区名称 name,上行Prb利用率 value ," + + " getkpicolor('上行Prb利用率', 上行Prb利用率,'5G','','',20) color from pm_kpi5g_cell_replay t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 上行Prb利用率 is not null " + + " and endtime="+sTime+" and venue_id="+sceneid +swhere+ + " order by t.上行Prb利用率 desc limit 5 "; + } + } + return SQL; + } + } + + @SelectProvider(type = class_get_right_1_data.class,method = "get_right_1_data_SQL") + List get_right_1_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype); + //endregion + + //region --------------------------------------------------------------------------------------------右侧TOP5图表2 + class class_get_right_2_data // 下行Prb利用率TOP5,15分钟/1分钟(中台控制),最终值TOP5降序排列,文本白色,指标值彩色(叠加颜色指示) + { + public String get_right_2_data_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype) + { + String SQL=" "; + + if (1==1) //15分钟 + { + if (typeid == 1) //4G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by 下行Prb利用率 desc) title,t.小区名称 name,下行Prb利用率 value," + + " getkpicolor('下行Prb利用率', 下行Prb利用率,'4G','','',20) color from pm_kpi4g_cell_replay t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 下行Prb利用率 is not null " + + " and endtime="+sTime+" and venue_id="+sceneid +swhere+ + " order by t.下行Prb利用率 desc limit 5 "; + } + else //5G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by 下行Prb利用率 desc) title,t.小区名称 name,下行Prb利用率 value," + + " getkpicolor('下行Prb利用率', 下行Prb利用率,'5G','','',20) color from pm_kpi5g_cell_replay t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 下行Prb利用率 is not null " + + " and endtime="+sTime+" and venue_id="+sceneid +swhere+ + " order by t.下行Prb利用率 desc limit 5 "; + } + } + return SQL; + } + } + + @SelectProvider(type = class_get_right_2_data.class,method = "get_right_2_data_SQL") + List get_right_2_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype); + //endregion + + //region --------------------------------------------------------------------------------------------右侧TOP5图表3 + class class_get_right_3_data // 最大干扰值TOP5,15分钟/1分钟(中台控制),最终值TOP5降序排列,文本白色,指标值彩色(叠加颜色指示) + { + public String get_right_3_data_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype) + { + String SQL=" "; + + if (1==1) //15分钟 + { + if (typeid == 1) //4G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by 上行平均干扰 desc) title,t,小区名称 name,上行平均干扰 value," + + " getkpicolor('平均干扰值', 上行平均干扰,'4G','','',20) color from pm_kpi4g_cell_replay t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 上行平均干扰 is not null " + + " and endtime="+sTime+" and venue_id="+sceneid +swhere+ + " order by t.上行平均干扰 desc limit 5 "; + } + else //5G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + String swhere=" "; + if (areaid>0) swhere=" and t2.场内场外='"+areaid+"' "; //1:场内,2:场外,0:默认全部 + SQL = " select row_number() over(order by 上行干扰值 desc) title,t.小区名称 name,上行干扰值 value," + + " getkpicolor('平均干扰值', 上行干扰值,'5G','','',20) color from pm_kpi5g_cell_replay t " + + " left join dp_scene_cell t2 on t.小区名称=t2.小区名称 "+ + " where 上行干扰值 is not null " + + " and endtime="+sTime+" and venue_id="+sceneid +swhere+ + " order by t.上行干扰值 desc limit 5 "; + } + } + return SQL; + } + } + + @SelectProvider(type = class_get_right_3_data.class,method = "get_right_3_data_SQL") + List get_right_3_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("mintype") int mintype, + @Param("areaid") int areaid,@Param("jobtype") String jobtype); + //endregion + + //region -------------------------------------------------------------------------------------------地图, 用新接口替换 + class class_get_maps_data + { + public String get_maps_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid) + { + String SQL=" select venue_name name," + + " cast(wgs84togcj02(longitude::numeric,latitude::numeric,'lng') as VARCHAR)||','||" + + " cast(wgs84togcj02(longitude::numeric,latitude::numeric,'lat') as VARCHAR) center" + + " from yw_scene where id= "+sceneid; + return SQL; + } + + public String get_bts_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid, + @Param("kpiname") String kpiname,@Param("mintype") int mintype,@Param("jobtype") String jobtype) + { + StringBuilder SQL = new StringBuilder(); + + if (1==1) //15分钟 + { + if (typeid == 1) //4G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + SQL.append("select ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.最大用户数,b.上行prb利用率,b.上行prb利用率,b.上行平均干扰,'4G',小区频段,设备类型,带宽) algoValue," + + " b.最大用户数 avgUsrValue," + + " b.上行prb利用率 uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.下行prb利用率 downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行平均干扰,'4G',小区频段,设备类型,带宽)) ,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.最大用户数,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.上行prb利用率,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.下行prb利用率,'4G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a" + + " left join pm_kpi4g_cell_replay b on a.小区名称=b.小区名称 and venue_id = #{sceneid} and b.endtime=" + sTime + + " where 网络='LTE' and 场馆id=" + sceneid + " order by level desc"); + } + else if (typeid == 2) //5G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + SQL.append("select a.ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行干扰值,'5G',小区频段,设备类型,带宽) algoValue," + + " b.最大用户数 avgUsrValue," + + " b.上行prb利用率 uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.下行prb利用率 downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行干扰值,'5G',小区频段,设备类型,带宽)),'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.最大用户数,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.上行prb利用率,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.下行prb利用率,'5G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a " + + " left join pm_kpi5g_cell_replay b on a.小区名称=b.小区名称 and venue_id = #{sceneid} and b.endtime=" + sTime + + " where 网络='NR' and 场馆id=" + sceneid + " order by level desc"); + } + } + return SQL.toString(); + } + } + + @SelectProvider(type = class_get_maps_data.class,method = "get_maps_SQL") + class_dp_maps get_maps_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid); + + @SelectProvider(type = class_get_maps_data.class,method = "get_bts_SQL") + List get_bts_data(@Param("sceneid") int sceneid, @Param("typeid") int typeid, @Param("kpiname") String kpiname, + @Param("mintype") int mintype,@Param("jobtype") String jobtype); + //endregion + + //region --------------------------------------------------------------------------------------------顶部统计值,用新接口替换 + class class_get_top_data + { + public String get_top_data_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("kpiname") String kpiname, + @Param("mintype") int mintype,@Param("jobtype") String jobtype) + { + StringBuilder SQL = new StringBuilder(); + + if(1==1) //15分钟 + { + if (typeid == 1) //4G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + SQL.append("select ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行平均干扰,'4G',小区频段,设备类型,带宽) algoValue," + + " b.最大用户数 avgUsrValue," + + " b.上行prb利用率 uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.下行prb利用率 downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行平均干扰,'4G',小区频段,设备类型,带宽)) ,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.最大用户数,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.上行prb利用率,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.下行prb利用率,'4G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a" + + " left join pm_kpi4g_cell_replay b on a.小区名称=b.小区名称 and venue_id = #{sceneid} and b.endtime=" + sTime + + " where 网络='LTE' and 场馆id=" + sceneid + " order by level desc"); + } + else if (typeid == 2) //5G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + SQL.append("select a.ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行干扰值,'5G',小区频段,设备类型,带宽) algoValue," + + " b.最大用户数 avgUsrValue," + + " b.上行prb利用率 uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.下行prb利用率 downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行干扰值,'5G',小区频段,设备类型,带宽)),'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.最大用户数,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.上行prb利用率,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.下行prb利用率,'5G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a " + + " left join pm_kpi5g_cell_replay b on a.小区名称=b.小区名称 and venue_id = #{sceneid} and b.endtime=" + sTime + + " where 网络='NR' and 场馆id=" + sceneid + " order by level desc"); + } + } + return SQL.toString(); + } + } + + @SelectProvider(type = class_get_top_data.class,method = "get_top_data_SQL") + List get_top_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid,@Param("kpiname") String kpiname, + @Param("mintype") int mintype,@Param("jobtype") String jobtype); + //endregion + + //region -------------------------------------------------------------------------------------------地图和统计值统一接口 + class class_get_maps_top_data + { + public String get_maps_top_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid) + { + String SQL=" select venue_name name," + + " cast(wgs84togcj02(longitude::numeric,latitude::numeric,'lng') as VARCHAR)||','||" + + " cast(wgs84togcj02(longitude::numeric,latitude::numeric,'lat') as VARCHAR) center" + + " from yw_scene where id= "+sceneid; + return SQL; + } + + public String get_bts_1to2_SQL(@Param("sceneid") int sceneid,@Param("typeid") int typeid, + @Param("kpiname") String kpiname,@Param("mintype") int mintype,@Param("jobtype") String jobtype) + { + StringBuilder SQL = new StringBuilder(); + + if (1==1) //15分钟 + { + if (typeid == 1) //4G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + SQL.append("select ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.最大用户数,b.上行prb利用率,b.上行prb利用率,b.上行平均干扰,'4G',小区频段,设备类型,带宽) algoValue," + + " b.最大用户数 avgUsrValue," + + " b.上行prb利用率 uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.下行prb利用率 downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行平均干扰,'4G',小区频段,设备类型,带宽)) ,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.最大用户数,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.上行prb利用率,'4G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.下行prb利用率,'4G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a" + + " left join pm_kpi4g_cell_replay b on a.小区名称=b.小区名称 and venue_id = #{sceneid} and b.endtime=" + sTime + + " where 网络='LTE' and 场馆id=" + sceneid + " order by level desc"); + } + else if (typeid == 2) //5G + { + String sTime=" ( select maxtime from dp_scene_currtime ) "; + if (jobtype.equals("WORK")) sTime=" ( select maxtime from dp_scene_currtime ) "; + SQL.append("select a.ci,基站全称 name,a.小区名称 name2,小区频段 \"type\",经度 longitude,纬度 latitude," + + " 方位角 direction,wgs84togcj02(经度::numeric,纬度::numeric,'lng') gdLong," + + " wgs84togcj02(经度::numeric,纬度::numeric,'lat') gdLat," + + " getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行干扰值,'5G',小区频段,设备类型,带宽) algoValue," + + " b.最大用户数 avgUsrValue," + + " b.上行prb利用率 uplnkPrbvalue," + + " a.室内室外 as cellType," + + " b.下行prb利用率 downlnkPrbvalue "); + if ("综合算法".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('综合算法',(getkpivalue(b.最大用户数,b.上行prb利用率,b.下行prb利用率,b.上行干扰值,'5G',小区频段,设备类型,带宽)),'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("最大用户数".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('最大用户数',b.最大用户数,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("上行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('上行Prb利用率',b.上行prb利用率,'5G',小区频段,设备类型,带宽)::numeric level "); + } else if ("下行Prb利用率".equalsIgnoreCase(kpiname)) { + SQL.append(" ,getkpilevel('下行Prb利用率',b.下行prb利用率,'5G',小区频段,设备类型,带宽)::numeric level "); + } + SQL.append(" from dp_scene_cell a " + + " left join pm_kpi5g_cell_replay b on a.小区名称=b.小区名称 and venue_id = #{sceneid} and b.endtime=" + sTime + + " where 网络='NR' and 场馆id=" + sceneid + " order by level desc"); + } + } + return SQL.toString(); + } + } + + @SelectProvider(type = class_get_maps_top_data.class,method = "get_maps_top_SQL") + class_dp_maps_topinfo get_maps_top_data(@Param("sceneid") int sceneid,@Param("typeid") int typeid); + + @SelectProvider(type = class_get_maps_top_data.class,method = "get_bts_1to2_SQL") + List get_bts_1to2_data(@Param("sceneid") int sceneid, @Param("typeid") int typeid, @Param("kpiname") String kpiname, + @Param("mintype") int mintype,@Param("jobtype") String jobtype); + //endregion + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/NewPmKpiMonitorCellService.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/NewPmKpiMonitorCellService.java new file mode 100644 index 0000000..2f60050 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/NewPmKpiMonitorCellService.java @@ -0,0 +1,15 @@ +package com.ruoyi.sunlm.service; + +import com.github.pagehelper.PageInfo; +import com.ruoyi.sunlm.daping.dp3d.*; + +/** + * @author yqf + * @date 2023/4/13 + */ +public interface NewPmKpiMonitorCellService { + + PageInfo getMonitorCellList(NewPmKpiCellMonitorQO qo); + + PageInfo getDpMonitorCellList(NewDpKpiMonitorQO qo); +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/YwDpNewYayunService.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/YwDpNewYayunService.java new file mode 100644 index 0000000..ade80c0 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/YwDpNewYayunService.java @@ -0,0 +1,14 @@ +package com.ruoyi.sunlm.service; + +/** + * @author yqf + * @date 2023/7/11 + */ +public interface YwDpNewYayunService { + + public void eastcomUpdateComprehensiveManageSchedule(); + + public void eastcomUpdateTransAlarmsSchedule(); + + public void eastcomUpdateNetAlarmsSchedule(); +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/dpAllMyServices.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/dpAllMyServices.java new file mode 100644 index 0000000..63e4d72 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/dpAllMyServices.java @@ -0,0 +1,27 @@ +package com.ruoyi.sunlm.service; + +/** + * @date 2023/4/13 + */ +public interface dpAllMyServices { + void get_wireless_outservice(); + void get_gbflow_wireless(); + void get_manage_counts(); + void get_dict_counts(); + void get_trans_counts(); + void get_gbflow_huanlu(); + void get_agis_internet_counts(); + void get_maps_all_alarms(); + void get_maps_wireless_kpi_min(); + void get_maps_wireless_kpi_cell(); + //-------------------------------------- + void get_maps_all_alarms_popup(); + void get_spot_wirelessalarms_popup(); + void get_maps_wireless_alarms_popup(); + //-------------------------------------DICT + void get_dict_monitor_project_list(); + void get_dict_monitor_alarm_list(); + void get_dict_link_alarm_list(); + void get_dict_map_alarm_list(); + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/impl/NewPmKpiMonitorCellServiceImpl.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/impl/NewPmKpiMonitorCellServiceImpl.java new file mode 100644 index 0000000..93af460 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/impl/NewPmKpiMonitorCellServiceImpl.java @@ -0,0 +1,505 @@ +package com.ruoyi.sunlm.service.impl; + +import cn.hutool.core.bean.BeanUtil; + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.redis.RedisCache; + + +import com.ruoyi.sunlm.daping.class_dp_2_kpi_spot_celldetail; +import com.ruoyi.sunlm.daping.class_dp_2_seat_chinesename; +import com.ruoyi.sunlm.daping.class_dp_2_wireless_alarm; +import com.ruoyi.sunlm.daping.dp3d.*; +import com.ruoyi.sunlm.mapper.*; +import com.ruoyi.sunlm.service.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + + +/** + * @author yqf + * @date 2023/4/13 + */ +@Service +public class NewPmKpiMonitorCellServiceImpl implements NewPmKpiMonitorCellService { + + @Autowired + private NewPmKpi4gCellMapper pmKpi4gCellMapper; + + @Autowired + private NewPmKpi5gCellMapper pmKpi5gCellMapper; + + @Autowired + private NewPmKpi4gMinMapper pmKpi4gMinMapper; + + @Autowired + private NewPmKpi5gMinMapper pmKpi5gMinMapper; + + @Autowired + private NewDpSceneConfigMapper dpSceneConfigMapper; + + @Autowired + private dpNewYayun_Wuxian_Mapper MydpNewYayun_Wuxian_Mapper; + + + @Autowired + private RedisCache redisCache; + + private String cell_key = CacheConstants.YW_KPIMONITORCELL_INFO; + private String min_key = CacheConstants.YW_KPIMONITORMIN_INFO; + + private List getMonitorVoList(NewPmKpiCellMonitorQO qo) { + List voList = new ArrayList<>(); + List kpiList = new ArrayList<>(); + if (qo.getDatatype().equals(NewKpiConstants.YW_DATATYPE_15)) { //15分钟 + if (qo.getNettype().equals(NewKpiConstants.YW_NETTYPE_4G)) { //4G + qo.setPageSize(0); + kpiList = pmKpi4gCellMapper.getKpiList(qo); + } else { //5G + qo.setPageSize(0); + kpiList = pmKpi5gCellMapper.getKpiList(qo); + } + } else { //1分钟 + if (qo.getNettype().equals(NewKpiConstants.YW_NETTYPE_4G)) { //4G + qo.setPageSize(0); + kpiList = pmKpi4gMinMapper.getKpiList(qo); + } else { //5G + qo.setPageSize(0); + kpiList = pmKpi5gMinMapper.getKpiList(qo); + } + } + kpiList = kpiList.stream().filter(e -> null != e.get坐席编号()).collect(Collectors.toList()); + //-------------------------------过滤掉空值和值为0的记录,综合得分是可能为0的,不能过滤掉 + //-------------------------------这个过滤掉可能导致某个坐席下的列表为空, 如果需要,注释这段代码 + /* + try { + if (qo.getKpiname().equals(NewKpiConstants.YW_FIELD_RPB_UP)) { + kpiList = kpiList.stream().filter(e -> null != e.get上行prb利用率() && !e.get上行prb利用率().equals(new BigDecimal("0.00"))).collect(Collectors.toList()); + } else if (qo.getKpiname().equals(NewKpiConstants.YW_FIELD_RPB_DOWN)) { + kpiList = kpiList.stream().filter(e -> null != e.get下行prb利用率() && !e.get下行prb利用率().equals(new BigDecimal("0.00"))).collect(Collectors.toList()); + } else if (qo.getKpiname().equals(NewKpiConstants.YW_FIELD_AVG_DIS)) { + kpiList = kpiList.stream().filter(e -> null != e.get上行平均干扰() && !e.get上行平均干扰().equals(new BigDecimal("0.00"))).collect(Collectors.toList()); + } else if (qo.getKpiname().equals(NewKpiConstants.YW_FIELD_MAX_USER)) { + kpiList = kpiList.stream().filter(e -> null != e.get最大用户数() && !e.get最大用户数().equals(BigDecimal.ZERO)).collect(Collectors.toList()); + } + } + catch(Exception e) + { + } */ + //-------------------------------- + for (NewPmKpiMonitorEntity monitorEntity : kpiList) { //循环算分数和颜色 + NewPmKpi15CellMonitorVO vo = new NewPmKpi15CellMonitorVO(); + BeanUtil.copyProperties(monitorEntity, vo); + + //NewDpSceneConfigQO configQO = new NewDpSceneConfigQO(); + //configQO.setNettype(qo.getNettype()); + + //根据各指标值查出对应的颜色 + //上行prb利用率 + NewPmKpiVO prbUp = new NewPmKpiVO(NewKpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != monitorEntity.get上行prb利用率()) { + prbUp.setValue(monitorEntity.get上行prb利用率()); + prbUp.setColor(monitorEntity.getPrbupColor()); + prbUp.setScore(monitorEntity.getPrbupScore()); + } + vo.set上行prb利用率(prbUp); + + //下行prb利用率 + NewPmKpiVO prbDown = new NewPmKpiVO(NewKpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != monitorEntity.get下行prb利用率()) { + prbDown.setValue(monitorEntity.get下行prb利用率()); + prbDown.setColor(monitorEntity.getPrbdownColor()); + prbDown.setScore(monitorEntity.getPrbdownScore()); + } + vo.set下行prb利用率(prbDown); + + //上行平均干扰 + NewPmKpiVO avgDisturb = new NewPmKpiVO(NewKpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != monitorEntity.get上行平均干扰()) { + avgDisturb.setValue(monitorEntity.get上行平均干扰()); + avgDisturb.setColor(monitorEntity.getAvgdisColor()); + avgDisturb.setScore(monitorEntity.getAvgdisScore()); + } + vo.set上行平均干扰(avgDisturb); + + //最大用户数 + NewPmKpiVO maxUser = new NewPmKpiVO(NewKpiConstants.YW_KPI_COLOR_DEFAULT); + if (null != monitorEntity.get最大用户数()) { + maxUser.setValue(monitorEntity.get最大用户数()); + maxUser.setColor(monitorEntity.getMaxuserColor()); + maxUser.setScore(monitorEntity.getMaxuserScore()); + } + vo.set最大用户数(maxUser); + + + ////综合得分 + NewPmKpiVO allkpi = new NewPmKpiVO(NewKpiConstants.YW_KPI_COLOR_DEFAULT); + + //--###########################################################################--------added by sunlm 20230724 + //-先预先算好每个场馆的每个小区的分值和颜色。包括四个指标和一个综合得分指标 + // 改成将 上行Prb利用率得分, 下行Prb利用率得分 ,最大用户数得分 的综合 作为综合得分 ,2023-06-18 sunlm + //取指标中的最大值作为综合得分,这个废除了 + //allkpi.setValue(BigDecimal.valueOf(getMaxScore(prbUp.getScore(), prbDown.getScore(), avgDisturb.getScore(), maxUser.getScore()))); + + //---##########-----allkpi.setValue(BigDecimal.valueOf(prbUp.getScore() + prbDown.getScore() + maxUser.getScore())); + /* + Map colorAndScore = dpSceneConfigMapper.getkpiColorAndScore(NewKpiConstants.YW_FIELD_ALL, + allkpi.getValue().doubleValue(), qo.getNettype(), null, null, null); + allkpi.setColor(colorAndScore.get("color").toString()); + allkpi.setScore(Float.parseFloat(colorAndScore.get("score").toString())); + */ + + allkpi.setValue(BigDecimal.valueOf(monitorEntity.get综合得分值())); //正式启用20230728 + allkpi.setColor(monitorEntity.get综合得分颜色()); + allkpi.setScore(Float.parseFloat(String.valueOf(monitorEntity.get综合得分score()))); //get综合得分score(), 后续增加这个。 + //--###########################################################################------------------------------ + + //configQO.setName(NewKpiConstants.YW_FIELD_ALL); + //configQO.setValue(allkpi.getValue()); + + vo.set综合得分(allkpi); + + vo.setNettype(qo.getNettype()); + voList.add(vo); + } + + //--------------------------------------根据指标进行排序,大的排在最前面, 嵌套类中的属性进行排序,sunlm 2023-08-27 + try { + if (qo.getKpiname().equals("综合算法")) + voList = voList.stream().sorted(Comparator.comparing((NewPmKpi15CellMonitorVO x) -> x.get综合得分().getValue()).reversed()).collect(Collectors.toList()); + else if (qo.getKpiname().equals("上行Prb利用率")) + voList = voList.stream().sorted(Comparator.comparing((NewPmKpi15CellMonitorVO x) -> x.get上行prb利用率().getValue()).reversed()).collect(Collectors.toList()); + else if (qo.getKpiname().equals("下行Prb利用率")) + voList = voList.stream().sorted(Comparator.comparing((NewPmKpi15CellMonitorVO x) -> x.get下行prb利用率().getValue()).reversed()).collect(Collectors.toList()); + else if (qo.getKpiname().equals("最大用户数")) + voList = voList.stream().sorted(Comparator.comparing((NewPmKpi15CellMonitorVO x) -> x.get最大用户数().getValue()).reversed()).collect(Collectors.toList()); + else if (qo.getKpiname().equals("平均干扰值")) + voList = voList.stream().sorted(Comparator.comparing((NewPmKpi15CellMonitorVO x) -> x.get上行平均干扰().getValue()).reversed()).collect(Collectors.toList()); + } + catch(Exception e) + { + } + //-------------------------------------- + + return voList; + } + + private float getMaxScore(float prbUp, float prbDown, float avgDisturb, float maxUser) { // 取指标的最大值,不用了 + float score = 0; + if (prbUp > score) { + score = prbUp; + } + if (prbDown > score) { + score = prbDown; + } + if (avgDisturb > score) { + score = avgDisturb; + } + if (maxUser > score) { + score = maxUser; + } + return score; + } + + public static PageInfo getPageInfo(int currentPage, int pageSize, List list) { + int total = list.size(); + if (total > pageSize) { + int toIndex = pageSize * currentPage; + if (toIndex > total) { + toIndex = total; + } + int totalPage = total % pageSize == 0 ? (total / pageSize) : (total / pageSize) + 1; + if (totalPage < currentPage) { + list = new ArrayList<>(); + } else { + list = list.subList(pageSize * (currentPage - 1), toIndex); + } + } + Page page = new Page<>(currentPage, pageSize); + page.addAll(list); + page.setPages((total + pageSize - 1) / pageSize); + page.setTotal(total); + return new PageInfo<>(page); + } + + @Override + public PageInfo getMonitorCellList(NewPmKpiCellMonitorQO qo) { + PageInfo pageInfo = new PageInfo(); + Integer pageNum = qo.getPageNum(); + Integer pageSize = qo.getPageSize(); + List allList = new ArrayList<>(); + //----------------------------------------------------------------------------获取坐席的中文名,20230904 sunlm + String keyname="dp_2_seat_chinesename_lists"; + List seatinfolists=new ArrayList(); + if (redisCache.hasKey(keyname)) { + seatinfolists = redisCache.getCacheObject(keyname); + } + else { + seatinfolists = MydpNewYayun_Wuxian_Mapper.get_seat_chinesename(); + redisCache.setCacheObject(keyname, seatinfolists,5, TimeUnit.MINUTES); //缓存保留分钟 + } + //------------------------------------------------------------------------------------------------------- + if (qo.getIscache()) { + if (qo.getDatatype().equals(NewKpiConstants.YW_DATATYPE_15)) { + allList = redisCache.getCacheObject(cell_key); + } else { + allList = redisCache.getCacheObject(min_key); + } + } else { + List voList = getMonitorVoList(qo); + + Map> map = voList.stream().collect(Collectors.groupingBy(e -> e.get坐席编号() + "|" + e.getVenueid())); + for (String key : map.keySet()) { //每个坐席 + List list = map.get(key); //坐席的小区列表 + BigDecimal num = new BigDecimal("0.00"); + float score = 0; + + //----##########################################-------added by sunlm 20230725 + String color=""; + //----##########################################------------------------------ + + NewMonitorCellVo monitorCellVo = new NewMonitorCellVo(); + monitorCellVo.setSeatid(key.substring(0, key.indexOf("|"))); + /* + monitorCellVo.setCelllist(map.get(key)); + monitorCellVo.setVenuename(map.get(key).get(0).getVenuename()); + monitorCellVo.setVenueid(map.get(key).get(0).getVenueid()); + monitorCellVo.setPointid(map.get(key).get(0).getPointid()); + monitorCellVo.setStationno(map.get(key).get(0).getStationno()); + monitorCellVo.setPointname(map.get(key).get(0).getPointname()); + monitorCellVo.setLongitude(map.get(key).get(0).getLongitude()); + monitorCellVo.setLatitude(map.get(key).get(0).getLatitude()); */ + + monitorCellVo.setCelllist(list); + monitorCellVo.setVenuename(list.get(0).getVenuename()); + monitorCellVo.setVenueid(list.get(0).getVenueid()); + monitorCellVo.setPointid(list.get(0).getPointid()); + monitorCellVo.setStationno(list.get(0).getStationno()); + monitorCellVo.setPointname(list.get(0).getPointname()); + monitorCellVo.setLongitude(list.get(0).getLongitude()); + monitorCellVo.setLatitude(list.get(0).getLatitude()); + + //根据坐席分值判断颜色 + //NewDpSceneConfigQO sceneConfigQO = new NewDpSceneConfigQO(); + //sceneConfigQO.setNettype(qo.getNettype()); + + String seatcolor = ""; + int seatscore = 0; + String frequency = null; + String devicetype = null; + Long bandwidth = null; + + if (qo.getKpiname().equals(NewKpiConstants.YW_FIELD_ALL)) { + for (NewPmKpi15CellMonitorVO vo : map.get(key)) { //坐席的每个小区遍历 + //------------##############################################------------------by sunlm + //if (null != vo.get综合得分().getValue()) { + // if (vo.get综合得分().getValue().compareTo(num) > 0) { //整个坐席的分数。坐席指标值按所有小区最差的 + if (null != vo.get综合得分().getValue()) { + if (score <= vo.get综合得分().getScore()) { //整个坐席的分数。坐席指标值按所有小区最差的 + //------------####################################################################### + num = vo.get综合得分().getValue(); + //----------########################################-----------------added by sunlm 20230725 + score = vo.get综合得分().getScore(); + color=vo.get综合得分().getColor(); + //---------#########################################---------------------------------------- + } +// num = num.add(vo.get综合得分().getValue()); + } + } + + } else if (qo.getKpiname().equals(NewKpiConstants.YW_FIELD_RPB_UP)) { + //坐席指标值按所有小区最差的,上行prb利用率越大越差 +// num = list.stream().map(s -> s.get上行prb利用率().getValue().intValue()).max(Integer::compareTo).get(); + for (NewPmKpi15CellMonitorVO vo : map.get(key)) { + if (null != vo.get上行prb利用率().getValue()) { + if (score <= vo.get上行prb利用率().getScore()) { + score = vo.get上行prb利用率().getScore(); + num = vo.get上行prb利用率().getValue(); + //----------########################################-----------------added by sunlm 20230725 + color=vo.get上行prb利用率().getColor(); + //---------#########################################---------------------------------------- + } + } + } + + + } else if (qo.getKpiname().equals(NewKpiConstants.YW_FIELD_RPB_DOWN)) { +// num = list.stream().map(s -> s.get下行prb利用率().getValue().intValue()).max(Integer::compareTo).get(); + for (NewPmKpi15CellMonitorVO vo : map.get(key)) { + if (null != vo.get下行prb利用率().getValue()) { + if (score <= vo.get下行prb利用率().getScore()) { + score = vo.get下行prb利用率().getScore(); + num = vo.get下行prb利用率().getValue(); + //----------########################################-----------------added by sunlm 20230725 + color=vo.get下行prb利用率().getColor(); + //---------#########################################---------------------------------------- + } + } + } + + } else if (qo.getKpiname().equals(NewKpiConstants.YW_FIELD_MAX_USER)) { + //分设备类型 +// num = list.stream().map(s -> s.get最大用户数().getValue().intValue()).max(Integer::compareTo).get(); + for (NewPmKpi15CellMonitorVO vo : map.get(key)) { + if (null != vo.get最大用户数().getValue()) { + if (score <= vo.get最大用户数().getScore()) { + score = vo.get最大用户数().getScore(); + num = vo.get最大用户数().getValue(); + frequency = vo.get小区频段(); + devicetype = vo.get设备类型(); + bandwidth = vo.get带宽(); + //----------########################################-----------------added by sunlm 20230725 + color=vo.get最大用户数().getColor(); + //---------#########################################---------------------------------------- + } + } + } + + } else if (qo.getKpiname().equals(NewKpiConstants.YW_FIELD_AVG_DIS)) { +// num = list.stream().map(s -> s.get上行平均干扰().getValue().intValue()).max(Integer::compareTo).get(); + for (NewPmKpi15CellMonitorVO vo : map.get(key)) { + if (null != vo.get上行平均干扰().getValue()) { + if (score <= vo.get上行平均干扰().getScore()) { + score = vo.get上行平均干扰().getScore(); + num = vo.get上行平均干扰().getValue(); + //----------########################################-----------------added by sunlm 20230725 + color=vo.get上行平均干扰().getColor(); + //---------#########################################---------------------------------------- + } + } + } + } + + //sceneConfigQO.setName(qo.getKpiname()); + //sceneConfigQO.setValue(num); + + //----------########################################-----------------added by sunlm 20230725 + /* + Map colorAndScore = dpSceneConfigMapper.getkpiColorAndScore(qo.getKpiname(), num.doubleValue(), qo.getNettype(), + frequency, devicetype, bandwidth); + + monitorCellVo.setColor(colorAndScore.get("color").toString()); + monitorCellVo.setScore(Float.valueOf(colorAndScore.get("score").toString())); + */ + monitorCellVo.setColor(color); + monitorCellVo.setScore(score); + //---------#########################################---------------------------------------- + + monitorCellVo.setKpiname(qo.getKpiname()); + monitorCellVo.setDatatype(qo.getDatatype()); + monitorCellVo.setNettype(qo.getNettype()); + + //-----------------------------------------------------获取坐席的中文名,sunlm 2023-09-04 + String seatname = ""; + try { + seatname = seatinfolists.stream().filter(e -> e.getSceneid() == monitorCellVo.getVenueid()). + filter(e -> e.getSeatid().equals(monitorCellVo.getSeatid())).collect(Collectors.toList()).get(0).chinesename; + } + catch(Exception e) + { + } + monitorCellVo.setSeatname(seatname); + + //---------------------------------------------------------增加一键优化功能 2023-09-11 + BigDecimal zhdfvalue = new BigDecimal("0.00"); + BigDecimal zhdf4 = new BigDecimal("4.00"); + for (NewPmKpi15CellMonitorVO vo : map.get(key)) { //坐席的每个小区遍历, 综合得分 >= 4的 触发一键优化 + if (null != vo.get综合得分().getValue()) { + if (zhdfvalue.compareTo(vo.get综合得分().getValue())<=0) { + zhdfvalue = vo.get综合得分().getValue(); + } + } + } + if (zhdfvalue.compareTo(zhdf4)>=0) ///// >=4 + monitorCellVo.setOnekey(1); + else + monitorCellVo.setOnekey(0); + //------------------------------------------------------------------ + + allList.add(monitorCellVo); + } + + //把多次查询组装查询 + + /* /////无用代码 + if (null != qo.getSeatcolor() && !qo.getSeatcolor().equals("")) { + allList = allList.stream().filter(e -> e.getColor().equals(qo.getSeatcolor())).collect(Collectors.toList()); + } + */ + + if (null != qo.getSortcol() && null != qo.getSort()) { //不会进入 + if (qo.getSort().equals(NewKpiConstants.YW_SORT_DESC)) { + allList = allList.stream().sorted(Comparator.comparing(NewMonitorCellVo::getScore).reversed()).collect(Collectors.toList()); + } else { + allList = allList.stream().sorted(Comparator.comparing(NewMonitorCellVo::getScore)).collect(Collectors.toList()); + } + + } + + int orderid = 1; + for (NewMonitorCellVo monitorCellVo : allList) { + monitorCellVo.setOrderid(orderid); + orderid++; + } + + + if (qo.getDatatype().equals(NewKpiConstants.YW_DATATYPE_15)) { + redisCache.deleteObject(cell_key); + redisCache.setCacheObject(cell_key, allList); + } else { + redisCache.deleteObject(min_key); + redisCache.setCacheObject(min_key, allList); + } + + } + pageInfo = getPageInfo(pageNum, pageSize, allList); + return pageInfo; + } + + @Override + public PageInfo getDpMonitorCellList(NewDpKpiMonitorQO qo) { //qo.getSeatno() 这个参数没用 + Map map = new HashMap<>(); + if (qo.getDatatype().equals(NewKpiConstants.YW_DATATYPE_15)) { + if (qo.getNettype().equals(NewKpiConstants.YW_NETTYPE_4G)) { + map = pmKpi4gCellMapper.getLastTime(qo.getSceneid(), qo.getSeatno(),qo.getInorout()); + } else { + map = pmKpi5gCellMapper.getLastTime(qo.getSceneid(), qo.getSeatno(),qo.getInorout()); + } + } else { + if (qo.getNettype().equals(NewKpiConstants.YW_NETTYPE_4G)) { + map = pmKpi4gMinMapper.getLastTime(qo.getSceneid(), qo.getSeatno(),qo.getInorout()); + } else { + map = pmKpi5gMinMapper.getLastTime(qo.getSceneid(), qo.getSeatno(),qo.getInorout()); + } + } + + PageInfo pageInfo = new PageInfo(); + if (null != map && map.size() > 0) { + LocalDateTime starttime = ((Timestamp) map.get("starttime")).toLocalDateTime(); + LocalDateTime endtime = ((Timestamp) map.get("endtime")).toLocalDateTime(); + qo.setStarttime(starttime); + qo.setEndtime(endtime); + NewPmKpiCellMonitorQO monitorQO = new NewPmKpiCellMonitorQO(); + monitorQO.setIscache(false); + BeanUtil.copyProperties(qo, monitorQO); + monitorQO.setPageNum(1); + monitorQO.setPageSize(20000); + //------------------------------------------------- + pageInfo = getMonitorCellList(monitorQO); + } + + return pageInfo; + } + + + +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/impl/YwDpNewYayunServiceImpl.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/impl/YwDpNewYayunServiceImpl.java new file mode 100644 index 0000000..1e5302c --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/impl/YwDpNewYayunServiceImpl.java @@ -0,0 +1,291 @@ +package com.ruoyi.sunlm.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.eastcom_yw.domain.dto.YwInspectStatDTO; +import com.ruoyi.eastcom_yw.domain.dto.YwSignLogDTO; +import com.ruoyi.eastcom_yw.domain.param.YwRoutInspectStatParam; +import com.ruoyi.eastcom_yw.domain.vo.YwDrsTempTaskVO; +import com.ruoyi.eastcom_yw.domain.vo.YwSignLogStaticVo; +import com.ruoyi.eastcom_yw.service.YwDrsTempTaskService; +import com.ruoyi.eastcom_yw.service.YwRoutInspectPlanService; +import com.ruoyi.eastcom_yw.service.YwScenePictureService; +import com.ruoyi.eastcom_yw.service.YwSignLogViewService; +import com.ruoyi.sunlm.daping.*; +import com.ruoyi.sunlm.mapper.dpNewYayun_ChuanDong_Mapper; +import com.ruoyi.sunlm.mapper.dpNewYayun_ZhuanWang_Mapper; +import com.ruoyi.sunlm.mapper.dpNewYayun_ZongHe_Mapper; +import com.ruoyi.sunlm.mapper.dpNewYayun_Gailan_Mapper; +import com.ruoyi.sunlm.service.YwDpNewYayunService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * @author yqf + * @date 2023/7/11 + */ +@Service +@Slf4j +public class YwDpNewYayunServiceImpl implements YwDpNewYayunService { + + @Resource + private RedisCache redisCache; + + @Resource + private dpNewYayun_ChuanDong_Mapper dpNewYayunChuanDongMapper; + + @Resource + private dpNewYayun_ZhuanWang_Mapper dpNewYayunZhuanWangMapper; + + @Resource + private dpNewYayun_ZongHe_Mapper dpNewYayunZongHeMapper; + + @Resource + private dpNewYayun_Gailan_Mapper MydpNewYayun_Gailan_Mapper; + + @Resource + YwScenePictureService ywScenePictureService; + + @Resource + YwDrsTempTaskService ywDrsTempTaskService; + + + @Resource + private YwSignLogViewService ywSignLogViewService; + + @Resource + YwRoutInspectPlanService ywRoutInspectPlanService; + + //---------------------------------------获取缓存配置 + public int getcachesecond() + { + String keyname="dp_1_cache_config"; + if (redisCache.hasKey(keyname)) { + int iret=1; + try + { + iret= redisCache.getCacheObject(keyname); + } + catch(Exception ee) { + } + return iret; + } + else { + class_dp_1_cache_config cache=MydpNewYayun_Gailan_Mapper.get_cache_config(); + int iret=1; + try + { + iret=cache.cachesecond; + } + catch(Exception ee) + { + } + redisCache.setCacheObject(keyname, iret,58, TimeUnit.SECONDS); //缓存 + return iret; + } + } + //---------------------------------------- + + + public void eastcomUpdateComprehensiveManageSchedule() { + Map allMap = new HashMap<>(); + //签到top5 +// YwSignLogDTO signLogDTO = new YwSignLogDTO(); +// String today = DateUtils.getDate(); +// signLogDTO.setStartDate(today); +// signLogDTO.setEndDate(today); +// signLogDTO.setTaskFlag(true); +// List signLogStatic = ywSignLogViewService.getSignLogStatic(signLogDTO); +// if (CollectionUtil.isNotEmpty(signLogStatic)) { +// if (signLogStatic.size() > 6) { +// signLogStatic = signLogStatic.subList(1, 6); +// } else { +// signLogStatic = signLogStatic.subList(1, signLogStatic.size()); +// } +// +// } + List sign_top5 = dpNewYayunZongHeMapper.get_sign_top5(); + allMap.put("signrateTop5", sign_top5); + //巡检top5 +// YwRoutInspectStatParam param = new YwRoutInspectStatParam(); +// param.setBeginDate(today); +// param.setEndDate(today + " 23:59:59"); +// param.setTaskFlag(true); +// Map statListData = ywRoutInspectPlanService.getStatListData(param); +// List statList = (List) statListData.get("list"); +// if (CollectionUtil.isNotEmpty(statList)) { +// if (statList.size() > 5) { +// statList = statList.subList(0, 5); +// } +// +// } + List inspect_top5 = dpNewYayunZongHeMapper.get_inspect_top5(); + allMap.put("inspectrateTop5", inspect_top5); + //场馆联系人清单 + List contacts = dpNewYayunZongHeMapper.get_scene_contacts_list(); + allMap.put("contacts", contacts); + //统计数据 + class_dp_5_scenesta scenesta = dpNewYayunZongHeMapper.get_scene_sta(); + allMap.put("scenesta", scenesta); + //int cachesecond=getcachesecond(); + redisCache.setCacheObject(CacheConstants.YW_COM_MANAGE_ALL, allMap,58, TimeUnit.SECONDS); + //场馆级别数据 + Map result = new HashMap<>(); + Long[] ids = new Long[]{2L, 25L, 42L}; + for (int i = 0; i < ids.length; i++) { + Map map = new HashMap<>(); + Long id = ids[i]; + LocalDate date = LocalDate.now(); + //场馆基本信息 + JSONObject baseinfo = ywScenePictureService.listMatchTop3(id); + map.put("baseinfo", baseinfo); + //任务管理统计 + JSONObject task = ywScenePictureService.listTaskManage2(id,true); + map.put("task", task); + //人员签到统计 + JSONObject sign = ywScenePictureService.listSign(id); + map.put("sign", sign); + //drs管理 + List drs = ywDrsTempTaskService.drsPreview(id, date); + map.put("drs", drs); + result.put("scene_" + id, map); + } + redisCache.setCacheObject(CacheConstants.YW_COM_MANAGE_SCENE, result,58, TimeUnit.SECONDS); + } + + public void eastcomUpdateTransAlarmsSchedule() { + //告警数据 + int cachesecond=getcachesecond(); + List alarmlist = dpNewYayunChuanDongMapper.get_trans_alarms_all_list(); + redisCache.setCacheObject(CacheConstants.YW_TRANS_ALARM, alarmlist,cachesecond, TimeUnit.SECONDS); + //机房环境数据 + List powerlists = dpNewYayunChuanDongMapper.get_machineroom_alarms_all_list(); + redisCache.setCacheObject(CacheConstants.YW_MACHINEROOM_ALARM, powerlists,cachesecond, TimeUnit.SECONDS); + //流量top5 + List gblist = dpNewYayunChuanDongMapper.get_huanlu_top5_all(); + redisCache.setCacheObject(CacheConstants.YW_GB_TOP5, gblist,58, TimeUnit.SECONDS); + //光功率数据 + List list = dpNewYayunChuanDongMapper.get_opticalpower_all_list(); + redisCache.setCacheObject(CacheConstants.YW_OPTICALPOWER, list,58, TimeUnit.SECONDS); + //地图 + List dpdata = dpNewYayunChuanDongMapper.get_maps_all_alarms(); + List alarmsList = dpNewYayunChuanDongMapper.get_maps_alarms_all_alarms(); + List poweralarmlist = dpNewYayunChuanDongMapper.get_machineroom_alarms_all_list(); + Map> map = new HashMap<>(); + Map> powermap = new HashMap<>(); + if(CollectionUtil.isNotEmpty(alarmsList)){ + map = alarmsList.stream().collect(Collectors.groupingBy(class_dp_map_alarms::getSceneid)); + } + if (CollectionUtil.isNotEmpty(poweralarmlist)) { + powermap = poweralarmlist.stream().collect(Collectors.groupingBy(class_dp_2_power_alarm::get场馆id)); + } + + for (class_dp_4_maps_alarms dpdatum : dpdata) { + List alarms = new ArrayList<>(); + if (dpdatum.getAlarmcount() > 0) { + List sceneList = map.get(Long.valueOf(dpdatum.getVenueid())); + alarms.addAll(sceneList); + } + + if (CollectionUtil.isNotEmpty(powermap)) { + List powerlist = powermap.get(dpdatum.getVenueid() + ""); + if (CollectionUtil.isNotEmpty(powerlist)) { + for (class_dp_2_power_alarm powerAlarm : powerlist) { + class_dp_map_alarms alarm = new class_dp_map_alarms(); + BeanUtil.copyProperties(powerAlarm, alarm); + alarm.setMajor("动环"); + alarm.setHandlepeople(powerAlarm.get故障处理人()); + alarm.setSceneid(Long.valueOf(powerAlarm.get场馆id())); + alarm.setNetname(powerAlarm.getSiteName()); + alarms.add(alarm); + + } + dpdatum.setAlarmcount(dpdatum.getAlarmcount() + powerlist.size()); + dpdatum.setPowercount(powerlist.size()); + } + + } + dpdatum.setLists(alarms); + } + redisCache.setCacheObject(CacheConstants.YW_TRANS_MAP, dpdata,cachesecond, TimeUnit.SECONDS); + } + + + public void eastcomUpdateNetAlarmsSchedule() { + int cachesecond=getcachesecond(); + List list = dpNewYayunZhuanWangMapper.get_net_alarms_all_list(); + redisCache.setCacheObject(CacheConstants.YW_NET_ALARM, list,cachesecond, TimeUnit.SECONDS); + //地图 + List dpdata = dpNewYayunZhuanWangMapper.get_maps_all_alarms(); + List alarmsList = dpNewYayunZhuanWangMapper.get_map_alarms_all_list(); + List linkAllList = dpNewYayunZhuanWangMapper.get_map_agis_link_all_list(); + List devAllList = dpNewYayunZhuanWangMapper.get_map_agis_dev_all_list(); + Map> map = new HashMap<>(); + Map> linkmap = new HashMap<>(); + Map> devmap = new HashMap<>(); + if(CollectionUtil.isNotEmpty(alarmsList)){ + map = alarmsList.stream().collect(Collectors.groupingBy(class_dp_map_alarms::getSceneid)); + } + if (CollectionUtil.isNotEmpty(linkAllList)) { + linkmap = linkAllList.stream().collect(Collectors.groupingBy(class_dp_map_agis_link_5mi::getVenueid)); + } + if (CollectionUtil.isNotEmpty(devAllList)) { + devmap = devAllList.stream().collect(Collectors.groupingBy(class_dp_map_agis_dev_15mi::getVenueid)); + } + for (class_dp_3_maps_alarms dpdatum : dpdata) { + if (dpdatum.getAlarmcount() > 0) { + List sceneList = map.get(Long.valueOf(dpdatum.getVenueid())); + dpdatum.setLists(sceneList); + } + if (CollectionUtil.isNotEmpty(linkmap)) { + dpdatum.setLinklists(linkmap.get(Long.valueOf(dpdatum.getVenueid()))); + } + if (CollectionUtil.isNotEmpty(devmap)) { + dpdatum.setDevlists(devmap.get(Long.valueOf(dpdatum.getVenueid()))); + } + } + redisCache.setCacheObject(CacheConstants.YW_NET_MAP, dpdata,cachesecond, TimeUnit.SECONDS); + + //功能区的告警和性能输出 + List codeList = dpNewYayunZhuanWangMapper.get_code_all_list(); + List alarmList = dpNewYayunZhuanWangMapper.get_code_alarms_all_list(); + List codedevAllList = dpNewYayunZhuanWangMapper.get_code_agis_dev_all_list(); + Map> codemap = new HashMap<>(); + Map> codedevmap = new HashMap<>(); + + if (CollectionUtil.isNotEmpty(alarmList)) { + codemap = alarmList.stream().collect(Collectors.groupingBy(class_dp_map_alarms::getCode)); + } + + if (CollectionUtil.isNotEmpty(codedevAllList)) { + codedevmap = codedevAllList.stream().collect(Collectors.groupingBy(class_dp_map_agis_dev_15mi::getCode)); + } + + for (class_dp_2_code_net_alarms codeNetAlarm : codeList) { + if (CollectionUtil.isNotEmpty(codemap)) { + codeNetAlarm.setLists(codemap.get(codeNetAlarm.getCode())); + if(CollectionUtil.isNotEmpty(codemap.get(codeNetAlarm.getCode()))){ + codeNetAlarm.setAlarmcount(codemap.get(codeNetAlarm.getCode()).size()); + } + } + if (CollectionUtil.isNotEmpty(codedevmap)) { + codeNetAlarm.setKpilist(codedevmap.get(codeNetAlarm.getCode())); + } + } + redisCache.setCacheObject(CacheConstants.YW_NET_CODE_AGIS, codeList,cachesecond, TimeUnit.SECONDS); + + } +} diff --git a/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/impl/dpAllMyServicesImpl.java b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/impl/dpAllMyServicesImpl.java new file mode 100644 index 0000000..50ebd43 --- /dev/null +++ b/ruoyi-sunlm/src/main/java/com/ruoyi/sunlm/service/impl/dpAllMyServicesImpl.java @@ -0,0 +1,218 @@ +package com.ruoyi.sunlm.service.impl; + + +import com.ruoyi.common.core.redis.RedisCache; + +import com.ruoyi.sunlm.daping.*; +import com.ruoyi.sunlm.mapper.*; +import com.ruoyi.sunlm.service.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * @date 2023/4/13 + */ +@Service +public class dpAllMyServicesImpl implements dpAllMyServices { + + @Autowired + dpNewYayun_Gailan_Mapper MydpNewYayun_Gailan_Mapper; + + @Autowired + dpNewYayun_Wuxian_Mapper MydpNewYayun_Wuxian_Mapper; + + @Autowired + dpNewYayun_Dict_Mapper MydpNewYayun_Dict_Mapper; + + @Autowired + private RedisCache redisCache; + + //---------------------------------------获取缓存配置 + public int getcachesecond() + { + String keyname="dp_1_cache_config"; + if (redisCache.hasKey(keyname)) { + int iret=1; + try + { + iret= redisCache.getCacheObject(keyname); + } + catch(Exception ee) { + } + return iret; + } + else { + class_dp_1_cache_config cache=MydpNewYayun_Gailan_Mapper.get_cache_config(); + int iret=1; + try + { + iret=cache.cachesecond; + } + catch(Exception ee) + { + } + redisCache.setCacheObject(keyname, iret,58, TimeUnit.SECONDS); //缓存 + return iret; + } + } + //---------------------------------------- + + @Override + public void get_wireless_outservice() { //设备告警 + String keyname="dp_1_wireless_outservice_list"; + int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Gailan_Mapper.get_wireless_outservice(); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,cachesecond, TimeUnit.SECONDS); //缓存 + } + + @Override + public void get_gbflow_wireless() { //4/5G流量 + String keyname="dp_1_gbflow_wireless_list_1"; + //int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Gailan_Mapper.get_gbflow_wireless(1); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,58,TimeUnit.SECONDS); //缓存 + //----------------------------------- + keyname="dp_1_gbflow_wireless_list_2"; + dpData=MydpNewYayun_Gailan_Mapper.get_gbflow_wireless(2); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,58,TimeUnit.SECONDS); //缓存 + } + + @Override + public void get_manage_counts() { //综合管理 + String keyname="dp_1_manage_counts_list"; + //int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Gailan_Mapper.get_manage_counts(); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,58,TimeUnit.SECONDS); //缓存 + } + + @Override + public void get_dict_counts() { //DICT + String keyname="dp_1_dict_counts_list"; + //int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Gailan_Mapper.get_dict_counts(); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,58, TimeUnit.SECONDS); //缓存 + } + + @Override + public void get_trans_counts() { //传输动力 + String keyname="dp_1_trans_counts_list"; + //int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Gailan_Mapper.get_trans_counts(); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,58, TimeUnit.SECONDS); //缓存 + } + + @Override + public void get_gbflow_huanlu() { //环路流量 + String keyname="dp_1_gbflow_huanlu_list"; + //int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Gailan_Mapper.get_gbflow_huanlu(); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,58, TimeUnit.SECONDS); //缓存 + } + + @Override + public void get_agis_internet_counts() { //专网 + String keyname="dp_1_agis_internet_counts_list"; + //int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Gailan_Mapper.get_agis_internet_counts(); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,58, TimeUnit.SECONDS); //缓存 + } + + @Override + public void get_maps_all_alarms() { //中间地图 + String keyname="dp_1_maps_all_alarms_list_1"; + int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Gailan_Mapper.get_maps_all_alarms(1); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,cachesecond, TimeUnit.SECONDS); //缓存 + //----------------------------------- + keyname="dp_1_maps_all_alarms_list_2"; + dpData=MydpNewYayun_Gailan_Mapper.get_maps_all_alarms(2); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,cachesecond, TimeUnit.SECONDS); //缓存 + } + //----------------------------------------------------------------------------------- + @Override + public void get_maps_wireless_kpi_min() { //中间地图无线KPI,1min + String keyname="dp_2_maps_wireless_kpicells_list_4G_1"; + int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Wuxian_Mapper.get_maps_wireless_kpi_cells("4G",1); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,cachesecond, TimeUnit.SECONDS); //缓存 + //----------------------------------- + keyname="dp_2_maps_wireless_kpicells_list_5G_1"; + dpData=MydpNewYayun_Wuxian_Mapper.get_maps_wireless_kpi_cells("5G",1); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,cachesecond, TimeUnit.SECONDS); //缓存 + } + + @Override + public void get_maps_wireless_kpi_cell() { //中间地图无线KPI,15min + String keyname="dp_2_maps_wireless_kpicells_list_4G_15"; + int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Wuxian_Mapper.get_maps_wireless_kpi_cells("4G",15); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,cachesecond, TimeUnit.SECONDS); //缓存 + //----------------------------------- + keyname="dp_2_maps_wireless_kpicells_list_5G_15"; + dpData=MydpNewYayun_Wuxian_Mapper.get_maps_wireless_kpi_cells("5G",15); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,cachesecond, TimeUnit.SECONDS); //缓存 + } + + @Override + public void get_maps_all_alarms_popup() { + String keyname="dp_1_maps_all_alarms_popup_list"; + int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Gailan_Mapper.get_maps_all_alarms_popup(); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,cachesecond, TimeUnit.SECONDS); //缓存 + } + + @Override + public void get_spot_wirelessalarms_popup() { + String keyname="dp_2_spot_wireless_alarms_popup_list"; + int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Wuxian_Mapper.get_spot_wirelessalarms_popup(); //景区的告警 + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,cachesecond, TimeUnit.SECONDS); //缓存 + } + + @Override + public void get_maps_wireless_alarms_popup() { + String keyname="dp_2_maps_wireless_alarms_popup_list"; + int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Wuxian_Mapper.get_maps_wireless_alarms_popup(); //场馆的告警 + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,cachesecond, TimeUnit.SECONDS); //缓存 + } + + //--------------------------------- + + @Override + public void get_dict_monitor_project_list() { + String keyname="dp_6_dict_monitor_project_list"; + //int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Dict_Mapper.get_dict_monitor_project_list(); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,58, TimeUnit.SECONDS); //缓存 + } + + @Override + public void get_dict_monitor_alarm_list() { + String keyname="dp_6_dict_monitor_alarm_list"; + //int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Dict_Mapper.get_dict_monitor_alarm_list(); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,58, TimeUnit.SECONDS); //缓存 + } + + @Override + public void get_dict_link_alarm_list() { + String keyname="dp_6_dict_link_alarm_list"; + //int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Dict_Mapper.get_dict_link_alarm_list(); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,58, TimeUnit.SECONDS); //缓存 + } + + @Override + public void get_dict_map_alarm_list() { + String keyname="dp_6_dict_map_alarm_list"; + //int cachesecond=getcachesecond(); + List dpData=MydpNewYayun_Dict_Mapper.get_map_alarm_list(); + if (dpData!=null) redisCache.setCacheObject(keyname, dpData,58, TimeUnit.SECONDS); //缓存 + } + + +} diff --git a/ruoyi-sunlm/src/main/resources/mapper/sunlm/NewDpSceneConfigMapper.xml b/ruoyi-sunlm/src/main/resources/mapper/sunlm/NewDpSceneConfigMapper.xml new file mode 100644 index 0000000..e9aa824 --- /dev/null +++ b/ruoyi-sunlm/src/main/resources/mapper/sunlm/NewDpSceneConfigMapper.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + diff --git a/ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi4gCellMapper.xml b/ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi4gCellMapper.xml new file mode 100644 index 0000000..85c9375 --- /dev/null +++ b/ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi4gCellMapper.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + diff --git a/ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi4gMinMapper.xml b/ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi4gMinMapper.xml new file mode 100644 index 0000000..2135f31 --- /dev/null +++ b/ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi4gMinMapper.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + diff --git a/ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi5gCellMapper.xml b/ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi5gCellMapper.xml new file mode 100644 index 0000000..9ed5992 --- /dev/null +++ b/ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi5gCellMapper.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + diff --git a/ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi5gMinMapper.xml b/ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi5gMinMapper.xml new file mode 100644 index 0000000..19fc695 --- /dev/null +++ b/ruoyi-sunlm/src/main/resources/mapper/sunlm/NewPmKpi5gMinMapper.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + diff --git a/ruoyi-system/pom.xml b/ruoyi-system/pom.xml new file mode 100644 index 0000000..f5a2114 --- /dev/null +++ b/ruoyi-system/pom.xml @@ -0,0 +1,28 @@ + + + + ruoyi + com.ruoyi + 3.8.4 + + 4.0.0 + + ruoyi-system + + + system系统模块 + + + + + + + com.ruoyi + ruoyi-common + + + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysAppRoleMenu.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysAppRoleMenu.java new file mode 100644 index 0000000..f3a3703 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysAppRoleMenu.java @@ -0,0 +1,51 @@ +package com.ruoyi.system.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 角色和菜单关联 sys_app_role_menu app + * + * @author ruoyi + */ +@TableName("sys_app_role_menu") +public class SysAppRoleMenu +{ + /** 角色ID */ + @TableField(value = "role_id") + private Long roleId; + + /** 菜单ID */ + @TableField(value = "menu_id") + private Long menuId; + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public Long getMenuId() + { + return menuId; + } + + public void setMenuId(Long menuId) + { + this.menuId = menuId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("menuId", getMenuId()) + .toString(); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysAppUserMenu.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysAppUserMenu.java new file mode 100644 index 0000000..89e7c2f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysAppUserMenu.java @@ -0,0 +1,51 @@ +package com.ruoyi.system.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 用户和菜单关联 sys_app_user_menu + * + * @author ruoyi + */ +@TableName("sys_app_user_menu") +public class SysAppUserMenu +{ + /** 用户ID */ + @TableField(value = "user_id") + private Long userId; + + /** 菜单ID */ + @TableField(value = "menu_id") + private Long menuId; + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getMenuId() + { + return menuId; + } + + public void setMenuId(Long menuId) + { + this.menuId = menuId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("menuId", getMenuId()) + .toString(); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java new file mode 100644 index 0000000..83f0703 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java @@ -0,0 +1,81 @@ +package com.ruoyi.system.domain; + +import com.ruoyi.common.utils.StringUtils; + +/** + * 缓存信息 + * + * @author ruoyi + */ +public class SysCache +{ + /** 缓存名称 */ + private String cacheName = ""; + + /** 缓存键名 */ + private String cacheKey = ""; + + /** 缓存内容 */ + private String cacheValue = ""; + + /** 备注 */ + private String remark = ""; + + public SysCache() + { + + } + + public SysCache(String cacheName, String remark) + { + this.cacheName = cacheName; + this.remark = remark; + } + + public SysCache(String cacheName, String cacheKey, String cacheValue) + { + this.cacheName = StringUtils.replace(cacheName, ":", ""); + this.cacheKey = StringUtils.replace(cacheKey, cacheName, ""); + this.cacheValue = cacheValue; + } + + public String getCacheName() + { + return cacheName; + } + + public void setCacheName(String cacheName) + { + this.cacheName = cacheName; + } + + public String getCacheKey() + { + return cacheKey; + } + + public void setCacheKey(String cacheKey) + { + this.cacheKey = cacheKey; + } + + public String getCacheValue() + { + return cacheValue; + } + + public void setCacheValue(String cacheValue) + { + this.cacheValue = cacheValue; + } + + public String getRemark() + { + return remark; + } + + public void setRemark(String remark) + { + this.remark = remark; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfig.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfig.java new file mode 100644 index 0000000..784d686 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfig.java @@ -0,0 +1,121 @@ +package com.ruoyi.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.annotation.Excel.ColumnType; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 参数配置表 sys_config + * + * @author ruoyi + */ +@TableName("sys_config") +public class SysConfig extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 参数主键 */ + @Excel(name = "参数主键", cellType = ColumnType.NUMERIC) + @TableId(value = "config_id") + private Long configId; + + /** 参数名称 */ + @Excel(name = "参数名称") + @TableField(value = "config_name") + private String configName; + + /** 参数键名 */ + @Excel(name = "参数键名") + @TableField(value = "config_key") + private String configKey; + + /** 参数键值 */ + @Excel(name = "参数键值") + @TableField(value = "config_value") + private String configValue; + + /** 系统内置(Y是 N否) */ + @Excel(name = "系统内置", readConverterExp = "Y=是,N=否") + @TableField(value = "config_type") + private String configType; + + public Long getConfigId() + { + return configId; + } + + public void setConfigId(Long configId) + { + this.configId = configId; + } + + @NotBlank(message = "参数名称不能为空") + @Size(min = 0, max = 100, message = "参数名称不能超过100个字符") + public String getConfigName() + { + return configName; + } + + public void setConfigName(String configName) + { + this.configName = configName; + } + + @NotBlank(message = "参数键名长度不能为空") + @Size(min = 0, max = 100, message = "参数键名长度不能超过100个字符") + public String getConfigKey() + { + return configKey; + } + + public void setConfigKey(String configKey) + { + this.configKey = configKey; + } + + @NotBlank(message = "参数键值不能为空") + @Size(min = 0, max = 500, message = "参数键值长度不能超过500个字符") + public String getConfigValue() + { + return configValue; + } + + public void setConfigValue(String configValue) + { + this.configValue = configValue; + } + + public String getConfigType() + { + return configType; + } + + public void setConfigType(String configType) + { + this.configType = configType; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("configId", getConfigId()) + .append("configName", getConfigName()) + .append("configKey", getConfigKey()) + .append("configValue", getConfigValue()) + .append("configType", getConfigType()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysLogininfor.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysLogininfor.java new file mode 100644 index 0000000..70657cc --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysLogininfor.java @@ -0,0 +1,156 @@ +package com.ruoyi.system.domain; + +import java.util.Date; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.annotation.Excel.ColumnType; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 系统访问记录表 sys_logininfor + * + * @author ruoyi + */ +@TableName("sys_logininfor") +public class SysLogininfor extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** ID */ + @Excel(name = "序号", cellType = ColumnType.NUMERIC) + @TableId(value = "info_id") + private Long infoId; + + /** 用户账号 */ + @Excel(name = "用户账号") + @TableField(value = "user_name") + private String userName; + + /** 登录状态 0成功 1失败 */ + @Excel(name = "登录状态", readConverterExp = "0=成功,1=失败") + private String status; + + /** 登录IP地址 */ + @Excel(name = "登录地址") + private String ipaddr; + + /** 登录地点 */ + @Excel(name = "登录地点") + @TableField(value = "login_location") + private String loginLocation; + + /** 浏览器类型 */ + @Excel(name = "浏览器") + private String browser; + + /** 操作系统 */ + @Excel(name = "操作系统") + private String os; + + + + /** 提示消息 */ + @Excel(name = "提示消息") + private String msg; + + + /** 访问时间 */ +// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @Excel(name = "访问时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField(value = "login_time") + private Date loginTime; + + public Long getInfoId() + { + return infoId; + } + + public void setInfoId(Long infoId) + { + this.infoId = infoId; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getLoginLocation() + { + return loginLocation; + } + + public void setLoginLocation(String loginLocation) + { + this.loginLocation = loginLocation; + } + + public String getBrowser() + { + return browser; + } + + public void setBrowser(String browser) + { + this.browser = browser; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public Date getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Date loginTime) + { + this.loginTime = loginTime; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOperLog.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOperLog.java new file mode 100644 index 0000000..348d526 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOperLog.java @@ -0,0 +1,273 @@ +package com.ruoyi.system.domain; + +import java.util.Date; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.annotation.Excel.ColumnType; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 操作日志记录表 oper_log + * + * @author ruoyi + */ +@TableName("sys_oper_log") +public class SysOperLog extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 日志主键 */ + @Excel(name = "操作序号", cellType = ColumnType.NUMERIC) + @TableId(value = "oper_id") + private Long operId; + + /** 操作模块 */ + @Excel(name = "操作模块") + private String title; + + /** 业务类型(0其它 1新增 2修改 3删除) */ + @Excel(name = "业务类型", readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据") + @TableField(value = "business_type") + private Integer businessType; + + /** 业务类型数组 */ + private Integer[] businessTypes; + + /** 请求方法 */ + @Excel(name = "请求方法") + private String method; + + /** 请求方式 */ + @Excel(name = "请求方式") + @TableField(value = "request_method") + private String requestMethod; + + /** 操作类别(0其它 1后台用户 2手机端用户) */ + @Excel(name = "操作类别", readConverterExp = "0=其它,1=后台用户,2=手机端用户") + @TableField(value = "operator_type") + private Integer operatorType; + + /** 操作人员 */ + @Excel(name = "操作人员") + @TableField(value = "oper_name") + private String operName; + + /** 部门名称 */ + @Excel(name = "部门名称") + @TableField(value = "dept_name") + private String deptName; + + /** 请求url */ + @Excel(name = "请求地址") + @TableField(value = "oper_url") + private String operUrl; + + /** 操作地址 */ + @Excel(name = "操作地址") + @TableField(value = "oper_ip") + private String operIp; + + /** 操作地点 */ + @Excel(name = "操作地点") + @TableField(value = "oper_location") + private String operLocation; + + /** 请求参数 */ + @Excel(name = "请求参数") + @TableField(value = "oper_param") + private String operParam; + + /** 返回参数 */ + @Excel(name = "返回参数") + @TableField(value = "json_result") + private String jsonResult; + + /** 操作状态(0正常 1异常) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=异常") + private Integer status; + + /** 错误消息 */ + @Excel(name = "错误消息") + @TableField(value = "error_msg") + private String errorMsg; + + /** 操作时间 */ +// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8", locale = "zh") + @Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField(value = "oper_time") + private Date operTime; + + public Long getOperId() + { + return operId; + } + + public void setOperId(Long operId) + { + this.operId = operId; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public Integer getBusinessType() + { + return businessType; + } + + public void setBusinessType(Integer businessType) + { + this.businessType = businessType; + } + + public Integer[] getBusinessTypes() + { + return businessTypes; + } + + public void setBusinessTypes(Integer[] businessTypes) + { + this.businessTypes = businessTypes; + } + + public String getMethod() + { + return method; + } + + public void setMethod(String method) + { + this.method = method; + } + + public String getRequestMethod() + { + return requestMethod; + } + + public void setRequestMethod(String requestMethod) + { + this.requestMethod = requestMethod; + } + + public Integer getOperatorType() + { + return operatorType; + } + + public void setOperatorType(Integer operatorType) + { + this.operatorType = operatorType; + } + + public String getOperName() + { + return operName; + } + + public void setOperName(String operName) + { + this.operName = operName; + } + + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + public String getOperUrl() + { + return operUrl; + } + + public void setOperUrl(String operUrl) + { + this.operUrl = operUrl; + } + + public String getOperIp() + { + return operIp; + } + + public void setOperIp(String operIp) + { + this.operIp = operIp; + } + + public String getOperLocation() + { + return operLocation; + } + + public void setOperLocation(String operLocation) + { + this.operLocation = operLocation; + } + + public String getOperParam() + { + return operParam; + } + + public void setOperParam(String operParam) + { + this.operParam = operParam; + } + + public String getJsonResult() + { + return jsonResult; + } + + public void setJsonResult(String jsonResult) + { + this.jsonResult = jsonResult; + } + + public Integer getStatus() + { + return status; + } + + public void setStatus(Integer status) + { + this.status = status; + } + + public String getErrorMsg() + { + return errorMsg; + } + + public void setErrorMsg(String errorMsg) + { + this.errorMsg = errorMsg; + } + + public Date getOperTime() + { + return operTime; + } + + public void setOperTime(Date operTime) + { + this.operTime = operTime; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java new file mode 100644 index 0000000..2c8eb4f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java @@ -0,0 +1,133 @@ +package com.ruoyi.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.annotation.Excel.ColumnType; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 岗位表 sys_post + * + * @author ruoyi + */ +@TableName("sys_post") +public class SysPost extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 岗位序号 */ + @Excel(name = "岗位序号", cellType = ColumnType.NUMERIC) + @TableId(value = "post_id") + private Long postId; + + /** 岗位编码 */ + @Excel(name = "岗位编码") + @TableField(value = "post_code") + private String postCode; + + /** 岗位名称 */ + @Excel(name = "岗位名称") + @TableField(value = "post_name") + private String postName; + + /** 岗位排序 */ + @Excel(name = "岗位排序") + @TableField(value = "post_sort") + private Integer postSort; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 用户是否存在此岗位标识 默认不存在 */ + private boolean flag = false; + + public Long getPostId() + { + return postId; + } + + public void setPostId(Long postId) + { + this.postId = postId; + } + + @NotBlank(message = "岗位编码不能为空") + @Size(min = 0, max = 64, message = "岗位编码长度不能超过64个字符") + public String getPostCode() + { + return postCode; + } + + public void setPostCode(String postCode) + { + this.postCode = postCode; + } + + @NotBlank(message = "岗位名称不能为空") + @Size(min = 0, max = 50, message = "岗位名称长度不能超过50个字符") + public String getPostName() + { + return postName; + } + + public void setPostName(String postName) + { + this.postName = postName; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getPostSort() + { + return postSort; + } + + public void setPostSort(Integer postSort) + { + this.postSort = postSort; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public boolean isFlag() + { + return flag; + } + + public void setFlag(boolean flag) + { + this.flag = flag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("postId", getPostId()) + .append("postCode", getPostCode()) + .append("postName", getPostName()) + .append("postSort", getPostSort()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleDept.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleDept.java new file mode 100644 index 0000000..97b5974 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleDept.java @@ -0,0 +1,48 @@ +package com.ruoyi.system.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 角色和部门关联 sys_role_dept + * + * @author ruoyi + */ +@TableName("sys_dept") +public class SysRoleDept +{ + /** 角色ID */ + private Long roleId; + + /** 部门ID */ + private Long deptId; + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("deptId", getDeptId()) + .toString(); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java new file mode 100644 index 0000000..1b2c831 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java @@ -0,0 +1,51 @@ +package com.ruoyi.system.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 角色和菜单关联 sys_role_menu + * + * @author ruoyi + */ +@TableName("sys_role_menu") +public class SysRoleMenu +{ + /** 角色ID */ + @TableField(value = "role_id") + private Long roleId; + + /** 菜单ID */ + @TableField(value = "menu_id") + private Long menuId; + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public Long getMenuId() + { + return menuId; + } + + public void setMenuId(Long menuId) + { + this.menuId = menuId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("menuId", getMenuId()) + .toString(); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java new file mode 100644 index 0000000..32bd227 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java @@ -0,0 +1,123 @@ +package com.ruoyi.system.domain; + +/** + * 当前在线会话 + * + * @author ruoyi + */ +public class SysUserOnline +{ + /** 会话编号 */ + private String tokenId; + + /** 部门名称 */ + private String deptName; + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + private Long userId; + + /** 用户名称 */ + private String userName; + + /** 登录IP地址 */ + private String ipaddr; + + /** 登录地址 */ + private String loginLocation; + + /** 浏览器类型 */ + private String browser; + + /** 操作系统 */ + private String os; + + /** 登录时间 */ + private Long loginTime; + + public String getTokenId() + { + return tokenId; + } + + public void setTokenId(String tokenId) + { + this.tokenId = tokenId; + } + + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getLoginLocation() + { + return loginLocation; + } + + public void setLoginLocation(String loginLocation) + { + this.loginLocation = loginLocation; + } + + public String getBrowser() + { + return browser; + } + + public void setBrowser(String browser) + { + this.browser = browser; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public Long getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Long loginTime) + { + this.loginTime = loginTime; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserPost.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserPost.java new file mode 100644 index 0000000..9e024e3 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserPost.java @@ -0,0 +1,51 @@ +package com.ruoyi.system.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 用户和岗位关联 sys_user_post + * + * @author ruoyi + */ +@TableName("sys_user_post") +public class SysUserPost +{ + /** 用户ID */ + @TableField(value = "user_id") + private Long userId; + + /** 岗位ID */ + @TableField(value = "post_id") + private Long postId; + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getPostId() + { + return postId; + } + + public void setPostId(Long postId) + { + this.postId = postId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("postId", getPostId()) + .toString(); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserRole.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserRole.java new file mode 100644 index 0000000..bde9e6f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserRole.java @@ -0,0 +1,62 @@ +package com.ruoyi.system.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 用户和角色关联 sys_user_role + * + * @author ruoyi + */ +@TableName("sys_user_role") +public class SysUserRole +{ + /** 用户ID */ + @TableField(value = "user_id") + private Long userId; + + /** 角色ID */ + @TableField(value = "role_id") + private Long roleId; + + public String getRoleName() { + return roleName; + } + + public void setRoleName(String roleName) { + this.roleName = roleName; + } + + @TableField(value = "role_name") + private String roleName; + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("roleId", getRoleId()) + .toString(); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/YwUserVenue.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/YwUserVenue.java new file mode 100644 index 0000000..03b3939 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/YwUserVenue.java @@ -0,0 +1,12 @@ +package com.ruoyi.system.domain; + +import lombok.Data; + +@Data +public class YwUserVenue { + + private Long venueId; + + private String venueName; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MetaVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MetaVo.java new file mode 100644 index 0000000..a5d5fdc --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MetaVo.java @@ -0,0 +1,106 @@ +package com.ruoyi.system.domain.vo; + +import com.ruoyi.common.utils.StringUtils; + +/** + * 路由显示信息 + * + * @author ruoyi + */ +public class MetaVo +{ + /** + * 设置该路由在侧边栏和面包屑中展示的名字 + */ + private String title; + + /** + * 设置该路由的图标,对应路径src/assets/icons/svg + */ + private String icon; + + /** + * 设置为true,则不会被 缓存 + */ + private boolean noCache; + + /** + * 内链地址(http(s)://开头) + */ + private String link; + + public MetaVo() + { + } + + public MetaVo(String title, String icon) + { + this.title = title; + this.icon = icon; + } + + public MetaVo(String title, String icon, boolean noCache) + { + this.title = title; + this.icon = icon; + this.noCache = noCache; + } + + public MetaVo(String title, String icon, String link) + { + this.title = title; + this.icon = icon; + this.link = link; + } + + public MetaVo(String title, String icon, boolean noCache, String link) + { + this.title = title; + this.icon = icon; + this.noCache = noCache; + if (StringUtils.ishttp(link)) + { + this.link = link; + } + } + + public boolean isNoCache() + { + return noCache; + } + + public void setNoCache(boolean noCache) + { + this.noCache = noCache; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getIcon() + { + return icon; + } + + public void setIcon(String icon) + { + this.icon = icon; + } + + public String getLink() + { + return link; + } + + public void setLink(String link) + { + this.link = link; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/RouterVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/RouterVo.java new file mode 100644 index 0000000..afff8c9 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/RouterVo.java @@ -0,0 +1,148 @@ +package com.ruoyi.system.domain.vo; + +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; + +/** + * 路由配置信息 + * + * @author ruoyi + */ +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class RouterVo +{ + /** + * 路由名字 + */ + private String name; + + /** + * 路由地址 + */ + private String path; + + /** + * 是否隐藏路由,当设置 true 的时候该路由不会再侧边栏出现 + */ + private boolean hidden; + + /** + * 重定向地址,当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 + */ + private String redirect; + + /** + * 组件地址 + */ + private String component; + + /** + * 路由参数:如 {"id": 1, "name": "ry"} + */ + private String query; + + /** + * 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 + */ + private Boolean alwaysShow; + + /** + * 其他元素 + */ + private MetaVo meta; + + /** + * 子路由 + */ + private List children; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getPath() + { + return path; + } + + public void setPath(String path) + { + this.path = path; + } + + public boolean getHidden() + { + return hidden; + } + + public void setHidden(boolean hidden) + { + this.hidden = hidden; + } + + public String getRedirect() + { + return redirect; + } + + public void setRedirect(String redirect) + { + this.redirect = redirect; + } + + public String getComponent() + { + return component; + } + + public void setComponent(String component) + { + this.component = component; + } + + public String getQuery() + { + return query; + } + + public void setQuery(String query) + { + this.query = query; + } + + public Boolean getAlwaysShow() + { + return alwaysShow; + } + + public void setAlwaysShow(Boolean alwaysShow) + { + this.alwaysShow = alwaysShow; + } + + public MetaVo getMeta() + { + return meta; + } + + public void setMeta(MetaVo meta) + { + this.meta = meta; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserInfoVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserInfoVo.java new file mode 100644 index 0000000..c922496 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserInfoVo.java @@ -0,0 +1,10 @@ +package com.ruoyi.system.domain.vo; + +import lombok.Data; + +@Data +public class SysUserInfoVo { + + private String logoutTime; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/UserTypeInfoVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/UserTypeInfoVO.java new file mode 100644 index 0000000..0c94578 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/UserTypeInfoVO.java @@ -0,0 +1,11 @@ +package com.ruoyi.system.domain.vo; + +import lombok.Data; + +@Data +public class UserTypeInfoVO { + + private String userType; + + private Integer num; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysAppMenuMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysAppMenuMapper.java new file mode 100644 index 0000000..c94ab15 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysAppMenuMapper.java @@ -0,0 +1,127 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.common.core.domain.entity.SysAppMenu; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 菜单表 数据层 + * + * @author ruoyi + */ +public interface SysAppMenuMapper { + /** + * 查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + public List selectMenuList(SysAppMenu menu); + + /** + * 根据用户所有权限 + * + * @return 权限列表 + */ + public List selectMenuPerms(); + + /** + * 根据用户查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + public List selectMenuListByUserId(SysAppMenu menu); + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + public List selectMenuPermsByRoleId(Long roleId); + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public List selectMenuPermsByUserId(Long userId); + + /** + * 根据用户ID查询菜单 + * + * @return 菜单列表 + */ + public List selectMenuTreeAll(); + + /** + * 根据用户ID查询菜单 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuTreeByUserId(Long userId); + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @param menuCheckStrictly 菜单树选择项是否关联显示 + * @return 选中菜单列表 + */ + public List selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly); + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + public SysAppMenu selectMenuById(Long menuId); + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int hasChildByMenuId(Long menuId); + + /** + * 新增菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int insertMenu(SysAppMenu menu); + + /** + * 修改菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int updateMenu(SysAppMenu menu); + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int deleteMenuById(Long menuId); + + /** + * 校验菜单名称是否唯一 + * + * @param menuName 菜单名称 + * @param parentId 父菜单ID + * @return 结果 + */ + public SysAppMenu checkMenuNameUnique(@Param("menuName") String menuName, @Param("parentId") Long parentId); + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysAppRoleMenuMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysAppRoleMenuMapper.java new file mode 100644 index 0000000..be2066d --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysAppRoleMenuMapper.java @@ -0,0 +1,47 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.system.domain.SysAppRoleMenu; +import com.ruoyi.system.domain.SysRoleMenu; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 角色与菜单关联表 数据层 + * + * @author ruoyi + */ +public interface SysAppRoleMenuMapper { + /** + * 查询菜单使用数量 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int checkMenuExistRole(Long menuId); + + /** + * 通过角色ID删除角色和菜单关联 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteAppRoleMenuByRoleId(Long roleId); + + /** + * 批量删除角色菜单关联信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteAppRoleMenu(Long[] ids); + + + /** + * 批量新增角色菜单信息 + * + * @param appRoleMenuList 角色菜单列表 + * @return 结果 + */ + public int batchAppRoleMenu(List appRoleMenuList); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysAppUserMenuMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysAppUserMenuMapper.java new file mode 100644 index 0000000..8936d61 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysAppUserMenuMapper.java @@ -0,0 +1,50 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.common.core.domain.entity.SysAppMenu; +import com.ruoyi.system.domain.SysAppUserMenu; + +import java.util.List; + +/** + * 用户与菜单关联表 数据层 + * + * @author ruoyi + */ +public interface SysAppUserMenuMapper { + /** + * 查询菜单使用数量 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int checkMenuExistUser(Long menuId); + + /** + * 通过用户ID删除角色和菜单关联 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteAppUserMenuByUserId(Long userId); + + /** + * 批量删除用户菜单关联信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteAppUserMenu(Long[] ids); + + /** + * 批量新增用户菜单信息 + * + * @param roleMenuList 用户菜单列表 + * @return 结果 + */ + public int batchAppUserMenu(List userMenuList); + + /** + * 获取个人定制菜单列表(sys_app_user_menu) + */ + List selectCustomList(Long userId); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java new file mode 100644 index 0000000..0ed0c0a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java @@ -0,0 +1,68 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.domain.SysConfig; + +/** + * 参数配置 数据层 + * + * @author ruoyi + */ +public interface SysConfigMapper +{ + /** + * 查询参数配置信息 + * + * @param config 参数配置信息 + * @return 参数配置信息 + */ + public SysConfig selectConfig(SysConfig config); + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + public List selectConfigList(SysConfig config); + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数键名 + * @return 参数配置信息 + */ + public SysConfig checkConfigKeyUnique(String configKey); + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int insertConfig(SysConfig config); + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int updateConfig(SysConfig config); + + /** + * 删除参数配置 + * + * @param configId 参数ID + * @return 结果 + */ + public int deleteConfigById(Long configId); + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + * @return 结果 + */ + public int deleteConfigByIds(Long[] configIds); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java new file mode 100644 index 0000000..384a9b6 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java @@ -0,0 +1,118 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.ruoyi.common.core.domain.entity.SysDept; + +/** + * 部门管理 数据层 + * + * @author ruoyi + */ +public interface SysDeptMapper +{ + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + public List selectDeptList(SysDept dept); + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @param deptCheckStrictly 部门树选择项是否关联显示 + * @return 选中部门列表 + */ + public List selectDeptListByRoleId(@Param("roleId") Long roleId, @Param("deptCheckStrictly") boolean deptCheckStrictly); + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + public SysDept selectDeptById(Long deptId); + + /** + * 根据ID查询所有子部门 + * + * @param deptId 部门ID + * @return 部门列表 + */ + public List selectChildrenDeptById(Long deptId); + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + public int selectNormalChildrenDeptById(Long deptId); + + /** + * 是否存在子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + public int hasChildByDeptId(Long deptId); + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 + */ + public int checkDeptExistUser(Long deptId); + + /** + * 校验部门名称是否唯一 + * + * @param deptName 部门名称 + * @param parentId 父部门ID + * @return 结果 + */ + public SysDept checkDeptNameUnique(@Param("deptName") String deptName, @Param("parentId") Long parentId); + + /** + * 新增部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int insertDept(SysDept dept); + + /** + * 修改部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int updateDept(SysDept dept); + + /** + * 修改所在部门正常状态 + * + * @param deptIds 部门ID组 + */ + public void updateDeptStatusNormal(Long[] deptIds); + + /** + * 修改子元素关系 + * + * @param depts 子元素 + * @return 结果 + */ + public int updateDeptChildren(@Param("depts") List depts); + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + public int deleteDeptById(Long deptId); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java new file mode 100644 index 0000000..52282be --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java @@ -0,0 +1,116 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.common.core.domain.entity.SysDictData; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 字典表 数据层 + * + * @author ruoyi + */ +public interface SysDictDataMapper +{ + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + public List selectDictDataList(SysDictData dictData); + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + public List selectDictDataByType(String dictType); + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + public String selectDictLabel(@Param("dictType") String dictType, @Param("dictValue") String dictValue); + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValues 字典键值数组(null或空时查出所有) + * @return 字典标签 + */ + List selectDictLabelByValues(@Param("dictType")String dictType, @Param("dictValues")List dictValues); + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + public SysDictData selectDictDataById(Long dictCode); + + /** + * 查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据 + */ + public int countDictDataByType(String dictType); + + /** + * 通过字典ID删除字典数据信息 + * + * @param dictCode 字典数据ID + * @return 结果 + */ + public int deleteDictDataById(Long dictCode); + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + * @return 结果 + */ + public int deleteDictDataByIds(Long[] dictCodes); + + /** + * 新增字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int insertDictData(SysDictData dictData); + + /** + * 修改字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int updateDictData(SysDictData dictData); + + /** + * 同步修改字典类型 + * + * @param oldDictType 旧字典类型 + * @param newDictType 新旧字典类型 + * @return 结果 + */ + public int updateDictDataType(@Param("oldDictType") String oldDictType, @Param("newDictType") String newDictType); + + /** + * 根据字典类型城市查询下属区域 + * + * @param cityValue 城市 + * @return 结果 + */ + List selectCountyByCity(@Param("cityValue")String cityValue); + + + String selectDictValue(@Param("dictType")String dictType,@Param("dictLable") String dictLable); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java new file mode 100644 index 0000000..5fb48fb --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java @@ -0,0 +1,83 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.common.core.domain.entity.SysDictType; + +/** + * 字典表 数据层 + * + * @author ruoyi + */ +public interface SysDictTypeMapper +{ + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + public List selectDictTypeList(SysDictType dictType); + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + public List selectDictTypeAll(); + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + public SysDictType selectDictTypeById(Long dictId); + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + public SysDictType selectDictTypeByType(String dictType); + + /** + * 通过字典ID删除字典信息 + * + * @param dictId 字典ID + * @return 结果 + */ + public int deleteDictTypeById(Long dictId); + + /** + * 批量删除字典类型信息 + * + * @param dictIds 需要删除的字典ID + * @return 结果 + */ + public int deleteDictTypeByIds(Long[] dictIds); + + /** + * 新增字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int insertDictType(SysDictType dictType); + + /** + * 修改字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int updateDictType(SysDictType dictType); + + /** + * 校验字典类型称是否唯一 + * + * @param dictType 字典类型 + * @return 结果 + */ + public SysDictType checkDictTypeUnique(String dictType); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java new file mode 100644 index 0000000..6333d0a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java @@ -0,0 +1,46 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.domain.SysLogininfor; + +/** + * 系统访问日志情况信息 数据层 + * + * @author ruoyi + */ +public interface SysLogininforMapper +{ + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + public void insertLogininfor(SysLogininfor logininfor); + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + public List selectLogininforList(SysLogininfor logininfor); + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + public int deleteLogininforByIds(Long[] infoIds); + + /** + * 清空系统登录日志 + * + * @return 结果 + */ + public int cleanLogininfor(); + + public int deleteLogininforSchedule(); + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java new file mode 100644 index 0000000..60d6a79 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java @@ -0,0 +1,127 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.ruoyi.common.core.domain.entity.SysMenu; + +/** + * 菜单表 数据层 + * + * @author ruoyi + */ +public interface SysMenuMapper +{ + /** + * 查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + public List selectMenuList(SysMenu menu); + + /** + * 根据用户所有权限 + * + * @return 权限列表 + */ + public List selectMenuPerms(); + + /** + * 根据用户查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + public List selectMenuListByUserId(SysMenu menu); + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + public List selectMenuPermsByRoleId(Long roleId); + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public List selectMenuPermsByUserId(Long userId); + + /** + * 根据用户ID查询菜单 + * + * @return 菜单列表 + */ + public List selectMenuTreeAll(); + + /** + * 根据用户ID查询菜单 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuTreeByUserId(Long userId); + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @param menuCheckStrictly 菜单树选择项是否关联显示 + * @return 选中菜单列表 + */ + public List selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly); + + public List selectMenuNameListByRoleId(@Param("roleId") Long roleId); + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + public SysMenu selectMenuById(Long menuId); + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int hasChildByMenuId(Long menuId); + + /** + * 新增菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int insertMenu(SysMenu menu); + + /** + * 修改菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int updateMenu(SysMenu menu); + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int deleteMenuById(Long menuId); + + /** + * 校验菜单名称是否唯一 + * + * @param menuName 菜单名称 + * @param parentId 父菜单ID + * @return 结果 + */ + public SysMenu checkMenuNameUnique(@Param("menuName") String menuName, @Param("parentId") Long parentId); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java new file mode 100644 index 0000000..80f3359 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java @@ -0,0 +1,52 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.domain.SysOperLog; + +/** + * 操作日志 数据层 + * + * @author ruoyi + */ +public interface SysOperLogMapper +{ + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + */ + public void insertOperlog(SysOperLog operLog); + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + public List selectOperLogList(SysOperLog operLog); + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + public int deleteOperLogByIds(Long[] operIds); + + /** + * 查询操作日志详细 + * + * @param operId 操作ID + * @return 操作日志对象 + */ + public SysOperLog selectOperLogById(Long operId); + + /** + * 清空操作日志 + */ + public void cleanOperLog(); + + + public int deleteOperLogSchedule(); + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java new file mode 100644 index 0000000..19be227 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java @@ -0,0 +1,99 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.domain.SysPost; + +/** + * 岗位信息 数据层 + * + * @author ruoyi + */ +public interface SysPostMapper +{ + /** + * 查询岗位数据集合 + * + * @param post 岗位信息 + * @return 岗位数据集合 + */ + public List selectPostList(SysPost post); + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + public List selectPostAll(); + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + public SysPost selectPostById(Long postId); + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + public List selectPostListByUserId(Long userId); + + /** + * 查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + public List selectPostsByUserName(String userName); + + /** + * 删除岗位信息 + * + * @param postId 岗位ID + * @return 结果 + */ + public int deletePostById(Long postId); + + /** + * 批量删除岗位信息 + * + * @param postIds 需要删除的岗位ID + * @return 结果 + */ + public int deletePostByIds(Long[] postIds); + + /** + * 修改岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int updatePost(SysPost post); + + /** + * 新增岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int insertPost(SysPost post); + + /** + * 校验岗位名称 + * + * @param postName 岗位名称 + * @return 结果 + */ + public SysPost checkPostNameUnique(String postName); + + /** + * 校验岗位编码 + * + * @param postCode 岗位编码 + * @return 结果 + */ + public SysPost checkPostCodeUnique(String postCode); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java new file mode 100644 index 0000000..f9d3a2f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java @@ -0,0 +1,44 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.domain.SysRoleDept; + +/** + * 角色与部门关联表 数据层 + * + * @author ruoyi + */ +public interface SysRoleDeptMapper +{ + /** + * 通过角色ID删除角色和部门关联 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleDeptByRoleId(Long roleId); + + /** + * 批量删除角色部门关联信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteRoleDept(Long[] ids); + + /** + * 查询部门使用数量 + * + * @param deptId 部门ID + * @return 结果 + */ + public int selectCountRoleDeptByDeptId(Long deptId); + + /** + * 批量新增角色部门信息 + * + * @param roleDeptList 角色部门列表 + * @return 结果 + */ + public int batchRoleDept(List roleDeptList); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java new file mode 100644 index 0000000..3cb7238 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java @@ -0,0 +1,114 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import org.apache.ibatis.annotations.Param; + +/** + * 角色表 数据层 + * + * @author ruoyi + */ +public interface SysRoleMapper +{ + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + public List selectRoleList(SysRole role); + + /** + * 根据用户ID查询角色 + * + * @param userId 用户ID + * @return 角色列表 + */ + public List selectRolePermissionByUserId(Long userId); + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + public List selectRoleAll(); + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + public List selectRoleListByUserId(Long userId); + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + public SysRole selectRoleById(Long roleId); + + /** + * 根据用户ID查询角色 + * + * @param userName 用户名 + * @return 角色列表 + */ + public List selectRolesByUserName(String userName); + + /** + * 校验角色名称是否唯一 + * + * @param roleName 角色名称 + * @return 角色信息 + */ + public SysRole checkRoleNameUnique(String roleName); + + /** + * 校验角色权限是否唯一 + * + * @param roleKey 角色权限 + * @return 角色信息 + */ + public SysRole checkRoleKeyUnique(String roleKey); + + /** + * 修改角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int updateRole(SysRole role); + + /** + * 新增角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int insertRole(SysRole role); + + /** + * 通过角色ID删除角色 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleById(Long roleId); + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + public int deleteRoleByIds(Long[] roleIds); + + /** + * 根据角色ID查询用户 + */ + List selectNameByUserId(Long userId); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java new file mode 100644 index 0000000..af50e56 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java @@ -0,0 +1,45 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.domain.SysRoleMenu; +import org.apache.ibatis.annotations.Param; + +/** + * 角色与菜单关联表 数据层 + * + * @author ruoyi + */ +public interface SysRoleMenuMapper +{ + /** + * 查询菜单使用数量 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int checkMenuExistRole(Long menuId); + + /** + * 通过角色ID删除角色和菜单关联 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleMenuByRoleId(Long roleId); + + /** + * 批量删除角色菜单关联信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteRoleMenu(Long[] ids); + + /** + * 批量新增角色菜单信息 + * + * @param roleMenuList 角色菜单列表 + * @return 结果 + */ + public int batchRoleMenu(List roleMenuList); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java new file mode 100644 index 0000000..aa4eeef --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java @@ -0,0 +1,191 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.system.domain.vo.SysUserInfoVo; +import com.ruoyi.system.domain.vo.UserTypeInfoVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 用户表 数据层 + * + * @author ruoyi + */ +@Mapper +public interface SysUserMapper +{ + /** + * 根据条件分页查询用户列表 + * + * @param sysUser 用户信息 + * @return 用户信息集合信息 + */ + public List selectUserList(SysUser sysUser); + + public List selectUserALL(SysUser sysUser); + + /** + * 根据条件分页查询用户列表 + * + * @param sysUser 用户信息 + * @return 用户信息集合信息 + */ + public List selectNoSceneUserList(SysUser sysUser); + + /** + * 查询没有专业的用户 + * + * @return 用户信息集合信息 + */ + public List selectNoSpecUserList(SysUser sysUser); + + /** + * 根据条件分页查询已配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectAllocatedList(SysUser user); + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUnallocatedList(SysUser user); + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByUserName(String userName); + + /** + * 通过用户昵称查询用户 + * + * @param nickName 用户名 + * @return 用户对象信息 + */ + public List selectUserByNickName(String nickName); + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + public SysUser selectUserById(Long userId); + + public SysUser selectAllUserById(Long userId); + + public SysUser selectUserByPhone(String phone); + + public List selectUserListByPhones(@Param("phones") String[] phones); + + /** + * 新增用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int insertUser(SysUser user); + + /** + * 修改用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUser(SysUser user); + + /** + * 修改用户登录信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUserLogin(SysUser user); + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar); + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + public int resetUserPwd(@Param("userName") String userName, @Param("password") String password); + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserById(Long userId); + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + public int deleteUserByIds(Long[] userIds); + + /** + * 校验用户名称是否唯一 + * + * @param userName 用户名称 + * @return 结果 + */ + public SysUser checkUserNameUnique(String userName); + + /** + * 校验手机号码是否唯一 + * + * @param phonenumber 手机号码 + * @return 结果 + */ + public SysUser checkPhoneUnique(String phonenumber); + + /** + * 校验email是否唯一 + * + * @param email 用户邮箱 + * @return 结果 + */ + public SysUser checkEmailUnique(String email); + + + public SysUserInfoVo getUserInfo(String userName); + + List selectUserByUserNameAndPhone(@Param("phone") String phone); + + List selectUserByIds(@Param("userIds") List userIds); + + List selectUserByRoleIdsAndSceneId(@Param("roleIds") Long[] roleIds,@Param("sceneId") Long sceneId); + + + List selectCheckUserIdList(); + + SysUser selectUserByNickNameAndPhone(@Param("nickName")String nickName,@Param("phone") String phone); + + List selectUserByRoleKey(@Param("roleKey")String roleKey); + + List selectUserByUserType(); + + List selectUserByKeywords(@Param("keywords")String keywords,@Param("sceneId")Long sceneId); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java new file mode 100644 index 0000000..e08991d --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java @@ -0,0 +1,44 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.domain.SysUserPost; + +/** + * 用户与岗位关联表 数据层 + * + * @author ruoyi + */ +public interface SysUserPostMapper +{ + /** + * 通过用户ID删除用户和岗位关联 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserPostByUserId(Long userId); + + /** + * 通过岗位ID查询岗位使用数量 + * + * @param postId 岗位ID + * @return 结果 + */ + public int countUserPostById(Long postId); + + /** + * 批量删除用户和岗位关联 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteUserPost(Long[] ids); + + /** + * 批量新增用户岗位信息 + * + * @param userPostList 用户角色列表 + * @return 结果 + */ + public int batchUserPost(List userPostList); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java new file mode 100644 index 0000000..d0e3fc9 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java @@ -0,0 +1,77 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.system.domain.SysUserRole; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 用户与角色关联表 数据层 + * + * @author ruoyi + */ +public interface SysUserRoleMapper +{ + /** + * 通过用户ID删除用户和角色关联 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserRoleByUserId(Long userId); + + /** + * 批量删除用户和角色关联 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteUserRole(Long[] ids); + + /** + * 通过角色ID查询角色使用数量 + * + * @param roleId 角色ID + * @return 结果 + */ + public int countUserRoleByRoleId(Long roleId); + + /** + * 批量新增用户角色信息 + * + * @param userRoleList 用户角色列表 + * @return 结果 + */ + public int batchUserRole(List userRoleList); + + /** + * 删除用户和角色关联信息 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + public int deleteUserRoleInfo(SysUserRole userRole); + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要删除的用户数据ID + * @return 结果 + */ + public int deleteUserRoleInfos(@Param("roleId") Long roleId, @Param("userIds") Long[] userIds); + + /** + * 查询用户是否有某一角色 + * + * @param userId 用户ID + * @param roleKey 角色key + * @return 结果 + */ + public SysUserRole hasRole(@Param("userId") Long userId,@Param("roleKey")String roleKey); + + public List selectRolePermissionByUserIds(@Param("userIds") List userIds); + + public List selectRoleByUserId(@Param("userId") Long userId); + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserVenueMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserVenueMapper.java new file mode 100644 index 0000000..745895b --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserVenueMapper.java @@ -0,0 +1,17 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.system.domain.SysUserRole; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 用户与角色关联表 数据层 + * + * @author ruoyi + */ +public interface SysUserVenueMapper +{ + public int deleteUserVenue(Long[] userId); + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysAppMenuService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysAppMenuService.java new file mode 100644 index 0000000..1037fb7 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysAppMenuService.java @@ -0,0 +1,154 @@ +package com.ruoyi.system.service; + +import com.ruoyi.common.core.domain.TreeSelect; +import com.ruoyi.common.core.domain.entity.SysAppMenu; +import com.ruoyi.system.domain.vo.RouterVo; + +import java.util.List; +import java.util.Set; + +/** + * 菜单 业务层 app + * + * @author ruoyi + */ +public interface ISysAppMenuService { + /** + * 根据用户查询系统菜单列表 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuList(Long userId); + + /** + * 根据用户查询系统菜单列表 + * + * @param menu 菜单信息 + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuList(SysAppMenu menu, Long userId); + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public Set selectMenuPermsByUserId(Long userId); + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + public Set selectMenuPermsByRoleId(Long roleId); + + /** + * 根据用户ID查询菜单树信息 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuTreeByUserId(Long userId); + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @return 选中菜单列表 + */ + public List selectMenuListByRoleId(Long roleId,Boolean menuCheckStrictly); + + /** + * 构建前端路由所需要的菜单 + * + * @param menus 菜单列表 + * @return 路由列表 + */ + public List buildMenus(List menus); + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + public List buildMenuTree(List menus); + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + public List buildMenuTreeSelect(List menus); + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + public SysAppMenu selectMenuById(Long menuId); + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 true 存在 false 不存在 + */ + public boolean hasChildByMenuId(Long menuId); + + /** + * 查询菜单是否存在角色 + * + * @param menuId 菜单ID + * @return 结果 true 存在 false 不存在 + */ + public boolean checkMenuExistRole(Long menuId); + + /** + * 新增保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int insertMenu(SysAppMenu menu); + + /** + * 修改保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int updateMenu(SysAppMenu menu); + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int deleteMenuById(Long menuId); + + /** + * 校验菜单名称是否唯一 + * + * @param menu 菜单信息 + * @return 结果 + */ + public String checkMenuNameUnique(SysAppMenu menu); + + /** + * 获取个人定制菜单列表(sys_app_user_menu) + */ + List selectCustomList(Long userId); + + /** + * 更改个人定制菜单列表(sys_app_user_menu) + */ + Boolean updateCustomList(Long userId,List menuIds); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java new file mode 100644 index 0000000..f6af7b0 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java @@ -0,0 +1,92 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.system.domain.SysConfig; + +/** + * 参数配置 服务层 + * + * @author ruoyi + */ +public interface ISysConfigService +{ + /** + * 查询参数配置信息 + * + * @param configId 参数配置ID + * @return 参数配置信息 + */ + public SysConfig selectConfigById(Long configId); + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数键名 + * @return 参数键值 + */ + public String selectConfigByKey(String configKey); + + /** + * 获取验证码开关 + * + * @return true开启,false关闭 + */ + public boolean selectCaptchaEnabled(); + + + public boolean selectDistinctEnabled(); + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + public List selectConfigList(SysConfig config); + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int insertConfig(SysConfig config); + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int updateConfig(SysConfig config); + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + */ + public void deleteConfigByIds(Long[] configIds); + + /** + * 加载参数缓存数据 + */ + public void loadingConfigCache(); + + /** + * 清空参数缓存数据 + */ + public void clearConfigCache(); + + /** + * 重置参数缓存数据 + */ + public void resetConfigCache(); + + /** + * 校验参数键名是否唯一 + * + * @param config 参数信息 + * @return 结果 + */ + public String checkConfigKeyUnique(SysConfig config); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java new file mode 100644 index 0000000..166ba16 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java @@ -0,0 +1,124 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.common.core.domain.TreeSelect; +import com.ruoyi.common.core.domain.entity.SysDept; + +/** + * 部门管理 服务层 + * + * @author ruoyi + */ +public interface ISysDeptService +{ + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + public List selectDeptList(SysDept dept); + + /** + * 查询部门树结构信息 + * + * @param dept 部门信息 + * @return 部门树信息集合 + */ + public List selectDeptTreeList(SysDept dept); + + /** + * 构建前端所需要树结构 + * + * @param depts 部门列表 + * @return 树结构列表 + */ + public List buildDeptTree(List depts); + + /** + * 构建前端所需要下拉树结构 + * + * @param depts 部门列表 + * @return 下拉树结构列表 + */ + public List buildDeptTreeSelect(List depts); + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @return 选中部门列表 + */ + public List selectDeptListByRoleId(Long roleId); + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + public SysDept selectDeptById(Long deptId); + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + public int selectNormalChildrenDeptById(Long deptId); + + /** + * 是否存在部门子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + public boolean hasChildByDeptId(Long deptId); + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 true 存在 false 不存在 + */ + public boolean checkDeptExistUser(Long deptId); + + /** + * 校验部门名称是否唯一 + * + * @param dept 部门信息 + * @return 结果 + */ + public String checkDeptNameUnique(SysDept dept); + + /** + * 校验部门是否有数据权限 + * + * @param deptId 部门id + */ + public void checkDeptDataScope(Long deptId); + + /** + * 新增保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int insertDept(SysDept dept); + + /** + * 修改保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int updateDept(SysDept dept); + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + public int deleteDeptById(Long deptId); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java new file mode 100644 index 0000000..65a16d9 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java @@ -0,0 +1,78 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.common.core.domain.entity.SysDictData; + +/** + * 字典 业务层 + * + * @author ruoyi + */ +public interface ISysDictDataService +{ + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + public List selectDictDataList(SysDictData dictData); + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + public String selectDictLabel(String dictType, String dictValue); + + /** + * 根据字典类型和字典标签查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictLable 字典键值 + * @return 字典标签 + */ + public String selectDictValue(String dictType, String dictLable); + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValues 字典键值数组(null或空时查出所有) + * @return 字典标签 + */ + public List selectDictLabelByValues(String dictType, List dictValues); + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + public SysDictData selectDictDataById(Long dictCode); + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + */ + public void deleteDictDataByIds(Long[] dictCodes); + + /** + * 新增保存字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int insertDictData(SysDictData dictData); + + /** + * 修改保存字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int updateDictData(SysDictData dictData); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java new file mode 100644 index 0000000..267bcf9 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java @@ -0,0 +1,106 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.domain.entity.SysDictType; + +/** + * 字典 业务层 + * + * @author ruoyi + */ +public interface ISysDictTypeService +{ + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + public List selectDictTypeList(SysDictType dictType); + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + public List selectDictTypeAll(); + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + public List selectDictDataByType(String dictType); + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + public SysDictType selectDictTypeById(Long dictId); + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + public SysDictType selectDictTypeByType(String dictType); + + /** + * 批量删除字典信息 + * + * @param dictIds 需要删除的字典ID + */ + public void deleteDictTypeByIds(Long[] dictIds); + + /** + * 加载字典缓存数据 + */ + public void loadingDictCache(); + + /** + * 清空字典缓存数据 + */ + public void clearDictCache(); + + /** + * 重置字典缓存数据 + */ + public void resetDictCache(); + + /** + * 新增保存字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int insertDictType(SysDictType dictType); + + /** + * 修改保存字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int updateDictType(SysDictType dictType); + + /** + * 校验字典类型称是否唯一 + * + * @param dictType 字典类型 + * @return 结果 + */ + public String checkDictTypeUnique(SysDictType dictType); + + /** + * 根据字典类型城市查询下属区域 + * + * @param cityValue 城市 + * @return 结果 + */ + List selectCountyByCity(String cityValue); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java new file mode 100644 index 0000000..ce3151d --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java @@ -0,0 +1,40 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.system.domain.SysLogininfor; + +/** + * 系统访问日志情况信息 服务层 + * + * @author ruoyi + */ +public interface ISysLogininforService +{ + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + public void insertLogininfor(SysLogininfor logininfor); + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + public List selectLogininforList(SysLogininfor logininfor); + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + public int deleteLogininforByIds(Long[] infoIds); + + /** + * 清空系统登录日志 + */ + public void cleanLogininfor(); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java new file mode 100644 index 0000000..5a59bcb --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java @@ -0,0 +1,146 @@ +package com.ruoyi.system.service; + +import java.util.List; +import java.util.Set; +import com.ruoyi.common.core.domain.TreeSelect; +import com.ruoyi.common.core.domain.entity.SysMenu; +import com.ruoyi.system.domain.vo.RouterVo; + +/** + * 菜单 业务层 + * + * @author ruoyi + */ +public interface ISysMenuService +{ + /** + * 根据用户查询系统菜单列表 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuList(Long userId); + + /** + * 根据用户查询系统菜单列表 + * + * @param menu 菜单信息 + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuList(SysMenu menu, Long userId); + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public Set selectMenuPermsByUserId(Long userId); + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + public Set selectMenuPermsByRoleId(Long roleId); + + /** + * 根据用户ID查询菜单树信息 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuTreeByUserId(Long userId); + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @return 选中菜单列表 + */ + public List selectMenuListByRoleId(Long roleId,Boolean menuCheckStrictly); + + public List selectMenuNameListByRoleId(Long roleId); + + /** + * 构建前端路由所需要的菜单 + * + * @param menus 菜单列表 + * @return 路由列表 + */ + public List buildMenus(List menus); + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + public List buildMenuTree(List menus); + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + public List buildMenuTreeSelect(List menus); + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + public SysMenu selectMenuById(Long menuId); + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 true 存在 false 不存在 + */ + public boolean hasChildByMenuId(Long menuId); + + /** + * 查询菜单是否存在角色 + * + * @param menuId 菜单ID + * @return 结果 true 存在 false 不存在 + */ + public boolean checkMenuExistRole(Long menuId); + + /** + * 新增保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int insertMenu(SysMenu menu); + + /** + * 修改保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int updateMenu(SysMenu menu); + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int deleteMenuById(Long menuId); + + /** + * 校验菜单名称是否唯一 + * + * @param menu 菜单信息 + * @return 结果 + */ + public String checkMenuNameUnique(SysMenu menu); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java new file mode 100644 index 0000000..4fd8e5a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java @@ -0,0 +1,48 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.system.domain.SysOperLog; + +/** + * 操作日志 服务层 + * + * @author ruoyi + */ +public interface ISysOperLogService +{ + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + */ + public void insertOperlog(SysOperLog operLog); + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + public List selectOperLogList(SysOperLog operLog); + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + public int deleteOperLogByIds(Long[] operIds); + + /** + * 查询操作日志详细 + * + * @param operId 操作ID + * @return 操作日志对象 + */ + public SysOperLog selectOperLogById(Long operId); + + /** + * 清空操作日志 + */ + public void cleanOperLog(); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java new file mode 100644 index 0000000..4ffee39 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java @@ -0,0 +1,99 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.system.domain.SysPost; + +/** + * 岗位信息 服务层 + * + * @author ruoyi + */ +public interface ISysPostService +{ + /** + * 查询岗位信息集合 + * + * @param post 岗位信息 + * @return 岗位列表 + */ + public List selectPostList(SysPost post); + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + public List selectPostAll(); + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + public SysPost selectPostById(Long postId); + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + public List selectPostListByUserId(Long userId); + + /** + * 校验岗位名称 + * + * @param post 岗位信息 + * @return 结果 + */ + public String checkPostNameUnique(SysPost post); + + /** + * 校验岗位编码 + * + * @param post 岗位信息 + * @return 结果 + */ + public String checkPostCodeUnique(SysPost post); + + /** + * 通过岗位ID查询岗位使用数量 + * + * @param postId 岗位ID + * @return 结果 + */ + public int countUserPostById(Long postId); + + /** + * 删除岗位信息 + * + * @param postId 岗位ID + * @return 结果 + */ + public int deletePostById(Long postId); + + /** + * 批量删除岗位信息 + * + * @param postIds 需要删除的岗位ID + * @return 结果 + */ + public int deletePostByIds(Long[] postIds); + + /** + * 新增保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int insertPost(SysPost post); + + /** + * 修改保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int updatePost(SysPost post); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java new file mode 100644 index 0000000..0bc73ce --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java @@ -0,0 +1,195 @@ +package com.ruoyi.system.service; + +import java.util.List; +import java.util.Set; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.system.domain.SysUserRole; + +/** + * 角色业务层 + * + * @author ruoyi + */ +public interface ISysRoleService +{ + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + public List selectRoleList(SysRole role); + + /** + * 根据用户ID查询角色列表 + * + * @param userId 用户ID + * @return 角色列表 + */ + public List selectRolesByUserId(Long userId); + + /** + * 根据用户ID查询同场馆拥有相同角色人员姓名 + */ + public List selectNameByUserId(Long userId); + + //RUOYI的原生方法不符合需求,没有改,另外加一个 + public List selectRolesByUserId2(Long userId); + + + public List selectRolesByUserIds(List userIds); + + /** + * 根据用户ID查询角色权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public Set selectRolePermissionByUserId(Long userId); + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + public List selectRoleAll(); + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + public List selectRoleListByUserId(Long userId); + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + public SysRole selectRoleById(Long roleId); + + /** + * 校验角色名称是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + public String checkRoleNameUnique(SysRole role); + + /** + * 校验角色权限是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + public String checkRoleKeyUnique(SysRole role); + + /** + * 校验角色是否允许操作 + * + * @param role 角色信息 + */ + public void checkRoleAllowed(SysRole role); + + /** + * 校验角色是否有数据权限 + * + * @param roleId 角色id + */ + public void checkRoleDataScope(Long roleId); + + /** + * 通过角色ID查询角色使用数量 + * + * @param roleId 角色ID + * @return 结果 + */ + public int countUserRoleByRoleId(Long roleId); + + /** + * 新增保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int insertRole(SysRole role); + + /** + * 修改保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int updateRole(SysRole role); + + /** + * 修改保存角色信息 app + * + * @param role 角色信息 + * @return 结果 + */ + public int updateAppRole(SysRole role); + + /** + * 修改角色状态 + * + * @param role 角色信息 + * @return 结果 + */ + public int updateRoleStatus(SysRole role); + + /** + * 修改数据权限信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int authDataScope(SysRole role); + + /** + * 通过角色ID删除角色 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleById(Long roleId); + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + public int deleteRoleByIds(Long[] roleIds); + + /** + * 取消授权用户角色 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + public int deleteAuthUser(SysUserRole userRole); + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要取消授权的用户数据ID + * @return 结果 + */ + public int deleteAuthUsers(Long roleId, Long[] userIds); + + /** + * 批量选择授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要删除的用户数据ID + * @return 结果 + */ + public int insertAuthUsers(Long roleId, Long[] userIds); + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java new file mode 100644 index 0000000..8eb5448 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java @@ -0,0 +1,48 @@ +package com.ruoyi.system.service; + +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.system.domain.SysUserOnline; + +/** + * 在线用户 服务层 + * + * @author ruoyi + */ +public interface ISysUserOnlineService +{ + /** + * 通过登录地址查询信息 + * + * @param ipaddr 登录地址 + * @param user 用户信息 + * @return 在线用户信息 + */ + public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user); + + /** + * 通过用户名称查询信息 + * + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + public SysUserOnline selectOnlineByUserName(String userName, LoginUser user); + + /** + * 通过登录地址/用户名称查询信息 + * + * @param ipaddr 登录地址 + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user); + + /** + * 设置在线用户信息 + * + * @param user 用户信息 + * @return 在线用户 + */ + public SysUserOnline loginUserToUserOnline(LoginUser user); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java new file mode 100644 index 0000000..e6a0d0d --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java @@ -0,0 +1,267 @@ +package com.ruoyi.system.service; + +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.system.domain.vo.SysUserInfoVo; +import com.ruoyi.system.domain.vo.UserTypeInfoVO; + +import java.util.HashMap; +import java.util.List; + +/** + * 用户 业务层 + * + * @author ruoyi + */ +public interface ISysUserService +{ + + public List selectUserListALL(SysUser sysUser); + + + /** + * 根据条件分页查询用户列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUserList(SysUser user); + + /** + * 根据条件分页查询用户列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public HashMap> selectUserSpecList(SysUser user); + + /** + * 根据条件分页查询已分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectAllocatedList(SysUser user); + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUnallocatedList(SysUser user); + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByUserName(String userName); + + /** + * 通过用户昵称查询用户 + * + * @param nickName 昵称 + * @return 用户对象信息 + */ + public List selectUserByNickName(String nickName); + + /** + * 通过用户昵称和手机号查询用户 + * + * @param nickName 昵称 + * @return 用户对象信息 + */ + public SysUser selectUserByNickNameAndPhone(String nickName,String phone); + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + public SysUser selectUserById(Long userId); + + + public SysUser selectAllUserById(Long userId); + + /** + * 通过用户IDs查询用户 + * + * @param userIds 用户ID + * @return 用户对象信息 + */ + public List selectUserByIds(List userIds); + + /** + * 通过角色ids与场馆id查询用户 + */ + public List selectUserByRoleIdsAndSceneId(Long[] roleIds,Long sceneId); + + + public SysUser selectUserByPhone(String phone); + + public List selectUserListByPhones(String[] phones); + + /** + * 根据用户ID查询用户所属角色组 + * + * @param userName 用户名 + * @return 结果 + */ + public String selectUserRoleGroup(String userName); + + /** + * 根据用户ID查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + public String selectUserPostGroup(String userName); + + /** + * 校验用户名称是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public String checkUserNameUnique(SysUser user); + + /** + * 校验手机号码是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public String checkPhoneUnique(SysUser user); + + /** + * 校验email是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public String checkEmailUnique(SysUser user); + + /** + * 校验用户是否允许操作 + * + * @param user 用户信息 + */ + public void checkUserAllowed(SysUser user); + + /** + * 校验用户是否有数据权限 + * + * @param userId 用户id + */ + public void checkUserDataScope(Long userId); + + /** + * 新增用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int insertUser(SysUser user); + + /** + * 注册用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean registerUser(SysUser user); + + /** + * 修改用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUser(SysUser user); + + /** + * 用户授权角色 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + public void insertUserAuth(Long userId, Long[] roleIds); + + /** + * 修改用户状态 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUserStatus(SysUser user); + + /** + * 修改用户基本信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUserProfile(SysUser user); + + + public int updateUserLogin(SysUser user); + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + public boolean updateUserAvatar(String userName, String avatar); + + /** + * 重置用户密码 + * + * @param user 用户信息 + * @return 结果 + */ + public int resetPwd(SysUser user); + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + public int resetUserPwd(String userName, String password); + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserById(Long userId); + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + public int deleteUserByIds(Long[] userIds); + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + public String importUser(List userList, Boolean isUpdateSupport, String operName); + + + public SysUserInfoVo getUserInfo(String userName); + + List selectUserByUserType(); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysAppMenuServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysAppMenuServiceImpl.java new file mode 100644 index 0000000..8ac4596 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysAppMenuServiceImpl.java @@ -0,0 +1,549 @@ +package com.ruoyi.system.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.domain.TreeSelect; +import com.ruoyi.common.core.domain.entity.SysAppMenu; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.domain.SysAppUserMenu; +import com.ruoyi.system.domain.vo.MetaVo; +import com.ruoyi.system.domain.vo.RouterVo; +import com.ruoyi.system.mapper.*; +import com.ruoyi.system.service.ISysAppMenuService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 菜单 业务层处理 + * + * @author ruoyi + */ +@Service +@Slf4j +public class SysAppMenuServiceImpl implements ISysAppMenuService { + public static final String PREMISSION_STRING = "perms[\"{0}\"]"; + + @Autowired + private SysAppMenuMapper appMenuMapper; + + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysAppRoleMenuMapper appRoleMenuMapper; + + @Autowired + private SysAppUserMenuMapper appUserMenuMapper; + + @Autowired + private SysUserMapper sysUserMapper; + + /** 文件访问地址前缀 */ + @Value("${file.visitpath}") + private String visitpath; + + /** + * 根据用户查询系统菜单列表 + * + * @param userId 用户ID + * @return 菜单列表 + */ + @Override + public List selectMenuList(Long userId) { + return selectMenuList(new SysAppMenu(), userId); + } + + /** + * 查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + @Override + public List selectMenuList(SysAppMenu menu, Long userId) { + List menuList = null; + + //根据专业去除告警菜单 + SysUser user = sysUserMapper.selectUserById(userId); + + // 管理员显示所有菜单信息 + if (SysUser.isAdmin(userId)) { + menuList = appMenuMapper.selectMenuList(menu); + } else { + menu.getParams().put("userId", userId); + menuList = appMenuMapper.selectMenuListByUserId(menu); + } + //拼接Url +// for (SysAppMenu sysAppMenu : menuList) { +// sysAppMenu.setIcon(visitpath+sysAppMenu.getIcon()); +// } + String userType = user.getUserType(); + List alarmMenus = menuList.stream().filter(l -> l.getParentId() == 101 && !"挂起".equals(l.getMenuName()) && !"亚运事件".equals(l.getMenuName()) && !"告警闭环".equals(l.getMenuName())).collect(Collectors.toList()); + if ("wx".equals(userType)) { + alarmMenus.removeIf(l -> "无线告警".equals(l.getMenuName())); + menuList.removeAll(alarmMenus); + } + if ("cs".equals(userType)) { + alarmMenus.removeIf(l -> "传输告警".equals(l.getMenuName())); + menuList.removeAll(alarmMenus); + } + if ("dh".equals(userType)) { + alarmMenus.removeIf(l -> "动环告警".equals(l.getMenuName())); + menuList.removeAll(alarmMenus); + } + if ("zw".equals(userType)) { + alarmMenus.removeIf(l -> "AGIS告警".equals(l.getMenuName()) || "互联网告警".equals(l.getMenuName()) || "固话告警".equals(l.getMenuName())); + menuList.removeAll(alarmMenus); + } + return menuList; + } + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + @Override + public Set selectMenuPermsByUserId(Long userId) { + List perms = appMenuMapper.selectMenuPermsByUserId(userId); + Set permsSet = new HashSet<>(); + for (String perm : perms) { + if (StringUtils.isNotEmpty(perm)) { + permsSet.addAll(Arrays.asList(perm.trim().split(","))); + } + } + return permsSet; + } + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + @Override + public Set selectMenuPermsByRoleId(Long roleId) { + List perms = appMenuMapper.selectMenuPermsByRoleId(roleId); + Set permsSet = new HashSet<>(); + for (String perm : perms) { + if (StringUtils.isNotEmpty(perm)) { + permsSet.addAll(Arrays.asList(perm.trim().split(","))); + } + } + return permsSet; + } + + /** + * 根据用户ID查询菜单 + * + * @param userId 用户名称 + * @return 菜单列表 + */ + @Override + public List selectMenuTreeByUserId(Long userId) { + List menus = null; + if (SecurityUtils.isAdmin(userId)) { + menus = appMenuMapper.selectMenuTreeAll(); + } else { + menus = appMenuMapper.selectMenuTreeByUserId(userId); + } + return getChildPerms(menus, 0); + } + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @return 选中菜单列表 + */ + @Override + public List selectMenuListByRoleId(Long roleId,Boolean menuCheckStrictly) { + SysRole role = roleMapper.selectRoleById(roleId); + return appMenuMapper.selectMenuListByRoleId(roleId, menuCheckStrictly); + } + + /** + * 构建前端路由所需要的菜单 + * + * @param menus 菜单列表 + * @return 路由列表 + */ + @Override + public List buildMenus(List menus) { + List routers = new LinkedList(); + for (SysAppMenu menu : menus) { + RouterVo router = new RouterVo(); + router.setHidden("1".equals(menu.getVisible())); + router.setName(getRouteName(menu)); + router.setPath(getRouterPath(menu)); + router.setComponent(getComponent(menu)); + router.setQuery(menu.getQuery()); + router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + List cMenus = menu.getChildren(); + if (!cMenus.isEmpty() && cMenus.size() > 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType())) { + router.setAlwaysShow(true); + router.setRedirect("noRedirect"); + router.setChildren(buildMenus(cMenus)); + } else if (isMenuFrame(menu)) { + router.setMeta(null); + List childrenList = new ArrayList(); + RouterVo children = new RouterVo(); + children.setPath(menu.getPath()); + children.setComponent(menu.getComponent()); + children.setName(StringUtils.capitalize(menu.getPath())); + children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + children.setQuery(menu.getQuery()); + childrenList.add(children); + router.setChildren(childrenList); + } else if (menu.getParentId().intValue() == 0 && isInnerLink(menu)) { + router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon())); + router.setPath("/"); + List childrenList = new ArrayList(); + RouterVo children = new RouterVo(); + String routerPath = innerLinkReplaceEach(menu.getPath()); + children.setPath(routerPath); + children.setComponent(UserConstants.INNER_LINK); + children.setName(StringUtils.capitalize(routerPath)); + children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath())); + childrenList.add(children); + router.setChildren(childrenList); + } + routers.add(router); + } + return routers; + } + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + @Override + public List buildMenuTree(List menus) { + List returnList = new ArrayList(); + List tempList = menus.stream().map(SysAppMenu::getMenuId).collect(Collectors.toList()); + for (Iterator iterator = menus.iterator(); iterator.hasNext(); ) { + SysAppMenu menu = (SysAppMenu) iterator.next(); + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(menu.getParentId())) { + recursionFn(menus, menu); + returnList.add(menu); + } + } + if (returnList.isEmpty()) { + returnList = menus; + } + return returnList; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + @Override + public List buildMenuTreeSelect(List menus) { + List menuTrees = buildMenuTree(menus); + return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + @Override + public SysAppMenu selectMenuById(Long menuId) { + return appMenuMapper.selectMenuById(menuId); + } + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public boolean hasChildByMenuId(Long menuId) { + int result = appMenuMapper.hasChildByMenuId(menuId); + return result > 0; + } + + /** + * 查询菜单使用数量 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public boolean checkMenuExistRole(Long menuId) { + int result = appRoleMenuMapper.checkMenuExistRole(menuId); + return result > 0; + } + + /** + * 新增保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public int insertMenu(SysAppMenu menu) { + return appMenuMapper.insertMenu(menu); + } + + /** + * 修改保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public int updateMenu(SysAppMenu menu) { + return appMenuMapper.updateMenu(menu); + } + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public int deleteMenuById(Long menuId) { + return appMenuMapper.deleteMenuById(menuId); + } + + /** + * 校验菜单名称是否唯一 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public String checkMenuNameUnique(SysAppMenu menu) { + Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId(); + SysAppMenu info = appMenuMapper.checkMenuNameUnique(menu.getMenuName(), menu.getParentId()); + if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue()) { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + @Override + public List selectCustomList(Long userId) { + SysAppMenu sysAppMenu = new SysAppMenu(); + List allAppMenus = selectMenuList(sysAppMenu,userId); + List customAppMenus = appUserMenuMapper.selectCustomList(userId); + //为空时新增一次 + if(CollUtil.isEmpty(customAppMenus)){ + ArrayList userMenus = new ArrayList<>(); +// 签到打卡10302 我的待办10201 无线告警10101 巡检任务10402 + long[] menuIds={10302,10201,10402}; + for (long menuId : menuIds) { + SysAppUserMenu userMenu = new SysAppUserMenu(); + userMenu.setMenuId(menuId); + userMenu.setUserId(userId); + userMenus.add(userMenu); + } + log.info("新增一次首页默认展示应用"); + appUserMenuMapper.batchAppUserMenu(userMenus); + } + List customAppMenuList = appUserMenuMapper.selectCustomList(userId); + List res = allAppMenus.stream().filter(item -> customAppMenuList.stream() + .anyMatch(l -> l.getMenuId().equals(item.getMenuId()))).collect(Collectors.toList()); +// //拼接Url +// for (SysAppMenu menu : res) { +// sysAppMenu.setIcon(visitpath+menu.getIcon()); +// } + return res; + } + + @Override + public Boolean updateCustomList(Long userId, List menuIds) { + // 删除用户与菜单关联 + appUserMenuMapper.deleteAppUserMenuByUserId(userId); + // 新增用户与菜单管理 + if(CollUtil.isNotEmpty(menuIds)) { + ArrayList menus = new ArrayList<>(); + for (Long menuId : menuIds) { + SysAppUserMenu menu = new SysAppUserMenu(); + menu.setUserId(userId); + menu.setMenuId(menuId); + menus.add(menu); + } + appUserMenuMapper.batchAppUserMenu(menus); + } + return true; + } + + /** + * 获取路由名称 + * + * @param menu 菜单信息 + * @return 路由名称 + */ + public String getRouteName(SysAppMenu menu) { + String routerName = StringUtils.capitalize(menu.getPath()); + // 非外链并且是一级目录(类型为目录) + if (isMenuFrame(menu)) { + routerName = StringUtils.EMPTY; + } + return routerName; + } + + /** + * 获取路由地址 + * + * @param menu 菜单信息 + * @return 路由地址 + */ + public String getRouterPath(SysAppMenu menu) { + String routerPath = menu.getPath(); + // 内链打开外网方式 + if (menu.getParentId().intValue() != 0 && isInnerLink(menu)) { + routerPath = innerLinkReplaceEach(routerPath); + } + // 非外链并且是一级目录(类型为目录) + if (0 == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType()) + && UserConstants.NO_FRAME.equals(menu.getIsFrame())) { + routerPath = "/" + menu.getPath(); + } + // 非外链并且是一级目录(类型为菜单) + else if (isMenuFrame(menu)) { + routerPath = "/"; + } + return routerPath; + } + + /** + * 获取组件信息 + * + * @param menu 菜单信息 + * @return 组件信息 + */ + public String getComponent(SysAppMenu menu) { + String component = UserConstants.LAYOUT; + if (StringUtils.isNotEmpty(menu.getComponent()) && !isMenuFrame(menu)) { + component = menu.getComponent(); + } else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != 0 && isInnerLink(menu)) { + component = UserConstants.INNER_LINK; + } else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu)) { + component = UserConstants.PARENT_VIEW; + } + return component; + } + + /** + * 是否为菜单内部跳转 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isMenuFrame(SysAppMenu menu) { + return menu.getParentId().intValue() == 0 && UserConstants.TYPE_MENU.equals(menu.getMenuType()) + && menu.getIsFrame().equals(UserConstants.NO_FRAME); + } + + /** + * 是否为内链组件 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isInnerLink(SysAppMenu menu) { + return menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath()); + } + + /** + * 是否为parent_view组件 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isParentView(SysAppMenu menu) { + return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType()); + } + + /** + * 根据父节点的ID获取所有子节点 + * + * @param list 分类表 + * @param parentId 传入的父节点ID + * @return String + */ + public List getChildPerms(List list, int parentId) { + List returnList = new ArrayList(); + for (Iterator iterator = list.iterator(); iterator.hasNext(); ) { + SysAppMenu t = (SysAppMenu) iterator.next(); + // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点 + if (t.getParentId() == parentId) { + recursionFn(list, t); + returnList.add(t); + } + } + return returnList; + } + + /** + * 递归列表 + * + * @param list 分类表 + * @param t 子节点 + */ + private void recursionFn(List list, SysAppMenu t) { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (SysAppMenu tChild : childList) { + if (hasChild(list, tChild)) { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysAppMenu t) { + List tlist = new ArrayList(); + Iterator it = list.iterator(); + while (it.hasNext()) { + SysAppMenu n = (SysAppMenu) it.next(); + if (n.getParentId().longValue() == t.getMenuId().longValue()) { + tlist.add(n); + } + } + return tlist; + } + + /** + * 判断是否有子节点 + */ + private boolean hasChild(List list, SysAppMenu t) { + return getChildList(list, t).size() > 0; + } + + /** + * 内链域名特殊字符替换 + * + * @return 替换后的内链域名 + */ + public String innerLinkReplaceEach(String path) { + return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, "."}, + new String[]{"", "", "", "/"}); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java new file mode 100644 index 0000000..7b6d566 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java @@ -0,0 +1,236 @@ +package com.ruoyi.system.service.impl; + +import java.util.Collection; +import java.util.List; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.annotation.DataSource; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.enums.DataSourceType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.domain.SysConfig; +import com.ruoyi.system.mapper.SysConfigMapper; +import com.ruoyi.system.service.ISysConfigService; + +/** + * 参数配置 服务层实现 + * + * @author ruoyi + */ +@Service +public class SysConfigServiceImpl implements ISysConfigService +{ + @Autowired + private SysConfigMapper configMapper; + + @Autowired + private RedisCache redisCache; + + /** + * 项目启动时,初始化参数到缓存 + */ + @PostConstruct + public void init() + { + loadingConfigCache(); + } + + /** + * 查询参数配置信息 + * + * @param configId 参数配置ID + * @return 参数配置信息 + */ + @Override + @DataSource(DataSourceType.MASTER) + public SysConfig selectConfigById(Long configId) + { + SysConfig config = new SysConfig(); + config.setConfigId(configId); + return configMapper.selectConfig(config); + } + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数key + * @return 参数键值 + */ + @Override + public String selectConfigByKey(String configKey) + { + String configValue = Convert.toStr(redisCache.getCacheObject(getCacheKey(configKey))); + if (StringUtils.isNotEmpty(configValue)) + { + return configValue; + } + SysConfig config = new SysConfig(); + config.setConfigKey(configKey); + SysConfig retConfig = configMapper.selectConfig(config); + if (StringUtils.isNotNull(retConfig)) + { + redisCache.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue()); + return retConfig.getConfigValue(); + } + return StringUtils.EMPTY; + } + + /** + * 获取验证码开关 + * + * @return true开启,false关闭 + */ + @Override + public boolean selectCaptchaEnabled() + { + String captchaEnabled = selectConfigByKey("sys.account.captchaEnabled"); + if (StringUtils.isEmpty(captchaEnabled)) + { + return true; + } + return Convert.toBool(captchaEnabled); + } + + @Override + public boolean selectDistinctEnabled() { + String captchaEnabled = selectConfigByKey("sys.account.distinctEnabled"); + if (StringUtils.isEmpty(captchaEnabled)) + { + return true; + } + return Convert.toBool(captchaEnabled); + } + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + @Override + public List selectConfigList(SysConfig config) + { + return configMapper.selectConfigList(config); + } + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public int insertConfig(SysConfig config) + { + int row = configMapper.insertConfig(config); + if (row > 0) + { + redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + return row; + } + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public int updateConfig(SysConfig config) + { + int row = configMapper.updateConfig(config); + if (row > 0) + { + redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + return row; + } + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + */ + @Override + public void deleteConfigByIds(Long[] configIds) + { + for (Long configId : configIds) + { + SysConfig config = selectConfigById(configId); + if (StringUtils.equals(UserConstants.YES, config.getConfigType())) + { + throw new ServiceException(String.format("内置参数【%1$s】不能删除 ", config.getConfigKey())); + } + configMapper.deleteConfigById(configId); + redisCache.deleteObject(getCacheKey(config.getConfigKey())); + } + } + + /** + * 加载参数缓存数据 + */ + @Override + public void loadingConfigCache() + { + List configsList = configMapper.selectConfigList(new SysConfig()); + for (SysConfig config : configsList) + { + redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + } + + /** + * 清空参数缓存数据 + */ + @Override + public void clearConfigCache() + { + Collection keys = redisCache.keys(CacheConstants.SYS_CONFIG_KEY + "*"); + redisCache.deleteObject(keys); + } + + /** + * 重置参数缓存数据 + */ + @Override + public void resetConfigCache() + { + clearConfigCache(); + loadingConfigCache(); + } + + /** + * 校验参数键名是否唯一 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public String checkConfigKeyUnique(SysConfig config) + { + Long configId = StringUtils.isNull(config.getConfigId()) ? -1L : config.getConfigId(); + SysConfig info = configMapper.checkConfigKeyUnique(config.getConfigKey()); + if (StringUtils.isNotNull(info) && info.getConfigId().longValue() != configId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 设置cache key + * + * @param configKey 参数键 + * @return 缓存键key + */ + private String getCacheKey(String configKey) + { + return CacheConstants.SYS_CONFIG_KEY + configKey; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java new file mode 100644 index 0000000..bdd0df7 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java @@ -0,0 +1,338 @@ +package com.ruoyi.system.service.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.annotation.DataScope; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.domain.TreeSelect; +import com.ruoyi.common.core.domain.entity.SysDept; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.system.mapper.SysDeptMapper; +import com.ruoyi.system.mapper.SysRoleMapper; +import com.ruoyi.system.service.ISysDeptService; + +/** + * 部门管理 服务实现 + * + * @author ruoyi + */ +@Service +public class SysDeptServiceImpl implements ISysDeptService +{ + @Autowired + private SysDeptMapper deptMapper; + + @Autowired + private SysRoleMapper roleMapper; + + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + @Override + @DataScope(deptAlias = "d") + public List selectDeptList(SysDept dept) + { + return deptMapper.selectDeptList(dept); + } + + /** + * 查询部门树结构信息 + * + * @param dept 部门信息 + * @return 部门树信息集合 + */ + @Override + public List selectDeptTreeList(SysDept dept) + { + List depts = SpringUtils.getAopProxy(this).selectDeptList(dept); + return buildDeptTreeSelect(depts); + } + + /** + * 构建前端所需要树结构 + * + * @param depts 部门列表 + * @return 树结构列表 + */ + @Override + public List buildDeptTree(List depts) + { + List returnList = new ArrayList(); + List tempList = depts.stream().map(SysDept::getDeptId).collect(Collectors.toList()); + for (SysDept dept : depts) + { + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(dept.getParentId())) + { + recursionFn(depts, dept); + returnList.add(dept); + } + } + if (returnList.isEmpty()) + { + returnList = depts; + } + return returnList; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param depts 部门列表 + * @return 下拉树结构列表 + */ + @Override + public List buildDeptTreeSelect(List depts) + { + List deptTrees = buildDeptTree(depts); + return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @return 选中部门列表 + */ + @Override + public List selectDeptListByRoleId(Long roleId) + { + SysRole role = roleMapper.selectRoleById(roleId); + return deptMapper.selectDeptListByRoleId(roleId, role.isDeptCheckStrictly()); + } + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + @Override + public SysDept selectDeptById(Long deptId) + { + return deptMapper.selectDeptById(deptId); + } + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + @Override + public int selectNormalChildrenDeptById(Long deptId) + { + return deptMapper.selectNormalChildrenDeptById(deptId); + } + + /** + * 是否存在子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + @Override + public boolean hasChildByDeptId(Long deptId) + { + int result = deptMapper.hasChildByDeptId(deptId); + return result > 0; + } + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 true 存在 false 不存在 + */ + @Override + public boolean checkDeptExistUser(Long deptId) + { + int result = deptMapper.checkDeptExistUser(deptId); + return result > 0; + } + + /** + * 校验部门名称是否唯一 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public String checkDeptNameUnique(SysDept dept) + { + Long deptId = StringUtils.isNull(dept.getDeptId()) ? -1L : dept.getDeptId(); + SysDept info = deptMapper.checkDeptNameUnique(dept.getDeptName(), dept.getParentId()); + if (StringUtils.isNotNull(info) && info.getDeptId().longValue() != deptId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验部门是否有数据权限 + * + * @param deptId 部门id + */ + @Override + public void checkDeptDataScope(Long deptId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + SysDept dept = new SysDept(); + dept.setDeptId(deptId); + List depts = SpringUtils.getAopProxy(this).selectDeptList(dept); + if (StringUtils.isEmpty(depts)) + { + throw new ServiceException("没有权限访问部门数据!"); + } + } + } + + /** + * 新增保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public int insertDept(SysDept dept) + { + SysDept info = deptMapper.selectDeptById(dept.getParentId()); + // 如果父节点不为正常状态,则不允许新增子节点 + if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) + { + throw new ServiceException("部门停用,不允许新增"); + } + dept.setAncestors(info.getAncestors() + "," + dept.getParentId()); + return deptMapper.insertDept(dept); + } + + /** + * 修改保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public int updateDept(SysDept dept) + { + SysDept newParentDept = deptMapper.selectDeptById(dept.getParentId()); + SysDept oldDept = deptMapper.selectDeptById(dept.getDeptId()); + if (StringUtils.isNotNull(newParentDept) && StringUtils.isNotNull(oldDept)) + { + String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getDeptId(); + String oldAncestors = oldDept.getAncestors(); + dept.setAncestors(newAncestors); + updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors); + } + int result = deptMapper.updateDept(dept); + if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors()) + && !StringUtils.equals("0", dept.getAncestors())) + { + // 如果该部门是启用状态,则启用该部门的所有上级部门 + updateParentDeptStatusNormal(dept); + } + return result; + } + + /** + * 修改该部门的父级部门状态 + * + * @param dept 当前部门 + */ + private void updateParentDeptStatusNormal(SysDept dept) + { + String ancestors = dept.getAncestors(); + Long[] deptIds = Convert.toLongArray(ancestors); + deptMapper.updateDeptStatusNormal(deptIds); + } + + /** + * 修改子元素关系 + * + * @param deptId 被修改的部门ID + * @param newAncestors 新的父ID集合 + * @param oldAncestors 旧的父ID集合 + */ + public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) + { + List children = deptMapper.selectChildrenDeptById(deptId); + for (SysDept child : children) + { + child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors)); + } + if (children.size() > 0) + { + deptMapper.updateDeptChildren(children); + } + } + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + @Override + public int deleteDeptById(Long deptId) + { + return deptMapper.deleteDeptById(deptId); + } + + /** + * 递归列表 + */ + private void recursionFn(List list, SysDept t) + { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (SysDept tChild : childList) + { + if (hasChild(list, tChild)) + { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysDept t) + { + List tlist = new ArrayList(); + Iterator it = list.iterator(); + while (it.hasNext()) + { + SysDept n = (SysDept) it.next(); + if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue()) + { + tlist.add(n); + } + } + return tlist; + } + + /** + * 判断是否有子节点 + */ + private boolean hasChild(List list, SysDept t) + { + return getChildList(list, t).size() > 0; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java new file mode 100644 index 0000000..212ea5a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java @@ -0,0 +1,123 @@ +package com.ruoyi.system.service.impl; + +import java.util.List; + +import com.ruoyi.common.utils.SecurityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.system.mapper.SysDictDataMapper; +import com.ruoyi.system.service.ISysDictDataService; + +/** + * 字典 业务层处理 + * + * @author ruoyi + */ +@Service +public class SysDictDataServiceImpl implements ISysDictDataService +{ + @Autowired + private SysDictDataMapper dictDataMapper; + + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + @Override + public List selectDictDataList(SysDictData dictData) + { + return dictDataMapper.selectDictDataList(dictData); + } + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + @Override + public String selectDictLabel(String dictType, String dictValue) + { + return dictDataMapper.selectDictLabel(dictType, dictValue); + } + + @Override + public String selectDictValue(String dictType, String dictLable) { + return dictDataMapper.selectDictValue(dictType, dictLable); + } + + @Override + public List selectDictLabelByValues(String dictType, List dictValues) { + return dictDataMapper.selectDictLabelByValues(dictType, dictValues); + } + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + @Override + public SysDictData selectDictDataById(Long dictCode) + { + return dictDataMapper.selectDictDataById(dictCode); + } + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + */ + @Override + public void deleteDictDataByIds(Long[] dictCodes) + { + for (Long dictCode : dictCodes) + { + SysDictData data = selectDictDataById(dictCode); + dictDataMapper.deleteDictDataById(dictCode); + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + } + + /** + * 新增保存字典数据信息 + * + * @param data 字典数据信息 + * @return 结果 + */ + @Override + public int insertDictData(SysDictData data) + { + int row = dictDataMapper.insertDictData(data); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + return row; + } + + /** + * 修改保存字典数据信息 + * + * @param data 字典数据信息 + * @return 结果 + */ + @Override + public int updateDictData(SysDictData data) + { + int row = dictDataMapper.updateDictData(data); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + return row; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java new file mode 100644 index 0000000..605beed --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java @@ -0,0 +1,234 @@ +package com.ruoyi.system.service.impl; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.domain.entity.SysDictType; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.mapper.SysDictDataMapper; +import com.ruoyi.system.mapper.SysDictTypeMapper; +import com.ruoyi.system.service.ISysDictTypeService; + +/** + * 字典 业务层处理 + * + * @author ruoyi + */ +@Service +public class SysDictTypeServiceImpl implements ISysDictTypeService +{ + @Autowired + private SysDictTypeMapper dictTypeMapper; + + @Autowired + private SysDictDataMapper dictDataMapper; + + /** + * 项目启动时,初始化字典到缓存 + */ + @PostConstruct + public void init() + { + loadingDictCache(); + } + + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + @Override + public List selectDictTypeList(SysDictType dictType) + { + return dictTypeMapper.selectDictTypeList(dictType); + } + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + @Override + public List selectDictTypeAll() + { + return dictTypeMapper.selectDictTypeAll(); + } + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + @Override + public List selectDictDataByType(String dictType) + { + List dictDatas = DictUtils.getDictCache(dictType); + if (StringUtils.isNotEmpty(dictDatas)) + { + return dictDatas; + } + dictDatas = dictDataMapper.selectDictDataByType(dictType); + if (StringUtils.isNotEmpty(dictDatas)) + { + DictUtils.setDictCache(dictType, dictDatas); + return dictDatas; + } + return null; + } + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + @Override + public SysDictType selectDictTypeById(Long dictId) + { + return dictTypeMapper.selectDictTypeById(dictId); + } + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + @Override + public SysDictType selectDictTypeByType(String dictType) + { + return dictTypeMapper.selectDictTypeByType(dictType); + } + + /** + * 批量删除字典类型信息 + * + * @param dictIds 需要删除的字典ID + */ + @Override + public void deleteDictTypeByIds(Long[] dictIds) + { + for (Long dictId : dictIds) + { + SysDictType dictType = selectDictTypeById(dictId); + if (dictDataMapper.countDictDataByType(dictType.getDictType()) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName())); + } + dictTypeMapper.deleteDictTypeById(dictId); + DictUtils.removeDictCache(dictType.getDictType()); + } + } + + /** + * 加载字典缓存数据 + */ + @Override + public void loadingDictCache() + { + SysDictData dictData = new SysDictData(); + dictData.setStatus("0"); + Map> dictDataMap = dictDataMapper.selectDictDataList(dictData).stream().collect(Collectors.groupingBy(SysDictData::getDictType)); + for (Map.Entry> entry : dictDataMap.entrySet()) + { + DictUtils.setDictCache(entry.getKey(), entry.getValue().stream().sorted(Comparator.comparing(SysDictData::getDictSort)).collect(Collectors.toList())); + } + } + + /** + * 清空字典缓存数据 + */ + @Override + public void clearDictCache() + { + DictUtils.clearDictCache(); + } + + /** + * 重置字典缓存数据 + */ + @Override + public void resetDictCache() + { + clearDictCache(); + loadingDictCache(); + } + + /** + * 新增保存字典类型信息 + * + * @param dict 字典类型信息 + * @return 结果 + */ + @Override + public int insertDictType(SysDictType dict) + { + int row = dictTypeMapper.insertDictType(dict); + if (row > 0) + { + DictUtils.setDictCache(dict.getDictType(), null); + } + return row; + } + + /** + * 修改保存字典类型信息 + * + * @param dict 字典类型信息 + * @return 结果 + */ + @Override + @Transactional + public int updateDictType(SysDictType dict) + { + SysDictType oldDict = dictTypeMapper.selectDictTypeById(dict.getDictId()); + dictDataMapper.updateDictDataType(oldDict.getDictType(), dict.getDictType()); + int row = dictTypeMapper.updateDictType(dict); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(dict.getDictType()); + DictUtils.setDictCache(dict.getDictType(), dictDatas); + } + return row; + } + + /** + * 校验字典类型称是否唯一 + * + * @param dict 字典类型 + * @return 结果 + */ + @Override + public String checkDictTypeUnique(SysDictType dict) + { + Long dictId = StringUtils.isNull(dict.getDictId()) ? -1L : dict.getDictId(); + SysDictType dictType = dictTypeMapper.checkDictTypeUnique(dict.getDictType()); + if (StringUtils.isNotNull(dictType) && dictType.getDictId().longValue() != dictId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 根据字典类型城市查询下属区域 + * + * @param cityValue 城市 + * @return 结果 + */ + @Override + public List selectCountyByCity(String cityValue) { + return dictDataMapper.selectCountyByCity(cityValue); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java new file mode 100644 index 0000000..216aecb --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java @@ -0,0 +1,65 @@ +package com.ruoyi.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.system.domain.SysLogininfor; +import com.ruoyi.system.mapper.SysLogininforMapper; +import com.ruoyi.system.service.ISysLogininforService; + +/** + * 系统访问日志情况信息 服务层处理 + * + * @author ruoyi + */ +@Service +public class SysLogininforServiceImpl implements ISysLogininforService +{ + + @Autowired + private SysLogininforMapper logininforMapper; + + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + @Override + public void insertLogininfor(SysLogininfor logininfor) + { + logininforMapper.insertLogininfor(logininfor); + } + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + @Override + public List selectLogininforList(SysLogininfor logininfor) + { + return logininforMapper.selectLogininforList(logininfor); + } + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + @Override + public int deleteLogininforByIds(Long[] infoIds) + { + return logininforMapper.deleteLogininforByIds(infoIds); + } + + /** + * 清空系统登录日志 + */ + @Override + public void cleanLogininfor() + { + logininforMapper.cleanLogininfor(); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java new file mode 100644 index 0000000..7c59a61 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java @@ -0,0 +1,536 @@ +package com.ruoyi.system.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.domain.TreeSelect; +import com.ruoyi.common.core.domain.entity.SysMenu; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.domain.vo.MetaVo; +import com.ruoyi.system.domain.vo.RouterVo; +import com.ruoyi.system.mapper.SysMenuMapper; +import com.ruoyi.system.mapper.SysRoleMapper; +import com.ruoyi.system.mapper.SysRoleMenuMapper; +import com.ruoyi.system.service.ISysMenuService; + +/** + * 菜单 业务层处理 + * + * @author ruoyi + */ +@Service +public class SysMenuServiceImpl implements ISysMenuService +{ + public static final String PREMISSION_STRING = "perms[\"{0}\"]"; + + @Autowired + private SysMenuMapper menuMapper; + + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysRoleMenuMapper roleMenuMapper; + + /** + * 根据用户查询系统菜单列表 + * + * @param userId 用户ID + * @return 菜单列表 + */ + @Override + public List selectMenuList(Long userId) + { + return selectMenuList(new SysMenu(), userId); + } + + /** + * 查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + @Override + public List selectMenuList(SysMenu menu, Long userId) + { + List menuList = null; + // 管理员显示所有菜单信息 + if (SysUser.isAdmin(userId)) + { + menuList = menuMapper.selectMenuList(menu); + } + else + { + menu.getParams().put("userId", userId); + menuList = menuMapper.selectMenuListByUserId(menu); + } + return menuList; + } + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + @Override + public Set selectMenuPermsByUserId(Long userId) + { + List perms = menuMapper.selectMenuPermsByUserId(userId); + Set permsSet = new HashSet<>(); + for (String perm : perms) + { + if (StringUtils.isNotEmpty(perm)) + { + permsSet.addAll(Arrays.asList(perm.trim().split(","))); + } + } + return permsSet; + } + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + @Override + public Set selectMenuPermsByRoleId(Long roleId) + { + List perms = menuMapper.selectMenuPermsByRoleId(roleId); + Set permsSet = new HashSet<>(); + for (String perm : perms) + { + if (StringUtils.isNotEmpty(perm)) + { + permsSet.addAll(Arrays.asList(perm.trim().split(","))); + } + } + return permsSet; + } + + /** + * 根据用户ID查询菜单 + * + * @param userId 用户名称 + * @return 菜单列表 + */ + @Override + public List selectMenuTreeByUserId(Long userId) + { + List menus = null; + if (SecurityUtils.isAdmin(userId)) + { + menus = menuMapper.selectMenuTreeAll(); + } + else + { + menus = menuMapper.selectMenuTreeByUserId(userId); + } + return getChildPerms(menus, 0); + } + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @return 选中菜单列表 + */ + @Override + public List selectMenuListByRoleId(Long roleId,Boolean menuCheckStrictly) + { + SysRole role = roleMapper.selectRoleById(roleId); + return menuMapper.selectMenuListByRoleId(roleId, menuCheckStrictly); + } + + @Override + public List selectMenuNameListByRoleId(Long roleId) { + return menuMapper.selectMenuNameListByRoleId(roleId); + } + + /** + * 构建前端路由所需要的菜单 + * + * @param menus 菜单列表 + * @return 路由列表 + */ + @Override + public List buildMenus(List menus) + { + List routers = new LinkedList(); + for (SysMenu menu : menus) + { + RouterVo router = new RouterVo(); + router.setHidden("1".equals(menu.getVisible())); + router.setName(getRouteName(menu)); + router.setPath(getRouterPath(menu)); + router.setComponent(getComponent(menu)); + router.setQuery(menu.getQuery()); + router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + List cMenus = menu.getChildren(); + if (!cMenus.isEmpty() && cMenus.size() > 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType())) + { + router.setAlwaysShow(true); + router.setRedirect("noRedirect"); + router.setChildren(buildMenus(cMenus)); + } + else if (isMenuFrame(menu)) + { + router.setMeta(null); + List childrenList = new ArrayList(); + RouterVo children = new RouterVo(); + children.setPath(menu.getPath()); + children.setComponent(menu.getComponent()); + children.setName(StringUtils.capitalize(menu.getPath())); + children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + children.setQuery(menu.getQuery()); + childrenList.add(children); + router.setChildren(childrenList); + } + else if (menu.getParentId().intValue() == 0 && isInnerLink(menu)) + { + router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon())); + router.setPath("/"); + List childrenList = new ArrayList(); + RouterVo children = new RouterVo(); + String routerPath = innerLinkReplaceEach(menu.getPath()); + children.setPath(routerPath); + children.setComponent(UserConstants.INNER_LINK); + children.setName(StringUtils.capitalize(routerPath)); + children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath())); + childrenList.add(children); + router.setChildren(childrenList); + } + routers.add(router); + } + return routers; + } + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + @Override + public List buildMenuTree(List menus) + { + List returnList = new ArrayList(); + List tempList = menus.stream().map(SysMenu::getMenuId).collect(Collectors.toList()); + for (Iterator iterator = menus.iterator(); iterator.hasNext();) + { + SysMenu menu = (SysMenu) iterator.next(); + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(menu.getParentId())) + { + recursionFn(menus, menu); + returnList.add(menu); + } + } + if (returnList.isEmpty()) + { + returnList = menus; + } + return returnList; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + @Override + public List buildMenuTreeSelect(List menus) + { + List menuTrees = buildMenuTree(menus); + return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + @Override + public SysMenu selectMenuById(Long menuId) + { + return menuMapper.selectMenuById(menuId); + } + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public boolean hasChildByMenuId(Long menuId) + { + int result = menuMapper.hasChildByMenuId(menuId); + return result > 0; + } + + /** + * 查询菜单使用数量 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public boolean checkMenuExistRole(Long menuId) + { + int result = roleMenuMapper.checkMenuExistRole(menuId); + return result > 0; + } + + /** + * 新增保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public int insertMenu(SysMenu menu) + { + return menuMapper.insertMenu(menu); + } + + /** + * 修改保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public int updateMenu(SysMenu menu) + { + return menuMapper.updateMenu(menu); + } + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public int deleteMenuById(Long menuId) + { + return menuMapper.deleteMenuById(menuId); + } + + /** + * 校验菜单名称是否唯一 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public String checkMenuNameUnique(SysMenu menu) + { + Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId(); + SysMenu info = menuMapper.checkMenuNameUnique(menu.getMenuName(), menu.getParentId()); + if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 获取路由名称 + * + * @param menu 菜单信息 + * @return 路由名称 + */ + public String getRouteName(SysMenu menu) + { + String routerName = StringUtils.capitalize(menu.getPath()); + // 非外链并且是一级目录(类型为目录) + if (isMenuFrame(menu)) + { + routerName = StringUtils.EMPTY; + } + return routerName; + } + + /** + * 获取路由地址 + * + * @param menu 菜单信息 + * @return 路由地址 + */ + public String getRouterPath(SysMenu menu) + { + String routerPath = menu.getPath(); + // 内链打开外网方式 + if (menu.getParentId().intValue() != 0 && isInnerLink(menu)) + { + routerPath = innerLinkReplaceEach(routerPath); + } + // 非外链并且是一级目录(类型为目录) + if (0 == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType()) + && UserConstants.NO_FRAME.equals(menu.getIsFrame())) + { + routerPath = "/" + menu.getPath(); + } + // 非外链并且是一级目录(类型为菜单) + else if (isMenuFrame(menu)) + { + routerPath = "/"; + } + return routerPath; + } + + /** + * 获取组件信息 + * + * @param menu 菜单信息 + * @return 组件信息 + */ + public String getComponent(SysMenu menu) + { + String component = UserConstants.LAYOUT; + if (StringUtils.isNotEmpty(menu.getComponent()) && !isMenuFrame(menu)) + { + component = menu.getComponent(); + } + else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != 0 && isInnerLink(menu)) + { + component = UserConstants.INNER_LINK; + } + else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu)) + { + component = UserConstants.PARENT_VIEW; + } + return component; + } + + /** + * 是否为菜单内部跳转 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isMenuFrame(SysMenu menu) + { + return menu.getParentId().intValue() == 0 && UserConstants.TYPE_MENU.equals(menu.getMenuType()) + && menu.getIsFrame().equals(UserConstants.NO_FRAME); + } + + /** + * 是否为内链组件 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isInnerLink(SysMenu menu) + { + return menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath()); + } + + /** + * 是否为parent_view组件 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isParentView(SysMenu menu) + { + return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType()); + } + + /** + * 根据父节点的ID获取所有子节点 + * + * @param list 分类表 + * @param parentId 传入的父节点ID + * @return String + */ + public List getChildPerms(List list, int parentId) + { + List returnList = new ArrayList(); + for (Iterator iterator = list.iterator(); iterator.hasNext();) + { + SysMenu t = (SysMenu) iterator.next(); + // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点 + if (t.getParentId() == parentId) + { + recursionFn(list, t); + returnList.add(t); + } + } + return returnList; + } + + /** + * 递归列表 + * + * @param list 分类表 + * @param t 子节点 + */ + private void recursionFn(List list, SysMenu t) + { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (SysMenu tChild : childList) + { + if (hasChild(list, tChild)) + { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysMenu t) + { + List tlist = new ArrayList(); + Iterator it = list.iterator(); + while (it.hasNext()) + { + SysMenu n = (SysMenu) it.next(); + if (n.getParentId().longValue() == t.getMenuId().longValue()) + { + tlist.add(n); + } + } + return tlist; + } + + /** + * 判断是否有子节点 + */ + private boolean hasChild(List list, SysMenu t) + { + return getChildList(list, t).size() > 0; + } + + /** + * 内链域名特殊字符替换 + * + * @return 替换后的内链域名 + */ + public String innerLinkReplaceEach(String path) + { + return StringUtils.replaceEach(path, new String[] { Constants.HTTP, Constants.HTTPS, Constants.WWW, "." }, + new String[] { "", "", "", "/" }); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java new file mode 100644 index 0000000..5489815 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java @@ -0,0 +1,76 @@ +package com.ruoyi.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.system.domain.SysOperLog; +import com.ruoyi.system.mapper.SysOperLogMapper; +import com.ruoyi.system.service.ISysOperLogService; + +/** + * 操作日志 服务层处理 + * + * @author ruoyi + */ +@Service +public class SysOperLogServiceImpl implements ISysOperLogService +{ + @Autowired + private SysOperLogMapper operLogMapper; + + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + */ + @Override + public void insertOperlog(SysOperLog operLog) + { + operLogMapper.insertOperlog(operLog); + } + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + @Override + public List selectOperLogList(SysOperLog operLog) + { + return operLogMapper.selectOperLogList(operLog); + } + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + @Override + public int deleteOperLogByIds(Long[] operIds) + { + return operLogMapper.deleteOperLogByIds(operIds); + } + + /** + * 查询操作日志详细 + * + * @param operId 操作ID + * @return 操作日志对象 + */ + @Override + public SysOperLog selectOperLogById(Long operId) + { + return operLogMapper.selectOperLogById(operId); + } + + /** + * 清空操作日志 + */ + @Override + public void cleanOperLog() + { + operLogMapper.cleanOperLog(); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java new file mode 100644 index 0000000..78f1cb7 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java @@ -0,0 +1,178 @@ +package com.ruoyi.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.domain.SysPost; +import com.ruoyi.system.mapper.SysPostMapper; +import com.ruoyi.system.mapper.SysUserPostMapper; +import com.ruoyi.system.service.ISysPostService; + +/** + * 岗位信息 服务层处理 + * + * @author ruoyi + */ +@Service +public class SysPostServiceImpl implements ISysPostService +{ + @Autowired + private SysPostMapper postMapper; + + @Autowired + private SysUserPostMapper userPostMapper; + + /** + * 查询岗位信息集合 + * + * @param post 岗位信息 + * @return 岗位信息集合 + */ + @Override + public List selectPostList(SysPost post) + { + return postMapper.selectPostList(post); + } + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + @Override + public List selectPostAll() + { + return postMapper.selectPostAll(); + } + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + @Override + public SysPost selectPostById(Long postId) + { + return postMapper.selectPostById(postId); + } + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + @Override + public List selectPostListByUserId(Long userId) + { + return postMapper.selectPostListByUserId(userId); + } + + /** + * 校验岗位名称是否唯一 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public String checkPostNameUnique(SysPost post) + { + Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId(); + SysPost info = postMapper.checkPostNameUnique(post.getPostName()); + if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验岗位编码是否唯一 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public String checkPostCodeUnique(SysPost post) + { + Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId(); + SysPost info = postMapper.checkPostCodeUnique(post.getPostCode()); + if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 通过岗位ID查询岗位使用数量 + * + * @param postId 岗位ID + * @return 结果 + */ + @Override + public int countUserPostById(Long postId) + { + return userPostMapper.countUserPostById(postId); + } + + /** + * 删除岗位信息 + * + * @param postId 岗位ID + * @return 结果 + */ + @Override + public int deletePostById(Long postId) + { + return postMapper.deletePostById(postId); + } + + /** + * 批量删除岗位信息 + * + * @param postIds 需要删除的岗位ID + * @return 结果 + */ + @Override + public int deletePostByIds(Long[] postIds) + { + for (Long postId : postIds) + { + SysPost post = selectPostById(postId); + if (countUserPostById(postId) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", post.getPostName())); + } + } + return postMapper.deletePostByIds(postIds); + } + + /** + * 新增保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public int insertPost(SysPost post) + { + return postMapper.insertPost(post); + } + + /** + * 修改保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public int updatePost(SysPost post) + { + return postMapper.updatePost(post); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java new file mode 100644 index 0000000..f8f41db --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java @@ -0,0 +1,508 @@ +package com.ruoyi.system.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import cn.hutool.core.util.ArrayUtil; +import com.ruoyi.system.domain.SysAppRoleMenu; +import com.ruoyi.system.mapper.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.ruoyi.common.annotation.DataScope; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.system.domain.SysRoleDept; +import com.ruoyi.system.domain.SysRoleMenu; +import com.ruoyi.system.domain.SysUserRole; +import com.ruoyi.system.service.ISysRoleService; + +/** + * 角色 业务层处理 + * + * @author ruoyi + */ +@Service +@Slf4j +public class SysRoleServiceImpl implements ISysRoleService +{ + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysRoleMenuMapper roleMenuMapper; + + @Autowired + private SysAppRoleMenuMapper appRoleMenuMapper; + + @Autowired + private SysUserRoleMapper userRoleMapper; + + @Autowired + private SysRoleDeptMapper roleDeptMapper; + + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + @Override + @DataScope(deptAlias = "d") + public List selectRoleList(SysRole role) + { + return roleMapper.selectRoleList(role); + } + + /** + * 根据用户ID查询角色 + * + * @param userId 用户ID + * @return 角色列表 + */ + @Override + public List selectRolesByUserId(Long userId) + { + List userRoles = roleMapper.selectRolePermissionByUserId(userId); + List roles = selectRoleAll(); + for (SysRole role : roles) + { + for (SysRole userRole : userRoles) + { + if (role.getRoleId().longValue() == userRole.getRoleId().longValue()) + { + role.setFlag(true); + break; + } + } + } + return roles; + } + + @Override + public List selectNameByUserId(Long userId) { + return roleMapper.selectNameByUserId(userId); + } + + @Override + public List selectRolesByUserId2(Long userId) { + List userRoles = roleMapper.selectRolePermissionByUserId(userId); + return userRoles; + } + + @Override + public List selectRolesByUserIds(List userIds) { + return userRoleMapper.selectRolePermissionByUserIds(userIds); + } + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + @Override + public Set selectRolePermissionByUserId(Long userId) + { + List perms = roleMapper.selectRolePermissionByUserId(userId); + Set permsSet = new HashSet<>(); + for (SysRole perm : perms) + { + if (StringUtils.isNotNull(perm)) + { + permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(","))); + } + } + return permsSet; + } + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + @Override + public List selectRoleAll() + { + return SpringUtils.getAopProxy(this).selectRoleList(new SysRole()); + } + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + @Override + public List selectRoleListByUserId(Long userId) + { + return roleMapper.selectRoleListByUserId(userId); + } + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + @Override + public SysRole selectRoleById(Long roleId) + { + return roleMapper.selectRoleById(roleId); + } + + /** + * 校验角色名称是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public String checkRoleNameUnique(SysRole role) + { + Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId(); + SysRole info = roleMapper.checkRoleNameUnique(role.getRoleName()); + if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验角色权限是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public String checkRoleKeyUnique(SysRole role) + { + Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId(); + SysRole info = roleMapper.checkRoleKeyUnique(role.getRoleKey()); + if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验角色是否允许操作 + * + * @param role 角色信息 + */ + @Override + public void checkRoleAllowed(SysRole role) + { + if (StringUtils.isNotNull(role.getRoleId()) && role.isAdmin()) + { + throw new ServiceException("不允许操作超级管理员角色"); + } + } + + /** + * 校验角色是否有数据权限 + * + * @param roleId 角色id + */ + @Override + public void checkRoleDataScope(Long roleId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + SysRole role = new SysRole(); + role.setRoleId(roleId); + List roles = SpringUtils.getAopProxy(this).selectRoleList(role); + if (StringUtils.isEmpty(roles)) + { + throw new ServiceException("没有权限访问角色数据!"); + } + } + } + + /** + * 通过角色ID查询角色使用数量 + * + * @param roleId 角色ID + * @return 结果 + */ + @Override + public int countUserRoleByRoleId(Long roleId) + { + return userRoleMapper.countUserRoleByRoleId(roleId); + } + + /** + * 新增保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional + public int insertRole(SysRole role) + { + // 新增角色信息 + roleMapper.insertRole(role); + return insertRoleMenu(role); + } + + /** + * 修改保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional + public int updateRole(SysRole role) + { + // 修改角色信息 + roleMapper.updateRole(role); + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenuByRoleId(role.getRoleId()); + // 删除角色与app菜单关联 + appRoleMenuMapper.deleteAppRoleMenuByRoleId(role.getRoleId()); + return insertRoleMenu(role); + } + + /** + * app修改保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional + public int updateAppRole(SysRole role) + { + // 修改角色信息 + roleMapper.updateRole(role); + // 删除角色与菜单关联 + appRoleMenuMapper.deleteAppRoleMenuByRoleId(role.getRoleId()); + return insertAppRoleMenu(role); + } + + /** + * 修改角色状态 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public int updateRoleStatus(SysRole role) + { + return roleMapper.updateRole(role); + } + + /** + * 修改数据权限信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional + public int authDataScope(SysRole role) + { + // 修改角色信息 + roleMapper.updateRole(role); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDeptByRoleId(role.getRoleId()); + // 新增角色和部门信息(数据权限) + return insertRoleDept(role); + } + + /** + * 新增角色菜单信息 + * + * @param role 角色对象 + */ + public int insertRoleMenu(SysRole role) + { + int rows = 1; + // 新增用户与角色管理 + List list = new ArrayList(); + for (Long menuId : role.getMenuIds()) + { + SysRoleMenu rm = new SysRoleMenu(); + rm.setRoleId(role.getRoleId()); + rm.setMenuId(menuId); + list.add(rm); + } + if (list.size() > 0) + { + rows = roleMenuMapper.batchRoleMenu(list); + } + + // 新增app菜单与角色管理 + if(ArrayUtil.isNotEmpty(role.getAppMenuIds())) { + List appList = new ArrayList(); + for (Long appMenuId : role.getAppMenuIds()) { + SysAppRoleMenu rm = new SysAppRoleMenu(); + rm.setRoleId(role.getRoleId()); + rm.setMenuId(appMenuId); + appList.add(rm); + } + if (appList.size() > 0) { + rows = appRoleMenuMapper.batchAppRoleMenu(appList); + } + } + return rows; + } + + /** + * 新增角色菜单信息 app + * + * @param role 角色对象 + */ + public int insertAppRoleMenu(SysRole role) + { + int rows = 1; + // 新增用户与角色管理 + List list = new ArrayList(); + for (Long menuId : role.getMenuIds()) + { + SysAppRoleMenu rm = new SysAppRoleMenu(); + rm.setRoleId(role.getRoleId()); + rm.setMenuId(menuId); + list.add(rm); + } + if (list.size() > 0) + { + rows = appRoleMenuMapper.batchAppRoleMenu(list); + } + return rows; + } + + /** + * 新增角色部门信息(数据权限) + * + * @param role 角色对象 + */ + public int insertRoleDept(SysRole role) + { + int rows = 1; + // 新增角色与部门(数据权限)管理 + List list = new ArrayList(); + for (Long deptId : role.getDeptIds()) + { + SysRoleDept rd = new SysRoleDept(); + rd.setRoleId(role.getRoleId()); + rd.setDeptId(deptId); + list.add(rd); + } + if (list.size() > 0) + { + rows = roleDeptMapper.batchRoleDept(list); + } + return rows; + } + + /** + * 通过角色ID删除角色 + * + * @param roleId 角色ID + * @return 结果 + */ + @Override + @Transactional + public int deleteRoleById(Long roleId) + { + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenuByRoleId(roleId); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDeptByRoleId(roleId); + return roleMapper.deleteRoleById(roleId); + } + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + @Override + @Transactional + public int deleteRoleByIds(Long[] roleIds) + { + for (Long roleId : roleIds) + { + checkRoleAllowed(new SysRole(roleId)); + checkRoleDataScope(roleId); + SysRole role = selectRoleById(roleId); + if (countUserRoleByRoleId(roleId) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", role.getRoleName())); + } + } + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenu(roleIds); + // 删除角色与app菜单关联 + appRoleMenuMapper.deleteAppRoleMenu(roleIds); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDept(roleIds); + return roleMapper.deleteRoleByIds(roleIds); + } + + /** + * 取消授权用户角色 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + @Override + public int deleteAuthUser(SysUserRole userRole) + { + String userName = SecurityUtils.getUsername(); + log.info(userName + "删除用户角色,参数:" + userRole); + return userRoleMapper.deleteUserRoleInfo(userRole); + } + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要取消授权的用户数据ID + * @return 结果 + */ + @Override + public int deleteAuthUsers(Long roleId, Long[] userIds) + { + String userName = SecurityUtils.getUsername(); + log.info(userName + "删除用户角色,参数:" + roleId + ", " + userIds); + return userRoleMapper.deleteUserRoleInfos(roleId, userIds); + } + + /** + * 批量选择授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要授权的用户数据ID + * @return 结果 + */ + @Override + public int insertAuthUsers(Long roleId, Long[] userIds) + { + // 新增用户与角色管理 + List list = new ArrayList(); + for (Long userId : userIds) + { + SysUserRole ur = new SysUserRole(); + ur.setUserId(userId); + ur.setRoleId(roleId); + list.add(ur); + } + return userRoleMapper.batchUserRole(list); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java new file mode 100644 index 0000000..aaa10ce --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java @@ -0,0 +1,97 @@ +package com.ruoyi.system.service.impl; + +import org.springframework.stereotype.Service; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.domain.SysUserOnline; +import com.ruoyi.system.service.ISysUserOnlineService; + +/** + * 在线用户 服务层处理 + * + * @author ruoyi + */ +@Service +public class SysUserOnlineServiceImpl implements ISysUserOnlineService +{ + /** + * 通过登录地址查询信息 + * + * @param ipaddr 登录地址 + * @param user 用户信息 + * @return 在线用户信息 + */ + @Override + public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user) + { + if (StringUtils.equals(ipaddr, user.getIpaddr())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 通过用户名称查询信息 + * + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + @Override + public SysUserOnline selectOnlineByUserName(String userName, LoginUser user) + { + if (StringUtils.equals(userName, user.getUsername())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 通过登录地址/用户名称查询信息 + * + * @param ipaddr 登录地址 + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + @Override + public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user) + { + if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 设置在线用户信息 + * + * @param user 用户信息 + * @return 在线用户 + */ + @Override + public SysUserOnline loginUserToUserOnline(LoginUser user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUser())) + { + return null; + } + SysUserOnline sysUserOnline = new SysUserOnline(); + sysUserOnline.setTokenId(user.getToken()); + sysUserOnline.setUserId(user.getUserId()); + sysUserOnline.setUserName(user.getUsername()); + sysUserOnline.setIpaddr(user.getIpaddr()); + sysUserOnline.setLoginLocation(user.getLoginLocation()); + sysUserOnline.setBrowser(user.getBrowser()); + sysUserOnline.setOs(user.getOs()); + sysUserOnline.setLoginTime(user.getLoginTime()); + if (StringUtils.isNotNull(user.getUser().getDept())) + { + sysUserOnline.setDeptName(user.getUser().getDept().getDeptName()); + } + return sysUserOnline; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..7f64ff7 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java @@ -0,0 +1,780 @@ +package com.ruoyi.system.service.impl; + +import cn.hutool.core.util.PhoneUtil; +import com.github.pagehelper.util.StringUtil; +import com.ruoyi.common.annotation.DataScope; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanValidators; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.system.domain.SysPost; +import com.ruoyi.system.domain.SysUserPost; +import com.ruoyi.system.domain.SysUserRole; +import com.ruoyi.system.domain.vo.SysUserInfoVo; +import com.ruoyi.system.domain.vo.UserTypeInfoVO; +import com.ruoyi.system.mapper.*; +import com.ruoyi.system.service.ISysConfigService; +import com.ruoyi.system.service.ISysUserService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import javax.validation.Validator; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 用户 业务层处理 + * + * @author ruoyi + */ +@Service +public class SysUserServiceImpl implements ISysUserService +{ + private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class); + + @Autowired + private SysUserMapper userMapper; + + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysPostMapper postMapper; + + @Autowired + private SysUserRoleMapper userRoleMapper; + + @Autowired + private SysUserPostMapper userPostMapper; + + @Autowired + private SysUserVenueMapper userVenueMapper; + + @Autowired + private ISysConfigService configService; + + @Autowired + private SysDictDataMapper dictData; + + @Autowired + protected Validator validator; + + @Autowired + private RedisCache redisCache; + + + @Override + public List selectUserListALL(SysUser sysUser) { + return userMapper.selectUserALL(sysUser); + } + + /** + * 根据条件分页查询用户列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectUserList(SysUser user) + { + return userMapper.selectUserList(user); + } + + @Override + public HashMap> selectUserSpecList(SysUser user) { + + if(StringUtils.isNotEmpty(user.getUserVenueId())) { + if (!StringUtils.isNum(user.getUserVenueId())) { + throw new ServiceException("传入的场馆ID有问题"); + } + } + HashMap> mapSysUser=new HashMap>(); + + List lstDict = dictData.selectDictDataByType("yw_specialty"); + + for(SysDictData dict : lstDict) + { + if(!mapSysUser.containsKey(dict.getDictValue())) + { + mapSysUser.put(dict.getDictValue(),new ArrayList()); + } + +// SysUser user=new SysUser(); + + user.setUserType(dict.getDictValue()); + + List lstUser = userMapper.selectUserList(user); + + for(SysUser sysUser : lstUser) + { + //不要显示冻结的 + if("2".equals(sysUser.getStatus())) + { + continue; + } + mapSysUser.get(dict.getDictValue()).add(sysUser); + } + + } + + //把没有专业的用户加上 + mapSysUser.put("noSpec",new ArrayList()); + mapSysUser.put("noSpec",userMapper.selectNoSpecUserList(user)); + + return mapSysUser; + } + + /** + * 根据条件分页查询已分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectAllocatedList(SysUser user) + { + return userMapper.selectAllocatedList(user); + } + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectUnallocatedList(SysUser user) + { + return userMapper.selectUnallocatedList(user); + } + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + @Override + public SysUser selectUserByUserName(String userName) + { + return userMapper.selectUserByUserName(userName); + } + + @Override + public List selectUserByNickName(String nickName) { + return userMapper.selectUserByNickName(nickName); + } + + @Override + public SysUser selectUserByNickNameAndPhone(String nickName, String phone) { + return userMapper.selectUserByNickNameAndPhone(nickName,phone); + } + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + @Override + public SysUser selectUserById(Long userId) + { + return userMapper.selectUserById(userId); + } + + @Override + public SysUser selectAllUserById(Long userId) { + return userMapper.selectAllUserById(userId); + } + + @Override + public List selectUserByIds(List userIds) { + return userMapper.selectUserByIds(userIds); + } + + @Override + public List selectUserByRoleIdsAndSceneId(Long[] roleIds, Long sceneId) { + return userMapper.selectUserByRoleIdsAndSceneId(roleIds,sceneId); + } + + @Override + public SysUser selectUserByPhone(String phone) { + return userMapper.selectUserByPhone(phone); + } + + @Override + public List selectUserListByPhones(String[] phones) { + return userMapper.selectUserListByPhones(phones); + } + + /** + * 查询用户所属角色组 + * + * @param userName 用户名 + * @return 结果 + */ + @Override + public String selectUserRoleGroup(String userName) + { + List list = roleMapper.selectRolesByUserName(userName); + if (CollectionUtils.isEmpty(list)) + { + return StringUtils.EMPTY; + } + return list.stream().map(SysRole::getRoleName).collect(Collectors.joining(",")); + } + + /** + * 查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + @Override + public String selectUserPostGroup(String userName) + { + List list = postMapper.selectPostsByUserName(userName); + if (CollectionUtils.isEmpty(list)) + { + return StringUtils.EMPTY; + } + return list.stream().map(SysPost::getPostName).collect(Collectors.joining(",")); + } + + /** + * 校验用户名称是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public String checkUserNameUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkUserNameUnique(user.getUserName()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验手机号码是否唯一 + * + * @param user 用户信息 + * @return + */ + @Override + public String checkPhoneUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验email是否唯一 + * + * @param user 用户信息 + * @return + */ + @Override + public String checkEmailUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkEmailUnique(user.getEmail()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验用户是否允许操作 + * + * @param user 用户信息 + */ + @Override + public void checkUserAllowed(SysUser user) + { + if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) + { + throw new ServiceException("不允许操作超级管理员用户"); + } + } + + /** + * 校验用户是否有数据权限 + * + * @param userId 用户id + */ + @Override + public void checkUserDataScope(Long userId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + SysUser user = new SysUser(); + user.setUserId(userId); + List users = SpringUtils.getAopProxy(this).selectUserList(user); + if (StringUtils.isEmpty(users)) + { + throw new ServiceException("没有权限访问用户数据!"); + } + } + } + + /** + * 新增保存用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + @Transactional + public int insertUser(SysUser user) + { + // 新增用户信息 + int rows = userMapper.insertUser(user); + // 新增用户岗位关联 + insertUserPost(user); + // 新增用户与角色管理 + insertUserRole(user); + return rows; + } + + /** + * 注册用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public boolean registerUser(SysUser user) + { + return userMapper.insertUser(user) > 0; + } + + /** + * 修改保存用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + @Transactional + public int updateUser(SysUser user) + { + Long userId = user.getUserId(); + String userName = SecurityUtils.getUsername(); + log.info(userName + "删除用户角色,参数:" + user); + + // 删除用户与角色关联 + userRoleMapper.deleteUserRoleByUserId(userId); + // 新增用户与角色管理 + insertUserRole(user); + // 删除用户与岗位关联 + userPostMapper.deleteUserPostByUserId(userId); + // 新增用户与岗位管理 + insertUserPost(user); + return userMapper.updateUser(user); + } + + /** + * 用户授权角色 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + @Override + @Transactional + public void insertUserAuth(Long userId, Long[] roleIds) + { + String userName = SecurityUtils.getUsername(); + log.info(userName + "删除用户角色,参数:" + userId + ", " + roleIds); + + userRoleMapper.deleteUserRoleByUserId(userId); + insertUserRole(userId, roleIds); + } + + /** + * 修改用户状态 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int updateUserStatus(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 修改用户基本信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int updateUserProfile(SysUser user) + { + return userMapper.updateUser(user); + } + + @Override + public int updateUserLogin(SysUser user) + { + return userMapper.updateUserLogin(user); + } + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + @Override + public boolean updateUserAvatar(String userName, String avatar) + { + return userMapper.updateUserAvatar(userName, avatar) > 0; + } + + /** + * 重置用户密码 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int resetPwd(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + @Override + public int resetUserPwd(String userName, String password) + { + return userMapper.resetUserPwd(userName, password); + } + + /** + * 新增用户角色信息 + * + * @param user 用户对象 + */ + public void insertUserRole(SysUser user) + { + this.insertUserRole(user.getUserId(), user.getRoleIds()); + } + + /** + * 新增用户岗位信息 + * + * @param user 用户对象 + */ + public void insertUserPost(SysUser user) + { + Long[] posts = user.getPostIds(); + if (StringUtils.isNotEmpty(posts)) + { + // 新增用户与岗位管理 + List list = new ArrayList(posts.length); + for (Long postId : posts) + { + SysUserPost up = new SysUserPost(); + up.setUserId(user.getUserId()); + up.setPostId(postId); + list.add(up); + } + userPostMapper.batchUserPost(list); + } + } + + /** + * 新增用户角色信息 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + public void insertUserRole(Long userId, Long[] roleIds) + { + if (StringUtils.isNotEmpty(roleIds)) + { + // 新增用户与角色管理 + List list = new ArrayList(roleIds.length); + for (Long roleId : roleIds) + { + SysUserRole ur = new SysUserRole(); + ur.setUserId(userId); + ur.setRoleId(roleId); + list.add(ur); + } + userRoleMapper.batchUserRole(list); + } + } + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + @Override + @Transactional + public int deleteUserById(Long userId) + { + String userName = SecurityUtils.getUsername(); + log.info(userName + "删除用户角色,参数:" + userId); + // 删除用户与角色关联 + userRoleMapper.deleteUserRoleByUserId(userId); + // 删除用户与岗位表 + userPostMapper.deleteUserPostByUserId(userId); + return userMapper.deleteUserById(userId); + } + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + @Override + @Transactional + public int deleteUserByIds(Long[] userIds) + { + for (Long userId : userIds) + { + checkUserAllowed(new SysUser(userId)); + checkUserDataScope(userId); + } + String userName = SecurityUtils.getUsername(); + log.info(userName + "删除用户角色,参数:" + userIds); + // 删除用户与角色关联 + userRoleMapper.deleteUserRole(userIds); + // 删除用户与岗位关联 + userPostMapper.deleteUserPost(userIds); + // 删除用户与场馆关联 + userVenueMapper.deleteUserVenue(userIds); + + //删除处理用户登录的缓存 + Collection keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); + //找到登录用户 + for (Long userId : userIds) { + for (String key : keys) { + LoginUser redisUser = redisCache.getCacheObject(key); + if (redisUser.getUserId().equals(userId)) { + redisCache.deleteObject(key); + } + } + } + return userMapper.deleteUserByIds(userIds); + } + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + @Override + public String importUser(List userList, Boolean isUpdateSupport, String operName) + { + if (StringUtils.isNull(userList) || userList.size() == 0) + { + throw new ServiceException("导入用户数据不能为空!"); + } + int successNum = 0; + int failureNum = 0; + int userNum=0; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder(); + String password = configService.selectConfigByKey("sys.user.initPassword"); + for (SysUser user : userList) + { + try + { + if ( StringUtil.isEmpty(user.getPhonenumber()) ) { + throw new ServiceException("手机号码不能为空"); + } + + if ( StringUtil.isEmpty(user.getNickName()) ) { + throw new ServiceException("姓名不能为空"); + } + + if (!PhoneUtil.isMobile(user.getPhonenumber())) { + throw new ServiceException("手机号码格式不正确"); + } + + //设置登录用户名为手机号码 + if(StringUtils.isEmpty(user.getUserName())) + { + user.setUserName(user.getPhonenumber()); + } + + if(StringUtils.isNotEmpty(user.getUserType())) + { + //转用户专业 + String value = DictUtils.getDictValue("yw_specialty", user.getUserType()); + if(StringUtils.isNotEmpty(value)) + { + user.setUserType(value); + } + else + { + throw new ServiceException("专业匹配不正确!"); + } + } + else { + throw new ServiceException("专业不能为空!"); + } + + if(StringUtils.isNotEmpty(user.getCity())) + { + //转用户city + String value = DictUtils.getDictValue("yw_city", user.getCity()); + if(StringUtils.isNotEmpty(value)) + { + user.setCity(value); + } + else + { + throw new ServiceException("地市匹配不正确!"); + } + } + + if(StringUtils.isNotEmpty(user.getCounty())) + { + //转用户county + String value = DictUtils.getDictValue("yw_county", user.getCounty()); + if(StringUtils.isNotEmpty(value)) + { + user.setCounty(value); + } + else + { + throw new ServiceException("县区匹配不正确!"); + } + } + if(StringUtils.isNotEmpty(user.getDistinctArea())) + { + //转用户场馆分区 + String value = DictUtils.getDictValue("yw_belong_area", user.getDistinctArea()); + if(StringUtils.isNotEmpty(value)) + { + user.setDistinctArea(value); + } + else + { + throw new ServiceException("场馆分区匹配不正确!"); + } + } + + // 验证是否存在这个用户 +// SysUser u = userMapper.selectUserByUserName(user.getUserName()); + SysUser u = userMapper.selectUserByPhone(user.getPhonenumber()); + + if (StringUtils.isNull(u)) + { + + if(!"0".equals(user.getStatus())) + { + throw new ServiceException("用户状态必须为正常"); + } + + BeanValidators.validateWithException(validator, user); + user.setPassword(SecurityUtils.encryptPassword(password)); + user.setCreateBy(operName); + this.insertUser(user); + successNum++; + successMsg.append("
" + successNum + "、手机号码 " + user.getPhonenumber() + " 导入成功"); + } + else if (isUpdateSupport) + { + if("1".equals(user.getStatus())) + { + throw new ServiceException("不允许将用户状态修改为锁定"); + } + + //设置用户ID,现在用户ID不一定正确,看存在用户手机号码 + user.setUserId(u.getUserId()); + BeanValidators.validateWithException(validator, user); + checkUserAllowed(user); + checkUserDataScope(user.getUserId()); + user.setUpdateBy(operName); + this.updateUser(user); + successNum++; + successMsg.append("
" + successNum + "、手机号码 " + user.getPhonenumber() + " 更新成功"); + } + else + { + failureNum++; + failureMsg.append("
" + failureNum + "、手机号码 " + user.getPhonenumber() + " 已存在"); + } + } + catch (Exception e) + { + failureNum++; + String msg = "
" + failureNum + "、第 " + userNum + "列 导入失败:"; + failureMsg.append(msg + e.getMessage()); + log.error(msg, e); + } + finally { + userNum++; + } + } + if (failureNum > 0) + { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new ServiceException(failureMsg.toString()); + } + else + { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + } + return successMsg.toString(); + } + + @Override + public SysUserInfoVo getUserInfo(String userName) { + return userMapper.getUserInfo(userName); + } + + @Override + public List selectUserByUserType() { + return userMapper.selectUserByUserType(); + } +} diff --git a/ruoyi-system/src/main/resources/mapper/system/SysAppMenuMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysAppMenuMapper.xml new file mode 100644 index 0000000..3ee4062 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysAppMenuMapper.xml @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, coalesce(perms,'') as perms, icon,icon2, create_time + from sys_app_menu + + + + + + + + + + + + + + + + + + + + + + + + + + + update sys_app_menu + + menu_name = #{menuName}, + parent_id = #{parentId}, + order_num = #{orderNum}, + path = #{path}, + component = #{component}, + query = #{query}, + is_frame = #{isFrame}, + is_cache = #{isCache}, + menu_type = #{menuType}, + visible = #{visible}, + status = #{status}, + perms = #{perms}, + icon = #{icon}, + icon2 = #{icon2}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = now() + + where menu_id = #{menuId} + + + + insert into sys_app_menu( + + parent_id, + menu_name, + order_num, + path, + component, + query, + is_frame, + is_cache, + menu_type, + visible, + status, + perms, + icon, + icon2, + remark, + create_by, + create_time + )values( + + #{parentId}, + #{menuName}, + #{orderNum}, + #{path}, + #{component}, + #{query}, + #{isFrame}, + #{isCache}, + #{menuType}, + #{visible}, + #{status}, + #{perms}, + #{icon}, + #{icon2}, + #{remark}, + #{createBy}, + now() + ) + + + + delete from sys_app_menu where menu_id = #{menuId} + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysAppRoleMenuMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysAppRoleMenuMapper.xml new file mode 100644 index 0000000..cf74a03 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysAppRoleMenuMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + delete from sys_app_role_menu where role_id=#{roleId} + + + + delete from sys_app_role_menu where role_id in + + #{roleId} + + + + + insert into sys_app_role_menu(role_id, menu_id) values + + (#{item.roleId},#{item.menuId}) + + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysAppUserMenuMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysAppUserMenuMapper.xml new file mode 100644 index 0000000..bc9036d --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysAppUserMenuMapper.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + delete from sys_app_user_menu where user_id=#{userId} + + + + delete from sys_app_user_menu where user_id in + + #{ids} + + + + + insert into sys_app_user_menu(user_id, menu_id) values + + (#{item.userId},#{item.menuId}) + + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml new file mode 100644 index 0000000..4763eae --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + select config_id, config_name, config_key, config_value, config_type, create_by, create_time, update_by, update_time, remark + from sys_config + + + + + + + and config_id = #{configId} + + + and config_key = #{configKey} + + + + + + + + + + + + insert into sys_config ( + config_name, + config_key, + config_value, + config_type, + create_by, + remark, + create_time + )values( + #{configName}, + #{configKey}, + #{configValue}, + #{configType}, + #{createBy}, + #{remark}, + now() + ) + + + + update sys_config + + config_name = #{configName}, + config_key = #{configKey}, + config_value = #{configValue}, + config_type = #{configType}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = now() + + where config_id = #{configId} + + + + delete from sys_config where config_id = #{configId} + + + + delete from sys_config where config_id in + + #{configId} + + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml new file mode 100644 index 0000000..53dfe57 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time + from sys_dept d + + + + + + + + + + + + + + + + + + + + insert into sys_dept( + + parent_id, + dept_name, + ancestors, + order_num, + leader, + phone, + email, + status, + create_by, + create_time + )values( + + #{parentId}, + #{deptName}, + #{ancestors}, + #{orderNum}, + #{leader}, + #{phone}, + #{email}, + #{status}, + #{createBy}, + now() + ) + + + + update sys_dept + + parent_id = #{parentId}, + dept_name = #{deptName}, + ancestors = #{ancestors}, + order_num = #{orderNum}, + leader = #{leader}, + phone = #{phone}, + email = #{email}, + status = #{status}, + update_by = #{updateBy}, + update_time = now() + + where dept_id = #{deptId} + + + + update sys_dept set ancestors = + + when #{item.deptId} then #{item.ancestors} + + where dept_id in + + #{item.deptId} + + + + + update sys_dept set status = '0' where dept_id in + + #{deptId} + + + + + update sys_dept set del_flag = '2' where dept_id = #{deptId} + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml new file mode 100644 index 0000000..8b1bb76 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark + from sys_dict_data + + + + + + + + + + + + + + + + + + + + delete from sys_dict_data where dict_code = #{dictCode} + + + + delete from sys_dict_data where dict_code in + + #{dictCode} + + + + + update sys_dict_data + + dict_sort = #{dictSort}, + dict_label = #{dictLabel}, + dict_value = #{dictValue}, + dict_type = #{dictType}, + css_class = #{cssClass}, + list_class = #{listClass}, + is_default = #{isDefault}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = now() + + where dict_code = #{dictCode} + + + + update sys_dict_data set dict_type = #{newDictType} where dict_type = #{oldDictType} + + + + insert into sys_dict_data( + dict_sort, + dict_label, + dict_value, + dict_type, + css_class, + list_class, + is_default, + status, + remark, + create_by, + create_time + )values( + #{dictSort}, + #{dictLabel}, + #{dictValue}, + #{dictType}, + #{cssClass}, + #{listClass}, + #{isDefault}, + #{status}, + #{remark}, + #{createBy}, + now() + ) + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml new file mode 100644 index 0000000..9425800 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + select dict_id, dict_name, dict_type, status, create_by, create_time, remark + from sys_dict_type + + + + + + + + + + + + + + delete from sys_dict_type where dict_id = #{dictId} + + + + delete from sys_dict_type where dict_id in + + #{dictId} + + + + + update sys_dict_type + + dict_name = #{dictName}, + dict_type = #{dictType}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = now() + + where dict_id = #{dictId} + + + + insert into sys_dict_type( + dict_name, + dict_type, + status, + remark, + create_by, + create_time + )values( + #{dictName}, + #{dictType}, + #{status}, + #{remark}, + #{createBy}, + now() + ) + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml new file mode 100644 index 0000000..11da0f5 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + insert into sys_logininfor (user_name, status, ipaddr, login_location, browser, os, msg, login_time) + values (#{userName}, #{status}, #{ipaddr}, #{loginLocation}, #{browser}, #{os}, #{msg}, now()) + + + + + + delete from sys_logininfor where info_id in + + #{infoId} + + + + + delete from sys_logininfor where login_time < now() + '- 6 month' + + + + truncate table sys_logininfor + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml new file mode 100644 index 0000000..a5d4321 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, coalesce(perms,'') as perms, icon, create_time + from sys_menu + + + + + + + + + + + + + + + + + + + + + + + + + + + + update sys_menu + + menu_name = #{menuName}, + parent_id = #{parentId}, + order_num = #{orderNum}, + path = #{path}, + component = #{component}, + query = #{query}, + is_frame = #{isFrame}, + is_cache = #{isCache}, + menu_type = #{menuType}, + visible = #{visible}, + status = #{status}, + perms = #{perms}, + icon = #{icon}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = now() + + where menu_id = #{menuId} + + + + insert into sys_menu( + + parent_id, + menu_name, + order_num, + path, + component, + query, + is_frame, + is_cache, + menu_type, + visible, + status, + perms, + icon, + remark, + create_by, + create_time + )values( + + #{parentId}, + #{menuName}, + #{orderNum}, + #{path}, + #{component}, + #{query}, + #{isFrame}, + #{isCache}, + #{menuType}, + #{visible}, + #{status}, + #{perms}, + #{icon}, + #{remark}, + #{createBy}, + now() + ) + + + + delete from sys_menu where menu_id = #{menuId} + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml new file mode 100644 index 0000000..f1598d0 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select oper_id, title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time + from sys_oper_log + + + + insert into sys_oper_log(title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time) + values (#{title}, #{businessType}, #{method}, #{requestMethod}, #{operatorType}, #{operName}, #{deptName}, #{operUrl}, #{operIp}, #{operLocation}, #{operParam}, #{jsonResult}, #{status}, #{errorMsg}, now()) + + + + + + delete from sys_oper_log where oper_id in + + #{operId} + + + + + delete from sys_oper_log where oper_time < now() + '- 6 month' + + + + + + truncate table sys_oper_log + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml new file mode 100644 index 0000000..d9bd120 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + select post_id, post_code, post_name, post_sort, status, create_by, create_time, remark + from sys_post + + + + + + + + + + + + + + + + + + update sys_post + + post_code = #{postCode}, + post_name = #{postName}, + post_sort = #{postSort}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = now() + + where post_id = #{postId} + + + + insert into sys_post( + + post_code, + post_name, + post_sort, + status, + remark, + create_by, + create_time + )values( + + #{postCode}, + #{postName}, + #{postSort}, + #{status}, + #{remark}, + #{createBy}, + now() + ) + + + + delete from sys_post where post_id = #{postId} + + + + delete from sys_post where post_id in + + #{postId} + + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml new file mode 100644 index 0000000..7c4139b --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + delete from sys_role_dept where role_id=#{roleId} + + + + + + delete from sys_role_dept where role_id in + + #{roleId} + + + + + insert into sys_role_dept(role_id, dept_id) values + + (#{item.roleId},#{item.deptId}) + + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml new file mode 100644 index 0000000..0c1f445 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + select distinct r.role_id, + r.role_name, + r.role_key, + r.role_sort, + r.data_scope, + r.menu_check_strictly, + r.dept_check_strictly, + r.status, + r.del_flag, + r.create_time, + r.update_time, + r.remark + from sys_role r + left join sys_user_role ur on ur.role_id = r.role_id + left join sys_user u on u.user_id = ur.user_id + left join sys_dept d on u.dept_id = d.dept_id + + + + + + + + + + + + + + + + + + + + + insert into sys_role( + + role_name, + role_key, + role_sort, + data_scope, + menu_check_strictly, + dept_check_strictly, + status, + remark, + create_by, + create_time + )values( + + #{roleName}, + #{roleKey}, + #{roleSort}, + #{dataScope}, + #{menuCheckStrictly}, + #{deptCheckStrictly}, + #{status}, + #{remark}, + #{createBy}, + now() + ) + + + + update sys_role + + role_name = #{roleName}, + role_key = #{roleKey}, + role_sort = #{roleSort}, + data_scope = #{dataScope}, + menu_check_strictly = #{menuCheckStrictly}, + dept_check_strictly = #{deptCheckStrictly}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = now() + + where role_id = #{roleId} + + + + update sys_role + set del_flag = '2' + where role_id = #{roleId} + + + + update sys_role set del_flag = '2' where role_id in + + #{roleId} + + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml new file mode 100644 index 0000000..cb60a85 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + delete from sys_role_menu where role_id=#{roleId} + + + + delete from sys_role_menu where role_id in + + #{roleId} + + + + + insert into sys_role_menu(role_id, menu_id) values + + (#{item.roleId},#{item.menuId}) + + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml new file mode 100644 index 0000000..adc2b55 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -0,0 +1,539 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select u.user_id, + u.dept_id, + u.user_name, + u.nick_name, + u.user_type, + u.email, + u.avatar, + u.phonenumber, + u.password, + u.sex, + u.status, + u.del_flag, + u.login_ip, + u.login_date, + u.create_by, + u.create_time, + u.remark, + u.first_page, + u.city, + u.county, + u.distinct_area, + u.yw_user_belong, + d.dept_id, + d.parent_id, + d.ancestors, + d.dept_name, + d.order_num, + d.leader, + d.status as dept_status, + r.role_id, + r.role_name, + r.role_key, + r.role_sort, + r.data_scope, + r.status as role_status, + dic.dict_label as belong_area + from sys_user u + left join sys_dept d on u.dept_id = d.dept_id + left join sys_user_role ur on u.user_id = ur.user_id + left join sys_role r on r.role_id = ur.role_id + left join (SELECT sys_dict_data.dict_label, + sys_dict_data.dict_value + FROM sys_dict_data + WHERE sys_dict_data.dict_type::text = 'yw_belong_area'::text) dic + on u.distinct_area = dic.dict_value + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + insert into sys_user( + + dept_id, + user_name, + nick_name, + user_type, + email, + avatar, + phonenumber, + sex, + password, + status, + create_by, + remark, + first_page, + city, + county, + distinct_area, + yw_user_belong, + login_date, + login_ip, + update_time, + update_by, + create_time + )values( + + #{deptId}, + #{userName}, + #{nickName}, + #{userType}, + #{email}, + #{avatar}, + #{phonenumber}, + #{sex}, + #{password}, + #{status}, + #{createBy}, + #{remark}, + #{firstPage}, + #{city}, + #{county}, + #{distinctArea}, + #{ywUserBelong}, + #{loginDate}, + #{loginIp}, + #{updateTime}, + #{updateBy}, + now() + ) + + + + update sys_user + + dept_id = #{deptId}, + user_name = #{userName}, + nick_name = #{nickName}, + user_type = #{userType}, + email = #{email}, + phonenumber = #{phonenumber}, + sex = #{sex}, + avatar = #{avatar}, + password = #{password}, + status = #{status}, + login_ip = #{loginIp}, + login_date = #{loginDate}, + update_by = #{updateBy}, + remark = #{remark}, + first_page =#{firstPage}, + city = #{city}, + county = #{county}, + distinct_area = #{distinctArea}, + yw_user_belong=#{ywUserBelong}, + update_time = now() + + where user_id = #{userId} + + + + update sys_user + + + login_ip = #{loginIp}, + login_date = #{loginDate}, + + + where user_id = #{userId} + + + + update sys_user + set status = #{status} + where user_id = #{userId} + + + + update sys_user + set avatar = #{avatar} + where user_name = #{userName} + + + + update sys_user + set password = #{password} + where user_name = #{userName} + + + + update sys_user + set del_flag = '2' + where user_id = #{userId} + + + + update sys_user set del_flag = '2' where user_id in + + #{userId} + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml new file mode 100644 index 0000000..2b90bc4 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + delete from sys_user_post where user_id=#{userId} + + + + + + delete from sys_user_post where user_id in + + #{userId} + + + + + insert into sys_user_post(user_id, post_id) values + + (#{item.userId},#{item.postId}) + + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml new file mode 100644 index 0000000..40c0d32 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + delete from sys_user_role where user_id=#{userId} + + + + + + + + + + + delete from sys_user_role where user_id in + + #{userId} + + + + + insert into sys_user_role(user_id, role_id) values + + (#{item.userId},#{item.roleId}) + + + + + delete from sys_user_role where user_id=#{userId} and role_id=#{roleId} + + + + delete from sys_user_role where role_id=#{roleId} + + and user_id in + + #{userId} + + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserVenueMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserVenueMapper.xml new file mode 100644 index 0000000..be173c5 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/SysUserVenueMapper.xml @@ -0,0 +1,16 @@ + + + + + + + delete from yw_scene_user where user_id in + + #{userId} + + + + + \ No newline at end of file diff --git a/ry.bat b/ry.bat new file mode 100644 index 0000000..ac1e437 --- /dev/null +++ b/ry.bat @@ -0,0 +1,67 @@ +@echo off + +rem jarƽĿ¼ +set AppName=ruoyi-admin.jar + +rem JVM +set JVM_OPTS="-Dname=%AppName% -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC" + + +ECHO. + ECHO. [1] %AppName% + ECHO. [2] ر%AppName% + ECHO. [3] %AppName% + ECHO. [4] ״̬ %AppName% + ECHO. [5] +ECHO. + +ECHO.ѡĿ: +set /p ID= + IF "%id%"=="1" GOTO start + IF "%id%"=="2" GOTO stop + IF "%id%"=="3" GOTO restart + IF "%id%"=="4" GOTO status + IF "%id%"=="5" EXIT +PAUSE +:start + for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do ( + set pid=%%a + set image_name=%%b + ) + if defined pid ( + echo %%is running + PAUSE + ) + +start javaw %JVM_OPTS% -jar %AppName% + +echo starting +echo Start %AppName% success... +goto:eof + +rem stopͨjpspid +:stop + for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do ( + set pid=%%a + set image_name=%%b + ) + if not defined pid (echo process %AppName% does not exists) else ( + echo prepare to kill %image_name% + echo start kill %pid% ... + rem ݽIDkill + taskkill /f /pid %pid% + ) +goto:eof +:restart + call :stop + call :start +goto:eof +:status + for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do ( + set pid=%%a + set image_name=%%b + ) + if not defined pid (echo process %AppName% is dead ) else ( + echo %image_name% is running + ) +goto:eof diff --git a/ry.sh b/ry.sh new file mode 100644 index 0000000..d6a9cf3 --- /dev/null +++ b/ry.sh @@ -0,0 +1,86 @@ +#!/bin/sh +# ./ry.sh start 启动 stop 停止 restart 重启 status 状态 +AppName=ruoyi-admin.jar + +# JVM参数 +JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC" +APP_HOME=`pwd` +LOG_PATH=$APP_HOME/logs/$AppName.log + +if [ "$1" = "" ]; +then + echo -e "\033[0;31m 未输入操作名 \033[0m \033[0;34m {start|stop|restart|status} \033[0m" + exit 1 +fi + +if [ "$AppName" = "" ]; +then + echo -e "\033[0;31m 未输入应用名 \033[0m" + exit 1 +fi + +function start() +{ + PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'` + + if [ x"$PID" != x"" ]; then + echo "$AppName is running..." + else + nohup java $JVM_OPTS -jar $AppName > /dev/null 2>&1 & + echo "Start $AppName success..." + fi +} + +function stop() +{ + echo "Stop $AppName" + + PID="" + query(){ + PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'` + } + + query + if [ x"$PID" != x"" ]; then + kill -TERM $PID + echo "$AppName (pid:$PID) exiting..." + while [ x"$PID" != x"" ] + do + sleep 1 + query + done + echo "$AppName exited." + else + echo "$AppName already stopped." + fi +} + +function restart() +{ + stop + sleep 2 + start +} + +function status() +{ + PID=`ps -ef |grep java|grep $AppName|grep -v grep|wc -l` + if [ $PID != 0 ];then + echo "$AppName is running..." + else + echo "$AppName is not running..." + fi +} + +case $1 in + start) + start;; + stop) + stop;; + restart) + restart;; + status) + status;; + *) + +esac diff --git a/sql/quartz.sql b/sql/quartz.sql new file mode 100644 index 0000000..cee613b --- /dev/null +++ b/sql/quartz.sql @@ -0,0 +1,174 @@ +DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; +DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE; +DROP TABLE IF EXISTS QRTZ_LOCKS; +DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; +DROP TABLE IF EXISTS QRTZ_CALENDARS; + +-- ---------------------------- +-- 1、存储每一个已配置的 jobDetail 的详细信息 +-- ---------------------------- +create table QRTZ_JOB_DETAILS ( + sched_name varchar(120) not null comment '调度名称', + job_name varchar(200) not null comment '任务名称', + job_group varchar(200) not null comment '任务组名', + description varchar(250) null comment '相关介绍', + job_class_name varchar(250) not null comment '执行任务类名称', + is_durable varchar(1) not null comment '是否持久化', + is_nonconcurrent varchar(1) not null comment '是否并发', + is_update_data varchar(1) not null comment '是否更新数据', + requests_recovery varchar(1) not null comment '是否接受恢复执行', + job_data blob null comment '存放持久化job对象', + primary key (sched_name, job_name, job_group) +) engine=innodb comment = '任务详细信息表'; + +-- ---------------------------- +-- 2、 存储已配置的 Trigger 的信息 +-- ---------------------------- +create table QRTZ_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment '触发器的名字', + trigger_group varchar(200) not null comment '触发器所属组的名字', + job_name varchar(200) not null comment 'qrtz_job_details表job_name的外键', + job_group varchar(200) not null comment 'qrtz_job_details表job_group的外键', + description varchar(250) null comment '相关介绍', + next_fire_time bigint(13) null comment '上一次触发时间(毫秒)', + prev_fire_time bigint(13) null comment '下一次触发时间(默认为-1表示不触发)', + priority integer null comment '优先级', + trigger_state varchar(16) not null comment '触发器状态', + trigger_type varchar(8) not null comment '触发器的类型', + start_time bigint(13) not null comment '开始时间', + end_time bigint(13) null comment '结束时间', + calendar_name varchar(200) null comment '日程表名称', + misfire_instr smallint(2) null comment '补偿执行的策略', + job_data blob null comment '存放持久化job对象', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, job_name, job_group) references QRTZ_JOB_DETAILS(sched_name, job_name, job_group) +) engine=innodb comment = '触发器详细信息表'; + +-- ---------------------------- +-- 3、 存储简单的 Trigger,包括重复次数,间隔,以及已触发的次数 +-- ---------------------------- +create table QRTZ_SIMPLE_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + repeat_count bigint(7) not null comment '重复的次数统计', + repeat_interval bigint(12) not null comment '重复的间隔时间', + times_triggered bigint(10) not null comment '已经触发的次数', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = '简单触发器的信息表'; + +-- ---------------------------- +-- 4、 存储 Cron Trigger,包括 Cron 表达式和时区信息 +-- ---------------------------- +create table QRTZ_CRON_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + cron_expression varchar(200) not null comment 'cron表达式', + time_zone_id varchar(80) comment '时区', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = 'Cron类型的触发器表'; + +-- ---------------------------- +-- 5、 Trigger 作为 Blob 类型存储(用于 Quartz 用户用 JDBC 创建他们自己定制的 Trigger 类型,JobStore 并不知道如何存储实例的时候) +-- ---------------------------- +create table QRTZ_BLOB_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + blob_data blob null comment '存放持久化Trigger对象', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = 'Blob类型的触发器表'; + +-- ---------------------------- +-- 6、 以 Blob 类型存储存放日历信息, quartz可配置一个日历来指定一个时间范围 +-- ---------------------------- +create table QRTZ_CALENDARS ( + sched_name varchar(120) not null comment '调度名称', + calendar_name varchar(200) not null comment '日历名称', + calendar blob not null comment '存放持久化calendar对象', + primary key (sched_name, calendar_name) +) engine=innodb comment = '日历信息表'; + +-- ---------------------------- +-- 7、 存储已暂停的 Trigger 组的信息 +-- ---------------------------- +create table QRTZ_PAUSED_TRIGGER_GRPS ( + sched_name varchar(120) not null comment '调度名称', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + primary key (sched_name, trigger_group) +) engine=innodb comment = '暂停的触发器表'; + +-- ---------------------------- +-- 8、 存储与已触发的 Trigger 相关的状态信息,以及相联 Job 的执行信息 +-- ---------------------------- +create table QRTZ_FIRED_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + entry_id varchar(95) not null comment '调度器实例id', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + instance_name varchar(200) not null comment '调度器实例名', + fired_time bigint(13) not null comment '触发的时间', + sched_time bigint(13) not null comment '定时器制定的时间', + priority integer not null comment '优先级', + state varchar(16) not null comment '状态', + job_name varchar(200) null comment '任务名称', + job_group varchar(200) null comment '任务组名', + is_nonconcurrent varchar(1) null comment '是否并发', + requests_recovery varchar(1) null comment '是否接受恢复执行', + primary key (sched_name, entry_id) +) engine=innodb comment = '已触发的触发器表'; + +-- ---------------------------- +-- 9、 存储少量的有关 Scheduler 的状态信息,假如是用于集群中,可以看到其他的 Scheduler 实例 +-- ---------------------------- +create table QRTZ_SCHEDULER_STATE ( + sched_name varchar(120) not null comment '调度名称', + instance_name varchar(200) not null comment '实例名称', + last_checkin_time bigint(13) not null comment '上次检查时间', + checkin_interval bigint(13) not null comment '检查间隔时间', + primary key (sched_name, instance_name) +) engine=innodb comment = '调度器状态表'; + +-- ---------------------------- +-- 10、 存储程序的悲观锁的信息(假如使用了悲观锁) +-- ---------------------------- +create table QRTZ_LOCKS ( + sched_name varchar(120) not null comment '调度名称', + lock_name varchar(40) not null comment '悲观锁名称', + primary key (sched_name, lock_name) +) engine=innodb comment = '存储的悲观锁信息表'; + +-- ---------------------------- +-- 11、 Quartz集群实现同步机制的行锁表 +-- ---------------------------- +create table QRTZ_SIMPROP_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + str_prop_1 varchar(512) null comment 'String类型的trigger的第一个参数', + str_prop_2 varchar(512) null comment 'String类型的trigger的第二个参数', + str_prop_3 varchar(512) null comment 'String类型的trigger的第三个参数', + int_prop_1 int null comment 'int类型的trigger的第一个参数', + int_prop_2 int null comment 'int类型的trigger的第二个参数', + long_prop_1 bigint null comment 'long类型的trigger的第一个参数', + long_prop_2 bigint null comment 'long类型的trigger的第二个参数', + dec_prop_1 numeric(13,4) null comment 'decimal类型的trigger的第一个参数', + dec_prop_2 numeric(13,4) null comment 'decimal类型的trigger的第二个参数', + bool_prop_1 varchar(1) null comment 'Boolean类型的trigger的第一个参数', + bool_prop_2 varchar(1) null comment 'Boolean类型的trigger的第二个参数', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = '同步机制的行锁表'; + +commit; \ No newline at end of file diff --git a/sql/ry_20220822.sql b/sql/ry_20220822.sql new file mode 100644 index 0000000..f588416 --- /dev/null +++ b/sql/ry_20220822.sql @@ -0,0 +1,692 @@ +-- ---------------------------- +-- 1、部门表 +-- ---------------------------- +drop table if exists sys_dept; +create table sys_dept ( + dept_id bigint(20) not null auto_increment comment '部门id', + parent_id bigint(20) default 0 comment '父部门id', + ancestors varchar(50) default '' comment '祖级列表', + dept_name varchar(30) default '' comment '部门名称', + order_num int(4) default 0 comment '显示顺序', + leader varchar(20) default null comment '负责人', + phone varchar(11) default null comment '联系电话', + email varchar(50) default null comment '邮箱', + status char(1) default '0' comment '部门状态(0正常 1停用)', + del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + primary key (dept_id) +) engine=innodb auto_increment=200 comment = '部门表'; + +-- ---------------------------- +-- 初始化-部门表数据 +-- ---------------------------- +insert into sys_dept values(100, 0, '0', '若依科技', 0, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(101, 100, '0,100', '深圳总公司', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(102, 100, '0,100', '长沙分公司', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(103, 101, '0,100,101', '研发部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(104, 101, '0,100,101', '市场部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(105, 101, '0,100,101', '测试部门', 3, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(106, 101, '0,100,101', '财务部门', 4, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(107, 101, '0,100,101', '运维部门', 5, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(108, 102, '0,100,102', '市场部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(109, 102, '0,100,102', '财务部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); + + +-- ---------------------------- +-- 2、用户信息表 +-- ---------------------------- +drop table if exists sys_user; +create table sys_user ( + user_id bigint(20) not null auto_increment comment '用户ID', + dept_id bigint(20) default null comment '部门ID', + user_name varchar(30) not null comment '用户账号', + nick_name varchar(30) not null comment '用户昵称', + user_type varchar(2) default '00' comment '用户类型(00系统用户)', + email varchar(50) default '' comment '用户邮箱', + phonenumber varchar(11) default '' comment '手机号码', + sex char(1) default '0' comment '用户性别(0男 1女 2未知)', + avatar varchar(100) default '' comment '头像地址', + password varchar(100) default '' comment '密码', + status char(1) default '0' comment '帐号状态(0正常 1停用)', + del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', + login_ip varchar(128) default '' comment '最后登录IP', + login_date datetime comment '最后登录时间', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (user_id) +) engine=innodb auto_increment=100 comment = '用户信息表'; + +-- ---------------------------- +-- 初始化-用户信息表数据 +-- ---------------------------- +insert into sys_user values(1, 103, 'admin', '若依', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '管理员'); +insert into sys_user values(2, 105, 'ry', '若依', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '测试员'); + + +-- ---------------------------- +-- 3、岗位信息表 +-- ---------------------------- +drop table if exists sys_post; +create table sys_post +( + post_id bigint(20) not null auto_increment comment '岗位ID', + post_code varchar(64) not null comment '岗位编码', + post_name varchar(50) not null comment '岗位名称', + post_sort int(4) not null comment '显示顺序', + status char(1) not null comment '状态(0正常 1停用)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (post_id) +) engine=innodb comment = '岗位信息表'; + +-- ---------------------------- +-- 初始化-岗位信息表数据 +-- ---------------------------- +insert into sys_post values(1, 'ceo', '董事长', 1, '0', 'admin', sysdate(), '', null, ''); +insert into sys_post values(2, 'se', '项目经理', 2, '0', 'admin', sysdate(), '', null, ''); +insert into sys_post values(3, 'hr', '人力资源', 3, '0', 'admin', sysdate(), '', null, ''); +insert into sys_post values(4, 'user', '普通员工', 4, '0', 'admin', sysdate(), '', null, ''); + + +-- ---------------------------- +-- 4、角色信息表 +-- ---------------------------- +drop table if exists sys_role; +create table sys_role ( + role_id bigint(20) not null auto_increment comment '角色ID', + role_name varchar(30) not null comment '角色名称', + role_key varchar(100) not null comment '角色权限字符串', + role_sort int(4) not null comment '显示顺序', + data_scope char(1) default '1' comment '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)', + menu_check_strictly tinyint(1) default 1 comment '菜单树选择项是否关联显示', + dept_check_strictly tinyint(1) default 1 comment '部门树选择项是否关联显示', + status char(1) not null comment '角色状态(0正常 1停用)', + del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (role_id) +) engine=innodb auto_increment=100 comment = '角色信息表'; + +-- ---------------------------- +-- 初始化-角色信息表数据 +-- ---------------------------- +insert into sys_role values('1', '超级管理员', 'admin', 1, 1, 1, 1, '0', '0', 'admin', sysdate(), '', null, '超级管理员'); +insert into sys_role values('2', '普通角色', 'common', 2, 2, 1, 1, '0', '0', 'admin', sysdate(), '', null, '普通角色'); + + +-- ---------------------------- +-- 5、菜单权限表 +-- ---------------------------- +drop table if exists sys_menu; +create table sys_menu ( + menu_id bigint(20) not null auto_increment comment '菜单ID', + menu_name varchar(50) not null comment '菜单名称', + parent_id bigint(20) default 0 comment '父菜单ID', + order_num int(4) default 0 comment '显示顺序', + path varchar(200) default '' comment '路由地址', + component varchar(255) default null comment '组件路径', + query varchar(255) default null comment '路由参数', + is_frame int(1) default 1 comment '是否为外链(0是 1否)', + is_cache int(1) default 0 comment '是否缓存(0缓存 1不缓存)', + menu_type char(1) default '' comment '菜单类型(M目录 C菜单 F按钮)', + visible char(1) default 0 comment '菜单状态(0显示 1隐藏)', + status char(1) default 0 comment '菜单状态(0正常 1停用)', + perms varchar(100) default null comment '权限标识', + icon varchar(100) default '#' comment '菜单图标', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default '' comment '备注', + primary key (menu_id) +) engine=innodb auto_increment=2000 comment = '菜单权限表'; + +-- ---------------------------- +-- 初始化-菜单信息表数据 +-- ---------------------------- +-- 一级菜单 +insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', 1, 0, 'M', '0', '0', '', 'system', 'admin', sysdate(), '', null, '系统管理目录'); +insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', sysdate(), '', null, '系统监控目录'); +insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', sysdate(), '', null, '系统工具目录'); +insert into sys_menu values('4', '若依官网', '0', '4', 'http://ruoyi.vip', null, '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', sysdate(), '', null, '若依官网地址'); +-- 二级菜单 +insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', sysdate(), '', null, '用户管理菜单'); +insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', sysdate(), '', null, '角色管理菜单'); +insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', sysdate(), '', null, '菜单管理菜单'); +insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', sysdate(), '', null, '部门管理菜单'); +insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', sysdate(), '', null, '岗位管理菜单'); +insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', sysdate(), '', null, '字典管理菜单'); +insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', sysdate(), '', null, '参数设置菜单'); +insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', sysdate(), '', null, '通知公告菜单'); +insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', sysdate(), '', null, '日志管理菜单'); +insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', sysdate(), '', null, '在线用户菜单'); +insert into sys_menu values('110', '定时任务', '2', '2', 'job', 'monitor/job/index', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', sysdate(), '', null, '定时任务菜单'); +insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', sysdate(), '', null, '数据监控菜单'); +insert into sys_menu values('112', '服务监控', '2', '4', 'server', 'monitor/server/index', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', sysdate(), '', null, '服务监控菜单'); +insert into sys_menu values('113', '缓存监控', '2', '5', 'cache', 'monitor/cache/index', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', sysdate(), '', null, '缓存监控菜单'); +insert into sys_menu values('114', '缓存列表', '2', '6', 'cacheList', 'monitor/cache/list', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis-list', 'admin', sysdate(), '', null, '缓存列表菜单'); +insert into sys_menu values('115', '表单构建', '3', '1', 'build', 'tool/build/index', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', sysdate(), '', null, '表单构建菜单'); +insert into sys_menu values('116', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单'); +insert into sys_menu values('117', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单'); +-- 三级菜单 +insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', sysdate(), '', null, '操作日志菜单'); +insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', sysdate(), '', null, '登录日志菜单'); +-- 用户管理按钮 +insert into sys_menu values('1000', '用户查询', '100', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1001', '用户新增', '100', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1002', '用户修改', '100', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1003', '用户删除', '100', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1004', '用户导出', '100', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1005', '用户导入', '100', '6', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1006', '重置密码', '100', '7', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', sysdate(), '', null, ''); +-- 角色管理按钮 +insert into sys_menu values('1007', '角色查询', '101', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1008', '角色新增', '101', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1009', '角色修改', '101', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1010', '角色删除', '101', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1011', '角色导出', '101', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', sysdate(), '', null, ''); +-- 菜单管理按钮 +insert into sys_menu values('1012', '菜单查询', '102', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1013', '菜单新增', '102', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1014', '菜单修改', '102', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1015', '菜单删除', '102', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', sysdate(), '', null, ''); +-- 部门管理按钮 +insert into sys_menu values('1016', '部门查询', '103', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1017', '部门新增', '103', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1018', '部门修改', '103', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1019', '部门删除', '103', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', sysdate(), '', null, ''); +-- 岗位管理按钮 +insert into sys_menu values('1020', '岗位查询', '104', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1021', '岗位新增', '104', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1022', '岗位修改', '104', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1023', '岗位删除', '104', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1024', '岗位导出', '104', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', sysdate(), '', null, ''); +-- 字典管理按钮 +insert into sys_menu values('1025', '字典查询', '105', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1026', '字典新增', '105', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1027', '字典修改', '105', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1028', '字典删除', '105', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1029', '字典导出', '105', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', sysdate(), '', null, ''); +-- 参数设置按钮 +insert into sys_menu values('1030', '参数查询', '106', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1031', '参数新增', '106', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1032', '参数修改', '106', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1033', '参数删除', '106', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1034', '参数导出', '106', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', sysdate(), '', null, ''); +-- 通知公告按钮 +insert into sys_menu values('1035', '公告查询', '107', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1036', '公告新增', '107', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1037', '公告修改', '107', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1038', '公告删除', '107', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', sysdate(), '', null, ''); +-- 操作日志按钮 +insert into sys_menu values('1039', '操作查询', '500', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1040', '操作删除', '500', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1041', '日志导出', '500', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', sysdate(), '', null, ''); +-- 登录日志按钮 +insert into sys_menu values('1042', '登录查询', '501', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1043', '登录删除', '501', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1044', '日志导出', '501', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1045', '账户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', sysdate(), '', null, ''); +-- 在线用户按钮 +insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1048', '单条强退', '109', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', sysdate(), '', null, ''); +-- 定时任务按钮 +insert into sys_menu values('1049', '任务查询', '110', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1050', '任务新增', '110', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1051', '任务修改', '110', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1052', '任务删除', '110', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1053', '状态修改', '110', '5', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1054', '任务导出', '110', '6', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', sysdate(), '', null, ''); +-- 代码生成按钮 +insert into sys_menu values('1055', '生成查询', '116', '1', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1056', '生成修改', '116', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1057', '生成删除', '116', '3', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1058', '导入代码', '116', '4', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1059', '预览代码', '116', '5', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1060', '生成代码', '116', '6', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', sysdate(), '', null, ''); + + +-- ---------------------------- +-- 6、用户和角色关联表 用户N-1角色 +-- ---------------------------- +drop table if exists sys_user_role; +create table sys_user_role ( + user_id bigint(20) not null comment '用户ID', + role_id bigint(20) not null comment '角色ID', + primary key(user_id, role_id) +) engine=innodb comment = '用户和角色关联表'; + +-- ---------------------------- +-- 初始化-用户和角色关联表数据 +-- ---------------------------- +insert into sys_user_role values ('1', '1'); +insert into sys_user_role values ('2', '2'); + + +-- ---------------------------- +-- 7、角色和菜单关联表 角色1-N菜单 +-- ---------------------------- +drop table if exists sys_role_menu; +create table sys_role_menu ( + role_id bigint(20) not null comment '角色ID', + menu_id bigint(20) not null comment '菜单ID', + primary key(role_id, menu_id) +) engine=innodb comment = '角色和菜单关联表'; + +-- ---------------------------- +-- 初始化-角色和菜单关联表数据 +-- ---------------------------- +insert into sys_role_menu values ('2', '1'); +insert into sys_role_menu values ('2', '2'); +insert into sys_role_menu values ('2', '3'); +insert into sys_role_menu values ('2', '4'); +insert into sys_role_menu values ('2', '100'); +insert into sys_role_menu values ('2', '101'); +insert into sys_role_menu values ('2', '102'); +insert into sys_role_menu values ('2', '103'); +insert into sys_role_menu values ('2', '104'); +insert into sys_role_menu values ('2', '105'); +insert into sys_role_menu values ('2', '106'); +insert into sys_role_menu values ('2', '107'); +insert into sys_role_menu values ('2', '108'); +insert into sys_role_menu values ('2', '109'); +insert into sys_role_menu values ('2', '110'); +insert into sys_role_menu values ('2', '111'); +insert into sys_role_menu values ('2', '112'); +insert into sys_role_menu values ('2', '113'); +insert into sys_role_menu values ('2', '114'); +insert into sys_role_menu values ('2', '115'); +insert into sys_role_menu values ('2', '116'); +insert into sys_role_menu values ('2', '117'); +insert into sys_role_menu values ('2', '500'); +insert into sys_role_menu values ('2', '501'); +insert into sys_role_menu values ('2', '1000'); +insert into sys_role_menu values ('2', '1001'); +insert into sys_role_menu values ('2', '1002'); +insert into sys_role_menu values ('2', '1003'); +insert into sys_role_menu values ('2', '1004'); +insert into sys_role_menu values ('2', '1005'); +insert into sys_role_menu values ('2', '1006'); +insert into sys_role_menu values ('2', '1007'); +insert into sys_role_menu values ('2', '1008'); +insert into sys_role_menu values ('2', '1009'); +insert into sys_role_menu values ('2', '1010'); +insert into sys_role_menu values ('2', '1011'); +insert into sys_role_menu values ('2', '1012'); +insert into sys_role_menu values ('2', '1013'); +insert into sys_role_menu values ('2', '1014'); +insert into sys_role_menu values ('2', '1015'); +insert into sys_role_menu values ('2', '1016'); +insert into sys_role_menu values ('2', '1017'); +insert into sys_role_menu values ('2', '1018'); +insert into sys_role_menu values ('2', '1019'); +insert into sys_role_menu values ('2', '1020'); +insert into sys_role_menu values ('2', '1021'); +insert into sys_role_menu values ('2', '1022'); +insert into sys_role_menu values ('2', '1023'); +insert into sys_role_menu values ('2', '1024'); +insert into sys_role_menu values ('2', '1025'); +insert into sys_role_menu values ('2', '1026'); +insert into sys_role_menu values ('2', '1027'); +insert into sys_role_menu values ('2', '1028'); +insert into sys_role_menu values ('2', '1029'); +insert into sys_role_menu values ('2', '1030'); +insert into sys_role_menu values ('2', '1031'); +insert into sys_role_menu values ('2', '1032'); +insert into sys_role_menu values ('2', '1033'); +insert into sys_role_menu values ('2', '1034'); +insert into sys_role_menu values ('2', '1035'); +insert into sys_role_menu values ('2', '1036'); +insert into sys_role_menu values ('2', '1037'); +insert into sys_role_menu values ('2', '1038'); +insert into sys_role_menu values ('2', '1039'); +insert into sys_role_menu values ('2', '1040'); +insert into sys_role_menu values ('2', '1041'); +insert into sys_role_menu values ('2', '1042'); +insert into sys_role_menu values ('2', '1043'); +insert into sys_role_menu values ('2', '1044'); +insert into sys_role_menu values ('2', '1045'); +insert into sys_role_menu values ('2', '1046'); +insert into sys_role_menu values ('2', '1047'); +insert into sys_role_menu values ('2', '1048'); +insert into sys_role_menu values ('2', '1049'); +insert into sys_role_menu values ('2', '1050'); +insert into sys_role_menu values ('2', '1051'); +insert into sys_role_menu values ('2', '1052'); +insert into sys_role_menu values ('2', '1053'); +insert into sys_role_menu values ('2', '1054'); +insert into sys_role_menu values ('2', '1055'); +insert into sys_role_menu values ('2', '1056'); +insert into sys_role_menu values ('2', '1057'); +insert into sys_role_menu values ('2', '1058'); +insert into sys_role_menu values ('2', '1059'); +insert into sys_role_menu values ('2', '1060'); + +-- ---------------------------- +-- 8、角色和部门关联表 角色1-N部门 +-- ---------------------------- +drop table if exists sys_role_dept; +create table sys_role_dept ( + role_id bigint(20) not null comment '角色ID', + dept_id bigint(20) not null comment '部门ID', + primary key(role_id, dept_id) +) engine=innodb comment = '角色和部门关联表'; + +-- ---------------------------- +-- 初始化-角色和部门关联表数据 +-- ---------------------------- +insert into sys_role_dept values ('2', '100'); +insert into sys_role_dept values ('2', '101'); +insert into sys_role_dept values ('2', '105'); + + +-- ---------------------------- +-- 9、用户与岗位关联表 用户1-N岗位 +-- ---------------------------- +drop table if exists sys_user_post; +create table sys_user_post +( + user_id bigint(20) not null comment '用户ID', + post_id bigint(20) not null comment '岗位ID', + primary key (user_id, post_id) +) engine=innodb comment = '用户与岗位关联表'; + +-- ---------------------------- +-- 初始化-用户与岗位关联表数据 +-- ---------------------------- +insert into sys_user_post values ('1', '1'); +insert into sys_user_post values ('2', '2'); + + +-- ---------------------------- +-- 10、操作日志记录 +-- ---------------------------- +drop table if exists sys_oper_log; +create table sys_oper_log ( + oper_id bigint(20) not null auto_increment comment '日志主键', + title varchar(50) default '' comment '模块标题', + business_type int(2) default 0 comment '业务类型(0其它 1新增 2修改 3删除)', + method varchar(100) default '' comment '方法名称', + request_method varchar(10) default '' comment '请求方式', + operator_type int(1) default 0 comment '操作类别(0其它 1后台用户 2手机端用户)', + oper_name varchar(50) default '' comment '操作人员', + dept_name varchar(50) default '' comment '部门名称', + oper_url varchar(255) default '' comment '请求URL', + oper_ip varchar(128) default '' comment '主机地址', + oper_location varchar(255) default '' comment '操作地点', + oper_param varchar(2000) default '' comment '请求参数', + json_result varchar(2000) default '' comment '返回参数', + status int(1) default 0 comment '操作状态(0正常 1异常)', + error_msg varchar(2000) default '' comment '错误消息', + oper_time datetime comment '操作时间', + primary key (oper_id) +) engine=innodb auto_increment=100 comment = '操作日志记录'; + + +-- ---------------------------- +-- 11、字典类型表 +-- ---------------------------- +drop table if exists sys_dict_type; +create table sys_dict_type +( + dict_id bigint(20) not null auto_increment comment '字典主键', + dict_name varchar(100) default '' comment '字典名称', + dict_type varchar(100) default '' comment '字典类型', + status char(1) default '0' comment '状态(0正常 1停用)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (dict_id), + unique (dict_type) +) engine=innodb auto_increment=100 comment = '字典类型表'; + +insert into sys_dict_type values(1, '用户性别', 'sys_user_sex', '0', 'admin', sysdate(), '', null, '用户性别列表'); +insert into sys_dict_type values(2, '菜单状态', 'sys_show_hide', '0', 'admin', sysdate(), '', null, '菜单状态列表'); +insert into sys_dict_type values(3, '系统开关', 'sys_normal_disable', '0', 'admin', sysdate(), '', null, '系统开关列表'); +insert into sys_dict_type values(4, '任务状态', 'sys_job_status', '0', 'admin', sysdate(), '', null, '任务状态列表'); +insert into sys_dict_type values(5, '任务分组', 'sys_job_group', '0', 'admin', sysdate(), '', null, '任务分组列表'); +insert into sys_dict_type values(6, '系统是否', 'sys_yes_no', '0', 'admin', sysdate(), '', null, '系统是否列表'); +insert into sys_dict_type values(7, '通知类型', 'sys_notice_type', '0', 'admin', sysdate(), '', null, '通知类型列表'); +insert into sys_dict_type values(8, '通知状态', 'sys_notice_status', '0', 'admin', sysdate(), '', null, '通知状态列表'); +insert into sys_dict_type values(9, '操作类型', 'sys_oper_type', '0', 'admin', sysdate(), '', null, '操作类型列表'); +insert into sys_dict_type values(10, '系统状态', 'sys_common_status', '0', 'admin', sysdate(), '', null, '登录状态列表'); + + +-- ---------------------------- +-- 12、字典数据表 +-- ---------------------------- +drop table if exists sys_dict_data; +create table sys_dict_data +( + dict_code bigint(20) not null auto_increment comment '字典编码', + dict_sort int(4) default 0 comment '字典排序', + dict_label varchar(100) default '' comment '字典标签', + dict_value varchar(100) default '' comment '字典键值', + dict_type varchar(100) default '' comment '字典类型', + css_class varchar(100) default null comment '样式属性(其他样式扩展)', + list_class varchar(100) default null comment '表格回显样式', + is_default char(1) default 'N' comment '是否默认(Y是 N否)', + status char(1) default '0' comment '状态(0正常 1停用)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (dict_code) +) engine=innodb auto_increment=100 comment = '字典数据表'; + +insert into sys_dict_data values(1, 1, '男', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', sysdate(), '', null, '性别男'); +insert into sys_dict_data values(2, 2, '女', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别女'); +insert into sys_dict_data values(3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别未知'); +insert into sys_dict_data values(4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '显示菜单'); +insert into sys_dict_data values(5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '隐藏菜单'); +insert into sys_dict_data values(6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); +insert into sys_dict_data values(8, 1, '正常', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(9, 2, '暂停', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); +insert into sys_dict_data values(10, 1, '默认', 'DEFAULT', 'sys_job_group', '', '', 'Y', '0', 'admin', sysdate(), '', null, '默认分组'); +insert into sys_dict_data values(11, 2, '系统', 'SYSTEM', 'sys_job_group', '', '', 'N', '0', 'admin', sysdate(), '', null, '系统分组'); +insert into sys_dict_data values(12, 1, '是', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '系统默认是'); +insert into sys_dict_data values(13, 2, '否', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '系统默认否'); +insert into sys_dict_data values(14, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', sysdate(), '', null, '通知'); +insert into sys_dict_data values(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', sysdate(), '', null, '公告'); +insert into sys_dict_data values(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '关闭状态'); +insert into sys_dict_data values(18, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '其他操作'); +insert into sys_dict_data values(19, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '新增操作'); +insert into sys_dict_data values(20, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '修改操作'); +insert into sys_dict_data values(21, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '删除操作'); +insert into sys_dict_data values(22, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '授权操作'); +insert into sys_dict_data values(23, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导出操作'); +insert into sys_dict_data values(24, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导入操作'); +insert into sys_dict_data values(25, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '强退操作'); +insert into sys_dict_data values(26, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '生成操作'); +insert into sys_dict_data values(27, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '清空操作'); +insert into sys_dict_data values(28, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(29, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); + + +-- ---------------------------- +-- 13、参数配置表 +-- ---------------------------- +drop table if exists sys_config; +create table sys_config ( + config_id int(5) not null auto_increment comment '参数主键', + config_name varchar(100) default '' comment '参数名称', + config_key varchar(100) default '' comment '参数键名', + config_value varchar(500) default '' comment '参数键值', + config_type char(1) default 'N' comment '系统内置(Y是 N否)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (config_id) +) engine=innodb auto_increment=100 comment = '参数配置表'; + +insert into sys_config values(1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', sysdate(), '', null, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow' ); +insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', sysdate(), '', null, '初始化密码 123456' ); +insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', sysdate(), '', null, '深色主题theme-dark,浅色主题theme-light' ); +insert into sys_config values(4, '账号自助-验证码开关', 'sys.account.captchaEnabled', 'true', 'Y', 'admin', sysdate(), '', null, '是否开启验证码功能(true开启,false关闭)'); +insert into sys_config values(5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', sysdate(), '', null, '是否开启注册用户功能(true开启,false关闭)'); + + +-- ---------------------------- +-- 14、系统访问记录 +-- ---------------------------- +drop table if exists sys_logininfor; +create table sys_logininfor ( + info_id bigint(20) not null auto_increment comment '访问ID', + user_name varchar(50) default '' comment '用户账号', + ipaddr varchar(128) default '' comment '登录IP地址', + login_location varchar(255) default '' comment '登录地点', + browser varchar(50) default '' comment '浏览器类型', + os varchar(50) default '' comment '操作系统', + status char(1) default '0' comment '登录状态(0成功 1失败)', + msg varchar(255) default '' comment '提示消息', + login_time datetime comment '访问时间', + primary key (info_id) +) engine=innodb auto_increment=100 comment = '系统访问记录'; + + +-- ---------------------------- +-- 15、定时任务调度表 +-- ---------------------------- +drop table if exists sys_job; +create table sys_job ( + job_id bigint(20) not null auto_increment comment '任务ID', + job_name varchar(64) default '' comment '任务名称', + job_group varchar(64) default 'DEFAULT' comment '任务组名', + invoke_target varchar(500) not null comment '调用目标字符串', + cron_expression varchar(255) default '' comment 'cron执行表达式', + misfire_policy varchar(20) default '3' comment '计划执行错误策略(1立即执行 2执行一次 3放弃执行)', + concurrent char(1) default '1' comment '是否并发执行(0允许 1禁止)', + status char(1) default '0' comment '状态(0正常 1暂停)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default '' comment '备注信息', + primary key (job_id, job_name, job_group) +) engine=innodb auto_increment=100 comment = '定时任务调度表'; + +insert into sys_job values(1, '系统默认(无参)', 'DEFAULT', 'ryTask.ryNoParams', '0/10 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, ''); +insert into sys_job values(2, '系统默认(有参)', 'DEFAULT', 'ryTask.ryParams(\'ry\')', '0/15 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, ''); +insert into sys_job values(3, '系统默认(多参)', 'DEFAULT', 'ryTask.ryMultipleParams(\'ry\', true, 2000L, 316.50D, 100)', '0/20 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, ''); + + +-- ---------------------------- +-- 16、定时任务调度日志表 +-- ---------------------------- +drop table if exists sys_job_log; +create table sys_job_log ( + job_log_id bigint(20) not null auto_increment comment '任务日志ID', + job_name varchar(64) not null comment '任务名称', + job_group varchar(64) not null comment '任务组名', + invoke_target varchar(500) not null comment '调用目标字符串', + job_message varchar(500) comment '日志信息', + status char(1) default '0' comment '执行状态(0正常 1失败)', + exception_info varchar(2000) default '' comment '异常信息', + create_time datetime comment '创建时间', + primary key (job_log_id) +) engine=innodb comment = '定时任务调度日志表'; + + +-- ---------------------------- +-- 17、通知公告表 +-- ---------------------------- +drop table if exists sys_notice; +create table sys_notice ( + notice_id int(4) not null auto_increment comment '公告ID', + notice_title varchar(50) not null comment '公告标题', + notice_type char(1) not null comment '公告类型(1通知 2公告)', + notice_content longblob default null comment '公告内容', + status char(1) default '0' comment '公告状态(0正常 1关闭)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(255) default null comment '备注', + primary key (notice_id) +) engine=innodb auto_increment=10 comment = '通知公告表'; + +-- ---------------------------- +-- 初始化-公告信息表数据 +-- ---------------------------- +insert into sys_notice values('1', '温馨提醒:2018-07-01 若依新版本发布啦', '2', '新版本内容', '0', 'admin', sysdate(), '', null, '管理员'); +insert into sys_notice values('2', '维护通知:2018-07-01 若依系统凌晨维护', '1', '维护内容', '0', 'admin', sysdate(), '', null, '管理员'); + + +-- ---------------------------- +-- 18、代码生成业务表 +-- ---------------------------- +drop table if exists gen_table; +create table gen_table ( + table_id bigint(20) not null auto_increment comment '编号', + table_name varchar(200) default '' comment '表名称', + table_comment varchar(500) default '' comment '表描述', + sub_table_name varchar(64) default null comment '关联子表的表名', + sub_table_fk_name varchar(64) default null comment '子表关联的外键名', + class_name varchar(100) default '' comment '实体类名称', + tpl_category varchar(200) default 'crud' comment '使用的模板(crud单表操作 tree树表操作)', + package_name varchar(100) comment '生成包路径', + module_name varchar(30) comment '生成模块名', + business_name varchar(30) comment '生成业务名', + function_name varchar(50) comment '生成功能名', + function_author varchar(50) comment '生成功能作者', + gen_type char(1) default '0' comment '生成代码方式(0zip压缩包 1自定义路径)', + gen_path varchar(200) default '/' comment '生成路径(不填默认项目路径)', + options varchar(1000) comment '其它生成选项', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (table_id) +) engine=innodb auto_increment=1 comment = '代码生成业务表'; + + +-- ---------------------------- +-- 19、代码生成业务表字段 +-- ---------------------------- +drop table if exists gen_table_column; +create table gen_table_column ( + column_id bigint(20) not null auto_increment comment '编号', + table_id varchar(64) comment '归属表编号', + column_name varchar(200) comment '列名称', + column_comment varchar(500) comment '列描述', + column_type varchar(100) comment '列类型', + java_type varchar(500) comment 'JAVA类型', + java_field varchar(200) comment 'JAVA字段名', + is_pk char(1) comment '是否主键(1是)', + is_increment char(1) comment '是否自增(1是)', + is_required char(1) comment '是否必填(1是)', + is_insert char(1) comment '是否为插入字段(1是)', + is_edit char(1) comment '是否编辑字段(1是)', + is_list char(1) comment '是否列表字段(1是)', + is_query char(1) comment '是否查询字段(1是)', + query_type varchar(200) default 'EQ' comment '查询方式(等于、不等于、大于、小于、范围)', + html_type varchar(200) comment '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)', + dict_type varchar(200) default '' comment '字典类型', + sort int comment '排序', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + primary key (column_id) +) engine=innodb auto_increment=1 comment = '代码生成业务表字段'; \ No newline at end of file -- GitLab

XV5uyyHP+hmoAqzF=d-gReT+w^)5UvWfn;w{A!zq_-JI;VWT z61i)_U3Qy>cqP@|MRltJ)q(w)uMEM@9BNxf*`|rOQvNt=!E&`LGbr%MTs5w}`Ns zIt0pgH%yXanpM@YT#m0LQc$>s_ouj?)2V5@a!uch{XK5?$in!n`2@|`cOs=fTkcWK zSi9FjFm=vEO{sz>*Y&zK^Ud$$bdOeV>(7R*AWKUHD?1Zen3l&FT%NZ} z_t^qrCb7x)4NvcBNuS0&(LD9eN*T_Ux$rtOtob>0PO7V`>(Afb zITsU}&;Hz;-Y;jFKEF=WlHL9*2M3po*|+Jjb!VsdJl}u&a%7?F-o31hs>cOp&d8Xy zTrarZeDgzzM`{UDr`I*LXYeqFunQKnHB8#9<02*a!H(sE^Pcs-7nM{69ry!O5kGs8tCv!P+#;1(8mE5?IPibmXXe^H#bv?d>JFtPxvC#sBJZ^|SjkCf3DvyaIN0M%BX7VqUJBV;CI^F#n;c&=3P3pb;7z`x=#zf+3#ib-*Wi2 zK)@yEluuWrwd=nc&RhHMY4fd1ro2lfzx>Q~c5D0hA@9%j{JU%~Kd^t_dgb%S1ABP$ zwk*G_xL`?p!^fhESM8f79eyPDWp_=<_5%f01xx(*d+b*fUN@)6{l{8lJ!xZNi~({GYU?pA~2Ro22xUUfTX%$+-T!UTqE^KGlm zjE##Q9%?;!P$=BHTT6MT+MGq$gfuKndwT&w%j-uIuxY^mD6O*8J7UgR!b z`(R7wvE%=*n|aND+8w18$*!V)a>s(XD`y6TUljazV~dS33Wc z|H>&_m3!w8=f{=idS~{3Tz|N^*FNsrTAdX?Z@>7+d$yO)dDUr#9&QF*W%V>i78#`l z8`@7iT)Evy4%#tRUYzu+jU`yuR3-4r#jnwapTCzBy<2`IVU@z}l#)Nv+q$e(bGf6x zf7q=Z@pSvLjO6tWEGY^QL!^C6Vvo*5ba0Q^W@#!LpWbBW)Yi9g_p=#We4o26YrE;{ zA^v$ouEs5+2M2XxFUpt%Rhg-D6xAWUvMUJpSZ1y zTHB1X$>7dN?&9bR&NkORL`?Jnbw;iBKpG)%Ku((L21 zvBSYyAmB%2n6=5lMI8-df)4x_lU6VAyXDAW>tdbTI4eVt@r!`&Hm+AoWI@IEWw8~V zVuBx%_#4mHTE|a_()~7Z-P*}ka!od0*WG<>HTkPo700J5*1@M2ulpnr@TphPU`0($ z%`*S_d+@QO=o`Te2R2x$T?ASy}&akmNkL_MLdirz|J1kPU#+)Egf%8n)qkw(@w|g@Tm8PK&ugi~a_-X|srY zo51&c<#b7&l*#h7UV)iaA%&hReMO1`cNB(Cd;GqmK?bVib?~9$2)(L^tQ5J=3r-0Z z$M*f4!7fTx2U1wW3G6Wb^ z?@MgEZsS_i`e|<3S6K3S#p(?yX_H%SFzijwexl!k^_k+ zOtKW-X1Xv_NK}e>h4wwqU0WPl(<5c&{O1-n_-JXxc1+CUoO>?sck}&kWiS7&+4GUB zUvYuLrz=zQRi~_wW8$jr;Ib)|eq+$Et7`5^?d-4{&Q~6+yuHiAE%VpJnL5*DnO9V& zF8{hB&}*G@%0B*s6|dxS6W6S%<b@;+0Y3p`0iO2Uh;VjBQFbrMeAWRuzIw zw>}9xSy>%;{gY7emM4mFOq#PEhH_~9(K)?(gJZG)W0w>E!MFwv3ugvfmf!434RTGj z41yWjOcrfhL@jl$n+iDazm$606Shs1v2@-yCI7u^-?l!r>1$AxXm|gAcXv|QW^Eas1g&O zz=u7{#n$&&R%e_&`dB*4KSyb0&Eun&c&{#fo$dF;VOPMWcdxhqf90`S!2-4;<=au2fN<-JW*tq~O$f^HO$d>^m3tc=JbA+kW0_D=b+;B%EJmYc;dQUDQ@M zaQ%G0O8x)1TBfS+oNrz}=hjqES@P_Tr@Q$Uo@44A#sXedGZlMJB`KcuJ~d~iPf~+X zJ8$mXM`@{%SK55M#ip%2EvDCdUtroC{=mCO4t<>0#Ua2F@?k>R(ctY_rnO#fT&&h} z4=~;-y*Tm6F^1N|TDNxDrFN!TG`&I)3BJKX=aUT){!-rv*pQd;PY%aOGUd$x+W9BEBiv(`TR z-`j1aiyz-FxR$b1^=RPBNT2h1r|$;n%)HvQO|NTPUa72^hhSR94Nn0^Lnf_?j*BkW zL+AWlx8cF8*~@hF-)UO>sR`@Jfc=%c2#_mg+ zd5fk*2%XfwxwiXASH|nk5S#s1#N)3&J(HH6s`T)NuK*((qv$;et4AxFji&g8M~8m? z`fk0t+8(on9}!P)bCh2Wk_*B3DoE&;S4Mv2wEfSMFUgiVqSuP7;ed z!Y6pAtY^oQ0FK*wif*j@A5GS!_#X=?o2qng)y2zM3AJ;D8}%M2&fT0Cklm}W;E-3W z^0dWLpd#;r^OFTFmAmwqUMR+He|xdWl4C*p2}jP)C9y0QoOk8jUi`F3AmDA}wRwN8 zzxn$5;^FVRUcdjwFQedIdZwA9f`Rd>O-gv)Enh?b8xcP)Klfh!^1*Ahdy*{&7u#O= z5z)%S5;8kg^6cF+CaIH|s$Mm%=)N!aW6Q2rTbQ5T+%fM^{~7juPXuB`lxm~aecE}X z@@98TNr0b{h^QV%k(%alu=4u0L-n;) zKUlvk`SntZ|IKY3;hd2{g(KK-Qa(KnPurcM!=IV)qr zqP7YCAv#4~%F{UcG&J3pZJV+7vf_ee?K3i~{>}Nw{eEBJM`z=>%2#DS^8au2Z@c#) z=EjugvwL@$InJDKV=P>?;Q`}DNxglCX8GC)O#3i#Q?mP_OX7t#It9*-DYHcmJIxhk zylT^OX49D~zoYk^y-|>Gb(em8{O;|n~TxLIe`zTe*pzyE*xtNq9W+{ngJ#e9Cy^?SF^w z`or*}jcRLzcB^u)Z2iGe;FnXQV%A)6f33Jhk00Mtjdg}xR~VRHRdN`&)ogkDpn87Y z*K@~z^T@x6oVc_2X7tbVdpGi~+rBNAr;uyKhPn;24J|(jw%t43!YjJ7U)WMABOt^v zktO7_z~WAu)3e0Q-`%@;-QME+G52>fKfQW<`TmdJ-&pJT=bzq_^k!!I%D=&PwoNU_ zHh;1$)tjxm|H+MOoZbSr=Z4$~O0x(&-{FK_v`O_aogDgYK1J+r8Bjq8(f~d zJJ|9Y9=2-vbvyo;+8r~)k9{we?9Q9Uzifk0huIV9MTzPPH*U1QJ^y6deDTbi&)Ah# zoqskzm2+v%y~YTwv>KN$^E*a)9^A{k$7>RG z-BU2&taHNBd3z1R=U8brt=Lwsyx^9OH&fUy*2gQW%ky9NT+2M^Y^7YcV)J&8%<0>W zuD|!NFn$rx&-5@^+zhH%6cPg0Ojl@-d!)+SnN}jev})~@?aObzf9;pEC->ra*%YlV zSC(514Ow!NKHs`A)4wKpapB9p)~ELG-`n^x*&La3Q)yqAv=l>kh79A?v`DwjE?4*d z;*+r}nzZ<#>*Ih$RdJmSS#nGnx86Tt5RX*9`Quc@`WETlS0x-Po+rSQ%gVpW zbNKfAiv#CHH3ug32{-St+f964&a>&sriZ--zyB2U2uy07b4vI1R9oiWBv2T=iuSnL zzvfi)7srE&7VZ1r)IXf__v*!it=`+Y7N0vh{gK-eo2+FIRF1AZJ)>c#&U=|@*LZeL z+jMVv*erFpFhp( z=xvYfDtrrwMv@1v2)4#g_)!1n9aP zkOEEO3wAUZvs`fAP_F=**k>1L+@`ePmY3~ygUF!gJErL0%Hp2p%reE@!IyvL#)R#? zjt7GOZ~fzOy-4WCozzH|mE9FfPMOhoeDH8T%$+=` z)TOwQ?WxM8oik*P9(ts;*`-0St>S2Cd*Id7Z+iJBmd$Ht;GVv1;i}6I6m9=FxADn; zeR(Q+&VtkKLMk$#~|aGyer zn9rk1u61IP^7&^SRE#cNj=lcWOZ?B?&x#7GmCITp-8S?62>!17TOjD!wc7Brf3NS8 zKV@9>O?BTF#Q^?ZwYfcBC+FT3_3tX2U}5`1$a!OF!HdU_jxP48;HsE1VQ%W|meUtH zQYIeG6Ayf)cuYo4$_-TP9h7jgx67~cjeYzldNF&fn9POU;%9b0;EFM~y8HTwkf(v* zi|3D2*SRbyp6B&6ZAMJn#Hq)8&UDDD={~I78Ix?)yXxJXyM8M)Lguvw_A5_ryUQFB zeAYS2$LhzgzpE6d&$o)N{ge}$Tl=_=*}dLAoHhJ`)t^^IvXhQ~PxKD^?eV;2-?>8G z*j*i8GmaSCo!Kj!!0_i zCLIaR&-?ZKPxSP^_qUk8KViQ=O<>9Fs`~enmh(yLA9$u3rZ_iOn%hd5bMk2+p_vnQ zzS)pa?y;fltHI@_2XEL89^bP^dqL$SP!in`WIkKdL%IEr=7s&=uY43-FyCk1uA@T# z?A|XZ>}>9sXL+#9Vak=Nx#|yYbtI-mtrRlWS^3JPrd&MM*Q7CddBF|StvwA@a!juU zjCo&vJDEJq{)@RqCbN&(oTAy_IfY!givA||_&wbmGat6jy;|gUg5Ov-o3m+6nM-Io zyM0-L_mW42ikI4^eUA~mdT*tE^|Nog=iksUD|x{%muKFt=L-(b5@2+2*lT#iC+yXP zgx7K3^tZ7qEpPBm`q{4V7>9q8%ez{m8TU$w|kC#bto3bec%`+9FH*~O*@bQu^x7~6Vp3mogc z=QA)c%mc6YPFg+T5>e~DQ=#jmCrIn%shXB*%o&$$Wq}{g(GPN)$UNC1ml2_~O z&dSN?l(0%L!lL-unWMRvkF1`~-KYI(ci6*>RmUX$oNxcX+=WAcspUY3@`i#IT{){I zK6mz2eCs``+#S_D+j{n=UqKodcKWjkF5_AowoqY*KxW{Q#Ve=$%24#0xG}WBC~xca zpp~=MRIhSWeayk=l)xnrv7_k84d?CL&fE0o-M0OA<1pKG$!CR0UF$Y(U2$GK;^v(g z&L4fdiUn4O-l#G>G{at^ss7SIqw{b4uYX^CRqIXCmF}ZCcK2KSukLZ2vX(2Ek$e5t zs8{__XJ2VKnSL~?><=z@J%O|3z!c>T1%DnM4$BMnNjH}6Tsbp7%E@h&TBMN1s(Igb zS4BLXI(OO6)U|uI?c8*Vlj~n+!L=;Y2!T_l{}-NLcc?5viSfx!wmY1f6C_xH~A$=>NJ($<+NA+hr6jaN2?YnPtVkx#0T znx#FJ>4fX=-!D#W<=UBXMVv$7GHbKNPFB7t#W4lnla7|idYYWvyX$Y&-VA{kMpZRe zYwB!w^TeAu?-c2FXr02r=+q!k;C|rv{qp9$Et{oxe~alpzW>`%)sOq61Fm*Ol?cx~ z(0jQme}mDnu8(et6P{fO(O%*Ir&w9ShyB3oE|ys6Z3=Dl8n0l`aQf|IUk3U&g1@dnAJCp1hzm^IA8)v}HTp)aB-y~T)&Ie~ zlPPO@(w*Si8Yq0-r z;^A73eS!~tDq<~?WG9u}+;KfEgjs&K*qfsXr@T1?nAimvH@;iuFOu$M-_XLKXt0~3 zV(!dydHg4foEijX__K7}eO7#D<@J^W2i+TPynWDb_;msv;k<_4i}UNBMEnqF(SCAm z-{;twKbB@+Uw60Saqs6&?ys{16j;(^8Sl4V{^`72;ebf<#&3PLpI7v(JYIKET5+@8 zt`vJkgYz5_q7$qhCA0|_beb)^pP02xa+b>k{m_7*JhQnfam<|Y=RV(ct5s(?*4ePK zfn{x+CHt;D6S$_Yx5`Ha;&)_?fjQ-ANF?Vl%IdL&-KxR_QFt4d5gk3#m+~~qqn59JD&ddr8P>C zg@e)QfQ!T7yxY^w%EaIEdRrFF6KzqydgRKKr%!v-UCM1$qsl+C2&XEsa5O$tNZ2sj zf`?mJW?jSV71w_KeVG%nEALLda5eM9B;)f-4;+m&koAj_=vy1Y4UXM=f*+O%HhtQ$ zW|i342kT=z)}MX7H}RAw$Xf?I1YanJG4?ekRvckcb!re$U|A-?n7>bY-;K0+RS(Km z91gjLwXm-^+eKnwh@8SIOhH`JZFV<+Tg^SygT{S$sYxUw16rqU!eN@|w5C zpLYD**)Z7(aXI!sIVoV`7Jr@$grZk^U$0n&3~`SsbZ z2kEV6+Rmlo&%=6-P1YR! zd`)G4yQ7!A4Rv)BTT7~5GTP)!+U3I0Bf%(dAmtX@_`GbM?C$Tq#nQVEsCC!mblfr+7*9#`kfHs;*&ySP%^=XEDNe4V(I_3^HwtY6Ar>|M9xnBSX<=+_ko z^XB|G{leOE$-R7uQ=S|>9F47y`Q^8T@2$;j-WvO6VW}L`dEt2>?|;oG7H5C@V9A2n zk`s1`u|8DsxccPTDJ{9G{^PvUrWr1ZyOR0oR8*(q8L{)b!;Y=ltLlHWbnWlUH=m@f zY-(Y97V0(o|z4D5%$OF}<39AG)Y?Su#Drb)< zeB2k7?ERI0UUm2TZC3@@RaDl9|2=3R9ADz`@5ZM~QGM&P6Ipj|&0B6-5nW!Kc`mub`{AixoEqxbYK-c66%zJ8pkd_DE^Q>V&G3npjx_V|{s z#*dZK%=dlRc`7Dp?$@k{E1jYy?&>KkH(%cS)x&1brX*GKjlUD}re3(mWSiDDaD(72~wh}EF6qU+xNX^yfQy|iS>2!x{wJ15{68d#X3zNz2jS1wQp1V zZuPjbwDv1%q0SrvOnVg__C@Dc1m=NCJ5iPs<+G$Y0%19k{tZ$45#d)TBq~`2e5U%zqLM^r|nkOq?F#(AGS-@=RXUzm-9Fgapqp` zI;o_Iwlf>WOLV)`a$jkO8N}>b)Xdjy`S8jexo?Vw+*g9i9`x31W#ZBO$Lx6}z2@nq zIo-Q70(Ry$^5y@<`QhdLR-s#k8sX zn_-sYag9ZkGScW#kMn4;m|#yy{R^mYtk0F%RLg% zk7k*yl~X%cb;^WEKV3NvC(XWE(Qs92VZhB*n?k%BV>}I&Qv7HA-1GOXncsBQk1-$r zue2(y@?F*=bj+yZiPDZGtZ~uHrzM6>&GU*o_Sv77nRXr}}CzR5D&G?Komuzae2mBq|V`Ei#aQ&RcP zo3gE3y+7=DR`qV3c(Wp>*!HZ$x}|45;$~jFAGTJ_iRtbBnbYQVRA2CYa!RW`_1TrI z%9kyhznJ^nw)j?*eRIj49`+Tr$Bv)9nA!I-PdB{MaQ8~vt2fuFT;o6bCFI$qc|tn3 z?%&^4Aa%J_xA5iO@Ar)NfBwhW^nChDN#HM9$CbKH87Mrr__N8f}-aqcJP2!B$eAA^_f&E+i z_O9tVo#mni(*?T1tQ^!c?)s>e~?T+nz}>z32zROcTTPw3ibgo^9Lu2oBn zXx({r31i>UPbqRzM}MI)6lVBg?ab=meA8+Dms}-=|l7 zG4FYO_~PNUs_%7A#~#bh-M;E=*T1sR?)83yv+SKu;)c#liMo2ldHa%gSnoRfM=~SL=z;V>=Hu@@IFv;9tG){7xYE}owr^c% z#F`oFoFk7`eXY89;YGx;Xfe5IU*8znc`l6Ua=pOJAiw5Ri%(iY>T$RK6D6!lI^7fm zx|cTRq^7$5l>b*UYpKGORVRY>u|%(5e%ZA|Cgt}>$uh->OnA~!U z<&?VP^&QTie*azTz?Rsvm9o_fll&hf&h=4%%`k8g-wFzExI$M?4<9wbI8?^hO?+{M3$M{S4ZsgG5A z=W$+n@J-`*@AnlOMLxyt+a=d7%~~bJ<)$RqoyEQ5-qk;!tWr+vA7|<*-!gCOy^s~# zT7TS9dtEhAJJ#=R!4BTY+q{phrpe{&e$>tr=l%Td{udqnXA84(=gLZb3P_zFd1c^O~TQ zDi2mRTFWoDE7IL?W?H21a_1~RZb>)sBk#M+*QDIKvz1Sc;l7H{vp>=kwKmUKG4uSv zhbP9QbX`;H}H|K^t!TXs&+uTPqF zC|t*VCwC+t(?Q+E6LyxUCM4bJFPI%>$ayj_%i(RxPb-1?SEYvnj!EsC)BUN=y-Q=~ zx-yqL=2;b6=eX*e{IgqS&Mp_$9gAdEwe|GQ*1NFtcV1ReX3jMhrn!+3MzZoO8*9|U z?mp>aS;O$)okODNvAgmaDk0(7nt$5(d;gRMA5O7&cA_Zjz@Ntx2S%OSzvU_fd?E%{@pXLP_4Zl@UylmB)1&VN{t&1(JSkUr{{M;p zN$XWV?%!Nqy?#oO9~0%Xk@=Hf-6xy;`LwaM=XD_Wn2fHeOx6FIu}mJCh$dzSs*T>n!=r{#*#_q~-~CSUSe=Njby{r~ahQ*&NU z!+R61ExGQuU$S!hryr~1D__og#=r01gW0+p?rrt!SIFGO>Hn#A>3Oclf&!V#*Ogv( z+xJ!JxA(ovpZ(Wdy%VNY%6s=`%D0c<-qJzXzpd&)X#~ zUEnPH$vP*t?h$L*^W`_DKU7Li_usI6zqbCrE8GmrbA_-uhg==2ySz z!Z{x{_pJHu^~>)tk8k1J&V18*DcSv=_jSMNW>4FFd3nUSZ`SMAe(t>gROR=Bbo;e( zv-nEo{%2Pl*md@?$=#aY^S##FPMq4WD)FtwY31J1?~N6IRtw1|sG3X1NOif)`|;2F ze+x6So!$0o-$NpIb(bIw!9bj!;d91 z7P@)F-`b-W7X4?<_4$8Ywy(4O=k)aB^W7bJ`a% z>%OA)YrTrsLN7R*e^uChSF!vzzwy3|1b?}JU)#6e@P9vPbKs1n|K9Ju;h*sRv+TFa z(Kie2T>pMrex}s?$7j8}uIan;A3iZRW!*2xY_pnu^NNFcE6!?v>HpSedwKsq!9`1+ zwe8S57Jm816Yn39>F+DQ6?Uqu*>5ucUf)XAwBPHPa#rk}(4wiOSCQTQ`18-H>}O(G z17j{NT5~zZTHN>E+&{05$5)5eT$!~*_VKyWvc0+`caPkwjj@`ygW-DSM-Hiq-CrNC zJL_-aZzb;*&XZK}W<;T-ttO-be9;ITa?Vs>Sp@Wy<>o+Z*BoNJrrhVvf$^!aA> zEPemOD%mP~WgV9?Jox|f2LGDw*>Td6*94g7v(1WsyQ|>kRULP`F5|btJD5XqZY7ES zY8IO||K{;OCgvaddqY3}_w>MR_L|Ro?6nEDmEljbE%{}_+k;LeKlys*mX=6LNsCq3jO*;_Ed@$#RypmhNy?^mX1m^J zXdV53zjwpg&4x=AH7!D}zL>MLcKP2=4oRg(8QaVFuGL!T?ya<+zWd)|dEai+l;a5; zIx&%Z%y|@--i{6zOZ{;b)S90u#Pf1vSz*EtDfU$*JRm#^K{gL=!8S}JHAJS5# z)Somd#5EU-dUDS*>$p)QVOW?p{owEO|M&b`s=xRDlgUR4@8*4u{1G>&VOP0k{jWn} zH8*w@{3`i(X({)I^KtW+n;vG|{U;;F;>EVp2ai3|JoqRiw(`lkN{!WT=OmQgTUR(` zcZ2!N^^aDbj+m!@dgr;m$@PZ)i#-cF=N~(Bp6}S_o~xY~3+B$B!gt){@X3pwFNCgL z|9U0<^0Sm6Su6gj+ou}yFEjgZ}IM(k^?f*wd z|JOZW{CQvg@5Qb1|28~VZd!TZio%A3*p%D*D%e=7F7wMuwM{>2cbxvPg?fy9+aC->u7-7;E|c)WYENHe5`5!@vKU;_xariR(aNT;R%G zIty6p9>n=z4LqOc(#`~R}OCGFT8{{-8VvgjOX(yjYN@j3yvU&Cix2PP+ z5}IrH!0TjBm!QRQx6|hub3~;U{s}WV_~<|m=d|3m1^f7fb0^PczL;^~`0{;g*|-hu zSfBlEns&5CbbrU@Wg8XLC1rn3-kqCKWjT+tV^XuqkBu9D_Qt-foNz2{-FHy^8xp@`F{4w=9IU3pTKoXC9uS_c0N6nmX&2g!vz6Fz&&L(Kg4}T|gVa>D`QByB1n=vunnfKbN4GFVMFDRM> z>y~a|(5`Yc*tPJRw}7QWe1W{=?Z&HKODq%Y_rKX`FOe3_s~@6Xw3Ul9V&!8^A^*H} z66bRL4_hvud7G23L7{K&in67qhxp_p@i z=XssSsdE-LsvZb?aPT9G3#&|<%>#ZDh545C-QtOCH(GRCtE7zB3l_DDw47m^9P>`P z$yw}vd^+b|elgG4YuJ}AQZ3-`U$-g8l%<-n(JfOw!;fM5G~G4X2~YhG-*cWL%C*wX zAZ+D=xf3O#P0MS&FBaMCp8Qz0Az$cJl}V5F?56@h@?L}$oeNtt@1(JUt&i-U;~l3& zHFTd}T@=6M1`B`4&ONcU=l{9=WtjSj^-Axxdzz1S+?0C3r`=HdPOBn5cuTGnLr&k+ z@~sBvHqX5O@Qm-&BdcpBp1xslz;f;42E)%spT}NJUbpMC&?D|U78~BShOFL^z3`j5 z%^U5GP^UGVH4&yC&9)0XxGeN8Y{uupIeN)?_w3gFe|pud{jkXU13~8)1$KPX|DTkn zBVo<+RzBl=BEy8^!BZB!NPm62V~wmO)9?TP-e0eK|9zL)=Klxz?|rxu%sqcevB)kb z(~UeLou-B_Rz7^`a-jUU?CRCK_ww$F zABU9tf8^~-{G)vMX=oyF;*2d z)d_49*n726{wN+S9yZn0GyC^;P z&%yiwemdQ*j4#hre!H>q@m;fSwUm`L(rY;1Z&53$@>p!@y?1`w`lFX#Z&-Y^$}7wK z{>xrB@lBCyL-+mv(f|7Y2matBgP9lm8iE{}B3c>GXM~kT$I5<{+vhg(xbKbQLeA?8 zr~KLYbm>{yj_3nd)ZQGvdXr0{Q|tfotP4-K?E9SG7FsICy~$*~u)?JoDuE9dl=O9~ zFI~K{%C6SEZ-MQ_7rphrmUC~MA${=e|FiesbaP~QU2Z>cXoAJrH#2)!o*rb54!o`| z#jL&a$AnMa6%JZ9j|5y);%;5H^xArLs;^)V=f^LNbJx^7-Fa$?_tu@8gxkgcn}>TT z@?;!X;T=0yK!55Tos}QXM^*Zs$bIqJHKnq4edh#a2#hD}g(|>;F9$-Zphsx#NLl4JI;Ec%JjBidTC}H07Q6 zRlpWhC-o{}(S+k+`!uK6-f5{-`99NefnI4+!OjKS!xXoxdF||C)hzYRxi^KifJ>nC zg4Cla@3n%i@Tvq^y=uGgVSjsh6>rvSpMrgEk8j=o_x6MC0x5Pk2Q3BOnEpUV-BuBW zx%!&imMyn_?vl1ho}G0wHz85J$HKje`CD?O;*Qr*%LT=61%6CPn9O!4bJJS>lwW5= z%053>7r%qyW3=(*-kpXanhLzD55L%dqUEy1=38c|a(_-~zG;3Pm2J5*yTNX1?Eg#i zk?zHfMU?6u0$#ff)27O!&mF8J{4_SXGB zx&uu;zkcg(SlGa_YtMvpc?TwPJ^v6q|9$I+mrG{2K66^e(eF2t-PcT|`pIg!4L?G7 zy_d?zG!*~xim(;_^E~p#@vVL--fu?hSvtl*Q!#fvb?$K^-| z&*Qf(IKGOx>I?(G8fK1_CDm>;|CI{8Va#{ zYwF(LFrMKjn=buaKmP6hegR<>?%U41cd~Lsxjy-P3p@R&K!g3v%Z@EvE1h`#G+Z?& zgmnGCFSNS+=9d%o8epr#RJA85Bmz+s?uT%osx6SFUzi~A8)t9dZg&iV_ zTjE`7zt~R+*<{YLMo#8r`s^YvQp-zvAQ%XUMpzDnSS_-t$CgN@m1W-#eIwzQiRCCCv|{WG;t z=~aF0L++N7EP@GdbKl3FDlU56es_ae#i}2NS66=fD*Kcr+5ea@|C@$0OZ=?cUZ2qV zxwJ;k&(_b$_}k~nw@>(nZP}v2{A;qOO`qhCz=?`A$`T&Oll_z?xp8TW%#PxpWcI@E z%SorjtF#)sOirKcbw1K~+wF_lPWICZJH9(I^j&HZ$Ov}0wXdQq`Qwwt?Z3YZCnibp z{R;G3@%YGcgPE>*N$0?XAZo~(+%xwz9h3>F5>3K2*pz-o2~D}X=pEfx#4Kw!wcRX zb^n`vRljmb1cyxGpZP#HDcIpqv*@{vlh1!Sn;R2vw(D2`Kkt>h26OI}zV}-d)1?_F zdRMaKD39P4p-nDZ-n1+W&1i8DF+TXnK@-$OYe=(t!>?4%kiYcrzo_P;e{_U88!maY zy|-Za%(%DVMY00B(Uhjl9#I=VkC`UtJC-r2CK{ipczs}**J5FB)AEQq+qe0wMtNL$ z7lfuXI+fn@@#ws=^3>GV7FIH972RjEFE>5Vu*q(EoUf(8xOL(6YxY|?_Z9g0SZgj) zlzis2V69kU>Vj1~ryj3TsoB0mSgPLYL_^oBjcnI<_Lwv;thp!hv*C?XmZw^RjGvE2 z9^o#eYWi zPC<_8@uV|1Gz?wNHg0O&oE~AxCDS6Y{O;tr4|>g}`+9>42sM*mUW}aEd>sFHtdi$l z&~QXmVXu$R$4GXzm3qa~GLID2E&qN{DRc7I1tD8PnDQDdlTAbPwlMWx@|)o8|0zZ5 zUDtlg#|(yz?K5{S-Agj-vW#diZ zs`3cW&6yV>A`IdUd96xM7ctpN$y^Z8^U?{qrRmGV=vZ()@oTSNx!iw+l8E=Olh1E? ze${!O?W!_?v#AA3__tagH0R5C{r+l}+&9nAz~B3tYBgiu`pr0cRP^+`rMb=9a+^bP z(<7{(X(Zn7D|pv%=wEZmvp4rGqNJ?&@^&A$?H3T0U}D;F@`HN4QA^i~t~ddUhQKcs zUOaQuFMro$d;Gsu(y`lMd*7y4bD9m9Vpg7tbb7$xmb6ezzu3Mfdz#zw_~?fP+>5r= z9b8<*&eq8MVz=y!jSKrgix(9*WE}423RtYrQFP#tkznb#%XcOq$Q`ttsqFyEO<(!8 zygj?#S9Se0aKBK&e)iKp$^B;2uC?D3Uezt2z#_w;BjNtLQ~7^|7SAF9rMO9NXUkRy zG^lOZllvscO0L$7-F=enfJ0Kd{L^3V&H)Zm(p<0R8g|I^ zep`HPMg7eA`)^s_e?Pe=mu01*Q$h=*yIfNp&D`C7YklR$rt_~94oz{NRm5s0Sddb> zC8uuMuSMLJGmSmwhIbr4oBz%v)p=!;K>g+y`?iXTi|e#`EjIa_bldRLkM_(}$AzEi zuI=7bad6GiPvOyi`ZI#%oEii!C?`~Y6)(MOpm}tAU9zZ^*83UppRRvy{k?Ru&E`F4 z@~;LNne^$1>t5u#c7S!NbM&5Omw?%SwIU9!T%YpNvE6({saL?XSvqSgul2loTAO>y zo8yc&Q_hZ8Q)S#_cV|ADyXO3+#T|BYye@7I*|^0cW>#aUR8vNGuhA0i*o=tc$koT6 zeVli3n(2$P9p=W z!1VmfXH3l)c%)wJP<;@!$K05Q@yxw0NyT4ID_wj~E6=piZp@Q?likAGDJ*#=|NPDD z;wke56j)f8mN8B0Jn?N>o#8p{w0{XV7CN&8*%%$XyoN7!Lr8o0-KRPMKax{J<@P?f z%3*xJ;pop*i3_&uiHk4Ki>rt!7hZNC&EQ97cIr+3dMjzYP_Cz2ztve6eY=;e<;Wqx z)WL9FqJ4?j-L?(y(rOnwTg4tbBBFA5s@3+=O<6zE&SfqsIlpH5SuN9Gi@%qqF56MY zwKn_iu1UxDZ})AMeWg0fvT?27?kk-;KiqhC?b4Si&%#>{G;jpWdHJO7$$_t@TW5V) zboYr{LzLYO4uRdiSv8)EGlEV8@BZ9$fJJ%ZGuB7n>OOt7x|9C$+qn(jVy@QRi=G$1 zX65tZo(BH7Ea{~0_v`=v-PgBXei3JgD0n?xhl6<8@0;iA(vEV*^sU=)&?(`%&6Gv~ z(2!D~@`cvBb^kuk7v9}l#j^smI!=O>DfY(O>HGhrUJsMyyZiO^_1$6%dB7_}d!!om z-h5jf|JUpFZpK!}s0Sw#mCpLO+opxsD>`sgI4+oP8|;{S|KGRmCw)IN89oJNflh@B z#=AMQqGMzCe!Uj0o@8k11zO10AkI>iZ0?wQ|Hm*xho%Gn*=Lr@OR|1=nuL4F_s(m4HC?$33?Phc z$+s!?CErX<3=9lUz)QZH7hKXIX32N1K6J@@bm5+MvM{RQ7%9 z|0y%0@9kcntDi1$@1A-2vokZ_-z(o=ea^&xbJ%j9S${q>+<*F~;*Ld}jET*M^E@>Y zTZBHGIP>u1C3EAWVFBD5)h(A=>`UZ5s1PD@MUjEMk>Lo#9PWsygr{=)e~oQ^u-j=a z(38<8roaWF+)XX=8*?0667ZMWQnr=X6-53 ze|n`>hr^Nd&=%pqdASRhe<{DNq-E$N_xq*>f5h>X27&9Gew@r@`+Q+uUbV<8_bG2r zwVE7Xvox3avHxNBGqa5!M=09vQf4)`P+B-^-lN*Ady|#j?iBslvECIAD{bddJ|GXNfDOarP#Vf*eYIgie#TA>UcI-&xTI`YO5ST)NLjzfo6A^ryim%@u6+p5`IblrlQw|Ncwb&#!FCpz0v{C6Yt*=N0v9 z9G!J*yg484wt91wOJ8H@?Cra%7B7_NjL(}qt20|N(Ae!~=CqT{&MhGvOwahOw`}9c z|0MYNHG7My`(2k;HwBgA=axL%xWDG|ZZ)^Lt#bEk;%|A)O!{h@{d9Y}S?h(`{7BtC zsjuSETSI2YGVeZkxF>0q$n&p7%-15F=QMfE(B)u};E>pt)bU{fhlr^3(SiU89X*q- zZlfG9_9B@l`OgCNUHc!V`-PtA%2#|AzUZWapo)t{fT6=2sSi#m ziX{y5C8kDrt1Z9$yH|DQyT~wyiMEsU_J#(;D$LPtwW(Xv8mGx%TOs@Sy5P~>fBF{f zS9={UW?|6JsmEXQsF88L%k31#B(A;7A4tmzuhxH|f2^9*gI9uUolWHVUst<1B=q#- ziWb>EaeWl)yQ`pJ&xa!)h1EZ7{$Oz=In1Wfr|0F7Bd!OIoH^dw>M_CR%!EV7yOv)y zOwrRi6x{k{WyaJO(>$;9pW$-Jt>$D14Cz*0CG}OBVM^=m*)x7Y0v4lv2*D5!2Grl5C$;5>e`< z@Rw6Hc5cSf+xNoXPI_}kevwM{YNI2SiOL(+Njpk^;O+~~nsbxsLkb7O`9+KZI$B%~ zI(l4(j5pq3pI;$nA=J6k!Xtz?a%OPsVzr#oX-4AgjdvrNYMXqf_{->Ec_?&{p4IQYPxm-^l^r>qwp-TeJ{AIf(rEZ=l zw7dLdZMXW>*raCv*px>$rOpqxJ`LxrSf9XeY&GlWwSa#qZ@bHjziSsPtO)YTDk}0S z^6E058Rs2fePEW9L5EAOd4KPPJ{H0KiE%zy_+UG?|u{&rWx{BrAF zy**_g7EIuIF=gM|{^n!P{(iaHe(JN&HNKEjVuCE+yn~f2Q%xt@?*4fCYP{Hn1M%~3 zJ?T%MCpC|0`IhH1V=jCNNWc0~yKL6P_*r~5@^5V3Txwi3U-QS0#cPgOu92PByjz;JAJ!7(GWM0l7%*=cE z>k;lQk)!)!ivAl(PJZa4Cph8E-Bo7Fx89f@Gt-P`t2Ezm`sOvmHTTVSgkHOvXjdvR z@5KH9vCa!i67Oa%sxiG0_33!a9{I{wBkqm7L!k<>u1liDStQTwp;I? zkIxrPh$-)t`~B#VWnkXS?Bcwczm6m;O1@g6uD>hw!vg!~vVVTmPL4mgpQG_)MBt{I zhF&RWobnU9lLUarS9 zcTNsvXD;zqI6q-J>)%rs>bdgb%RViNzs27yYvXz5fTrdL&L!;YnLczLGx+`>NM3i> zve5lH-~2y((A&KFY87w5caeST4_dRv%9|sg%oAzaXVQ0ju!Zx{cmG)>9UX z_MV^3HtS~XrVp)F8&>|FBf8*Sv8hyd-`l|N#g}alDsM1R%i1veRpIhz7Uk@v$BQpc z&4^3)C3~B%i48nf7h%Z04;OPOmf8xNhRH z_@m;q*^TvAe{DazWgRoWdBFd*DP9-zIo~XKaLvN|byJS4K%Akx;??Q(F2zm_aw`?< zjCg&I2n%+%cx|rb7he{XqyDBcB=DE;taV3cy$nl>F216@K`(Fb)7SFB9TDr?)U)2s zsoE^?;pD{yUOz%#&$sx0;qIcMy&pBTM1^*;^Emy`{H(@$*hFR4@q7+e$FU8=~J6Z=2>tkFWfY5C6+JlZ$s{JO#Qs334! zCv!{}ccOxX+~*xv9w}|8j+pZ6aR0RA<9+|WT=wUcHnsTMb9udF#n%rP&2w&V%e}v^ zw!T(l{c%_EITwGHGgz_)wJ$yJvp_MK&PKeeU%PxUqNIDV}(cU`{8%NTDQ ziTKsHeBRnGd!D$w77IK6>R^WSo?exM7proj@;jE@s!8D69(H(Tg!b1BSC^jgx+?H` z0*^__ov;Ak#vuE2Q?uE#7OZS?D@oR^zJ70x(X+Mh4f*$KwelQzHot#b!ZvSSh3n3X zUxps5IlN$D?i1&wek@n#p1-CQV0ODCV`tR*pjj0kwsz^Q@9ml5KK+c3QRu>GOV&HL zZhYnv?0?9>`$oj-c$tdSl$7RA>g9sWH$VSK`O6*5%($g-^@Fgo&F^v;SaMoU*`B|Z zVWu0tZr0j}PdS$pOv~I?+wuOBK6K%hK=}K>zRhV{e>LPw%-*P26LUH9cFM{NZEAkU z)OJTNayoG~%)P`YY*Ea~2>V;IIj`1exa`>5`()#$I2WC{vYj(L|A%`W4!5;ojbD5+ZY1~}UvFcmr1I*Z!o%eYPC1J_NI3L_-Qt;V-GO;|*OKJBdYWf0l$+!K zu)|@#-?y#C8?E+jOP$+2YYDS(@l}Bb62Vc|Hf~;j+OVHB+3VWH&-cE`i?UAEW%wU{ zuI63A#e0{}ongy=lE3cd{Q2|$pD{jPyYD6U;mLRY?%ABbt1x1F@h;o1Pnv>nZ>=uB z`upvyxs_*Q%_p_GZ<}`fhL!fqPt_l^?*7h8s1SFZv(DcCxoz+L9KX!=UcTi%?-wVr zy7E6c@}zy?ry{3&=bxFs{FhL0YE#o~fAjkW4uAfc=f5vHdx`ztebYxizh~zjnLq7u z`hxenIrNWC6R^1T>3rYb_h#Px^{;Pi@cWh8UTyTVEbYM7yRIqQ>)(C|j+5H-`=fXC z2kj2cYl`=O{#LoO<7>vDOA=aJEHCCfIe4yM`OkzLn{T|%OY)LzSo2o~s7d~^yC}c* zMb}HA6@t&1RvtW=^+-T+O^V9pqk-GGXZQF;Y?-*?__K&%YRA zTgyCY>S~_EcQdao-crypO>WAI2L(@g1fMyfF$AeUbgr9-tYf^SH8~p z$*#tF8MBmAQ#8x(PYvJjeEDVTId_*9Z&$Yeajduc!Orymwby^x|NnMtb^YD`Dt+3RA;e= z9hnq`w6Wbyn_28vn_{GH!9t#}Kd(}|#cpV`R)+>(Qb=2} zbm{Vk>26U~YR7u4L_R9WCZ|=ou^rh`(lxUi84`L#)I zR>sXLv)qg-=|C}?_@HO8lWTuY+dQwy>7eP9TxGMT` z^{97BX`7#P_l0V(Yp|N!3;i|gBV%~OOoVf9>fBbiQn*$t(eXoCwt0=Ov51(&57+B? zvC8f6l!a|_g<5z@n^Z63Jx==yCk2iOTbWYMVo>-EmRi|}I<(EoX%DT`e zv$(#@nU&_|x@gX#is>uFE5%(IpIR$janfgukgc0l)1xnt!h2c6#Prv!Ye$oe!}qf+ z(4Tv(=kRI9T{i{ACht7EUGnd&WBD$9-b(RV@=Ss!Z#*&)4_GvX%l7H9tvVOa?NHpR zd1&iYQ{x#SnHx1HZ`^!%#^#$-1Lx$fpVcqxk~g(sF~_oLtF&L8U9|gUNxg#o^PidN z#%@>gCv+CPy8ll|$hRtN)`dw`GFQD#f_QkJamI3Ru1St#J!z-s$r}(g@8++=Q`7>) zPoLlW*)f>WqkZ$YgDy9|ruTl_==L#zUD5h&f!XqB32}9t^L*NC?lFZ}rys~ND_SC&|LVx$@mfTr2ulz{Y-i{;to+`h3y5`*cvZB9B!oE)STW4Qk zdO}%EE8=InS?{IWCg&`+dLGNoxnA{s?cd;MxyAE#Z1r@zee7kf)K=MFt3Fnp(_Ab4 zukLEyrjQCop0GvNRlipqTYLMA&y$uQHOsiW$4?eAy*ugrRE zzeY1)?uz&`p4O%3)Xwa9+8Hdpys#$Axa(KqRr%X@_avR2^QFx9(rxECn=huR&9qrF z|C-5Jsr@2rBrgBi#ag`n^$nZNkMH4ZEo8&%+Ezb(sB+i~XpsLln{@0q!ADa~AgeJ}qy_r72caEdg zV&6G#ewn_j-_(Y`HSsO@B(UJC|KB@*wmI#+m7=;@uCz9A>U-C6%@2zmo!+`GNIG$2 z>dnOy44!yP3DQ zTM87s|LABj@ACGa|NhL0|MTw8)b{r;w&efRm0kB^fA+MxO&j8cm3O4N70v$`{F(o$ zS(M?9+Xp`1x3SnIT*CaWy7-D@cxiO;qi1^6;rCgtSby!6cQ1FU{l0eJ$0_1<`>VgD zo?VzV+xf}nO5WY9_dmw&P50PdAOHX2<-fDuRVP1r$<3A*d*#p5DW{v{Ypq}DFbBnD zS#tCB>|LF2@$=U^>3yfl}Wy%k5f@1J{d_s$KIy}9fE>)!bE=jhoh+Hy)eUVhxRw|K)b& z)$Kp#n0)%p62^nPv-2&b(-|NBk&CmH`lH8I)n2ei=?nX171?=-XN>1g;ci-!R>!$8 zd!>58>dNG_{xx6MJdNB}(!JW{w&{gyJ3T{Zw6`|w=Gyw;;zbKDrswNFcgyV4-B5W- zxMr=m3~PSJ`hL*`{4 z`nNmq7Pt8IIJvTIHn+SZpA=6#*Rt&O`-eZj+OFTSG2Os_r`oML;cNW2&b*Ae_HTFj zlP?l)7v@)3eBr&nzxaIrmSxueg{FqN^S{%zD?Gy|@i%U5%ako=)=Zw&e#d+5tTf%4 zS1S#--{19f^+55;)(S_-PIPM5OD}t0>FFUIZFch4dDG|r9xi-&d%8_`UU=LN z0nvk3mrR~iFhNJ|!3)VN=kA&BxpV!2bG%si_tQ_5|4yps@_*>gc|PpZ!^vX(g+EU& zxGw)8VE)Egp*{Wk`^&{YE$*4v@Obb1J#%ZLcDM0Le|uklbp5&aclRVNpI_hRE8q8< z`FNpIw|c>z4;cr3{M3K^e^2`PdF9vsd^bPr7A@1`ucppxZ_cA3=ApGCGitTm!I}ke zE7)$9JD&S?bh^Z^1(JKc-^SW4dfeoAdzobU{5=vszFtauqjS?p`|YL&zw+J8B5RXp zt2*zSd38H$=AQDey=xV3&)KKz!_K|+*XByzU2Okf{||orRM|h;;6u0T*?6y)*)?0L zuSCvHUlx-l5-=8&QMgniwP4o@Ff8*8C`}NSurpy9P`_0t9Rr=DA63n~3SwT3ZlPnhYsY&9u0 zxzuyU?iPzLJCz4&{3^M2=EB4O0$kT#{@R|qi^b{ajNHpjUvu)JJyqwwxbrCb_QKvz zv0o-Hxz*`#az@163xW#8Cv;>bZ)-t33DGQXV7jqUmK^|$5P7cTj6;GOdQcN#y^t{=?b_vhp4 zSl0PDy!*|Kjmc+vzwg`mB6zm`p|ux%mK6RG%Z!^;dh*4kne$lwCH1wXx@$k* z9;fsp^pIEXwfEoJ<97Xfr`UgAc+YzEfc2pdKF>V4R@x_T`_=uw)&F<3hjcEheYf-c z=jWxfzvuq@-u?aW&ideKCO;qN^Z(i(Som@M?3G?qn5J2FygaqK;iz2fx5fXxJM49K zNpx)pW^MjSD%|F79=E*6&TH`sHh>Dd82v(^D{D+5Km3 zx1za@m%hH*zH;Ntmzft<9%cNs|H=XH&#No@_%iM+6Aew1vu8RlDR=bc(YQ?$8YT(z ze+V%OTCiKoc5NJU$I7qLD$Z-d?M+wL8M#vqgu!TCk=D zpW#%Nq&4hD8@og-R`h>OGs*Ldz5J%^@)GuLKmW=kr`2I=^Y(l^wtn9~CC#((_N)19 z>K{&g@sX|0uIz+|)xGuiQ|DTj|9ks&`u4neXT=@wMr~W2cu)S@ZoNM@45s}lJh|M& zApiZU-RuACXFR;iB>Ub^e&%@j8Qiw}G-~e8_Gjq-W;I*BrR$B(p{Ldk8yC-0@adFW z9K7D$cD-I@?Sa?fhaV-`uu4q5yS=>j!ztB%=H+a?z3=@R_Qd>oBRARh`+wW-t>N-- zFR~iXzxX;Z+3C8v`Q?*;^Lys}oVhpf)wL(l6IfpG&R(P5n|x@~HRFseFHD}?N^LH_ zf6u+z=xwZ>@%b4aR&VwRHp-Y&dQc^~Xnkh%O7*n*e-DPBE)j`}K~ybjMY`u8Co4 z4Gu0wX7ciRhZapKnxiEvxtp(j+iCOgBZW5KUvxJgE#*=d`(=|}V)y##(eq~cQ$n}% z?Mc@*O7mL!f7XoLFDp5xXPBSu`jOMH-lTzbp3J%>uQgV`w5v+e>hSjd*u+%&dTGj4 z@3qn9wyX29?yk8~6`A>UQ;;ERlGp@Q0pk>pbE~F@ZO`+1!Xfk~{b9C|%Y^3C*UPV* z^__!q}>xBmEk-*LV1{apwA@2+cYVxG?!_+-^m2EUi_ zEdQkgT-&zZ`Im0THq&!D>%spuW*Wt(T$4S29nfaisr-AVe}AI?*SHs=`wmq++&%Mx zvyTdUXo>uhUAEtjIlfUjCQ{&Ke|J6SH1_2s;mK?7znn6!EXzOnW&h3zlC1^G-*orO z#+;h1JN?tOo1Xhm220)Fe5~F%eNEk2-?ed4pYA@M?)0{z=5xKq;U)e17s#a^-dz6H zckMry&cE~i=Sij9-fy%0^VHM4k3T)%U;XAx|M9Y&pLn$l^OpYSpSwc4>DrTLu6h@J zd-rAhS|xMD<+9D3rn$Q>s4v7uPdZc%e0%gl@A}dOpV@=6u6kXO(+v45&{4SD#ZLC6PsXmF#zjesH%0Ex ze!Znq`?hPV`mOgB=Ok7A=Y}Z%{L%RP-S6yfwXgN{cX`i7%}d&~Y;Irl(zfc?IV)={ z($CG={eH*S<;kg=?;CK$eA><3cDDZGhjVM6ObeNNBa54T*4s&Mj@}HIvuM_w2foMG z>+dlZvHAJu!2&h+Ew|<=S$;jxxoB;C-Q%A*`7hoD8t2dZ{PX(%uW2Il%FfhekRrq~N{cdC4CtLa^?&-TcwX{F} ztCL#UzP@4JJ!Nmpa2%9AnzlpnP z9cB#`{=xlgm2Sxa`3>Kmh3WIF)ol$;UVqWaVS9XMYT=O`TMn@n8PqOa7@@|?{(#Rx z?HQ}Rfw4KK-lSbYUH`wF_gVQoz~o@{#LdwX2GXzlB9|MOS?KQ9&kSpIo*K4}>v33j zsCK+j+2bfSYel1N>1LvR^Lv7AkMaiBp8j+_@7I^bd+*mK$GyGqy~SW%Z&Cb#c^guz zucy@hIOe!FR`_@1+P#-nSoeGO?m2p6cE-0Xs|bhsK!1IpO^`=k|Jwa))NY?e{m7z81g#{$}w%*5`+ByyUlwsQ>kH z`P`CAp5O0&zVJ|2*XVUh+ST(?rq9`~Tsn5}$-S@|8MZlT30F8We)I;W>qz|gxhVd2 zn{1>xZ+sd1{gzJ(b9yq*TX-J0P6=YRbCjw|-8tjv=)`p)_)y!3V4QqFZ=+TpLXRhYC`8Z*oTpMbjx?MCymf=-^e zp?62+aY5C#ARD*4A&-}oC{H!#-m;&4M_utr0nL+zxvNg_Z=90Fz?&@{Z!eh6Q!T`H z{m|s9-;MwORXI#QZ~pGa@3RM6_5Utju;79I;^o`k-!R&ncd9+V{_4XepDzc!cHqDJ zmOJmzztpONPrsWVC0t&mD0ekwx%@sK*Wc6b-^x6=HCimz=WyRz?qzLuFBuJgM3ntb zyFPTV6`pke z{jw=#0w2Ua`kg*;?z!TP$+^pKFFKwdUv*M*`!=Ki*4*F+l-m5+bmaao0nU&=I*W;y}SGs^{xE2WJ{|rS>4N*=_OQX z;2X4vw|7eaESZbD4z5a;;K}qol=Ws(rK+r7Qm<>~yB#0qcQ4^!+A7y5VZZXk^4Rk& zYP0wa)XyoZJWq(MyLI!EyJFP2wCQP`o9ypzF`2Cqt+;)TVp3#7_2j!j!c_s5M(QD# z?yVELdvad?{)4)T&dt7@lNUY|Qwf9JcliwWDw<+sfwK~0JDX-u9 zrKch^-#t=O+b(^XulZitS5L>IeQS)o7bd&TR}ql#mRxu%Hv6vQAFBr5rE=9u)oC@Z z={fO}61)ZXME`u+FvT@m)cjZ~%Lc2o+|POHKUEszgJ-n)s_qQDBeIoE>uo@SmtT|ua>fgEW{mgXCpVMoy|&TUm3Wl z+T`Q!U@s1)t%8ji_UlhPSDIV6jKiAI_{o1r`_7$GZvT1Ob;xqe{;@d}$x>9&A7x|qrJSAdcJ$0(6n{jO6<7%U2 zrjKVvU!FAkDoZM!wcFf{k&G5s9BdV91hWb5?mynJ=GjkJGU~Px!a@%4Tc6rFH*-v+ zrcK_+tr+$F*si5&F1?~>j?DX?d+cwUu5{m9n`=$ImPtx~^P0Emo%KlKQoNkb@}%UdIEXaKzQ`#3W&1_xkY3WNe$VNOOaH$*+OX&QFYT@Uvpwai@9=1{UVrpK zO7!eY za=bsEqN{dPj*qjcK_P&V!{zr%S3B|9{fj4T)Q+EJv*31)Ve`yKIueuDif*=2dF`}~ z?Z#~(apCBqwXY{%5MHe`^Ty|Q>c3xJd~YIkGu-n^bMJxU+ma&s+281&J>qlt!~EK{ ztLD#;yMK#sSt+w2e~@}v_@qv^8lTj*DWWX#a@@BK-Fw9r z?k+Mtmoshlv#oEhc1In28^V}sB)K_5#c6Z?jXf>5Zm;V}m~>uc9n)e$4jlXu*>m>LQ7Z>y{Woe(x4%D>ih8w{;m3?PsiwLUP2I~bHJF?}xz^)))MLSG zD}uTMKkg1@wW(ji<>(*~z%iwvM_H8f`HTs3US&)8&wiQqZ-$Gs-l=no1)tp5)UsE= zKt}QW{14OGHf*hwR{e5klaYGJnX>c8g3opRlcqm>K)!kNR)!qn9%DS08VP;CtD5++L4+iQy1oH-}GH`S5!-#_w=FbvZkMUt~gKl zD9V1n=u1q=zP2xH3tt6h-F{aTbe+pYFFHQ7(u#|z$>FH7z}t;-=auaR+cp@l$o7^M zy(C_4RigdIYw|hw9byvkyYCe5TzX7>{h4*SXI|N4+uumGdl|j`OjYvF*V^~0+9P^% ztS9HLJU(IG?`5WE4t<=g8=B;mmUMLAn_Vf>^{gf0u$9FTcgY@-lcaMHqw?II|DzuBHZs0~{LDRJ&BCxw`3W3e+jkt!d?W=`qbh zZHCcd^)+oN&)k{VUVWY45Fw$V!zCih-msxCg|ENr>fCvT6Tctwdm~aPpnIuc)2tqm z%}Y|Cju&8ACB@`dY}T=D&HRpS5{n;&D}^kH*!ppG@-~6$8HI)kx$Mn*qd7Km@J2>W zYE0j0)qZ7~2*-oFDI1z+_FUA}y;k74a7qz0=tP?t{68=(7M{+XvQK55>$I&J*XE`k zHf3>gwNzl4do1G?)8i(MN0})xaT^xSVTwF_;>d$3$6U<|9%_S%GEm$!IfyzONV_Ez zeCQI#t?-^_YoeqY#gn?iV;|*DX=^k3Ic?$ou$w#fFu5FMd&6_AFY!l9>P&?Pr#ghd zF(JUh(%9wPz|Q~phQ{6O)8|r@qKrJRE^1c|>HJ>J`iw1k`-%3sI|_V?6Hd35o@JF> z;hMEiS6}yx>=}bk+#U1dH48eOW^F&+opIuphw7eVK|YWuR*+-SIkxoT2@em8U!47! zDZ;+bG)*lxo$P)*=V0*Kp4j7ForWP-x#c(8{n0w$lIQj%VRC`-p%s~Z4=x|umm*rq zc5cnFde#}u6WcPmSw(ZblaDeldm;!)JOV6>6c<<(<_0$uT-i8JB&2HB*6Y6Cwk(R1 zdUD44_e-5$4%WL0Pg}>m3;(RWSJ=Rs>F%$BRYH^WdQTdauYP7G%n+lMni*x1C+4> zDmhk!O62N2HA;wC=HvQ2>v{Q|OVhp`KB^eCBewUI<+6=YRrhC|I=nC^yG^!06|4tj z^E-|W^Ka%oo7QGpkuH-RE_3Tv+xK6AuMXzeRE`;8`HN(CnYD$btopn5+xnKY%oBUk zV*4yIZ{&R0B|a@nF7Dr}JEx8%#pbnts$;!j_}6K{yHD$uZfczJiV)V`T;LFSED%ta`PA2p-6?SY2BpVR*Pn6a1Spy0l)PkGvbrMw z_%`1*!#&>O-Aiudg*2XVpSsA$^WU=4`5Rxx+KIa?f%vhJLf9v+B7sd(Is8*qpNaR=2^-vJ<5xdsp#H+i#gQyCE}IcCTOU z7xUY*9d_s}=exZ^x}qZP$iByK3@h)*`>s0vW!Cg3RUVR#4gvx!r(_u8o(8UM2z>nP z?lj97Q5^$EDYH%1WsFg--}5=R_2+lBc&X`0FOV_e=Xd448tB5iMd`EU#=zjTlNm?9 z1Q=~Q)T<|Z_gJcB>5e9=*^B#r28r4C@^!y7UH`ya^C~AO={)FT(24AcX0J%(-s{zO zGS0t9=$J^~$$25NmxFB5eEdHyTb^|0!Hj2TuWa<&b-kz5c#q6xqe+{L46i+oP+z%E z*KEb?BO4Wu==7+kswS_Qe&>Xk^mYGdH&~LGdwea;eDbatv?hO^yynKDK(6D{1f-L5 zmOeh|8)Uhy?MBGa;91M&UE)cW?mHWNJIH5BTW=ln2?d_i#Ae=zO~SHb>mEHUou<2{ zy65KBH!=#LV)ja@o3*Z+Y8%%yTyA``$~j}vTIZSV8M@b-FWk7pUwCSI>pLZ9NO85G zOmTt%ueKcD#@2&xLiwV%bX00hYF-cDY3@p^!iI<(Zw6?BkV=W6#d zt9q_WA=G(NoekkV52Pw%mj;59B?r@0rp6=BdBeNYIwwIznjA_U95QxT#i(8kggU29 zNx>w>S$~ZQv~*u!rJ!IEBfDz=Nei5T`Rb zGOS57Yi?|1Ze);QXL{;*c*FjSx~Ez5Ze(68e)vU}sRa_M4GIecJ}i>#dD3mdBf?WJ zbdc>k|C0bklWv=5g^5N%&K!CZwbd)Z!6v}6iizold5=$z%9;Ad+uIud{E|LB;aKy* zw{z8|Dhev!brZV2xc%dypmx`t$-kED3}rk$!z!h}()`D}8EGd!8@d8O=6fdhM)<)>ld`uHN~#K8P=P->zL+ zvZZBPG@7ZGbb8LbLlej zJ*akIZ|rgQ{vbB>4LCo9G3#(xpsoGUBjvE%8*XZNyy zpLXIbxM5gpHS6w&bIkhUueas&f7kM~gXE^hRXq%s^e%0ZMHIcfF}K zut2quuZ`xBdh{l-enTm9{=3-kIKcAn?G~AHZTgkO4bo;UHeP9=HFbN8N$hqS8vP?U+l`we~6v8{78W z&%IKjJHCb`-`uo=YfAaD)YA@<0h}V*?^n6(gO)jqI4bV_`y(Lb|6=O5E!nfGj_;_R zcIJ2Wq97IfT?_c-`E34{6kJ?1X(8j`H8y8w7f1TH^SOmhQ+p z2@54Q`oxp5B{%Xi{Y`>uL+Z z1M?p2e&2W6`_9(Y-=EDsT^*;dx6L#^&ZfJuf#2rmM0Xom>ti>AAVo%lLVz4c#pFqQ zHq0_vr}eh=Z`;nv5l%523zVx~T(}`~XMg>r)B5V?=S1F<;qh`74G;`T|MFgbFYf{~ z4SwH_)hj1?f+CR7aY2p1hpNW5$qhZWo>|T9pH?nE=6RI!;AFL<3wF(!v&8(q&peBb zP3rHRN&_?}Y*bfQ-_>@3CGn9|dA?UO3!~!#E5!v75-TKL%-GeD+P?J0_4D?%RXlv} zZkc92bdul+?fkpm;n)I(6^RF!u1sV$VVNbo`|KoGb4x}*LCP&#BIdHs;YU;Y7&qr% zTB5OeQi8xVbA5iB!=X!Vi(YZ4uZWY=5L=meK_(-_@=mN$5X9LEY)nt4EOWTFfpIpU zcSjS0RNutk!OgN(D*s={hZa}~tYGPCtP-5f_V-Sb@aeVspu)qURoOw!py%wO4#zbQ zHU8aR>b>~J!3%=3KbpO?97Vb#Ry?uD6`{AKLtO@gFwBgY1J_rvV(%yksG zm<-G{z3L4rY8NVRd&S(5UH;^$>m^|+jqJFvzug*Aps_7qCkNgWn=B%>l@;vXvmtIO z|Fq6BTh_S;`)z_)WiL+53l0z!>AMojbGGH!wI$Ipx0Jvx3w1lNIkDXE#vzA&0{-is z?|l4j&*^jad$qD-GBM+%a-FHfbGdQV ziH;XSG2Agl+D)DOeXp}p?oVIvHpm4OxQ$v(4e5W)TU`#hDM;8Xbri~ZYw-QO@T!iY zP^VsHccV7m&%4%Mtx0+lQGb75sMEAL8jw+{;F%8PJw$0 z3LGwu2e{n|7?g9YdD<%!DsBpT{5@_TW4Yr)fBl+wGCXHn)Et}-t+z0-e0oy-sUNfn zsFBaI=SipgR) zZv!__19oyeI29@I!THRC3EqWII3ijePGA0FRyNby+u`q0wQt{AXn8>+y!nPj(UP3k zLYZJIIGD;<3ho)aHP87i(!$aBK-6PIkYvulC{f+wsNMw-)3|H82ER+4DOtN(B_#4x)|?mNUvCyqcU9 zk{2fKF`4H(`_TFc>uY~Il$D9@EJ|I+X2L5ap?7U_cKFQes!Y&UuLR?rgp&<_Wlsnk zsP-udGq(n<(}Q|`54cYf4kY*?{eqMq6YzmZfRbtkA2nt<21dn^{8`u z)wW!2!B>Bu+wXloC-|6Yrv=DnL5`a82Nw<=J|1m;iX-#vY5BU{1+Nco`F!qMTI#iq zHnlq)2PP)BzOT3X@}+J6-_+L{t+ucC>!}DGyK0@$zI4yc;A84B(Py;+jHJ%lE&Y{S zE>U;4X8YZ=nlBSC6rA0)c&TZV!%w9Rnb+?XNbP&M@_YXm8~fdfzuxdk+W-9$+|0(C zb^Ce8+vDXjHWRmgtN)yDqkoF^1KS^w7yR!(2JD-@`j%IFtM#h2?>aT&w&yABR9z2F zXYV-PSeG1%R-bGsQFP^ye}=UJgN4g}*F7Hl?e?Eo49V% z>u)C=w=-rJ%?D=#0pZ4GcK%0wtXqv7ZYMutmfTYpe}H|PLG7bu?R5(uRuoLOfhPTp zf-BtWkRqeIi#p!p-g^Cu4>X^mU zd25)uosujMZDVw@-L7NKJ!MjTbK>D8j+>sp*(@C30U5t?;9yufr}o>;t=FWUZ9Be4 zJmKXjg`D**lA+ILq)y;j8}Mz*iz)XNuBSG)&N!>p&NFYZyYM8dnwk5)-;-S|e&CIH z-mH&@E(Hi*J+pI-cOJX+!ef!L9B&QFCz;hu_djd8Ojl;|T-#@N7lanhS!8hgyuJE_ zNQk`xqK&-LW(y`x_lTHy`vO;O`a7Q`Ia5z@=k`B;w}4gWpgHg9$W>oAKf0Bec|&N! zHbb44Ci|i}JB41F1qBBG^Y`v)f*_(q#;=Z6hq z7xNE%Xj!uIjKY@VR!85Rj-Puw`GV-ui0@V!(md0jNP$Or3LF{I4oy2DWwy)z*8_%D z*L0sBPi22zy)y6EwrpneQ-2$)tpbk7@@J;LJd(G}E}X}Ejl-gyzkPmZ9zGn+Hf_Qy z;kCV=*>CL(s4dELB+-8E2nYaT=$^w<>Y7IUR+_EY_NY@_uJ!78m}ERnX~!$ z6JB*WH_pSKPy8sG(k0&Z;Njti+2sz2k-L@SSX4n>NejUrPbT|&F?;UryXzgir|9&t zn`Jj5IKPK^d3{q;J)GCxnOCwS``Q)O=kwC?PEVenUAg-05y^Rcns<-YC+IK)n=gyr zeK+;`oZShUKbGlcPwV$sqm>t$I62*aj%e88)!S5l*8kVGcxZI_^{ajSZ@PBZSLM~a zPCwTekB<}X}$lR&FyyfkyqXjcB-d~dSrR=%i+lP7GiJ3KG;ynBY5O>Zxg*5OA1N3UEC zIV-)cvi0thzN+vZnU`w}Cv96{=wbJ2+xic=;#>RgE9ZUtk;K1t?{cx2^L}#A=A3R@ z-<_hi`nIg>xf^d+?+cp0L9Ha|`<**_Ib73CcAVq?_UF@d)v4-FL9H`21p&Kr8uKQ) zUnrV?etX&5TZcK@79TzKYtQFd2^RY2?F%Ey_3F1=$hR^6VZXQR-JP8o9*+;N@69u+ zxO^n^1MlHKj}H2}?JxULaM|qcwfuW6H{*YwUzT^*Ecc#A`}vaHd)y!Q_V=GTJ#RhN z9rqx|6I0B*j;%T!Z^!RCCAMK3Gn3(ahHY&VTOQW`xn}VFuAbz#gFlXcN7boO8&{tAFJz<>s?buDv`w&FA&u;{mN75B|velh)w&ZJO+Er`NnI^;U%` z?A&=f&1>(swZ>kz?Rl#d_-8w>^4a_AY@}ID-hUSN3{816u7iC~A2NF-ay9oHm}UBK z`qAIr@hW9&RkkZAa9puqd9z1aot>F&!sk`1*LjuP5aH2#XO;N0jBoL__)B$%vcv>U z*v?lkP?ukSu72O^7R~G1!wyy7GgX5==ah=%4RS5oZKP*!3kDE`~aQ7rH@-~&yW_kBO zJbp(RPxU76n(=AM3_+UydC!Qvx_wZEn9`E*LV)2g!aRUenF{#nC)KR#*yXHn~0B{*5}e@;BHLyA0PkxAQfN zHTVczDs{3`TeYD=*9l~c74}%ql*8f ze=z;<<#M6Y+xm}3Kg_vc_{Q?>77JAmGf)8Boo`g2o0eT{Xe0f8)A5WWRASlcGp{!h^@Cwuu@U4dpfD4<>6h+;+#Vboo64cVC;FC zUABMLpL^Ac7po8Re!OF8;C8Fx@7E7=?rE>@S-t}@$EP5}XkZ>+_w#AX-Q8^;KR&UO zwY-ya=5E!0*Hh}ew&`g*Ui@2IY<+99ZM|&uis3)UwbeNsbGCDKq?;w8Hd`rjy4RzO_<2FG}^L8+u21 z%-Uhmcc&nH#ZQmK`c?mVA75&^YAsio8-6Oe|LT%&O`30R%~|q8=9VcZS7x_@0>>0x zrowOiv!>>C37iUB-8E4x{q|mm{ZBZjKWIAOYW#ht)RB|c~u;sZHJ^d-+|feN0v)IwedJGALZ)Hdn&> z+IzFzE4i8&VsAb0>tAx?qonbH9qXI2y1l?H<|`g72ZYQD483FgXZ7sNO1>ESU=~CvZ1>l5#`0XK(=XRxiDkVpCYE#iw29 zx)Km^O_^8b`tNU{zA6re0sK>XmdKf`-6ioQR5ctEjHNTDIy>v7U0pQB0K$D0JE zZPeNI<&wwF1iQjtD*{6cl!UDox%V=CRVwyy zLV;t7DU*dir}Ek~$@8-=rLJ|@IwjmD$z@7iQby3HW4#9RxUG`3FS_%FF8}lQ{Q@=( zVb;_P4wL0kacqH6U@yPwXRuf*yY5BBv_C8Ut<`H5b1=^;QERhWplnwBBH+OxF12K} zgcVk$Pfxw@UF*iY=k$YFog9v!InPycOeUAR%fg@Rm2GKzyx;A>5sSUcBR9WrZQyPc zJZL;;OJ3}sL*CPbS2c7!QcMVto-*AqQuT187kG>!AdI78o9qWeR%TA~m9KY}zG=DH z-=nYna;ww1iOLUZ`ZCLnL^fP&f8WH-ls@= z>$%-#K5SUCDQH2?EX5$mbbl{L#Wqm}-p6X*2M&82F27@({;K7ZQ_}S{`|if=Ogr2) z@$ISAZKo#9{&GtDCFeQmZ_JYOOT!jqUQYP@%;5}YCf^cn?&`|#@BM$hG49};YFqby zZ=;;8ke1R+XdnI*C*%2Te~&sGV7yhfBQxyMi8~+t?PiH@HF|RCqx=e;!_)qlto6UM z>uQV?8%KjwaN2pldt0^hEMz4A`p%X*dsS#sW7*rL($}+=Cq7MIuUYo~-jct+y~A49 z$68DDPStoieT|-`DrktIK|z3@XWY_3-Te?JR z4D|$;^)J8pbf)^xso_EMYp<1lefepPSzFGH9UETs*MD)1t6m~hI(Ze?-R)D{a)|(h%co4&C=<8{xgH_sMqN`S}HMSH5e_JR8U~KNM{jP zuZAX5oW%U4Vw0a8wNA;&0X|j>ZYIFTz4v$ zS1i<)t6vG8^=z~dydZ5g!#hKD%cN`TB7?=}RG&@FI&ihA(R=-mm&@m0h~*WrE;xNy z`hj$t>M@7z+DO9_2477|>kgZ)FHtTkn-XPM^kmC?Gn<-qjCap#6klH>_}KcOVk^t9 z#gADQ*=%B+ZK}vDLGiaoieX7&d1rC*4yi>qy7!)|Bh%)Wy5?i0{ zd0Y0F=C|gLcTeb)@>R=ibJ?8y?-J{CJDb}w{CCs89Dc4Bv1)BX(!-_PJi0AD_jIkx z5*O_a>Ck(-$$DX8j&c3%-WbO@@n4(Q`_Di0`<-+8SLJ?@_}bDlE01+<<6vou5a^py zf4?>$c9D?Ee(;b&lfzPl1J?}Ry*^;AtNGfZP49V@vw5AE&G#)6d~uBCK5ym<9}Onfg%&~j9Zb(Z zpO~m%6KFXp9+c}D9TyY{et2WmAUv&tcdgsZd(p>^7$WkK*(BH+Ec5N&KRA+)zw=o5@KO~@d=I;&OG;7He zXae+gUEu#d{_2%wQ_FYT#ETm6Cd(HdwmNy(tuOk+kNCxxKWyE^D;9tb)&XOnB_#2Y@CdNqIZo zzFYpUaQ%gXn{hl7A=9zEZU?5erJtQQcjm;2lP6!^QTSNu&NmHT>w*Ud9v$uOm$kPm zI?|zW)8_ua2#&{_D>fDUEqUL&y?_4qjCmId-tNghe65-y8NNt{Yi^n+$_J5p0;ZC ztDl!;h12Z*Oz$f3`k#Dj%Zw%sQw_mSnfbY<>lq`w+m*?$;~hS z$lGi7@3r#ROJDB&ntH6Vxkzf)71t^IZ=J|{rnN&PU3rVP-(S_)3JM%5Ee@4ci^HFo zorn$W6P@wNJ1)>BB6Q)r2iMf+=Nv1`yAJ7+@|(lEib^%lEZTG|)NIwK_iHck-8-7yIgLj<_1WIw@|A}sSiD-S+btfP z_T|DPW3fegsbNiKkGgbKSZwxQc$metQGWN8CRW`{h5Kdj940P z^*KB`mi14zx2UN*;hb&@ztx|=eSb8RDuNeP96lF0-MmX9@457Psk^)NV_vN|H)Vc= z>olj2F?CzoW_D=X9$1i@5WC=B&zC7ZTSOKl8ngxn2QSiQ)48)GSNgJ;-VG+^#Tq49 zK^s~-B~}!lzPRnK<<4+*=6$dFo+KxDmWR!}{$Pd{$KBgf@wKV%GtcE*mTjqJy~88q zI6OWkneDmP!%Sxld4O5M>HhgS5dSv&#_}nk8bDFE)N0j_Lb5=ZY z>r{zUY72;hWK&_hOo|b=6Fh8e?ahTJM_b&iX<1fnu`2YFSN}Jiq0N z&n5lW$NzrE_qgrdT&<7$ZvVY_yJZ#AwVL;a5{JF6_^c9R$uU3l6%|dK}JHN!Svf@W;1X3xbOVMa_U6L z-_tW^mi8<@F7s^zW76vy)@|PcXD_HYz3X-VzZ=rOZe{AIuE7+h$?tQlt*xwscjo{2 zWL&=Y|2ET0rD!)+j6*WJO3=bv&+No=bT1MwjROe?Om?@<_0?;87xr$u=iJ);|Lb|1RZFzXH{JSmVvWW|wxh*Qo!T>w1~0Suw8V%veMwr{ z0i!vYD-&3Q8$vx6g|Iho?z4=r@VjdC`bwv9`qQ-R>noJl<`wFSm+ZgNpm)1D`~TL* zXSx>&S~_0Jdr*5*`hCAe+f7-s=;9BxhdjTD_M22K*N;!Ub9h}V$J`5|>!)4O;J6~g zQe$`jVT<$k-_Q6f(+q5Gy6;b$TAN!kSu;26?UD_zK21NrxY)hB_tD}R$G_^R@ZB>B zoEmA8a-!Bc-1kiy&&>VB&lf57I&Z1UjhgrWliY+`d#_LUs=t5VME}{J&NjD5Gjkl- zGv}Ve0fS_j+LMN?(+rp+4nJt}YqS?R;COcagJpd>7h79T{ySRm=JnZlL)XK{H?B9E zeRuE2{uhVr60iE6xtCEA9^K@1BPf(-?fK=`wUfW^?O%{TBPeWzU(ySPx_`CGmp-Vb zU%mJ%cm{yB0Bu@6F$l zb6%|Gb90$T#E&WOR(WMQItXw$E>KZkQDwKG_V>4`!rSg$*;o6Ub9LaMSAU-O^76+q z-B*nH^nfk-^*ViKM%$uOUv*T<<{CWxb&ZczspsXPJ%6hLug%-bo?r1-SAcIJPg};( zV*83($HU?aJZ|%bhaJdEP)J;qm=MolP|B5QVQIv>+czXDN#p~=+OP3fUoHtdpTWfb zBIwzMqc5)9edXP^eD9s@Jb7==n9XhMxIX=?$W!iL_v#KiUOoToe%p(=`xd-s{%#sm zxp~%%-6wX~B>m5`i8}n--S574@Avr&8e@O^UA-3fBx=@^lKfxS`Yd+Je|!9@k{>h{ zxzt6w%e!{o;+oIDe=k@b*6+KSYud9l)0|?jod0~loO}L`DU(5KJOtF4I)4`A?(~=3 zRdIV;rDb>Cx#;GSjFPz%_MheIZlCA0@^J?x1Pkz@GB=k*M?{+U=qNr}f?&Q=?7p}e z#_z8j<^Q&XDO9@lcHEq?y?63;zd0E;9PJZk+-JY6G}p9yP3(>hXD=)~ zc4&^BbzZ2GPOHq)ok4mT)6a{l%J|v+d{X^xr}{CiDE2;f%YOwn6-+vhytw9`v)G$^ z+e|mgB>&Eez`bj97ChmRm^*bMpNx#Ba`B=d)s-=iSLsIVsY`zU?joE0^%k|o|949E zdAf{_lUqCtjD3a;T3z ze@poD?FCb=+5Rq#<#8$!+i-d2;oCpEd*|HKnXvThIYY7M`*SDfhdudFaQw6CyvoD# z%(wkM>s=V7{P zKkj&OZ+f?;jCkB6Pk|2cMvrR-Z%TiBy&ivDd#T#9?90n|-xNvQm0DLLwXXAo_iS); zdW9>8%c6&#lhtZjyNyHMURdfa9?oi>dn=^s=tTC@(#nkElVP&Ig(mj>9dW8qyS8JHa2OQ*dvkMx$dLn$%&)Jnk54t#4?oH$Yqcfi6|vOzTW|c;{FatIcRWdi1F2%8ehlv%X2VVODu%MWErDhw1lh z6Z%g7db)CE0`K|yoJAK3{y2Dp<~#&gvMiY5u@J=eKTc)Sd9(mD$7)>H_7Se1CmZvXk`%V&CD^W*<` zY64{SA_r(4e1Hv#tfy_gf znpnB_{r^`Tv42t7A=cH?w`5#Qy0Ibg;%xuZiskQwyOSm9-9aVz@gSSbTQ^dsE3gxbr*RoIb#|GMLZ|LdnV^=+?4Cxt9 zFko_M-Qe%|WJ7UU{EZ3Md3I_qde-+l#en0DeEGWwNl(xAtYv?0h|WA+!ysWU6{H<#nXT8>_@qU)RcZxk_Aat^ECU(Hh%o{(B#OMaL8} zId6I7=$m07H$|l%QUp493Us`j;>Kojc$T`l^k02D*2;4)tQ6~Ki;D5LUYW8Iyw&KqdsZXxjKd(6+2|LC- zQ#{lt*+vy+NrOVbGmbTLZ+v`~E4+*+mw8h4x063BKJD4Ms&A{X`lE-}xy2vNH**$$ z?*HP~$G-K-DaNA3qK`acb{8mmbP8O1rf*jCEHaAVEiPvd)`*{XWI|{iu(TMy6DvtkqK417k;>X;?UlWLZW)FdTsug)m;9xw%KFf z_ljq{)zfMhT1`m&x#sfhiiG_S>;3j=pUR!`|C;snf8V@zo`;oejBW=?_dneK@9X-> z>i++Jy*}|QO}Ama?`$(+H6I3zMO&_R?>#HIi2UKl z7-%4{vC!}KnQC>vIp1%%EPQyY@-nO}W(3t`MQP{ea6U^YEG*bqAK~%V zs`%l5&i~z=vVHfnabMoHJWT22bO8ni5XN?Sn>qH&+ZY})Ffb&7FK=6)82FW#%i9EO zJY5_^D&pS8#%BblOVylHphWRL8LR>x-OHft_jymrGTPu7)vh90h`gIb%K z&vAz@uVMAIi`kfHbVogPn%}Oqo)MZ~leTnC-n!#e+GMZ%W1p_BeyOK+KWE?b%KOEB zev>ADR?jT*d-Pe!(6;jbzjNo1pvZ$97@G+9k&q ze_vNyQyO^p*Rpw=W92gA&L3Z_{qS1i`7=v%m38xNBz)R#t(Mfvn(fQ+;?_l3_H)ae z{e_G3@6HN6`}9Zd%Tw96YyU*&EZBBz?%($()^wQGrrbYq>eY#fAGo4rGYhx3g7xZ z?u^Ksth<|4VHtks*>qAx7&r+;An^lzU^ zHh2E&c7H9m>DM-^Z>KKqeB$$9>QvDsFTV&r33xKMdvUzus_5r>J&9_sgWX?O?5fJ2 zoA4y@+R0y8*}tlmH+)&Y=kL|E$0u$q7WeZ%lHYsI_oK>oH8#a!uB$B#o_+Ub&rQp% zE?*JdrxLy6!>!lidA4!#zZ+y{MYx}PnYek=*=8Q=idq>vRpA@e6;e4Vw^dKPDp8L} zdJz8R^W?{zdEBbSJO2Mz8T&)RpzQONe~-&0b{GGy;L&{@5}*70;N;`}Z@+*0tDx?o zV}GP%0_TzC0lXYDqU38!luPQ?etpCEWW}cQEsp~?)K4s*q!_>BtAX^~&&AotPfiiG z>o~DERD!4Bt7zi)m#jXmKi}{lp5Lyv&uZEXA=%x}GaMq~&1AW*v;NT$iR1indqO=k zqghY#{TpvMjzs&ZJh&`=|NQ3GbhoOIgf(w$Rry^dKKJYL+6>^5Iyz8=k5I&mq}ukzomU*G--mHNHu#@DC0xs2zV9~VB$ zK5p~*_NVKwI~Rz0#V7YUna@8X)7iD`S9-#O9luRw%H8-Hr+V?r-+aY?rkPFOd`*k6 zU487`ZAU)ryOw|Z@@s~Tjj@mK|6P6T?&&_yC?7Z z8J)Rz?CZ*Q{<@X-Kc22M%snpotLXRRohv1EwK>$n&dhh3zD!Li*}!vF!%h*Ow~5pC z&-uWTu*&4mwpBAk4ds>w*m6h|mYkk<;ATUW)%v_&_b&W0xN&;dfhk7Oha`V(mpdtz zc7VnCs$H1;{no#wYl`zMOv)$9w!N=uQQ)`T+Soc#_5D-j9R1I#2ku<+nyj+&`+e40 z+Z$wdPay4QXA{p;;{rTXXYR21oXXB+z36}}~jHbtEaZlPA>eF|u z`RtDsD=W2PgXSGDaWB3xM@>^r$UfRL&NG48`uv=q_ut)hxxn;pR$l!7jF)+vR<`rI zm&?4!^zu7@@3g`Hc?V>~Zkl%f-TR{O@%QJdQC+9bu-a5s_k3$qknUHBP%=8##QY~# zL;K|1OTsU&E6=R?b~F9|p5J+|e!q{Em7UGTuD$q{->Rh#Zv_|i^1I($ymiU3-#&kq ze+%4F|Ikwkt97K-(Hc9Y zjKnk7pT3x8%YOUDm!JKHbLN+QPqB1ZnPz_P-?0}O+gsi){`ers{hg23=BjxI5|ZoP z>mM&j%GFiXUvqM)zv_*j_o`pV*EGIqdGL8}!N;VR-0RK>^;~l=j`DrIxXOj0tgnB4 z{O)7(Y&_kCS!!P{eU%dMGTK$xi=y1)p7axtxh+$1*dSb z$Vw*0U0oe^t!vQ@A*LgN+#w9gzuw$1oWZv9Ue)SlyQP=8tejte&Cj1@Yr|^CkVh+6 zbuM=N`!czZNoj?ln^=;>y8fsWt9LDaWcOQEz|)ZL%2Da$6xB9C_k*`Rxvm?1pRq=y zsW8znv`lrSj=aFmg|Fl5GpY#9cstznF@{t3?Wf6wyRSN&>^6lXYFBmgf{E3ObStO!yC1)CZdpd%L>R|W4| zH&0jJUE(uS_{|B~D;6@od2u0V!|BATr)fPJ2PVv#RaN$^N7F`Qk}FHkuPV*mHoy9o zab14*s?dUKZcY1k^FzDVx$KTi4>ze=dOM`=X-~?rj;>z`|N z%lPf@tXQNe&&tUD#`xf>$>t5ksxw?mH)MGISZJm6*i|OIHh7|t#$G4xlymR)`%CHy!UPWKH8;K@OD09=m7@C z$)BqZO%&L`%lK$T?uFokYJv)Vvsk(o-E3=^wfIt2Mw{@wO-{cG1LOQ%xARXA=Dx2M zTD?MJ=aTrn+pfni&B$40%iOy7friyFzIhp^BSLnT^Tw}!K6{~h**)9%CEP1xBaT%S z-VAM7VQ+Kf>gA-pD>x6VKf3$)-qz3e*M-^IKh=_HHJ(;%HYq^c-)c5zYUzwOEUA+7 zcy8`-68UyvdH?Tki6^GqHokWDvzdwak(7-m3yiP39Mqpw$M5me;a*H?Ym>0x1?hgS zpE3o?jMCNr-ksZ~rpEnR49S{?g!UwqwJ-FqMN)~#X}pKf*O40r!#?M)Y% zUloL|+>$eMU)z+hvj)uvf5$B`&)HYRs`X)i(u?-i>ga&(1@m=pZoD4F(04vj=&_}+ zmSwYXU4s9&n_sV8_~adBz2M^&n|k{`rrMulA3g^+a=a)kIUQymy@%`3*_e}&8&~z^de7_nxZKf3@$KS3 z#hK4OnjX54xI*z9=emfiUfH)k2gcXRKR>3X)@}ZIaqd%b_pSqKW_Rr0v#SSgS^h~w z@Ymmk8$QjNoc7E^tM}cFHF@*qh}=BE&D3b8=CTGzmWU)rlOaYDab+$9CXRMXzmG=Ir5p-{Acf-dyD~oQsnXcz!=~#TVP=57J(Wft8 zua%j!qWM2bP@zw(TVbibDbtaQLCQWq#k(6O=F4@w_;7uCcUh&@xt-^n zj8BJ6XtfHwk|bd8>Fni#8`{e(yu3Lg+!a3SxZMexi$Hn%jY;nlUW;!dfd0pef{aj zv$Nmtv$q<3_#=_u!Q6h-ZTAvBMN^+!>mS+qcV)|4X^Ou+n*LXCxyVxY1u`;Mb6n%@ z+mu*1I%~zB3O$x%zh=TFY#yV|O}VBYo5ld~VLRbAJ0 zT734APTojyZWlg(Ciba?Pg_+aY}}-ma{sv0aZdA*Kxl1%UcG(a?swf!oOzS#R9oLP zajnr;E#_j{690aRwd23Y|@lnRj19)iKh0(;8lu1?dMOF>&BNGlg@3?<&EAU-nsc+XIb3TGbcA> ztm2;bY+dBpt1bC*_l4biIlkP|K45;nOMaRclas1*TX?f$B(u_O^Ya1BPJ0*XyPrD| zq{}q%HOq>rHm5xumU~rl1yzf!O4a>Qx>zi8!IGB@Gm8V&lY6uuGTgNG6g&K;LgeZ^ zGbgX(uauV@IWKg%`SqR2n$PtzL>Ph=J8kw~F-eoDcGHykOBh=w7-Y3ZrM zlh=FgWL+tfWTCk3MEXy$p8jR=O8Zw_lezM;$m9wu_qsF3)J%>CE}YtZDrFn%=A^1s zj#FLS-n>eA8Dz64hI7*t`5kLKuA6|(`&_~O%u#*&fI@PZH1Az(};nMo*j;*h2mA>rbJfCX3qQI_U-r~*$4_Q{cb?y*6uFQH}xP&S7 z{`H)b@!4Jtks41wdYfDxV!UQ@D!1v&1W{%kq~)nT|W%)SbBgTSV;3lifiN z>pEYGDX!=ZRR3aj>8|>Ho5RPKu?QOZzi-{|u=cv+5)H@h?vs})Y@&SLO}WOxWbj|; z)*q2Af(q7I+{Oit-jaETd-{4-oXb_{yLBi~>k1RomFv+A-HUEDF%(`AyRkBWn?t}| zx4|_q*U`aN?kV@T4Z7>2HXUa^BIbJZPOkcg4ab)I&(FKJCvu&3&)@di;>B?@m<~+a zu~}w9&cVrCcPm)_@!w}&*Q@(%3p4sih6n>20|x^GgCawTX=Rx>KLbOu2?K*50|P^O zeo=~kacW6PW?p)+UPW%sp6KX)>64{({15&w;F+YrsN)-68oTS|+}M)v@=8(f>_qq3 zwH%)=IDb21pmft^^U8@bEDPT9?s*+8q)?XhUe(;<#Nvqz-%d$ZGVc8q&r{Fv-)Udo zq(yF@FB*KBP$^k9cipPs<>!8$TN%9ke#PsP6(z3=BhR;8ee%NL4kusU)X8#YIoyuhw0>2ZbDPGh%a503c=6cHp0+q}`Q5*PkquM3??uM;ES&Dn{(4&8 z2}kRzhj+cO-xY7Gm;QR&r!6!3XSE+aSs3hl@na#QrpC_1q5yGmi65)K7JNugz033a z=!=S|FBiAehGuMzJHMpLVE&icmCNhmwO@0_y;}BSzW5B`p8Tp^S(mO{&9HXJHZv{z zI`!Ud#`nDHsZrC9E{-hf`uD<6D@yv`v7fo${dS+~yJ`R9vHkzm;{X3WO4qNe-1=kr z>Z9tXkG7vaT0Xt|y}r18jNZSzoj=;2K01E-=eKw;)9qto z|DAvJ^Z080f2CiKp3gfsbDF`Yusu1K?*Bh*|MSz_d*T0HtoeB=y8h#J{eN$d*6;iA zvpfFZGwc07Uu1n;y!vSWdNKQ*Q8iUtfAp_DdVamw|I)2L-mgBoex2QqZ&%y*N9gU_ z8B>$J^T)TMj~9zR?tS`*{q)iMdgAr_WBz39{Biv0qs>>J?~kbcxBBYy{c*O@Yv$E% zsQPyK>Sq72^LEj(b;YGW*Is>ke~sS$&Aa|&l>Ypi$7>%OTeoM|pXXPfe!lwo=&PUV ztDnzbH?Mx%uSfCMyshM~9Djav%b9D|w$-0|SD9x^v(0Xc?yr6-oRMZJVa9OmWr2a- zJQ>*&4()F_W^Z>tdO7P}O!fAqTlM|dZ@nia;@kKx_x|DRxgTpT?ml_W^}R@yZDW@G zis-{P>>NKGK6vq9?#8&|*=OfACGE-myer>Q@(tT9n>}XdzFvE4aNTO%#63?_*;4gu zL-&`j4}LnCY1ak){)M*|8`a*L5^37Lb^HE%@_e&Czgv3l%)6;a9~-r&7W$w|N7gw?{@Rc+}xyAU`*AUs1HxVAsd`qoz8iY45W7{&V*-s$*fY!Am?NjBiZ9c|7e@e687e0X< zX##hyI~*38`_6Ae+udJnn>DZe$W1s=v*q>8uS}^oY%E@-4k#ydJPmYbIrEmW-Jv??G zbaBbr!q><24p_vsYg~B6d4#*6-t^6mc-~WD63@SWXw$#_nmb-;1p z$6VL{{iydwq`7>BG|S9wf%De)ZeE(FIq{s+b0w$F+^ntTztZH>*IYlhd-fEYv%%^r zl4oBV@VB1M`^I_8{?_u`aKHRLw^zq(7g_AXUitcJ-gV}#DQaCWZGw)^TspuFIdVce9v8tasKfacRo*z^8PNe z=cv_&*#{nOjqUK=mp;$M`ega-)=PqS589mLIR86kVNb>UGe25REAT5HO`R}1CPU4f z(R|j0N|%ICze?t#>eAcGW38CFW?ZrrRcu?lOWA4SvYIUhCbM2KF4|>r&v_%`=G+}IiT)6g;xNRoTc z;K0&Q|zC|kZ<>3vE;-ZwjwJner3CO*xb4x zX0%}2f`^Q@^VK(5JTo|b$xx>|YmwiA&?}otn9loNbhV!RW@2gE5x)169q+H0`-;cH zt2E?!~~H}W5zu>K136wP-t6dZJpJV|5HHJREsv60(Cm8Zt-;{l08o2?1W z9v#1{k{>Wx<{#TNqd(16DtM=)cCl~nZI>kfIT=bbJ+%Ub56%vdH8r%+JsK!H+hWO$ z>|4ST&vh?G9!j0CO5?eaNAEMc(+od@R^=a?X|N!L%ua^1kwk20Kt+`;eV8)H09m}^extG}W^L$&de`?tBlIJ-R&+ep0vWVV3 z-Sv9o{!q22H?p^S8t;=6UUDZp>AsPF`E9A(3YN^?UT3{P?OK~5Q|7+zh~99v zRHk_Cr-gwfwt)#Tez}TVYj`q61UUCTe{(0uBFH5ua-MyM)5Omjx-8+4i&P6w!sFpwaJceJvbY62$OoHVnSH9x`S+@h#_AL3QeyZe%@fO2R z%eqb}h#mSkL&n|g^m*vo>|F4CVvWTA(k z_7i7|e62GT^OVB0o)zY=$vNaNw2@6Fz_w#8U*#M5$7jTX?{q33*(-AL@fDXl=|}yZ z*%*skFa5Dn;oOvmmHR9Xx3XR}4-l$T7gRoc+nDbGC+- zx}(I$H{nVyLYFFqBrDEED=jq;IXX#TU&}lHMXm?_Iwj?tJO8zFt4FZ$`k5|D-7DHu zHhTVyR4d$}zc6B|g76vJs!1zbjw^ch39Gt3Wl8@&Bg;c;g5&auS+}13e37APWF)zD zzQ}gZIn5y_XDH{aay@oFlHqB`@y?Z;n;WV&oAro?ln1$FX8Fs%{uwJh>9^o{$7L4A zmM6a`Y&Cm&^O^~lioIvUrsLf%cg(Fa zw=9WjJ-tt1(T>N50zOWj7+lmJ*F5P%gyi)j)$f+c6#37KTD*D3xn<)KuQ zb@;s9XA86sgUqPm3#?E{S$|>~z-Txq9)=!(a9CM~haU zPrP&I|C5RX* zr+xI8@iAt3KkJl<>(s+Ik2B9#y6LIRK0oWUzr5T*)&0Le@I6g85o1<;yp#8R$T@!< zJLA6VmOpGdeo7vGe(AGyO8*)H4YPljrzdZn`XTji=#)MF*Eh#5*i;(J zwQH{5gKHJO(tZKL*7vrZf2O`dHa1vI<3N3@$$XxD|90egwp)LU`65-bz0oMVr)k&u zT;F)hoqz8YMt_gUTa~um_37Q(n)(p=?enXreD8i)68pNYNUe`A;9upvj&0G+%Nbue z?{1%LymR5nzP9DluGxzGE!$X8{dsY1;$PwX+`2cn4&_Gg$Uf}O`}+Hpb-wwxzpOi( zbNjBZxsu21)utx{aS?%LPWbA#UQq8EMe z<;$WY>HhHMkJhT6NrvCrC^Y-`h&Tal< z`Di9P+oU%&li7^xr#^rAGh+&?w%q17p*l>e#yii%vl_{rd>X`3vt^=|jPLQu8!M-4 zNq*2_-s(NgX44t{Ge>>1jh=F5=q~MwoVRz) z>fQgF?W2Ty>TX{v%gh%$6_b++mfm1<+Gu*iV0*HW({0VZH#RSR!nAw?XueaLL zld@oA$#d;#Mfba#KfnI%qP4B#z~Zw{j$D>}xt}?t#c0PP?`?gbeCk8YSN({nG18x( zGAaGuvpK1a0^1t|HVAPW{CKK#vW5SC!L+C1GZU`r+l!t5@?HDxhF?oxOQuvFeZVfr zRlmeleuvkB$I9Jl|E}1bs@usv`P0dz-%gupMY-zi)Sv(H$&0+WuldjZN6E(4UGEoD zF#SB!YF2zkva<1yPg{*RSI!o?y~-^4fSAJBJ3`{mChPA%^`No+v&_C3KOJ&Ee|Y!H zjdLYKv+@74vmZU2bNo>^hx0ndcr%|cr6>Q_R1{7BSn&JLarNfwhmsVod-4evSEVhI zNPT#GdBbw4;sw(UWEZ~Q#caUw%F*?>#TK#X{5Q?BR#pCp*Ni;#&2Oq``Yx5qWB>O$ zrCoV_&neh;(JO|Y*h%Y;|Mi{o#r)&0{hS)hYo9+_v!C-u$Cs~%p1G-Ne{?*XnlO3& zEaBt%ItpdW*1WrTV$nId-X$;JTs$%HoLuje7jG_}XgDX=+fe>3f9={=eD%SXf{1g) zs$a`CCc7;wlax90q`z=i(#(d~(&+)`SMI+WE&hJ9(1yQnCRF84UT>(jdG(Ex&9ggL zYg89c(0)J7{$_{JulnitY*HI<&M&vPZoDS`=wGex3E|7V^Pc<6+2&LA+b808yldLC zgnU!`TuHC#g&{ot(VsTm{b4TGRT|^Rn`B;;Rq4l3?0aa(j`}XYl8#y3JBmfD7-lHm zC~}l<+Svc$zL@x~TG`~D|Jy`lGvpuc*NtJnW&U%c{l1h-F$d2p$z@f}op}A-(w-$z z>lPRBmOOgcv!`h;OCHA)*Eeq#D-^oL9n}BuGM0t$&(pS(!9_aTWK>s7IGh-ICh2g0 ztIQOsZ)z=q6PZIU&l1}5YvVKpm$rBQ|1`ez@3@kbpz-$GthuLu?nq@@z_Re$1^a78 z@9#PLN6%;v-Rbw>`J|p|i>;5RO>Ga={&e!1wNuY;QM;yq{ahXbufn-FopgU*-1ofD zR8arYehZ;3CnCy1&n%IhbtXN<$XYRqQ({G)(zkfs)!S{wXO#*sbm9xxoTn6W;^NAy zM&agyQO#FZ;_I}~6K`1rl%?42aV$)H&?^9D{QK}uOp@;&hpv&d zOz`RtZX7e!rr3X-8z6d*L(xcD=WW;ho>RNh*Sz`vxQwAfIphRm)*DmQ%OPf?3m=&7Dr0EL3q`m^x{;(Tc`y$qFT+JI(pdELqPPIwz(h7x<76|EDZ_};d>mSMI~7drE{D! zKoL~*!7XEE%}ZX88;Vv4q`DkFAZ@q^?rMzCnE3HQ%c>7<920MD5Wbhz`=<;!40u<7 z0K}!C|-WTpt!k9BTnfl<=s5&`7L5IdHYs|Rw%ces3>p( z(>WKO=RDk_@vGw15>?I(&v{M-^JW~(^q#Px=_o_}C)Mx*?Fr@c`Ce*9^i5cBW0Kqr z#kvWf4jz_$W0&VCuw_bwi_|K0)F z#ji>gYtNpHxyoYy`MJotH%p$LEXw6wC-ky9@~Ei7>Po-*&>0#0;je1{qWm)~+S4ohZO{U`r>lQ>CKPid8xTG zYn((D`5xFIweFsOwb$HTi>B#q6P}gut?b$*cFXt`Z+|;3+>muK!^T&ldO;TF$6ulS z7jkOr*3I8gzP)JmwljzGPwiUw(Q0SJ%>N0R_!j3sy)k$Y@mAtHHFz_wqiUvbTF&&(D#Zq}=CbqkPWl ztm_`BiJ#}*&p+2w@#EZX|MZ2QkN96w=xbYh?rYiUkIMRT>=$ot`1<3^xvhVvO-{=* zDLZWOseNsF-L0zc$IjP(JNL=p?7Y^xR|i-Et1LdZt<9WvmcP6#DF4;@J7217zAOJI z5>hudZ|*;N^V}KVbK;+~<7{T{jx^vpq)@%>a_;u;QAx8}jJ$1TvdpWu{w8K@f9k`( zxkvaDk6CyvKWK9{Jvt~Y`q;^ec}M2WU$)?j&Xdn)?qgq-?QxCjsI7#^vf;(w?pRtQ&}Dx!^PtIi*jzfddGW#Ink=_{mSR(BTq2I zJvqnli*YyO9JYnJ4;MIeFPPHC9}-ab;kso?yCjFsZobr4yLEQUOo?aBvdN#WDX_@1 z)llSN?~^xc%{`JWe@}aQXRD2T!K6@YKArRIM{+{#&KPnRPChEvpKJN1ie1{M>270S zb_x5jr59x-3f;;Rd?fES1}2xVA8WlR`=WBO^@Z(EtnX-aHTFoFrv1Czb5yc%xta02 z`6lzygpSW_&9o7ZydU(pO{}Oc{lH;-Nfo$m-GJ+~0n4w}IHa zl$o~sZb|#p-Ir(Yj?9yaeXDc&{ORVmiUCJ@Irm*p*E2Glc%jL%VG+}MyECB&esX^L z9Cfs&?pbozpFNvy7S%QV*~53MsP61GH$KJ3fA;bom*&&l%XVyMwMcuRQDjRc-<3;; z4_GvFbIjs8<{5LwU#YXPkZt{i<;9mjKbX@fwEWn<2M#mRN<@;&3q*X(thzP^uR4>J zV4ln#x?vYv#MvF!7*5ao#U9RxvJbAg0E7z;mrhd#ub*8*PCyELd(!xWRBKkbH)=h zvH;fA3#=ePoS0yymd_**w~19CZDQx_HxtYqL3S`? z`Q7`f@a@FxhSW2>tjkYEzFB@0JIUk5|W_Izd2ngLHdi?phHuWW`PfZw|+PK^j1s-3%bpFFm$I5pH z+un6t{@y=l_nvf*o&3&OUw1}joStO8CPG@s>{a6&NgICKoU@M@+4e0vgXAlI9?&?q zEQiNMWV_>Y>D|BY_(zC~F_r#|efc@b!6bO;`ThuNnf)vDpB>~(u$!{S?Yh(MzD2P& zC%1a_#=KCe-Y;hebRgRiO<&38M_lzUWp);azj zY13Dq&*<*b{8_5)|K^Z@$Lf>!b>7Qf@LaL%lh^e|w{mgGctWtqpF({p zXEi5(Lp53T%O8UevV8bEQNHbatjZRhd9U?(|8hPSoU!8au_&zGwk2oxp1m#XV|n=P5WY}YFsPnT@Vm@Oh9Mb zp(jZ^LR%ITaiw-F^{;Vl(xP z0zxO0uU!?sitl~fbY=gNNGT1au=Kr3N)H;&d@N=Epg%$STHzbc+Ix>J`X7E}`Fn2N z44++WFZ%?A<2K!Ip6=RE@ZdnrK9i#7%MJ6sAKBvdG_to~;)){MV%CkD)*sc_gqsOYXI%Cb#Rf|4Fm%Y?~y1 zZ`yhmzV9Dj**)|Me(3Nq?BcXt2jjK9Im>gVPALDm;a+R@x8SU&_hVQ7soZu=7OJmW`P}5mtU2rW7W_K?dZ|m) z&IOz2&vq(zEx#cC>~ieI+s$D|dNuyutv%Se%d+e@yXmBNUlq@pE#j%#xwus0_uZP? zD|R#Sgehk(zbkj8<5s4;%#{$f+1eVX;%`D**gQ-MyJbCz?2 z@9RI&xQW;QVeO4 zC<-|G=;>n9r7rvGri5v^p9(gxOFQrNM<6hH>AYiJTYoP)^>K2nbLZFfTPBUX?_b^1rL=b@iCz;9J?f*>;dOM@n>%4UR=XK~y}>C`{rTbh(ymVV(trO& zgZ;nh#sB;K>3#jqny<4@`^U%BeVpod_?Bt)>sgO$&=!&+?*BbMwA zn!&L4q1NhucT$DUzB+07`Ri)^`1Nmqy!O)d{Z4gE$I{|9t3wAF;I| z{J|mJ>s$p<{mEO-+&E_PE6H(TzgpX(OUI?m{{HelvG)4^f3Ii%ue;ZJpz`n4`LA=7 zBo^7QB`vouxN>-BW9g|(`5JT9M7n$T&edGhsBZLT_tQnT4|A64e0(CjdXbBnLFbaW*WRe{ zOw;y~IGwUUX3Z3%eyhmxt;(-TWAjV?^Nc8ufet_pCp|5HZa?_A~bim^^{+`ho7eN8r($y_$}aCJg4$r z`}9t=+^y;EvB8-EP477qq^6$qy5o6c&GWs221S}_FYhgwR&a@Bvc;kR*%LFhJY!E; zu}*3^WGP*A&!qQy#3zxW$I`i6TKu^2!|y%TzVd-P(hl2SE-cC2cs%F*t{&T05)Dou}oO`tDPNI(f&xedQEYA&9dN(R?ONXaUpR_+g z=M-PHVEUD9S2AN>xGpllfGTE){R+uUd0C=At=*r&dQ>*_>#-qQy^KGOZWer1u- z^X~Is&jly&nSQ(1(elT?FFEbhQn?!|oZe0{*!phb`STv~+7$x2Zu?lwbRHaK75(|~ zlgNz?Ev4#B6FLPx{e1L?<%Ubc{d>~7u1dT9_?>>RC_AX||G|YP*bXd1y~y@(_lf$a4auz1nmp?|8S+~?Io^0TY<<0VgY~~1rS+yu z|LSc1n_cs1>+Vx??Ee4O^GmC}xbk*|V)3G7{Q99DYYD%0-_{j#85tP1GJzJ#A|>AB{G!y+ z)C){$P^BrF8;lIb^Hvi%3`(@|c!K z2E4dnW3=s=oy=Pn^O%|^!UrrBrFXEMSN$&Io^b1n%N7T(i^{Wwqe~ey4MGB%zwuq} zd1N2Ozpd=Q%nPgYQ?`EEtoCNhhTn5^kM6m-+JEk=*4*1^Zx?J9{1aTW<9FKrXwy)u zG*yO;L0yNm;~9UKR(}8R_u0$O(~sZw=f7WP6MO&vo*gwdyJxj+*u3Y+UV}ak?mN<_ z@6DU>ebsASZNm>;*88RJJ@aU+u}o(7^1i%FMd|$hX+QE^Wi}avek{GI5dYq!Rx##= ztI>YZ6rpK4&nD_vvp0vYKW^RewB?!RQq7xEmlHSoaXHz!RBL}Od|A0LZpI&dLv_uY zJ}(P=J}E6NhX80=YNg)aRp23=G#f7#M_LL#}E0c_krbZ$0uXts2YAs!E=l)Iq{`aphp6nGlC~G_|d#ci=?!W^f>(pa>gG;I>zg5xL z(6@?HG-{*BUE^-QzW99>Q9Rsh=kP9wzq#;Cuu1VcnYM*z(|v+=ul8Q{;JA~tr)-Vs z<$$2id2#QaL`}Q$(NO%(-FCrazgI{mo6TI*-Sj+X$>*IZr>_28n8>7-m72b1%iAqS z)h>(O^6^?+oTfV`lFQydXx+4Ak3Sg`p6t9BCY~qGC;Usc^{PgO`i{CuOsq!o`{rro zzKCGh&DwdfkXbK+M|5hyo`;ieKIqbIGLH%h)z?^gX_{a}vAb(m0n2wgxd*l~ht->w zOSE2HQsdT}nzvKncafv2`1jnaSBhVMRW1LyX6^mJ!>fCL%AH>R;qaZl!Y)07V;5bg zDaI>mTD6~Y+*E!oMCrzq{d}`eB}6i^9z6ES@~hCJ=MJpTOk%&D9V}-xRwRcA8u;b1CtADiIggAE7m|Vq?gn&UubH7E$8fr3y0o+S(hpC+eg&va;5MqE6=`R-iD zw21k}2ZC-}9WJi;{Ypn_!U}J3-W6vVJudWTJ}$Ra+kV0MYtrh~iJQ)_T?(70@L>16 z6K!r1-+q8*5wNV)i0V?UWMp7)VrF0vfhGF#)TCgfO%GFoeEpdW1@_MVA#b+VS=`0h z?9C*BMTQ6aHLBj1?eN$x%7CIZe>BBxhjnW!L zlj7JFtp`&$!;Jg=qXW;rIlk##!3ERLM$^51nZ7;#k@x1Q8^Iw9bX3KIA9(Bb@YiIu zI=LF;DQ0gE&h`t;J|MQ0Rd3GWx-D5>O(v)5UzV2P%si=Up;0S7dtt6?iE`_gI2oI@ z9!n~V;w3legj*b3X09OFw|;{5_N{@FPbjG#J{T&)|NFY)T<4ARPKhoH^Ld!Yakrtc z%sB8@tjRt1_>`?b)NR^-Nmw(!cl_U(Y&rQ*-oFp_GR@ZN93}CZ2TwaJPm`(Uuw!T4 zp|$PHg=q`%Zm;ansfu z%gsq?zvX8ZyJdn&wesoC162wq^L$_K4_B;xvwP2(rv+&@p2hYih@JCZ>^(z`g=yi= zmrL!Ye)zh8q@&&l(5_wEw?-KL)q z;P_4TPsZkDxyF+ecb%1BpJ%VQVR|}OUu_`Ny zVU5TaMg|5?E>L$25>5y*+BrY3BsH%jKBTfBwKx`(m;$^}4VW2P#|lb+51AMkxDh%T z7#MU}7#JWudvJ#yU1O{vo2Cd81H)2&1_l`vjY;g#JysCiDf!8zxv6<2AltE;B(y2^ zagYoH!`bVgW+$>yJGh`GA)A5j5Q*3u-&|Q37?QX^T`pwpmg-RL8L5dWsYS*h7oh9T zkXpa9k%fWb4-dNTHQFe;!ChN)-Re4*rt-;A>Q2kgFG(%JYIjr6F4aSf3=C6P(Sxnf5~@2jFC{O(Bo(|W58df*vb)}aw9jIN zG>i}dmt+mq4ze7l{HRceC^u7(f`+jI*&=%rM4ghR)K3>v_c(7(f`+jM+U{%rL`d#z)uB z(^Tvj7(f`+j5~|4m|=>|4F8^2R^b8+3?PhZhRH)LW*A~K!?;0+uU3nJ0fbS_*#8lW z87A1wSY22mU*OBY0K%Z-qabktA`4^~AzLt!;>8kS1fp!4wsq~JX>1G(0n!W%s7459 zL5(QMNX<>v2a`y71d%%YpNFdRe`a6+VN@gT6hMtYas}4F5cdC`Xr{o(0K%w7$fYo0 zcm!+u%9IL@UN6AF0K%x@+1|p8VT7RpA}|m>Ir;EJ#Kt8I3?Pi^jI61cW?+qye;dD9 zC7LoafH0~NepW0P&cK?=mzFM7+N;aJ0K%w7Jj!RqFam2Lw~}3KdO(+f0fbSFxHK2j z2n%dsvGW>VO;;`h0|=uUar88%5m>Vc`srq%gbBe-mTVXv0iSgSDK!wu6Mb7TL_3J| z@q!wGyvZ0{JNkNRkVXie6baLgZFM!eIjC#1ASOV_zC<>hE49!~L0_2!F#$wgOG0rC zwt5V8W&orKh9~DEI{{K3fR>DbGb`5G0CjvBW)6s+S%_>F+!S=5ppL+TG{W$XA~pu} z@mO@-s6${doglij6iGL1Knz_w`e*}4BLsU^K!Xuw>;YZ>L9~t=L@$W6tA^@F>&Bs* kfZCq`>4f2zHOL--_bvjwS=m5JG#E4(g18tM)apT80E&*P00000 literal 0 HcmV?d00001 diff --git a/eastcom_yw/pom.xml b/eastcom_yw/pom.xml new file mode 100644 index 0000000..5f6e821 --- /dev/null +++ b/eastcom_yw/pom.xml @@ -0,0 +1,85 @@ + + + + ruoyi + com.ruoyi + 3.8.4 + + + 4.0.0 + + jar + + eastcom_yw + + + 东信业务 + + + + + + + + + + + + + + + com.ruoyi + ruoyi-common + + + + + com.baomidou + mybatis-plus-boot-starter + + + com.ruoyi + ruoyi-system + + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + provided + + + org.mapstruct + mapstruct + ${mapstruct.version} + + + com.ruoyi + ruoyi-framework + + + org.springframework + spring-test + + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.core + jackson-core + + + + + + + 8 + 8 + UTF-8 + + + \ No newline at end of file diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/AlarmConstants.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/AlarmConstants.java new file mode 100644 index 0000000..4ab0bdf --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/AlarmConstants.java @@ -0,0 +1,9 @@ +package com.ruoyi.eastcom_yw.common.constant; + +public class AlarmConstants +{ + + public static final String [] ALARMS = new String[]{"cs","wx","dh","agis","wifi","voip","yayun"}; + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/CacheConstants.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/CacheConstants.java new file mode 100644 index 0000000..e3aaf02 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/CacheConstants.java @@ -0,0 +1,8 @@ +package com.ruoyi.eastcom_yw.common.constant; + +public class CacheConstants +{ + public static final String YW_ALARM_LAST_VENUES = "yw_alarm_last_venues:"; + +} + diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/KpiConstants.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/KpiConstants.java new file mode 100644 index 0000000..f63e535 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/KpiConstants.java @@ -0,0 +1,53 @@ +package com.ruoyi.eastcom_yw.common.constant; + +/** + * @author yqf + * @date 2023/4/12 + */ +public class KpiConstants { + + public static final String YW_KPI_COLOR_DEFAULT = "#000000"; + + public static final String YW_NETTYPE_4G = "4G"; + + public static final String YW_FIELD_RPB_UP = "上行Prb利用率"; + public static final String YW_FIELD_RPB_DOWN = "下行Prb利用率"; + public static final String YW_FIELD_MAX_USER = "最大用户数"; + public static final String YW_FIELD_AVG_DIS = "平均干扰值"; + public static final String YW_FIELD_ALL = "综合算法"; + + public static final String YW_QUERY_ALL = "综合得分"; + + + public static final String YW_SORT_DESC = "desc"; + + public static final String YW_DATATYPE_15 = "15分钟"; + public static final String YW_DATATYPE_1 = "1分钟"; + + public static final int YW_SCENE_RUNTYPE = 1; + + public static final int YW_MINTYPE_1 = 1; + + public static final String QUERYSEAT = "P"; + + public static final String FIELD_4G_GB = "上行流量mb"; + public static final String FIELD_4G_DISTURB = "上行平均干扰"; + public static final String FIELD_4G_MAXUSER = "最大用户数"; + public static final String FIELD_4G_PRBUP = "上行prb利用率"; + public static final String FIELD_4G_PRBDOWN = "下行prb利用率"; + + public static final String FIELD_5G_GB = "上行5g流量"; + public static final String FIELD_5G_DISTURB = "上行干扰值"; + public static final String FIELD_5G_MAXUSER = "最大用户数"; + public static final String FIELD_5G_PRBUP = "上行prb利用率"; + public static final String FIELD_5G_PRBDOWN = "下行prb利用率"; + + public static final String FIELD_AGIS_FLOWCOUNT = "ul_flow + dl_flow"; + public static final String FIELD_AGIS_UL_VELOCITY = "ul_velocity"; + public static final String FIELD_AGIS_DL_VELOCITY = "dl_velocity"; + public static final String FIELD_AGIS_UL_BAND_RATIO = "ul_band_ratio"; + public static final String FIELD_AGIS_DL_BAND_RATIO = "dl_band_ratio"; + + public static final String ORDER_DESC = "DESC"; + public static final String ORDER_ASC = "ASC"; +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/NetElementConstants.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/NetElementConstants.java new file mode 100644 index 0000000..b8dd395 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/constant/NetElementConstants.java @@ -0,0 +1,15 @@ +package com.ruoyi.eastcom_yw.common.constant; + +/** + * 网元常量 + * + * @author los + */ +public class NetElementConstants { + + /** + * 网元导入是否单场馆覆盖 1 是 0 全覆盖 + */ + public static final String SINGLE_SCENE_COVER = "1"; + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/FlowDealStatus.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/FlowDealStatus.java new file mode 100644 index 0000000..caa0a7c --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/FlowDealStatus.java @@ -0,0 +1,59 @@ +package com.ruoyi.eastcom_yw.common.enums; + +public enum FlowDealStatus { + + BUSINESS_STATUS_0("0", "待处理") ,BUSINESS_STATUS_1("1", "正在处理") ,BUSINESS_STATUS_2("2", "挂起") , + BUSINESS_STATUS_3("3","驳回"),BUSINESS_STATUS_4("4","已结束") ,BUSINESS_STATUS_5("5","撤销"); + + /** code */ + private String code; + + /** 显示标签 */ + private String label; + + FlowDealStatus(String code, String label){ + + this.code = code; + + this.label = label; + } + + public static String getLabelByCode (String code) { + + for (FlowDealStatus enuma : FlowDealStatus.values()) { + + if (enuma.getCode().equals(code)) { + + return enuma.getLabel(); + + } + + } + + return ""; + + } + + + @Override + public String toString(){ + + return label; + + } + + public String getLabel() { + + return label; + + } + + + public String getCode(){ + + return this.code; + + } + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/InRedLine.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/InRedLine.java new file mode 100644 index 0000000..3e2b406 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/InRedLine.java @@ -0,0 +1,45 @@ +package com.ruoyi.eastcom_yw.common.enums; + +import lombok.Getter; + +/** + * 是否红线内 + * + * @author los + */ +public enum InRedLine { + + /** + * 红线内 + */ + IN_RED_LINE("Y", "内"), + /** + * 红线外 + */ + NOT_IN_RED_LINE("N", "外"); + + /** + * code + */ + @Getter + private String code; + + /** + * 标签 + */ + @Getter + private String label; + + InRedLine(String code, String label) { + this.code = code; + this.label = label; + } + + @Override + public String toString() { + + return label; + + } + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/WireTaskSubType.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/WireTaskSubType.java new file mode 100644 index 0000000..6efa05a --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/WireTaskSubType.java @@ -0,0 +1,58 @@ +package com.ruoyi.eastcom_yw.common.enums; + +public enum WireTaskSubType { + + AGIS((Integer)1, "AGIS专网") ,INTERNET((Integer)2, "互联网(WIFI)专网") ,VOIP((Integer)3, "固话(VOIP)专网") ; ; + + /** code */ + private Integer code; + + /** 显示标签 */ + private String label; + + WireTaskSubType(Integer code, String label){ + + this.code = code; + + this.label = label; + } + + public static String getLabelByCode (Integer code) { + + for (WireTaskSubType enuma : WireTaskSubType.values()) { + + if (enuma.getCode().compareTo(code) == 0) { + + return enuma.getLabel(); + + } + + } + + return ""; + + } + + + @Override + public String toString(){ + + return label; + + } + + public String getLabel() { + + return label; + + } + + + public Integer getCode(){ + + return this.code; + + } + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/WireTaskType.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/WireTaskType.java new file mode 100644 index 0000000..334a737 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/common/enums/WireTaskType.java @@ -0,0 +1,58 @@ +package com.ruoyi.eastcom_yw.common.enums; + +public enum WireTaskType { + + WIRETASK1((Integer)1, "布线") ,WIRETASK2((Integer)2, "拆线") ,WIRETASK3((Integer) 3,"布线结算") ,WIRETASK4((Integer) 4,"拆线结算") ; + + /** code */ + private Integer code; + + /** 显示标签 */ + private String label; + + WireTaskType(Integer code, String label){ + + this.code = code; + + this.label = label; + } + + public static String getLabelByCode (Integer code) { + + for (WireTaskType enuma : WireTaskType.values()) { + + if (enuma.getCode().compareTo(code) == 0) { + + return enuma.getLabel(); + + } + + } + + return ""; + + } + + + @Override + public String toString(){ + + return label; + + } + + public String getLabel() { + + return label; + + } + + + public Integer getCode(){ + + return this.code; + + } + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/AppVersionConfig.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/AppVersionConfig.java new file mode 100644 index 0000000..ddfc526 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/AppVersionConfig.java @@ -0,0 +1,39 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("app_version_config") +public class AppVersionConfig { + + @TableId(value = "id") + private Long id; + + private String device; + + private String versionCode; + + private String packageUrl; + + private String describe; + + private String force; + + private String packageType; + + private String versionName; + + private String wgtVersion; + + private String wgtUrl; + + +} diff --git a/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2AgisLink5mi.java b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2AgisLink5mi.java new file mode 100644 index 0000000..9e8b875 --- /dev/null +++ b/eastcom_yw/src/main/java/com/ruoyi/eastcom_yw/domain/Dp2AgisLink5mi.java @@ -0,0 +1,133 @@ +package com.ruoyi.eastcom_yw.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *