From 196bb14112448857a885e32dc4149e308e00b01a Mon Sep 17 00:00:00 2001
From: feiyu02 <risaku@163.com>
Date: 星期四, 15 八月 2024 11:57:15 +0800
Subject: [PATCH] 2024.8.15 各项修正

---
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/VocPurifyDevice.java                             |  227 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/DustSiteMap.java                                 |  144 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/HourDustData.java                                |  324 
 src/main/kotlin/cn/flightfeather/supervision/common/docimport/ExcelImport.kt                                |   42 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnConstructionSiteInfo.kt                        |   69 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/LedgerSubTypeVo.kt                               |   14 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/LedgerSubType.java                               |   96 
 src/main/resources/application-pro.yml                                                                      |   17 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnLampDeviceData.kt                              |   93 
 src/main/kotlin/cn/flightfeather/supervision/SupervisionApplication.kt                                      |   22 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/BaseInfo.java                                    |   34 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/OnLineQuestionServiceImpl.kt           |  829 +
 src/main/kotlin/cn/flightfeather/supervision/bgtask/BaseTimingTask.kt                                       |    8 
 src/main/resources/mapper/IndustrialBaseInfoMapper.xml                                                      |   26 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/RiskEvaluation.java                              |  241 
 src/main/resources/application-dev.yml                                                                      |   18 
 src/main/resources/mapper/CityMapper.xml                                                                    |   20 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/NoticeTimingTask.kt                           |   76 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/ConfigController.kt                             |   33 
 src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskAuthenticated.kt                               |  101 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/OperationController.kt                          |   31 
 src/main/resources/mapper/LampEnterBaseInfoMapper.xml                                                       |   32 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnConstructionInfo.kt                         |   98 
 src/main/resources/font/方正兰亭超细黑简体.ttf                                                                       |    0 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/EnvironmentalSchedule.java                       |  409 +
 src/test/kotlin/cn/flightfeather/supervision/common/net/JinAnLianTongHttpServiceTest.kt                     |   24 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/NotificationVo.kt                                |    4 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/RiskServiceImpl.kt                     |  117 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/PracticalOperationVo.kt                          |    9 
 src/main/kotlin/cn/flightfeather/supervision/common/risk/DbMapper.kt                                        |   28 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/WxUserServiceImpl.kt                   |   24 
 src/main/kotlin/cn/flightfeather/supervision/common/score/EvaluationUtil.kt                                 |   46 
 src/main/resources/templates/word.html                                                                      |    4 
 src/main/kotlin/cn/flightfeather/supervision/common/wx/TemplateManager.kt                                   |   21 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AuthSceneVo.kt                                   |    6 
 src/main/kotlin/cn/flightfeather/supervision/common/pdf/PdfUtil.kt                                          |  138 
 src/main/kotlin/cn/flightfeather/supervision/common/net/FumeHttpService.kt                                  |   77 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/LampDeviceDataMapper.kt                          |    8 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/PracticalOperationMapper.kt                      |    8 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/ProvinceMapper.kt                                |    8 
 src/main/resources/mapper/FumeMinuteValueMapper.xml                                                         |    2 
 src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskLedger.kt                                      |  153 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ConfigService.kt                            |   24 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/IndustrialBaseInfoMapper.kt                      |    8 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/UserConfigMapper.kt                              |    8 
 pom.xml                                                                                                     |   56 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnLampDeviceData.kt                           |   33 
 src/main/kotlin/cn/flightfeather/supervision/domain/repository/PracticalOperationRep.kt                     |  107 
 src/main/kotlin/cn/flightfeather/supervision/common/risk/UtilFile.kt                                        |  148 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/UserSpecialInfoController.kt                    |   54 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SelfPatrolTaskMapper.kt                          |   27 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/SelfPatrolTask.java                              |  219 
 src/main/resources/mapper/TownMapper.xml                                                                    |   22 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/EvaluationController.kt                         |   47 
 src/test/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnConstructionSiteInfoTest.kt                    |   50 
 src/main/resources/mapper/RiskEvaluationMapper.xml                                                          |  225 
 src/test/kotlin/cn/flightfeather/supervision/bgtask/TaskLedgerCopyTest.kt                                   |    3 
 src/test/kotlin/cn/flightfeather/supervision/common/risk/RiskAnalysisTest.kt                                |  109 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/AuthController.kt                               |    8 
 src/main/resources/mapper/OverallEvaluationMapper.xml                                                       |  222 
 src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/UserType.kt                                 |    9 
 src/test/kotlin/cn/flightfeather/supervision/bgtask/PushFumeTest.kt                                         |   20 
 src/main/kotlin/cn/flightfeather/supervision/common/net/SkipCertificateValidation.kt                        |  150 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EnforceCaseServiceImpl.kt              |   17 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/BaseInfoController.kt                           |   41 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ComplaintServiceImpl.kt                |   20 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/OperationServiceImpl.kt                |   57 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/SysNoticeTemplate.kt                          |   47 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskLedgerRemind.kt                                     |   11 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EvaluationServiceImpl.kt               |  368 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/PersonalInfo.java                                |   41 
 src/test/kotlin/cn/flightfeather/supervision/common/wx/TemplateManagerTest.kt                               |   11 
 src/main/resources/application.yml                                                                          |   39 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ScheduleService.kt                          |   15 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/EvaluationService.kt                        |   15 
 src/main/resources/mapper/UserConfigMapper.xml                                                              |   40 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/LedgerServiceImpl.kt                   |  417 
 src/main/resources/mapper/DeviceInfoMapper.xml                                                              |    3 
 src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ConfigServiceImplTest.kt               |   34 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/ScheduleVo.kt                                    |  147 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/DistrictMapper.kt                                |    8 
 src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/ExcelUtil.kt                              |   19 
 src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/AssessmentRuleType.kt                       |    6 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskLedgerCopy.kt                                       |    4 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/HazardousWasteServiceImpl.kt           |   20 
 src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/LedgerServiceImplTest.kt               |    2 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnLampEnterBaseInfo.kt                        |   42 
 src/main/kotlin/cn/flightfeather/supervision/common/creditcode/EnvCreditCode.kt                             |  123 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ProblemService.kt                           |    4 
 src/main/kotlin/cn/flightfeather/supervision/domain/repository/LedgerMediaFileRep.kt                        |   69 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/ScheduleOption.kt                                |   23 
 src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/FileUtil.kt                               |   18 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/Userinfo.kt                                      |    6 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/OverallEvaluationMapper.kt                       |   11 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/UserSearchCondition.kt                           |  113 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ComplaintService.kt                         |   10 
 src/main/resources/mapper/VocPurifyDeviceMapper.xml                                                         |   26 
 src/test/kotlin/cn/flightfeather/supervision/CommonTest2.java                                               |   12 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/SelfPatrolServiceImpl.kt               |  461 +
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/UserBaseInfo.kt                                  |   18 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/UserinfoService.kt                          |   25 
 src/main/kotlin/cn/flightfeather/supervision/common/exception/ResponseErrorException.kt                     |   13 
 src/main/kotlin/cn/flightfeather/supervision/scheduler/ScheduleService.kt                                   |   57 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SceneTypeMapper.kt                               |    8 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/BaseInfoMapper.kt                                |    9 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/BaseResponse.kt                                  |   38 
 src/main/kotlin/cn/flightfeather/supervision/domain/repository/UserConfigRep.kt                             |   82 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/NotificationController.kt                       |   24 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/AuthService.kt                              |   10 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/NoticeConfig.kt                                  |    7 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/SelfPatrolController.kt                         |   86 
 src/main/resources/mapper/UserinfoMapper.xml                                                                |  125 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/package-info.java                                       |    2 
 src/main/resources/mapper/PracticalOperationMapper.xml                                                      |   34 
 src/main/kotlin/cn/flightfeather/supervision/domain/repository/UserInfoRep.kt                               |   70 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/LedgerController.kt                             |    9 
 src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskAnalysis.kt                                    |  189 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/Itemevaluation.kt                                |    3 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/EnforceCaseService.kt                       |   10 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/DeviceController.kt                             |   36 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/VOCHourValue.java                                |  153 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/CreditController.kt                             |   32 
 src/main/resources/mapper/NoticeMapper.xml                                                                  |    3 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnHourDustData.kt                             |   43 
 src/main/resources/mapper/PracticalOperationRecordMapper.xml                                                |   25 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/CompanyService.kt                           |   13 
 src/main/kotlin/cn/flightfeather/supervision/common/risk/DataSource.kt                                      |   61 
 src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/DateUtil.kt                               |   25 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/DataVo.kt                                        |    6 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/EnforceCaseController.kt                        |   28 
 src/main/resources/mapper/PersonalInfoMapper.xml                                                            |   36 
 src/main/resources/templates/qr_code_bg.png                                                                 |    0 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/RiskEvaluationMapper.kt                          |   17 
 src/main/resources/font/STSONG.TTF                                                                          |    0 
 src/main/resources/mapper/LedgerRecordMapper.xml                                                            |    6 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/UserSpecialInfoService.kt                   |   22 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnLampEnterBaseInfo.kt                           |   61 
 src/main/resources/mapper/UserMapMapper.xml                                                                 |   21 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskController.kt                                       |   34 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/SysNoticeManager.kt                           |  178 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/ScheduleRepositoryImpl.kt           |   24 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/NoticeTrigger.kt                              |   68 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/ScheduleSignRecordRepositoryImpl.kt |   21 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/BaseInfoService.kt                          |   17 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/BaseInfoVo.kt                                    |    9 
 src/main/kotlin/cn/flightfeather/supervision/common/autoledger/AutoLedger.kt                                |  172 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/AuthServiceImpl.kt                     |  118 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/CityMapper.kt                                    |    8 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/HourDustDataMapper.kt                            |   13 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/PracticalOperationRecordMapper.kt                |    8 
 src/test/kotlin/cn/flightfeather/supervision/common/creditcode/EnvCreditCodeTest.kt                         |   29 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/ScheduleSignRecord.java                          |  121 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/UserinfoServiceImpl.kt                 |  184 
 src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/QRCodeUtil.kt                             |   88 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/SceneType.java                                   |   58 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/IndustrialBaseInfo.java                          |  234 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/EvaluationMapper.kt                              |    4 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AuthSceneIndVo.kt                                |   65 
 src/main/resources/mapper/DustSiteMapMapper.xml                                                             |   24 
 src/main/resources/mapper/BaseInfoMapper.xml                                                                |  157 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/SelfPatrolRecord.java                            |  582 +
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/NoticeMapper.kt                                  |    3 
 src/main/resources/application-test.yml                                                                     |   22 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/QCondition.kt                                    |    2 
 src/main/kotlin/cn/flightfeather/supervision/common/docimport/BaseExcelRule.kt                              |    5 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/LedgerVo.kt                                      |   96 
 src/main/resources/templates/ledger-3206.html                                                               |  123 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/Town.java                                        |  126 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/HazardousWasteService.kt                    |    9 
 src/main/resources/mapper/SelfPatrolRecordMapper.xml                                                        |   47 
 src/main/resources/mapper/NoticeTemplateMapper.xml                                                          |   34 
 src/main/resources/mapper/UserLoginLogMapper.xml                                                            |   18 
 src/main/resources/templates/commitment-laboratory.ftl                                                      |  218 
 src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskAssessment.kt                                  |   90 
 src/main/kotlin/cn/flightfeather/supervision/common/score/item/ScoreItem_13.kt                              |    3 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ProblemServiceImpl.kt                  |   10 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/DustSiteMapMapper.kt                             |    8 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/ScheduleSignRecordRepository.kt          |   12 
 src/main/resources/mapper/VOCHourValueMapper.xml                                                            |   41 
 src/main/resources/mapper/EvaluationMapper.xml                                                              |   74 
 src/main/kotlin/cn/flightfeather/supervision/common/net/HttpMethod.kt                                       |   26 
 src/test/kotlin/cn/flightfeather/supervision/bgtask/TaskFetchVOCTest.kt                                     |   22 
 src/main/resources/templates/commitment-industrial.ftl                                                      |  183 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/UserConfig.java                                  |  430 +
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/DeviceService.kt                            |   20 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/LedgerService.kt                            |   14 
 src/main/resources/mapper/LedgerSubTypeMapper.xml                                                           |    6 
 src/main/resources/generator/generatorConfig.xml                                                            |   86 
 src/main/kotlin/cn/flightfeather/supervision/config/Swagger2Configuration.kt                                |    7 
 src/test/kotlin/cn/flightfeather/supervision/CommonTest.kt                                                  |   61 
 src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/SceneType.kt                                |   40 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/SelfPatrolTaskVo.kt                              |   24 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/LampEnterBaseInfo.java                           |  375 +
 src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/AuthenticationType.kt                       |    9 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/NoticeTemplateMapper.kt                          |    8 
 src/test/kotlin/cn/flightfeather/supervision/bgtask/maintenance/MTJinAnHourlyDustDataTest.kt                |   42 
 src/main/kotlin/cn/flightfeather/supervision/config/WebMvcConfig.kt                                         |   18 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ScheduleServiceImpl.kt                 |   95 
 src/main/resources/mapper/HourDustDataMapper.xml                                                            |   43 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/DeviceInfo.java                                  |   24 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/SelfPatrolMediaFile.java                         |  253 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/VocPurifyDeviceMapper.kt                         |    8 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/CompanyController.kt                            |   35 
 src/main/kotlin/cn/flightfeather/supervision/domain/util/MyMapper.java                                      |    6 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/SelfPatrolService.kt                        |   59 
 src/main/resources/mapper/EnvironmentalScheduleMapper.xml                                                   |   72 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/OverallEvaluation.java                           |  136 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/CreditInfoVo.kt                                  |    9 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/PracticalOperation.java                          |  408 +
 src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskAutoLedger.kt                                       |   52 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SelfPatrolMediaFileMapper.kt                     |    8 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ConfigServiceImpl.kt                   |   68 
 src/main/resources/mapper/DistrictMapper.xml                                                                |   21 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/ScheduleController.kt                           |   34 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/UserMap.java                                     |   18 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/Province.java                                    |   58 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/CompanyServiceImpl.kt                  |   50 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/MeetingVMRoomRepositoryImpl.kt      |    4 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/OpenApiWordController.java                      |   17 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/UserLoginLog.java                                |   66 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/CommitmentService.kt                        |    3 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/ScheduleSignRecordMapper.kt                      |    8 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/PracticalOperationRecord.java                    |  217 
 src/main/resources/mapper/LampDeviceDataMapper.xml                                                          |   28 
 src/test/kotlin/cn/flightfeather/supervision/common/autoledger/AutoLedgerTest.kt                            |   35 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskScoreRemind.kt                                      |   10 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/NotificationService.kt                      |   14 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/DataCatageryCountVo.kt                           |   16 
 src/main/kotlin/cn/flightfeather/supervision/domain/repository/EvaluationRep.kt                             |   57 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/maintenance/MTJinAnHourlyDustData.kt                    |   99 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/CreditServiceImpl.kt                   |   59 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/NoticeTemplate.java                              |  126 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/OperationService.kt                         |   25 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/DustSiteInfoMapper.kt                            |    8 
 src/test/kotlin/cn/flightfeather/supervision/common/score/AutoScoreTest.kt                                  |   10 
 src/test/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/UserInfoRepositoryImplTest.kt       |   73 
 src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/SelfPatrolTaskStatus.kt                     |   15 
 src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskCommitment.kt                                  |   61 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EvaluationsubruleServiceImpl.kt        |   27 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/CommitmentController.kt                         |    6 
 src/main/kotlin/cn/flightfeather/supervision/common/score/AutoScore.kt                                      |   54 
 src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/WxUserServiceImplTest.kt               |   25 
 src/main/resources/application-proapp.yml                                                                   |   13 
 src/main/resources/mapper/DustSiteInfoMapper.xml                                                            |   64 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/DustSiteInfo.java                                | 1036 +++
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/TownMapper.kt                                    |    8 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/City.java                                        |   92 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/CountVo.kt                                       |   12 
 src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EvaluationServiceImplTest.kt           |   34 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskPushFume.kt                                         |  224 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/District.java                                    |  109 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/CommitmentTemplate.java                          |  297 
 src/main/resources/mapper/ProvinceMapper.xml                                                                |   18 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/LampDeviceData.java                              |  288 
 src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/NotificationType.kt                         |   28 
 src/main/resources/mapper/SelfPatrolTaskMapper.xml                                                          |   61 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AuthSceneRestVo.kt                               |    4 
 src/main/kotlin/cn/flightfeather/supervision/common/net/JinAnLianTongHttpService.kt                         |  199 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/LampEnterBaseInfoMapper.kt                       |    8 
 src/main/kotlin/cn/flightfeather/supervision/common/docimport/UserExcelRule.kt                              |   26 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/CommitmentServiceImpl.kt               |   16 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/ScheduleRepository.kt                    |   19 
 src/main/resources/mapper/SelfPatrolMediaFileMapper.xml                                                     |   41 
 src/main/resources/mapper/ScheduleSignRecordMapper.xml                                                      |   20 
 src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskSelfLedger.kt                                  |   38 
 src/main/kotlin/cn/flightfeather/supervision/domain/entity/Evaluationrule.kt                                |    8 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskFetchVOC.kt                                         |  152 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/EnvironmentalScheduleMapper.kt                   |   11 
 src/main/kotlin/cn/flightfeather/supervision/domain/repository/LedgerRep.kt                                 |   46 
 src/main/kotlin/cn/flightfeather/supervision/config/FFInterceptor.kt                                        |   35 
 src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnHourlyDustData.kt                              |  108 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/CommitmentTemplateMapper.kt                      |    8 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SelfPatrolRecordMapper.kt                        |    8 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/UserSpecialInfoServiceImpl.kt          |   71 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/GradeDetailVo.kt                                 |    3 
 src/main/kotlin/cn/flightfeather/supervision/common/score/ScoreUtil.kt                                      |  226 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/CreditService.kt                            |   13 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/BaseInfoServiceImpl.kt                 |   56 
 src/main/resources/mapper/SceneTypeMapper.xml                                                               |   18 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/NotificationServiceImpl.kt             |  224 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/UserinfoController.kt                           |   20 
 /dev/null                                                                                                   |  158 
 src/main/kotlin/cn/flightfeather/supervision/common/risk/UtilDatabase.kt                                    |   62 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/RiskController.kt                               |   50 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/DeviceServiceImpl.kt                   |  160 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/service/RiskService.kt                              |   20 
 src/main/kotlin/cn/flightfeather/supervision/lightshare/web/BaseResPack.kt                                  |   26 
 src/main/kotlin/cn/flightfeather/supervision/config/AsyncConfig.kt                                          |   28 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/UserinfoMapper.kt                                |    6 
 src/main/kotlin/cn/flightfeather/supervision/domain/mapper/UserLoginLogMapper.kt                            |    8 
 src/test/kotlin/cn/flightfeather/supervision/SupervisionApplicationTests.kt                                 |   92 
 src/main/resources/mapper/CommitmentTemplateMapper.xml                                                      |   45 
 292 files changed, 18,811 insertions(+), 1,491 deletions(-)

diff --git a/ledgerserver.rar b/ledgerserver.rar
deleted file mode 100644
index 959d941..0000000
--- a/ledgerserver.rar
+++ /dev/null
Binary files differ
diff --git a/pom.xml b/pom.xml
index f5e580b..07b9561 100644
--- a/pom.xml
+++ b/pom.xml
@@ -121,9 +121,9 @@
 
         <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
         <dependency>
-        <groupId>com.alibaba</groupId>
-        <artifactId>druid</artifactId>
-        <version>1.1.6</version>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid</artifactId>
+            <version>1.1.6</version>
         </dependency>
 
         <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
@@ -375,6 +375,18 @@
             <artifactId>pinyin4j</artifactId>
             <version>2.5.1</version>
         </dependency>
+        <!-- https://mvnrepository.com/artifact/net.sf.cssbox/pdf2dom -->
+        <dependency>
+            <groupId>net.sf.cssbox</groupId>
+            <artifactId>pdf2dom</artifactId>
+            <version>2.0.3</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
+        <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>core</artifactId>
+            <version>3.4.0</version>
+        </dependency>
 
     </dependencies>
 
@@ -472,12 +484,31 @@
                     </dependency>
                 </dependencies>
             </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <configuration>
+                    <delimiters>@</delimiters>
+                    <useDefaultDelimiters>false</useDefaultDelimiters>
+                </configuration>
+            </plugin>
         </plugins>
 
         <resources>
             <resource>
                 <directory>src/main/resources</directory>
                 <filtering>true</filtering>
+                <excludes>
+                    <exclude>font/</exclude>
+                </excludes>
+            </resource>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>false</filtering>
+                <includes>
+                    <include>font/</include>
+                </includes>
             </resource>
         </resources>
     </build>
@@ -486,7 +517,7 @@
         <profile>
             <id>dev</id>
             <properties>
-                <profile.active>dev</profile.active>
+                <profileActive>dev</profileActive>
             </properties>
             <activation>
                 <activeByDefault>true</activeByDefault>
@@ -495,11 +526,20 @@
         <profile>
             <id>pro</id>
             <properties>
-                <profile.active>pro</profile.active>
+                <profileActive>pro</profileActive>
             </properties>
-            <activation>
-                <activeByDefault>false</activeByDefault>
-            </activation>
+        </profile>
+        <profile>
+            <id>proapp</id>
+            <properties>
+                <profileActive>proapp</profileActive>
+            </properties>
+        </profile>
+        <profile>
+            <id>test</id>
+            <properties>
+                <profileActive>test</profileActive>
+            </properties>
         </profile>
     </profiles>
 
diff --git a/src/main/kotlin/cn/flightfeather/supervision/SupervisionApplication.kt b/src/main/kotlin/cn/flightfeather/supervision/SupervisionApplication.kt
index 63fe9e1..892a5d6 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/SupervisionApplication.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/SupervisionApplication.kt
@@ -1,17 +1,23 @@
 package cn.flightfeather.supervision
 
 import cn.flightfeather.supervision.common.wx.WxTokenManager
-import cn.flightfeather.supervision.timingtask.TaskController
+import cn.flightfeather.supervision.bgtask.TaskController
 import cn.flightfeather.supervision.websocket.VMRoomWebSocketServer
 import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.beans.factory.annotation.Value
 import org.springframework.boot.ApplicationRunner
 import org.springframework.boot.autoconfigure.SpringBootApplication
 import org.springframework.boot.runApplication
 import org.springframework.context.annotation.Bean
+import org.springframework.scheduling.annotation.EnableScheduling
 
 
 @SpringBootApplication
-class SupervisionApplication {
+@EnableScheduling
+class SupervisionApplication(
+    @Value("\${systemIsApp}") var systemIsApp: Boolean,
+    @Value("\${mode}") var mode: String,
+) {
 
     @Autowired
     lateinit var webSocketServer: VMRoomWebSocketServer
@@ -24,9 +30,15 @@
 
     @Bean
     fun runner() = ApplicationRunner {
-        webSocketServer.start()
-        taskController.run()
-        wxTokenManager.run()
+        if (systemIsApp) {
+            webSocketServer.start()
+        } else {
+            wxTokenManager.run()
+        }
+        if (mode == "proapp") {
+            taskController.run()
+        }
+        println("mode: $mode")
     }
 }
 
diff --git a/src/main/kotlin/cn/flightfeather/supervision/timingtask/BaseTimingTask.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/BaseTimingTask.kt
similarity index 70%
rename from src/main/kotlin/cn/flightfeather/supervision/timingtask/BaseTimingTask.kt
rename to src/main/kotlin/cn/flightfeather/supervision/bgtask/BaseTimingTask.kt
index b9fa2ce..dc8f44d 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/timingtask/BaseTimingTask.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/BaseTimingTask.kt
@@ -1,17 +1,11 @@
-package cn.flightfeather.supervision.timingtask
+package cn.flightfeather.supervision.bgtask
 
 import java.time.LocalDateTime
-import java.util.concurrent.ExecutorService
-import java.util.concurrent.Executors
 
 /**
  * 瀹氭椂浠诲姟鍩虹被
  */
 abstract class BaseTimingTask {
-
-    companion object {
-        var threadPoo: ExecutorService? = Executors.newCachedThreadPool()
-    }
 
     // 璁板綍涓婃浠诲姟鎵ц鐨勬椂闂寸偣锛屽崟浣嶏細姣
     private var lastTime: LocalDateTime = LocalDateTime.MIN
diff --git a/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskAutoLedger.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskAutoLedger.kt
new file mode 100644
index 0000000..070f90c
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskAutoLedger.kt
@@ -0,0 +1,52 @@
+package cn.flightfeather.supervision.bgtask
+
+import cn.flightfeather.supervision.common.autoledger.AutoLedger
+import cn.flightfeather.supervision.domain.repository.PracticalOperationRep
+import cn.flightfeather.supervision.domain.repository.UserConfigRep
+import cn.flightfeather.supervision.domain.repository.UserInfoRep
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+import org.springframework.stereotype.Component
+import java.time.LocalDateTime
+
+/**
+ * 鍙拌处鑷姩鐢熸垚浠诲姟
+ */
+@Component
+class TaskAutoLedger(
+    private val autoLedger: AutoLedger,
+    private val userInfoRep: UserInfoRep,
+    private val practicalOperationRep: PracticalOperationRep,
+    private val userConfigRep: UserConfigRep
+) : BaseTimingTask() {
+
+    companion object {
+        // 涓婃捣甯傞潤瀹夊尯鎺掓薄浼佷笟
+        private const val CONFIG_ID = 18
+    }
+
+    override val period: Long
+        get() = 1440L
+
+    override fun doTask(localtime: LocalDateTime) {
+        val config = userConfigRep.select(CONFIG_ID)
+        val condition = UserSearchCondition.fromUserConfig(config).apply {
+            sceneTypes = config?.ucSceneRange?.split(";") ?: emptyList()
+        }
+        val userInfos = userInfoRep.searchUser(condition)
+        val operations = practicalOperationRep.getOperation(listOf(CONFIG_ID))
+        val year = localtime.year
+        val month = localtime.monthValue
+        userInfos.forEach {
+            autoLedger.create(it, operations, year, month)
+        }
+    }
+
+    /**
+     * 鍙拌处鑷姩鐢熸垚浠诲姟瀹氫负姣忔湀1鍙锋棭涓�0鐐�,鐢熸垚涓婁釜鏈堢殑鍙拌处
+     */
+    override fun execute(localtime: LocalDateTime) {
+        if (localtime.dayOfMonth == 1 && localtime.hour == 0 && localtime.minute == 0) {
+            doTask(localtime)
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskController.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskController.kt
similarity index 71%
rename from src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskController.kt
rename to src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskController.kt
index 26cf551..9aec38d 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskController.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskController.kt
@@ -1,6 +1,7 @@
-package cn.flightfeather.supervision.timingtask
+package cn.flightfeather.supervision.bgtask
 
 import org.slf4j.LoggerFactory
+import org.springframework.beans.factory.annotation.Value
 import org.springframework.stereotype.Component
 import java.time.LocalDateTime
 import java.time.LocalTime
@@ -14,7 +15,18 @@
  */
 @Component
 class TaskController(
-    fetchVOC: TaskFetchVOC, pushFume: TaskPushFume, ledgerCopy: TaskLedgerCopy
+    fetchVOC: TaskFetchVOC,
+    pushFume: TaskPushFume,
+    ledgerCopy: TaskLedgerCopy,
+    ledgerRemind: TaskLedgerRemind,
+    taskJinAnLampEnterBaseInfo: TaskJinAnLampEnterBaseInfo,
+    taskJinAnLampDeviceData: TaskJinAnLampDeviceData,
+    taskJinAnConstructionSiteInfo: TaskJinAnConstructionSiteInfo,
+    taskJinAnHourlyDustData: TaskJinAnHourlyDustData,
+    taskAutoLedger:TaskAutoLedger,
+    // 鏍规嵁app涓嶅悓锛屽垏鎹笉鍚岀殑瀹氭椂浠诲姟
+    @Value("\${systemIsApp}")
+    systemIsApp: Boolean,
 ) {
 
     companion object {
@@ -33,11 +45,19 @@
         LOGGER.info("娣诲姞瀹氭椂浠诲姟")
         timeTask.clear()
         //椋炵窘鐜锛岃幏鍙杤oc鏁版嵁銆佹帹閫佹补鐑熸暟鎹�
-//        timeTask.add(fetchVOC)
-//        timeTask.add(pushFume)
-
-        //寰俊灏忕▼搴忥紙涓皬浼佷笟瀹堟硶鑷姪锛夛紝鍙拌处澶嶅埗銆佸畾鏃朵换鍔℃帹閫佺瓑
-        timeTask.add(ledgerCopy)
+        if (systemIsApp) {
+            timeTask.add(fetchVOC)
+            timeTask.add(pushFume)
+        } else {
+            //寰俊灏忕▼搴忥紙涓皬浼佷笟瀹堟硶鑷姪锛夛紝鍙拌处澶嶅埗銆佸畾鏃朵换鍔℃帹閫佺瓑
+//        timeTask.add(ledgerCopy)
+            timeTask.add(ledgerRemind)
+            timeTask.add(taskJinAnLampEnterBaseInfo)
+//        timeTask.add(taskJinAnLampDeviceData)
+            timeTask.add(taskJinAnConstructionSiteInfo)
+//            timeTask.add(taskJinAnHourlyDustData)
+            timeTask.add(taskAutoLedger)
+        }
         LOGGER.info("娣诲姞瀹氭椂浠诲姟瀹屾垚锛屼换鍔℃�昏${timeTask.size}涓�")
     }
 
diff --git a/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskFetchVOC.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskFetchVOC.kt
new file mode 100644
index 0000000..0d50339
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskFetchVOC.kt
@@ -0,0 +1,152 @@
+package cn.flightfeather.supervision.bgtask
+
+import cn.flightfeather.supervision.common.net.VOCHttpService
+import cn.flightfeather.supervision.domain.entity.DeviceInfo
+import cn.flightfeather.supervision.domain.entity.VOCHourValue
+import cn.flightfeather.supervision.domain.enumeration.DistrictType
+import cn.flightfeather.supervision.domain.enumeration.SceneType
+import cn.flightfeather.supervision.domain.mapper.DeviceInfoMapper
+import cn.flightfeather.supervision.domain.mapper.VOCHourValueMapper
+import cn.flightfeather.supervision.infrastructure.utils.DateUtil
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Component
+import tk.mybatis.mapper.entity.Example
+import java.time.LocalDateTime
+import java.util.*
+import javax.annotation.PostConstruct
+
+/**
+ * 鑾峰彇voc鐩戞祴鏁版嵁
+ */
+@Component
+class TaskFetchVOC : BaseTimingTask() {
+
+    enum class Factor(val value: String, val des: String) {
+        Concentration("g29001", "娴撳害"),
+        Humidity("g18101", "婀垮害"),
+        Temperature("g18001", "娓╁害"),
+        FanElectricity1("e70101", "椋庢満鐢垫祦1"),
+        FanElectricity2("e70102", "椋庢満鐢垫祦2"),
+        FanElectricity3("e70103", "椋庢満鐢垫祦3"),
+        FanElectricity4("e70104", "椋庢満鐢垫祦4"),
+        FanElectricity5("e70105", "椋庢満鐢垫祦5"),
+        FanElectricity6("e70106", "椋庢満鐢垫祦6"),
+    }
+
+    companion object {
+        private lateinit var instance: TaskFetchVOC
+    }
+
+    @Autowired
+    lateinit var deviceInfoMapper: DeviceInfoMapper
+
+    @Autowired
+    lateinit var vocHourValueMapper: VOCHourValueMapper
+
+    @PostConstruct
+    fun init() {
+        instance = this
+    }
+
+    private val LOGGER: Logger? = LoggerFactory.getLogger(TaskFetchVOC::class.java)
+
+    override val period: Long
+        get() = 15L
+
+    override fun doTask(localtime:LocalDateTime) {
+        getVOCData()
+    }
+
+    private fun getVOCData() {
+        val deviceCodeList = mutableListOf<String>()
+        deviceInfoMapper.selectByExample(Example(DeviceInfo::class.java).apply {
+            createCriteria().andEqualTo("diProvinceCode", "31")
+                .andEqualTo("diCityCode", "3100")
+                .andEqualTo("diDistrictCode", DistrictType.XuHui.code)
+                .andEqualTo("diSceneTypeId", SceneType.VehicleRepair.value)
+                .andEqualTo("diDeviceTypeId", 1)
+                .andEqualTo("diOnline", true)
+        }).forEach {
+            it?.let {
+                deviceCodeList.add(it.diCode)
+            }
+        }
+
+        val cal = Calendar.getInstance(Locale.CHINA).apply {
+            set(Calendar.MINUTE, 0)
+            set(Calendar.SECOND, 0)
+        }
+        var endTime = DateUtil.DateToString(cal.time, "yyyy-MM-dd HH:mm:ss") ?: ""
+        cal.add(Calendar.HOUR_OF_DAY, -1)
+        var startTime = DateUtil.DateToString(cal.time, "yyyy-MM-dd HH:mm:ss") ?: ""
+
+//        startTime = "2023-05-06 13:00:00"
+//        endTime = "2023-05-06 15:00:00"
+        val deviceInfo = VOCHttpService.DeviceInfo(deviceCodeList, startTime, endTime)
+        VOCHttpService.getVOCData(deviceInfo)?.run {
+            try {
+                if (this["code"].asInt == 200) {
+                    val data = this["data"].asJsonObject
+                    val unit = mutableMapOf<String, String>()
+                    data["rtdMonitorFactorRespVOS"].asJsonArray.forEach { v ->
+                        v.asJsonObject.let { o ->
+                            if (o["factorCode"].asString.trim() == Factor.Concentration.value) {
+                                try {
+                                    unit[o["deviceCode"].asString.trim()] = o["factorName"].asString.trim().split("-")[1]
+                                } catch (e: IndexOutOfBoundsException) {
+                                    LOGGER?.error("鑾峰彇VOC娴撳害鍗曚綅澶辫触", e)
+                                }
+                            }
+                        }
+                    }
+                    data["rtdMinuteHourDayBeans"].asJsonArray.forEach { e ->
+                        e.asJsonObject.let { o ->
+                            val hourValueMap = mutableMapOf<String, VOCHourValue>()
+
+                            val collectTime = DateUtil.StringToDate(o["collectTime"].asString)
+
+                            o["minuteHourDayValueBeans"].asJsonArray.forEach { e1 ->
+                                e1.asJsonObject.let { o1 ->
+                                    val deviceCode = o1["deviceCode"].asString.toUpperCase()
+                                    if (!hourValueMap.containsKey(deviceCode)) {
+                                        hourValueMap[deviceCode] = VOCHourValue().apply { vocCreateTime = Date() }
+                                    }
+                                    val hourValue = hourValueMap[deviceCode]!!
+                                    hourValue.vocStatCode = deviceCode
+                                    hourValue.vocDataTime = collectTime
+                                    hourValue.vocUnit = unit[deviceCode]
+                                    val avg = o1["factorAvg"].asString.toDouble()
+                                    when (o1["factorCode"].asString) {
+                                        Factor.FanElectricity1.value -> hourValue.vocFanElectricity1 = avg
+                                        Factor.FanElectricity2.value -> hourValue.vocFanElectricity2 = avg
+                                        Factor.FanElectricity3.value -> hourValue.vocFanElectricity3 = avg
+                                        Factor.FanElectricity4.value -> hourValue.vocFanElectricity4 = avg
+                                        Factor.FanElectricity5.value -> hourValue.vocFanElectricity5 = avg
+                                        Factor.FanElectricity6.value -> hourValue.vocFanElectricity6 = avg
+                                        Factor.Concentration.value -> hourValue.vocValue = avg
+                                        Factor.Temperature.value -> hourValue.vocTemperature = avg
+                                        Factor.Humidity.value -> hourValue.vocRh = avg
+                                    }
+                                }
+                            }
+                            val r = vocHourValueMapper.selectByExample(Example(VOCHourValue::class.java).apply {
+                                createCriteria().andEqualTo("vocDataTime", collectTime)
+                            }).map { v ->
+                                v?.vocStatCode
+                            }
+                            hourValueMap.forEach { (t, u) ->
+                                if (!r.contains(t)) {
+                                    vocHourValueMapper.insertSelective(u)
+                                }
+                            }
+                        }
+                    }
+                }
+            } catch (e: Throwable) {
+                e.printStackTrace()
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnConstructionSiteInfo.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnConstructionSiteInfo.kt
new file mode 100644
index 0000000..50cd98c
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnConstructionSiteInfo.kt
@@ -0,0 +1,69 @@
+package cn.flightfeather.supervision.bgtask
+
+import cn.flightfeather.supervision.common.net.JinAnLianTongHttpService
+import cn.flightfeather.supervision.domain.entity.DustSiteInfo
+import cn.flightfeather.supervision.domain.mapper.DustSiteInfoMapper
+import cn.flightfeather.supervision.infrastructure.utils.DateUtil
+import cn.flightfeather.supervision.lightshare.vo.JinAnConstructionInfo
+import org.springframework.beans.BeanUtils
+import org.springframework.stereotype.Component
+import java.time.LocalDateTime
+
+/**
+ * 鑾峰彇闈欏畨宸ュ湴鐩戞祴鐐逛俊鎭�
+ */
+@Component
+class TaskJinAnConstructionSiteInfo(
+    private val dustSiteInfoMapper: DustSiteInfoMapper
+) : BaseTimingTask() {
+
+    private var isFirst = true
+
+    //鏈换鍔℃瘡鏃ユ墽琛屼竴娆�
+    override fun execute(localtime: LocalDateTime) {
+        if (isFirst || (localtime.hour == 0 && localtime.minute == 0)) {
+            isFirst = false
+            doTask(localtime)
+        }
+    }
+
+    //涓嶄娇鐢ㄦ鍙傛暟
+    override val period: Long
+        get() = 1440L
+
+    override fun doTask(localtime: LocalDateTime) {
+        var page = 1
+        var hasNextPage: Boolean
+        do {
+            val res = JinAnLianTongHttpService.getConstructionDustMonitorSiteInfo(page)
+            hasNextPage = res.first
+            page++
+            saveSiteInfo(res.second)
+        } while (hasNextPage)
+
+    }
+
+    /**
+     * 淇濆瓨鐩戞祴鐐逛俊鎭�
+     */
+    private fun saveSiteInfo(dataList:List<JinAnConstructionInfo>) {
+        dataList.forEach {d ->
+            val info = dustSiteInfoMapper.selectByPrimaryKey(d.id)
+            if (info == null) {
+                val b = DustSiteInfo()
+                BeanUtils.copyProperties(d, b)
+                b.apply {
+                    beginDate = d.beginDate?.let { DateUtil.StringToDate(it) }
+                    dataTime = d.dataTime?.let { DateUtil.StringToDate(it) }
+                    doTime = d.doTime?.let { DateUtil.StringToDate(it) }
+                    endDate = d.endDate?.let { DateUtil.StringToDate(it) }
+                    stageBeginDate = d.stageBeginDate?.let { DateUtil.StringToDate(it) }
+                    stopTime = d.stopTime?.let { DateUtil.StringToDate(it) }
+                    tsp = d.tsp?.toDouble()
+                    ywsjDate = d.ywsjDate?.let { DateUtil.StringToDate(it) }
+                }
+                dustSiteInfoMapper.insert(b)
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnHourlyDustData.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnHourlyDustData.kt
new file mode 100644
index 0000000..78bd2de
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnHourlyDustData.kt
@@ -0,0 +1,108 @@
+package cn.flightfeather.supervision.bgtask
+
+import cn.flightfeather.supervision.common.net.JinAnLianTongHttpService
+import cn.flightfeather.supervision.domain.entity.HourDustData
+import cn.flightfeather.supervision.domain.mapper.HourDustDataMapper
+import cn.flightfeather.supervision.infrastructure.utils.DateUtil
+import cn.flightfeather.supervision.lightshare.vo.JinAnHourDustData
+import com.github.pagehelper.PageHelper
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.springframework.beans.BeanUtils
+import org.springframework.stereotype.Component
+import tk.mybatis.mapper.entity.Example
+import java.time.LocalDateTime
+import java.time.ZoneId
+import java.util.*
+
+/**
+ * 鑾峰彇闈欏畨宸ュ湴鐩戞祴鐐瑰皬鏃舵暟鎹�
+ */
+@Component
+class TaskJinAnHourlyDustData(
+    private val hourDustDataMapper: HourDustDataMapper
+) : BaseTimingTask() {
+
+    private val log: Logger? = LoggerFactory.getLogger(TaskJinAnHourlyDustData::class.java)
+
+    private var times = 0
+
+    private var isFirst = true
+
+    //鏈换鍔℃瘡灏忔椂鏁寸偣鎵ц涓�娆�
+    override fun execute(localtime: LocalDateTime) {
+        if (isFirst || localtime.minute == 0) {
+            isFirst = false
+            doTask(localtime)
+        }
+//        println("=================check")
+//        if (times == 0) {
+//            doTask(localtime)
+//            println("=================TaskJinAnHourlyDustData")
+//            times++
+//        }
+    }
+
+    //涓嶄娇鐢ㄦ鍙傛暟
+    override val period: Long
+        get() = 1440L
+
+    override fun doTask(localtime: LocalDateTime) {
+        log?.info("===========寮�濮嬫墽琛岄潤瀹夋壃灏樼洃娴嬫暟鎹幏鍙栦换鍔�===============")
+        PageHelper.startPage<HourDustData>(1, 1)
+        val r = hourDustDataMapper.selectByExample(Example(HourDustData::class.java).apply {
+            orderBy("lst").desc()
+        })
+        var sDate = if (r.isEmpty()) null else r[0]?.lst
+//        val sDate = null
+        var eDate: Date? = null
+        if (sDate != null) {
+            val lastHour = LocalDateTime.ofInstant(sDate.toInstant(), ZoneId.systemDefault()).minusHours(12)
+            sDate = Date.from(lastHour.atZone(ZoneId.systemDefault()).toInstant())
+        }
+//        sDate = Date.from(LocalDateTime.of(2023, 8, 1, 0, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant())
+//        eDate = Date.from(LocalDateTime.of(2023, 8, 23, 0, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant())
+        var page = 1
+        var hasNextPage: Boolean = false
+        do {
+            try {
+                val res = JinAnLianTongHttpService.getHourlyDustData(page, sDate, eDate)
+                hasNextPage = res.first
+                page++
+                saveSiteInfo(res.second)
+            } catch (e: Exception) {
+                e.printStackTrace()
+            }
+        } while (hasNextPage)
+
+    }
+
+    /**
+     * 淇濆瓨鐩戞祴鐐瑰皬鏃舵暟鎹�
+     */
+    fun saveSiteInfo(dataList:List<JinAnHourDustData>) {
+        dataList.forEach {d ->
+            val info = hourDustDataMapper.selectByPrimaryKey(d.id)
+            if (info == null) {
+                val b = HourDustData()
+                BeanUtils.copyProperties(d, b)
+//                d.createTime?.let { b.inserttime = Date(it) }
+//                d.stTime?.let { b.lst = Date(it) }
+//                d.etTime?.let { b.lstEnd = Date(it) }
+                b.inserttime = d.createTime
+                b.lst = d.stTime
+                b.lstEnd = d.etTime
+                hourDustDataMapper.insert(b)
+            }
+        }
+    }
+
+    fun debugDoTask() {
+        val sDate = Date.from(LocalDateTime.of(2024, 6, 18, 0, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant())
+        val eDate = Date.from(LocalDateTime.of(2024, 6, 19, 0, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant())
+        val res = JinAnLianTongHttpService.getHourlyDustData(1, sDate, eDate, 10)
+        res.second.forEach {
+            println("${it.mncode}: ${DateUtil.DateToString(it.stTime, DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS)}")
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnLampDeviceData.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnLampDeviceData.kt
new file mode 100644
index 0000000..4ad6c28
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnLampDeviceData.kt
@@ -0,0 +1,93 @@
+package cn.flightfeather.supervision.bgtask
+
+import cn.flightfeather.supervision.common.net.JinAnLianTongHttpService
+import cn.flightfeather.supervision.domain.entity.LampDeviceData
+import cn.flightfeather.supervision.domain.mapper.LampDeviceDataMapper
+import cn.flightfeather.supervision.infrastructure.utils.DateUtil
+import cn.flightfeather.supervision.lightshare.vo.JinAnLampDeviceData
+import com.github.pagehelper.PageHelper
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.springframework.beans.BeanUtils
+import org.springframework.stereotype.Component
+import tk.mybatis.mapper.entity.Example
+import java.time.LocalDateTime
+import java.time.ZoneId
+import java.util.*
+
+/**
+ * 鑾峰彇闈欏畨娌圭儫璁惧鏁版嵁
+ */
+@Component
+class TaskJinAnLampDeviceData(
+    private val lampDeviceDataMapper: LampDeviceDataMapper
+) : BaseTimingTask() {
+
+    private val LOGGER: Logger? = LoggerFactory.getLogger(TaskJinAnLampDeviceData::class.java)
+
+    private var times = 0
+
+    //鏈换鍔℃瘡灏忔椂鎵ц涓�娆�
+    override fun execute(localtime: LocalDateTime) {
+        if (localtime.minute == 0) {
+            doTask(localtime)
+        }
+//        println("=================check")
+//        if (times == 0) {
+//            doTask(localtime)
+//            println("=================TaskJinAnLampDeviceData")
+//            times++
+//        }
+    }
+
+    //涓嶄娇鐢ㄦ鍙傛暟
+    override val period: Long
+        get() = 1440L
+
+    override fun doTask(localtime: LocalDateTime) {
+        LOGGER?.info("===========寮�濮嬫墽琛岄潤瀹夋补鐑熺洃娴嬫暟鎹幏鍙栦换鍔�===============")
+        PageHelper.startPage<LampDeviceData>(1, 1)
+        val r = lampDeviceDataMapper.selectByExample(Example(LampDeviceData::class.java).apply {
+            orderBy("monitorTime").desc()
+        })
+        var smDate = if (r.isEmpty()) null else r[0]?.monitorTime
+        var emDate: Date? = null
+        smDate = Date.from(LocalDateTime.of(2023, 4, 1, 12, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant())
+        emDate = Date.from(LocalDateTime.of(2023, 4, 1, 13, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant())
+        var page = 1
+        var hasNextPage: Boolean
+        do {
+            val res = JinAnLianTongHttpService.getLampDeviceData(page, smDate, emDate)
+            println("page: $page, count: ${res.second.size}")
+            hasNextPage = res.first
+            page++
+            saveSiteInfo(res.second)
+        } while (hasNextPage)
+
+    }
+
+    /**
+     * 淇濆瓨娌圭儫鐩戞祴鐐规暟鎹�
+     */
+    private fun saveSiteInfo(dataList:List<JinAnLampDeviceData>) {
+        dataList.forEach {d ->
+            if (d.monitorTime == null) return@forEach
+            val mStr = d.monitorTime!!.split(".")[0]
+            val mt = DateUtil.StringToDate(mStr)
+            val info = lampDeviceDataMapper.selectByExample(Example(LampDeviceData::class.java).apply {
+                createCriteria().andEqualTo("deviceCode", d.deviceCode)
+                    .andEqualTo("monitorTime", mt)
+            })
+            if (info.isEmpty()) {
+                val b = LampDeviceData()
+                BeanUtils.copyProperties(d, b)
+                b.apply {
+                    lampblackValue = d.lampblackValue?.toDouble()
+                    monitorTime = mt
+                    productionDate = d.productionDate?.let { DateUtil.StringToDate(it) }
+                }
+                lampDeviceDataMapper.insert(b)
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnLampEnterBaseInfo.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnLampEnterBaseInfo.kt
new file mode 100644
index 0000000..6eb47e4
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnLampEnterBaseInfo.kt
@@ -0,0 +1,61 @@
+package cn.flightfeather.supervision.bgtask
+
+import cn.flightfeather.supervision.common.net.JinAnLianTongHttpService
+import cn.flightfeather.supervision.domain.entity.LampEnterBaseInfo
+import cn.flightfeather.supervision.domain.mapper.LampEnterBaseInfoMapper
+import cn.flightfeather.supervision.infrastructure.utils.DateUtil
+import cn.flightfeather.supervision.lightshare.vo.JinAnLampEnterBaseInfo
+import org.springframework.beans.BeanUtils
+import org.springframework.stereotype.Component
+import java.time.LocalDateTime
+
+/**
+ * 鑾峰彇闈欏畨娌圭儫鐩戞祴浼佷笟
+ */
+@Component
+class TaskJinAnLampEnterBaseInfo(
+    private val lampEnterBaseInfoMapper: LampEnterBaseInfoMapper
+) : BaseTimingTask() {
+
+    //鏈换鍔℃瘡鏃ユ墽琛屼竴娆�
+    override fun execute(localtime: LocalDateTime) {
+        if (localtime.hour == 0 && localtime.minute == 0) {
+            doTask(localtime)
+        }
+    }
+
+    //涓嶄娇鐢ㄦ鍙傛暟
+    override val period: Long
+        get() = 1440L
+
+    override fun doTask(localtime: LocalDateTime) {
+        var page = 1
+        var hasNextPage: Boolean
+        do {
+            val res = JinAnLianTongHttpService.getLampEnterBaseInfo(page)
+            hasNextPage = res.first
+            page++
+            saveSiteInfo(res.second)
+        } while (hasNextPage)
+
+    }
+
+    /**
+     * 淇濆瓨娌圭儫鐩戞祴浼佷笟鏁版嵁
+     */
+    private fun saveSiteInfo(dataList:List<JinAnLampEnterBaseInfo>) {
+        dataList.forEach {d ->
+            val info = lampEnterBaseInfoMapper.selectByPrimaryKey(d.enterId)
+            if (info == null) {
+                val b = LampEnterBaseInfo()
+                BeanUtils.copyProperties(d, b)
+                b.apply {
+                    latitude = d.latitude?.toDouble()
+                    longitude = d.longitude?.toDouble()
+                    registDate = d.registDate?.let { DateUtil.StringToDate(it) }
+                }
+                lampEnterBaseInfoMapper.insert(b)
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskLedgerCopy.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskLedgerCopy.kt
similarity index 97%
rename from src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskLedgerCopy.kt
rename to src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskLedgerCopy.kt
index df4391a..a5f9251 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskLedgerCopy.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskLedgerCopy.kt
@@ -1,4 +1,4 @@
-package cn.flightfeather.supervision.timingtask
+package cn.flightfeather.supervision.bgtask
 
 import cn.flightfeather.supervision.domain.entity.LedgerMediaFile
 import cn.flightfeather.supervision.domain.entity.LedgerRecord
@@ -87,7 +87,7 @@
      * 鍙拌处鑷姩澶嶅埗浠诲姟瀹氫负姣忔湀11鍙锋棭涓�1鐐癸紝锛堟瘡鏈堢殑10鍙蜂负鍙拌处鍙婃椂鎻愪氦鐨勬渶鍚庢湡闄愶級
      */
     override fun execute(localtime: LocalDateTime) {
-        if (localtime.dayOfMonth == copyDay && localtime.hour == 1) {
+        if (localtime.dayOfMonth == copyDay && localtime.hour == 1 && localtime.minute == 0) {
             doTask(localtime)
         }
     }
diff --git a/src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskLedgerRemind.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskLedgerRemind.kt
similarity index 93%
rename from src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskLedgerRemind.kt
rename to src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskLedgerRemind.kt
index b8ac686..0ad5b59 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskLedgerRemind.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskLedgerRemind.kt
@@ -1,9 +1,8 @@
-package cn.flightfeather.supervision.timingtask
+package cn.flightfeather.supervision.bgtask
 
 import cn.flightfeather.supervision.common.wx.TemplateManager
 import cn.flightfeather.supervision.domain.entity.LedgerSubType
 import cn.flightfeather.supervision.domain.entity.MsgSubscribeWx
-import cn.flightfeather.supervision.domain.enumeration.SceneType
 import cn.flightfeather.supervision.domain.mapper.LedgerSubTypeMapper
 import cn.flightfeather.supervision.domain.mapper.MsgSubscribeWxMapper
 import cn.flightfeather.supervision.domain.mapper.UserInfoWxMapper
@@ -83,7 +82,8 @@
             if (mustCount < mustTotal) {
                 val leftDay = 10 - localtime.dayOfMonth
                 templateManager.sendMsg(0, it!!.msOpenId,
-                    listOf("鍙拌处涓婁紶", "${localtime.year}骞�${localtime.monthValue}鏈�10鏃�", leftDay.toString(), "璇烽噸鐐瑰叧娉ㄧ幇鍦鸿嚜瀵绘煡閮ㄥ垎"))
+                    listOf("鍙拌处涓婁紶", "${localtime.year}骞�${localtime.monthValue}鏈�10鏃�", leftDay.toString(),
+                        "璇烽噸鐐瑰叧娉ㄧ幇鍦鸿嚜宸℃煡閮ㄥ垎"))
                 count++
             }
         }
@@ -96,8 +96,9 @@
      */
     override fun execute(localtime: LocalDateTime) {
         if (localtime.dayOfMonth == 5 || localtime.dayOfMonth == 9) {
-            doTask(localtime)
-
+            if (localtime.hour == 10 && localtime.minute == 0 && localtime.second == 0) {
+                doTask(localtime)
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskPushFume.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskPushFume.kt
new file mode 100644
index 0000000..ce9a05a
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskPushFume.kt
@@ -0,0 +1,224 @@
+package cn.flightfeather.supervision.bgtask
+
+import cn.flightfeather.supervision.common.net.FumeHttpService
+import cn.flightfeather.supervision.domain.entity.DeviceInfo
+import cn.flightfeather.supervision.domain.entity.FumeMinuteValue
+import cn.flightfeather.supervision.domain.enumeration.DistrictType
+import cn.flightfeather.supervision.domain.enumeration.SceneType
+import cn.flightfeather.supervision.domain.mapper.DeviceInfoMapper
+import cn.flightfeather.supervision.domain.mapper.FumeMinuteValueMapper
+import org.slf4j.LoggerFactory
+import org.springframework.stereotype.Component
+import tk.mybatis.mapper.entity.Example
+import java.time.LocalDateTime
+import java.time.ZoneId
+import java.time.format.DateTimeFormatter
+import kotlin.math.round
+
+/**
+ * 涓婁紶娌圭儫鐩戞祴鏁版嵁
+ */
+@Component
+class TaskPushFume(
+    private val deviceInfoMapper: DeviceInfoMapper,
+    private val fumeMinuteValueMapper: FumeMinuteValueMapper,
+) : BaseTimingTask() {
+
+    companion object {
+        val LOGGER = LoggerFactory.getLogger(TaskPushFume::class.java)
+
+        // 璁惧鍝佺墝
+        const val ZQ = "zhuoquan"
+        const val HZY = "hengzhiyuan"
+        private val DEVICE_TYPE = listOf(ZQ, HZY)
+    }
+
+    // 璁惧淇℃伅缂撳瓨
+    private val deviceCodeMap = mutableMapOf<String, MutableList<DeviceInfo?>>()
+
+    override val period: Long
+        get() = 1L
+
+    override fun doTask(localtime: LocalDateTime) {
+        //姣�10鍒嗛挓璁$畻涓�娆″钩鍧囧�煎苟涓婁紶
+        if (!timeCheck(localtime)) return
+
+        LOGGER.info("===========寮�濮嬫墽琛屾补鐑熸暟鎹笂浼犱换鍔�===============")
+        DEVICE_TYPE.forEach { type ->
+            if (!deviceCodeMap.containsKey(type)) {
+                deviceCodeMap[type] = mutableListOf()
+            }
+            val deviceCodeList = deviceCodeMap[type]!!
+
+            //璁$畻鍙栧�兼椂闂�
+            val endTime = localtime.minusMinutes(1).withSecond(59)
+            val startTime = localtime.minusMinutes(10).withSecond(0)
+
+            doTask(type, deviceCodeList, startTime, endTime)
+        }
+    }
+
+    fun doTask(deviceType: String, deviceCodeList: MutableList<DeviceInfo?>, startTime: LocalDateTime, endTime:LocalDateTime) {
+        // 鍒锋柊鐩戞祴鐐圭紪鍙�
+        refreshDeviceCode(deviceType, deviceCodeList)
+        val p = getPostData(deviceType, deviceCodeList, startTime, endTime)
+        upload(p.first, p.second, deviceType, startTime)
+    }
+
+    fun getPostData(
+        deviceType: String,
+        deviceCodeList: MutableList<DeviceInfo?>,
+        startTime: LocalDateTime,
+        endTime: LocalDateTime,
+    ): Pair<FumeHttpService.PostData, List<FumeMinuteValue>> {
+        //鐢熸垚涓婁紶鏁版嵁缁撴瀯浣�
+        val postData = FumeHttpService.PostData.newInstance(deviceType)
+        val allData = mutableListOf<FumeMinuteValue>()
+        deviceCodeList.forEach { d ->
+            if (d == null) return@forEach
+
+            //鑾峰彇鏁版嵁
+            val dataList = fumeMinuteValueMapper.selectByExample(Example(FumeMinuteValue::class.java).apply {
+                createCriteria().andEqualTo("mvStatCode", d.diCode)
+                    .andBetween("mvCreateTime", startTime, endTime)
+                and(createCriteria().orIsNull("mvUpload")
+                    .orEqualTo("mvUpload", false))
+            })
+
+            // 姣�10鍒嗛挓涓�缁勭殑鏁版嵁闆嗗悎
+            val tempList = mutableListOf<FumeMinuteValue>()
+            // 鏃堕棿鎴筹紝浠h〃鏌�10鍒嗛挓闂撮殧
+            var tempTag = ""
+            var tagTime = startTime
+            dataList.forEach {data ->
+                val dataTime = LocalDateTime.ofInstant(data.mvCreateTime.toInstant(), ZoneId.systemDefault())
+                val minute = dataTime.minute / 10
+                val tag = dataTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:")) + minute + "0"
+                if (tag != tempTag) {
+                    tagTime = LocalDateTime.parse("${tag}:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
+                    // 杩涜鍧囧�艰绠楋紝鐢熸垚涓婁紶鏁版嵁瀵硅薄
+                    addPostData(deviceType, tempList, postData, allData, tagTime)
+                    tempList.clear()
+                    tempTag = tag
+                }
+                tempList.add(data)
+            }
+            if (tempList.isNotEmpty()) addPostData(deviceType, tempList, postData, allData, tagTime)
+        }
+
+        return postData to allData
+    }
+
+    fun addPostData(
+        deviceType: String,
+        tempList: List<FumeMinuteValue>,
+        postData: FumeHttpService.PostData,
+        allData: MutableList<FumeMinuteValue>,
+        startTime: LocalDateTime,
+    ) {
+        if (tempList.isEmpty()) return
+        //璁$畻鍧囧��
+        var count = 0
+        var total = 0.0
+        tempList.forEach {
+            val fc = when (deviceType) {
+                ZQ -> it.mvFumeConcentration
+                HZY -> it.mvFumeConcentration2
+                else -> it.mvFumeConcentration
+            }
+            total += fc
+            if (fc != 0.0) {
+                count++
+            }
+        }
+        if (count == 0) {
+            dataUpdate(tempList)
+            return
+        }
+        val average = round(total / count * 100) / 100
+
+        //鍧囧�肩瓑浜�0锛屼笉涓婃姤锛岀洿鎺ユ洿鏂颁笂浼犵姸鎬�
+        if (average == 0.0) {
+            dataUpdate(tempList)
+            return
+        }
+
+        //鐢熸垚涓婁紶鏁版嵁缁撴瀯浣�
+        tempList.last().let {
+            postData.data.add(FumeHttpService.FumeData(
+                "${deviceType}_${it.mvStatCode}",
+                startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
+                0.0, average,
+                if (it.mvFanStatus) 3 else 2,
+                it.mvFanElectricity, 0,
+                if (it.mvPurifierStatus) 3 else 2,
+                it.mvPurifierElectricity, 0,
+                0, 0.0
+            ))
+        }
+
+        allData.addAll(tempList)
+    }
+
+    fun upload(
+        postData: FumeHttpService.PostData,
+        allData: List<FumeMinuteValue>,
+        deviceType: String,
+        localtime: LocalDateTime,
+    ) {
+        if (postData.data.isEmpty()) return
+
+        //涓婁紶鏁版嵁骞舵洿鏂版暟鎹姸鎬�
+        LOGGER.info("===========鏁版嵁閲囨牱鏃堕棿锛�$localtime")
+        postData.data.forEach {
+            LOGGER.info("${it.equipmentShowId}   **   ${it.dataTime}")
+        }
+        LOGGER.info("=================================")
+        FumeHttpService.uploadData(postData)?.run {
+            LOGGER.info(this.toString())
+            if (this["code"].asInt == 0 && this["data"].asInt > 0) {
+                dataUpdate(allData)
+            }
+            LOGGER.info("===========${deviceType}娌圭儫鏁版嵁涓婁紶瀹屾垚============")
+        }
+    }
+
+
+    /**
+     * 涓婁紶鏃堕棿鐐规鏌ワ紝纭畾褰撳墠鏄惁搴旇涓婁紶鏁版嵁
+     */
+    fun timeCheck(localtime: LocalDateTime): Boolean {
+        val min = localtime.minute
+        return (min == 0 || min == 10 || min == 20 || min == 30 || min == 40 || min == 50)
+    }
+
+    /**
+     * 鍒锋柊鐩戞祴鐐圭紪鍙�
+     */
+    @Synchronized
+    private fun refreshDeviceCode(deviceType: String, deviceCodeList: MutableList<DeviceInfo?>) {
+        val now = LocalDateTime.now()
+        if (deviceCodeList.isEmpty() || (now.hour == 0 && now.minute <= period)) {
+            deviceCodeList.clear()
+            deviceInfoMapper.selectByExample(Example(DeviceInfo::class.java).apply {
+                createCriteria().andEqualTo("diProvinceCode", "31")
+                    .andEqualTo("diCityCode", "3100")
+                    .andEqualTo("diDistrictCode", DistrictType.XuHui.code)
+                    .andEqualTo("diSceneTypeId", SceneType.Restaurant.value)
+                    .andEqualTo("diDeviceTypeId", 1)
+                    .andEqualTo("diSupplier", deviceType)
+                    .andEqualTo("diOnline", true)
+            }).let { deviceCodeList.addAll(it) }
+        }
+    }
+
+    /**
+     * 鏇存柊鏁版嵁鐘舵��
+     */
+    private fun dataUpdate(dataList: List<FumeMinuteValue>) {
+        dataList.forEach {
+            it.mvUpload = true
+            fumeMinuteValueMapper.updateByPrimaryKey(it)
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskScoreRemind.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskScoreRemind.kt
similarity index 75%
rename from src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskScoreRemind.kt
rename to src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskScoreRemind.kt
index a68e843..26e1d58 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskScoreRemind.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/TaskScoreRemind.kt
@@ -1,4 +1,4 @@
-package cn.flightfeather.supervision.timingtask
+package cn.flightfeather.supervision.bgtask
 
 import cn.flightfeather.supervision.common.wx.TemplateManager
 import cn.flightfeather.supervision.domain.entity.MsgSubscribeWx
@@ -29,11 +29,13 @@
     }
 
     /**
-     * 鍙拌处鎻愰啋浠诲姟瀹氫负姣忔湀5鍙锋棭涓�10鐐规彁閱掑綋鏈�10鍙蜂箣鍓嶆彁浜ゅ彴璐�
+     * 鑷瘎鎻愰啋浠诲姟瀹氫负姣忔湀5鍙枫��15鍙枫��28鍙锋棭涓�10鐐规彁閱�
      */
     override fun execute(localtime: LocalDateTime) {
-        if (localtime.dayOfMonth == 5) {
-            doTask(localtime)
+        if (localtime.dayOfMonth == 5 || localtime.dayOfMonth == 15 || localtime.dayOfMonth == 28) {
+            if (localtime.hour == 10 && localtime.minute == 0 && localtime.second == 0) {
+                doTask(localtime)
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/bgtask/maintenance/MTJinAnHourlyDustData.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/maintenance/MTJinAnHourlyDustData.kt
new file mode 100644
index 0000000..8b30104
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/maintenance/MTJinAnHourlyDustData.kt
@@ -0,0 +1,99 @@
+package cn.flightfeather.supervision.bgtask.maintenance
+
+import cn.flightfeather.supervision.bgtask.TaskJinAnHourlyDustData
+import cn.flightfeather.supervision.common.net.JinAnLianTongHttpService
+import cn.flightfeather.supervision.domain.mapper.HourDustDataMapper
+import org.slf4j.LoggerFactory
+import org.springframework.stereotype.Component
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.ZoneId
+import java.time.format.DateTimeFormatter
+import java.util.*
+
+/**
+ * 鑾峰彇闈欏畨宸ュ湴鐩戞祴鐐瑰皬鏃舵暟鎹暟鎹ˉ鍏呯淮鎶や换鍔�
+ * @date 2024/6/3
+ * @author feiyu02
+ */
+@Component
+class MTJinAnHourlyDustData(
+    private val hourDustDataMapper: HourDustDataMapper,
+    private val taskJinAnHourlyDustData: TaskJinAnHourlyDustData
+) {
+    private val logger = LoggerFactory.getLogger(MTJinAnHourlyDustData::class.java)
+
+    /**
+     * 榛樿鎵ц鍓嶄竴鍛ㄦ椂娈靛唴鐨勬暟鎹ˉ鍏呬换鍔�
+     */
+    fun handle() {
+        val end = LocalDate.now().atStartOfDay()
+        val start = end.minusDays(7)
+        handle(start, end)
+    }
+
+    fun handle(year: Int, month: Int) {
+        val start = LocalDate.of(year, month, 1).atStartOfDay()
+        val end = start.plusMonths(1).minusSeconds(1)
+        handle(start, end)
+    }
+
+    fun handle(start:LocalDateTime, end:LocalDateTime) {
+        logger.info("=========<闈欏畨宸ュ湴鐩戞祴鐐瑰皬鏃舵暟鎹暟鎹ˉ鍏呯淮鎶や换鍔″紑鍚�>=========")
+        // 绛涢�夌己澶辩殑鏃堕棿锛堜互澶╀负鏈�灏忓崟浣嶏級
+        val timeList = findLostTime(start, end)
+        logger.info("==>鍏辨湁${timeList.size}澶╂暟鎹笉瀹屾暣")
+        // 鑾峰彇缂哄け鏁版嵁
+        timeList.forEach {
+            logger.info("==>寮�濮嬭幏鍙�${it.format(DateTimeFormatter.ofPattern("YYYY-MM-dd"))}鐨勭洃娴嬫暟鎹�")
+            val sT = Date.from(it.atZone(ZoneId.systemDefault()).toInstant())
+            val eT = Date.from(it.plusDays(1).atZone(ZoneId.systemDefault()).toInstant())
+            var page = 1
+            var hasNextPage: Boolean = false
+            var count = 0
+            do {
+                try {
+                    val res = JinAnLianTongHttpService.getHourlyDustData(page, sT, eT)
+                    hasNextPage = res.first
+                    page++
+                    count += res.second.size
+                    taskJinAnHourlyDustData.saveSiteInfo(res.second)
+                } catch (e: Exception) {
+                    e.printStackTrace()
+                }
+            } while (hasNextPage)
+            logger.info("==>${it.format(DateTimeFormatter.ofPattern("YYYY-MM-dd"))}鐩戞祴鏁版嵁鑾峰彇锛屾暟鎹噺${count}")
+        }
+    }
+
+    /**
+     * 绛涢�夌己澶辩殑鏃堕棿锛堢粨鏋滀互澶╀负鏈�灏忓崟浣嶏級
+     */
+    fun findLostTime(sT:LocalDateTime, eT:LocalDateTime): List<LocalDateTime> {
+        // 鑾峰彇宸叉湁鏁版嵁鐨勭洃娴嬬偣姣忔棩鏁版嵁閲�
+        val countList = hourDustDataMapper.findDataCountEachDay(sT, eT)
+        val countMap = mutableMapOf<String?, MutableMap<String?, Int?>>()
+        countList.forEach {
+            if (!countMap.containsKey(it.name)) {
+                countMap[it.name] = mutableMapOf()
+            }
+            countMap[it.name]!![it.category] = it.count
+        }
+        // 缁熻鏁版嵁涓嶅畬鏁寸殑鏃ユ湡
+        val resList = mutableListOf<LocalDateTime>()
+        var t = sT
+        while (t.isBefore(eT)) {
+            val timeTag = t.format(DateTimeFormatter.ofPattern("YYYY-MM-dd"))
+            for ((k, v) in countMap) {
+                // 鑷冲皯鏈変竴涓洃娴嬬偣褰撳ぉ娌℃湁鏁版嵁鎴栬�呮暟鎹暟閲忎笉瀹屾暣锛屽垯闇�瑕佽ˉ鍏ㄥ綋澶╂暟鎹�
+                if (v[timeTag] == null || v[timeTag]!! < 24) {
+                    resList.add(t)
+                    break
+                }
+            }
+            t = t.plusDays(1)
+        }
+
+        return resList
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/timingtask/package-info.java b/src/main/kotlin/cn/flightfeather/supervision/bgtask/package-info.java
similarity index 84%
rename from src/main/kotlin/cn/flightfeather/supervision/timingtask/package-info.java
rename to src/main/kotlin/cn/flightfeather/supervision/bgtask/package-info.java
index d84d84a..e43beae 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/timingtask/package-info.java
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/package-info.java
@@ -1,4 +1,4 @@
-package cn.flightfeather.supervision.timingtask;
+package cn.flightfeather.supervision.bgtask;
 /*
 * 鏁版嵁鎶撳彇鐩稿叧锛屽涓嬶細
 * 1. 瀹氭椂鑾峰彇涓婃捣寰愭眹姹戒慨鍦ㄧ嚎鐩戞祴鏁版嵁
diff --git a/src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/NoticeTimingTask.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/NoticeTimingTask.kt
new file mode 100644
index 0000000..e6080f7
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/NoticeTimingTask.kt
@@ -0,0 +1,76 @@
+package cn.flightfeather.supervision.bgtask.sysnotice
+
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.domain.repository.UserInfoRep
+import cn.flightfeather.supervision.lightshare.service.AuthService
+import cn.flightfeather.supervision.bgtask.BaseTimingTask
+import org.springframework.stereotype.Component
+import java.time.LocalDateTime
+import java.time.ZoneId
+
+@Component
+class NoticeTimingTask(
+    private val sysNoticeManager: SysNoticeManager,
+    private val authService: AuthService,
+    private val userInfoRep: UserInfoRep
+) : BaseTimingTask() {
+
+    override val period: Long = 60
+
+    override fun doTask(localtime: LocalDateTime) {
+        auth(localtime)
+        password(localtime)
+    }
+
+    //璁よ瘉鎿嶄綔鎻愰啋
+    private fun auth(localtime: LocalDateTime) {
+        if (localtime.dayOfMonth == 1 && localtime.hour == 1 && localtime.minute == 0) {
+            val users = mutableListOf<Userinfo?>()
+            authService.getUnAuthedUsers().data?.forEach {
+                val cT = LocalDateTime.ofInstant(it?.uiCreateTime?.toInstant(), ZoneId.systemDefault())
+                //(鐢ㄦ埛棣栨鐧诲綍3涓湀鍚庯紝姣忔湀鎻愰啋涓�娆★紝鐩磋嚦瀹屾垚韬唤楠岃瘉)
+                if (cT.plusMonths(3).isBefore(localtime)) {
+                    users.add(it)
+                }
+            }
+            sysNoticeManager.send(SysNoticeTemplate.Auth, users)
+        }
+    }
+
+    //瀵嗙爜淇敼鎻愰啋
+    private fun password(localtime: LocalDateTime) {
+        if (localtime.dayOfMonth == 1 && localtime.hour == 1 && localtime.minute == 0) {
+            val users = mutableListOf<Userinfo?>()
+            userInfoRep.pdUnChangeUsers().forEach {
+                val cT = LocalDateTime.ofInstant(it?.uiCreateTime?.toInstant(), ZoneId.systemDefault())
+                //(鐢ㄦ埛棣栨鐧诲綍3涓湀鍚庯紝姣忔湀鎻愰啋涓�娆★紝鐩磋嚦瀹屾垚鍒濆瀵嗙爜淇敼)
+                if (cT.plusMonths(3).isBefore(localtime)) {
+                    users.add(it)
+                }
+            }
+            sysNoticeManager.send(SysNoticeTemplate.Password, users)
+        }
+    }
+
+    //鐜繚鍙拌处鏇存柊鎻愰啋
+    private fun ledgerUpdate(localtime: LocalDateTime) {
+        // 姣忔湀1鍙枫��4鍙枫��7鍙蜂笂鍗�10锛�00
+        if ((localtime.dayOfMonth == 1 || localtime.dayOfMonth == 4 || localtime.dayOfMonth == 7)
+            && localtime.hour == 10
+            && localtime.minute == 0
+        ) {
+            sysNoticeManager
+        }
+    }
+
+    //鐜繚鍙拌处鍒版湡鎻愰啋
+    private fun ledgerDeadline(localtime: LocalDateTime) {
+        // 姣忔湀1鍙枫��4鍙枫��7鍙蜂笂鍗�10锛�00
+        if ((localtime.dayOfMonth == 10 || localtime.dayOfMonth == 20 || localtime.dayOfMonth == 26)
+            && localtime.hour == 10
+            && localtime.minute == 0
+        ) {
+            sysNoticeManager
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/NoticeTrigger.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/NoticeTrigger.kt
new file mode 100644
index 0000000..f0c19e3
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/NoticeTrigger.kt
@@ -0,0 +1,68 @@
+package cn.flightfeather.supervision.bgtask.sysnotice
+
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.lightshare.service.AuthService
+import org.springframework.scheduling.annotation.Async
+import org.springframework.stereotype.Component
+
+@Component
+class NoticeTrigger(
+    private val sysNoticeManager: SysNoticeManager,
+    private val authService: AuthService
+) {
+
+    inner class Sys() {
+        /**
+         * 鐢ㄦ埛鐧诲綍鎻愰啋
+         */
+        @Async
+        fun login(user: Userinfo) {
+            //韬唤楠岃瘉锛堜釜浜哄拰浼佷笟璁よ瘉锛夈�佸垵濮嬪瘑鐮佷慨鏀瑰垽鏂�
+//        val authStatus = authService.authStatus(null, user.guid).data
+//        if (authStatus?.get(0) == true && authStatus[2] && user.remark == "pwChanged") return
+            //鏄惁棣栨鐧诲綍
+            if (user.uiLoginTime == null) {
+                sysNoticeManager.send(SysNoticeTemplate.Login, listOf(user))
+            }
+        }
+
+        /**
+         * 璁よ瘉瀹屾垚閫氱煡
+         */
+        @Async
+        fun authed(user: Userinfo) {
+            sysNoticeManager.send(SysNoticeTemplate.Authed, listOf(user))
+        }
+
+        /**
+         * 瀵嗙爜淇敼閫氱煡
+         */
+        @Async
+        fun passwordChanged(user: Userinfo) {
+            sysNoticeManager.send(SysNoticeTemplate.PasswordChanged, listOf(user))
+        }
+
+        /**
+         * 瀵嗙爜閲嶇疆閫氱煡
+         */
+        @Async
+        fun passwordReset(user: Userinfo) {
+            sysNoticeManager.send(SysNoticeTemplate.PasswordReset, listOf(user))
+        }
+
+        /**
+         * 瀛︿範璧勬簮鎻愰啋
+         */
+        @Async
+        fun resources(user: Userinfo) {
+            sysNoticeManager.send(SysNoticeTemplate.Resources, listOf(user))
+        }
+    }
+
+    inner class Ledger() {
+        @Async
+        fun complete(user: Userinfo) {
+            sysNoticeManager.send(LedgerNoticeTemplate.Complete, listOf(user))
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/SysNoticeManager.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/SysNoticeManager.kt
new file mode 100644
index 0000000..a87774c
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/SysNoticeManager.kt
@@ -0,0 +1,178 @@
+package cn.flightfeather.supervision.bgtask.sysnotice
+
+import cn.flightfeather.supervision.domain.entity.NoticeTemplate
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.domain.enumeration.DistrictType
+import cn.flightfeather.supervision.domain.enumeration.SceneType
+import cn.flightfeather.supervision.domain.mapper.NoticeTemplateMapper
+import cn.flightfeather.supervision.lightshare.service.NotificationService
+import cn.flightfeather.supervision.lightshare.vo.NotificationVo
+import org.springframework.stereotype.Component
+import java.util.*
+
+/**
+ * 绯荤粺閫氱煡绠$悊
+ */
+@Component
+class SysNoticeManager(
+    private val noticeTemplateMapper: NoticeTemplateMapper,
+    private val notificationService:NotificationService
+) {
+
+    data class Receiver(
+        val receiverType: String = "-1",
+        val receiverId: String? = null,
+        val district: String = "-1",
+    )
+
+    private val userId = "sys"
+    private val regex = "#{param}"
+    private val templates = mutableMapOf<Int, NoticeTemplate?>()
+
+    /**
+     * 鍙戦�侀�氱煡
+     * @param code
+     * @see [SysNoticeTemplate],[LedgerNoticeTemplate],[SelfPatrolNoticeTemplate],
+     * [EmergencySelfPatrolNoticeTemplate],[AssessmentNoticeTemplate],[CommitmentNoticeTemplate]
+     */
+    private fun send(code: Int, receiver: Receiver, params: List<String> = emptyList()) {
+        val p = mutableListOf<String>().apply { addAll(params) }
+        val t = if (templates.containsKey(code)) {
+            templates[code]
+        } else {
+            val temp = noticeTemplateMapper.selectByPrimaryKey(code)
+            templates[code] = temp
+            temp
+        }
+        var template = t?.ntNoticeTemplate
+        while (p.isNotEmpty() && template?.contains(regex) == true) {
+            template = template.replace(regex, p.first())
+            p.removeFirst()
+        }
+
+        notificationService.releaseNotice(userId, NotificationVo(
+            authorId = userId,
+            authorName = userId,
+            typeId = t?.ntNoticeType?.toString(),
+            typeName = t?.ntNoticeTypeName,
+            subTypeId = t?.ntNoticeSubType?.toString(),
+            subTypeName = t?.ntNoticeSubTypeName,
+            title = t?.ntNoticeTitle,
+            content = t?.ntNoticeTemplate,
+            updateTime = Date(),
+            receiverType = receiver.receiverType,
+            receiverId = receiver.receiverId,
+            district = receiver.district
+        ))
+    }
+
+    /**
+     * 鍙戦�佺粰鐗瑰畾鐢ㄦ埛
+     */
+    private fun sendToUser(code: Int, users: List<Userinfo?>, params: List<String> = emptyList()) {
+        if (users.isNotEmpty()) {
+            val idList = users.map { it?.guid }.joinToString(";") + ";"
+            send(code, Receiver(receiverId = idList), params)
+        }
+    }
+
+    /**
+     * 鍙戦�佺粰涓�鐗囧尯鍩熷唴鐨勬墍鏈夌敤鎴�
+     */
+    private fun sendToArea(
+        code: Int,
+        sceneTypes: List<SceneType>,
+        districts: List<DistrictType>,
+        params: List<String> = emptyList(),
+    ) {
+        val receiverType = if (sceneTypes.isEmpty()) {
+            "0;"
+        } else {
+            sceneTypes.map { it.value }.joinToString(";") + ";"
+        }
+        val district = if (districts.isEmpty()) {
+            "0"
+        } else {
+            districts.joinToString(";") + ";"
+        }
+        send(code, Receiver(receiverType = receiverType, district = district), params)
+    }
+
+    /**
+     * 绯荤粺鎻愰啋/閫氱煡
+     */
+    fun send(t: SysNoticeTemplate, users: List<Userinfo?>, params: List<String> = emptyList()) =
+        sendToUser(t.value, users, params)
+
+    fun send(
+        t: SysNoticeTemplate,
+        sceneTypes: List<SceneType>,
+        districts: List<DistrictType>,
+        params: List<String> = emptyList(),
+    ) = sendToArea(t.value, sceneTypes, districts, params)
+
+    /**
+     * 鐜繚鍙拌处鎻愰啋/閫氱煡
+     */
+    fun send(t: LedgerNoticeTemplate, users: List<Userinfo?>, params: List<String> = emptyList()) =
+        sendToUser(t.value, users, params)
+
+    fun send(
+        t: LedgerNoticeTemplate,
+        sceneTypes: List<SceneType>,
+        districts: List<DistrictType>,
+        params: List<String> = emptyList(),
+    ) = sendToArea(t.value, sceneTypes, districts, params)
+
+    /**
+     * 鑷贰鏌ユ彁閱�/閫氱煡
+     */
+    fun send(t: SelfPatrolNoticeTemplate, users: List<Userinfo?>, params: List<String> = emptyList()) =
+        sendToUser(t.value, users, params)
+
+    fun send(
+        t: SelfPatrolNoticeTemplate,
+        sceneTypes: List<SceneType>,
+        districts: List<DistrictType>,
+        params: List<String> = emptyList(),
+    ) = sendToArea(t.value, sceneTypes, districts, params)
+
+    /**
+     * 搴旀�ヨ嚜宸℃煡鎻愰啋/閫氱煡
+     */
+    fun send(t: EmergencySelfPatrolNoticeTemplate, users: List<Userinfo?>, params: List<String> = emptyList()) =
+        sendToUser(t.value, users, params)
+
+    fun send(
+        t: EmergencySelfPatrolNoticeTemplate,
+        sceneTypes: List<SceneType>,
+        districts: List<DistrictType>,
+        params: List<String> = emptyList(),
+    ) = sendToArea(t.value, sceneTypes, districts, params)
+
+    /**
+     * 鑷祴鏅鸿瘎鎻愰啋/閫氱煡
+     */
+    fun send(t: AssessmentNoticeTemplate, users: List<Userinfo?>, params: List<String> = emptyList()) =
+        sendToUser(t.value, users, params)
+
+    fun send(
+        t: AssessmentNoticeTemplate,
+        sceneTypes: List<SceneType>,
+        districts: List<DistrictType>,
+        params: List<String> = emptyList(),
+    ) = sendToArea(t.value, sceneTypes, districts, params)
+
+    /**
+     * 瀹堟硶鎵胯鎻愰啋/閫氱煡
+     */
+    fun send(t: CommitmentNoticeTemplate, users: List<Userinfo?>, params: List<String> = emptyList()) =
+        sendToUser(t.value, users, params)
+
+    fun send(
+        t: CommitmentNoticeTemplate,
+        sceneTypes: List<SceneType>,
+        districts: List<DistrictType>,
+        params: List<String> = emptyList(),
+    ) = sendToArea(t.value, sceneTypes, districts, params)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/SysNoticeTemplate.kt b/src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/SysNoticeTemplate.kt
new file mode 100644
index 0000000..c54ac7d
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/bgtask/sysnotice/SysNoticeTemplate.kt
@@ -0,0 +1,47 @@
+package cn.flightfeather.supervision.bgtask.sysnotice
+
+//绯荤粺鎻愰啋/閫氱煡
+enum class SysNoticeTemplate(val value: Int, val des: String, val condition: String){
+    Login(5, "鐧诲綍鎻愰啋", "鐢ㄦ埛棣栨鐧诲綍锛堝疁鍦ㄩ娆$櫥褰曞悗鐨�3涓湀鍐呮瘡娆$櫥褰曞潎鎻愰啋锛岀洿鑷宠秴鏃舵垨宸插畬鎴愯韩浠介獙璇併�佸垵濮嬪瘑鐮佷慨鏀癸級"),
+    Auth(6, "璁よ瘉鎿嶄綔鎻愰啋", "棣栨鐧诲綍3涓湀鍚庯紝姣忔湀鎻愰啋涓�娆★紝鐩磋嚦瀹屾垚韬唤楠岃瘉"),
+    Authed(7, "璁よ瘉瀹屾垚閫氱煡", "韬唤楠岃瘉瀹屾垚鍚�"),
+    Password(8, "瀵嗙爜淇敼鎻愰啋", "棣栨鐧诲綍3涓湀鍚庯紝姣忔湀鎻愰啋涓�娆★紝鐩磋嚦瀹屾垚鍒濆瀵嗙爜淇敼"),
+    PasswordChanged(9, "瀵嗙爜淇敼閫氱煡","淇敼瀵嗙爜鍚�"),
+    PasswordReset(10, "瀵嗙爜閲嶇疆閫氱煡", "閲嶇疆瀵嗙爜鍚�"),
+    Resources(11, "瀛︿範璧勬簮鎻愰啋", "娑夊強鍦ㄧ嚎瀹堟硶瀛︿範涓叧鑱斿尯鍩熴�佺浉鍏宠涓氭渶鏂版帹鑽愬涔犺祫婧愬彂甯冩椂"),
+}
+
+//鐜繚鍙拌处鎻愰啋/閫氱煡
+enum class LedgerNoticeTemplate(val value: Int, val des: String, val condition: String){
+    Update(12, "鐜繚鍙拌处鏇存柊鎻愰啋", "姣忔湀1鍙枫��4鍙枫��7鍙蜂笂鍗�10锛�00"),
+    Deadline(13, "鐜繚鍙拌处鍒版湡鎻愰啋", "姣忔湀10鍙枫��20鍙枫��26鍙蜂笂鍗�10锛�00"),
+    Complete(14, "鐜繚鍙拌处瀹屾垚閫氱煡", "蹇呭~鍙拌处鍏ㄩ儴鎻愪氦瀹屾垚鍚�"),
+}
+
+//鑷贰鏌ユ彁閱�/閫氱煡
+enum class SelfPatrolNoticeTemplate(val value: Int, val des: String, val condition: String){
+    Update(15, "鑷贰鏌ユ搷浣滄彁閱�", "姣忔湀2鍙枫��5鍙枫��8鍙蜂笂鍗�10锛�00"),
+    Deadline(16, "鑷贰鏌ュ埌鏈熸彁閱�", "姣忔湀10鍙枫��18鍙枫��25鍙蜂笂鍗�10锛�00"),
+    Complete(17, "鑷贰鏌ュ畬鎴愰�氱煡", "鑷贰鏌ュ叏閮ㄦ彁浜ゅ悗"),
+}
+
+//搴旀�ヨ嚜宸℃煡鎻愰啋/閫氱煡
+enum class EmergencySelfPatrolNoticeTemplate(val value: Int, val des: String, val condition: String){
+    Update(18, "搴旀�ヨ嚜宸℃煡浠诲姟閫氱煡", "鏀跺埌搴旀�ヨ嚜宸℃煡浠诲姟鍚�"),
+    Deadline(19, "搴旀�ヨ嚜宸℃煡鍒版湡鎻愰啋", "搴旀�ヨ嚜宸℃煡浠诲姟鍒版湡鍓�1灏忔椂"),
+    Complete(20, "搴旀�ヨ嚜宸℃煡瀹屾垚閫氱煡", "搴旀�ヨ嚜宸℃煡鍏ㄩ儴鎻愪氦鍚�"),
+}
+
+//鑷祴鏅鸿瘎鎻愰啋/閫氱煡
+enum class AssessmentNoticeTemplate(val value: Int, val des: String, val condition: String){
+    Update(21, "鑷祴鏅鸿瘎鎿嶄綔鎻愰啋","姣忔湀3鍙枫��6鍙枫��9鍙蜂笂鍗�10锛�00"),
+    Deadline(22, "鑷祴鏅鸿瘎鍒版湡鎻愰啋", "姣忔湀10鍙枫��22鍙枫��28鍙蜂笂鍗�10锛�00"),
+    Complete(23, "鑷祴鏅鸿瘎瀹屾垚閫氱煡", "鑷瘎浼板畬鎴愬悗"),
+    Abnormal(24, "鑷祴鏅鸿瘎寮傚父閫氱煡", "鑷瘎浼拌瘎鍒嗕负浣庨闄╀笖鍙拌处鎴栬嚜宸℃煡涓婁紶鐜囦綆浜�60%鏃舵彁閱�"),
+}
+//瀹堟硶鎵胯鎻愰啋/閫氱煡
+enum class CommitmentNoticeTemplate(val value: Int, val des: String, val condition: String){
+    Update(25, "瀹堟硶鎵胯鎿嶄綔鎻愰啋", "瀹堟硶鎵胯鍒版湡鍓�30澶┿��20澶┿��10澶╁垎鍒彁閱掍竴娆�"),
+    Deadline(26, "瀹堟硶鎵胯澶辨晥鎻愰啋", "瀹堟硶鎵胯澶辨晥鍚�10澶┿��20澶┿��30澶╁垎鍒彁閱掍竴娆�"),
+    Complete(27, "瀹堟硶鎵胯瀹屾垚閫氱煡", "瀹堟硶鎵胯瀹屾垚鍚�"),
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/autoledger/AutoLedger.kt b/src/main/kotlin/cn/flightfeather/supervision/common/autoledger/AutoLedger.kt
new file mode 100644
index 0000000..762b145
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/autoledger/AutoLedger.kt
@@ -0,0 +1,172 @@
+package cn.flightfeather.supervision.common.autoledger
+
+import cn.flightfeather.supervision.common.pdf.PdfUtil
+import cn.flightfeather.supervision.domain.entity.LedgerSubType
+import cn.flightfeather.supervision.domain.entity.PracticalOperation
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.domain.repository.LedgerRep
+import cn.flightfeather.supervision.domain.repository.PracticalOperationRep
+import cn.flightfeather.supervision.infrastructure.utils.DateUtil
+import cn.flightfeather.supervision.lightshare.service.LedgerService
+import cn.flightfeather.supervision.lightshare.vo.LedgerVo
+import org.springframework.stereotype.Component
+import org.thymeleaf.context.Context
+import org.thymeleaf.spring5.SpringTemplateEngine
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.ZoneId
+import java.time.ZoneOffset
+import java.time.format.DateTimeFormatter
+import java.util.*
+
+/**
+ * 鍙拌处鑷姩鐢熸垚
+ */
+@Component
+class AutoLedger(
+    private val springTemplateEngine: SpringTemplateEngine,
+    private val ledgerRep: LedgerRep,
+    private val practicalOperationRep: PracticalOperationRep,
+    private val ledgerService: LedgerService,
+) {
+
+    /**
+     * 鏍规嵁瀹炴搷浜嬪姟鐨勯厤缃紝鐢熸垚瀵瑰簲鐨勫彴璐﹁褰�
+     * 褰撴湀鐨勫彴璐﹁褰曞簲璇ョ敱涓婁釜鏈堢殑瀹炴搷璁板綍浣滀负鍐呭杩涜鐢熸垚
+     * @param userInfo 鐢熸垚鍙拌处瀵瑰簲鐨勭敤鎴蜂俊鎭�
+     * @param operations 瀹炴搷浜嬪姟
+     * @param year 鐢熸垚鐨勫彴璐︽墍鍦ㄥ勾浠�
+     * @param month 鐢熸垚鐨勫彴璐︽墍鍦ㄦ湀浠�
+     */
+    fun create(userInfo: Userinfo?, operations: List<PracticalOperation?>, year: Int, month: Int) {
+        if (userInfo == null || operations.isEmpty()) {
+            return
+        }
+        // 鍙拌处鐨勬椂闂磋寖鍥�
+        val thisMonth = LocalDateTime.of(year, month, 1, 0, 0)
+        val sT = thisMonth.minusMonths(1)
+        val eT = thisMonth.minusSeconds(1)
+
+        val ledger = ledgerRep.selectLedger(operations[0]?.poLedgerTypeId)
+
+        val map = hashMapOf<String, Any>()
+        map["info"] = getBaseInfo(ledger, userInfo, operations)
+        val records = getRecords(userInfo, operations, sT, eT)
+        // 褰撶敤鎴锋病鏈夋搷浣滆褰曟椂锛屼笉鐢熸垚瀵瑰簲鍙拌处
+        if (records.isEmpty()) return
+        map["table"] = records
+
+        val context = Context()
+        context.setVariables(map)
+        val content = springTemplateEngine.process("ledger-3206", context)
+        val pdf = PdfUtil.htmlToPdf(content)
+        val pics = PdfUtil.pdfToPic(pdf)
+        val files = pics.map { Pair(it, "jpg") }
+
+        // 鐢熸垚鐨勫彴璐︽椂闂翠负浼犲叆鐨勬椂闂�
+        val ledgerVo = LedgerVo.fromLedgerSubtype(ledger).apply {
+            updateDate = Date.from(thisMonth.atZone(ZoneId.systemDefault()).toInstant())
+        }
+        ledgerService.uploadLedger(userInfo.guid!!, ledgerVo, files)
+    }
+
+    /**
+     *
+     */
+    private fun getBaseInfo(ledger: LedgerSubType?, userInfo: Userinfo, operations: List<PracticalOperation?>):
+            UserBaseInfo {
+        val title = operations[0]?.poLedgerTypeName ?: ""
+        val stateRange = operations[0]?.poStateRange?.split(";")
+        val stateNames = getStateNames(stateRange)
+        val now = LocalDate.now().format(DateTimeFormatter.ofPattern("YYYY骞碝M鏈�"))
+        return UserBaseInfo(title, userInfo.realname ?: "", now, stateNames)
+    }
+
+    /**
+     * 鑾峰彇鐘舵�佹爣棰�
+     */
+    private fun getStateNames(stateRange: List<String>?): List<String> {
+        stateRange ?: return emptyList()
+        val res = mutableListOf<String>()
+        res.addAll(stateRange.subList(1, stateRange.size))
+        res.add(stateRange[0])
+        return res
+    }
+
+    /**
+     *
+     */
+    private fun getRecords(
+        userInfo: Userinfo,
+        operations: List<PracticalOperation?>,
+        sT: LocalDateTime,
+        eT: LocalDateTime,
+    ): List<Record> {
+        val userId = userInfo.guid
+        val records = mutableListOf<Record>()
+        operations.forEach {
+            val deviceName = it?.poSubTypeName + it?.poDeviceCode
+            val stateRange = it?.poStateRangeId?.split(";") ?: return@forEach
+            // 鐘舵�佹渶灏戞湁涓ょ锛屽惁鍒欏簲璇ユ槸閰嶇疆閿欒
+            if (stateRange.size < 2) return@forEach
+            val opRecords = practicalOperationRep.getRecords(userId, listOf(it.poId), sT, eT, true)
+
+            // 鍒ゆ柇浜嬪姟鐨勭姸鎬佽鍒欐槸鍚︿负渚濇鍙樻崲鍨�
+            if (it.poStateRule == 0) {
+                // 璇ヨ鍒欎笅鐨勫彴璐﹁褰曚細灏嗕竴缁勫畬鏁寸殑鐘舵�佸彉鎹㈣涓轰竴鏉¤褰曪紝
+                // 閫氬父棣栦釜鐘舵�佸惈涔変负鍏抽棴锛屾墍浠ヤ竴鑸粠绗簩涓姸鎬佸紑濮�
+                opRecords.forEach { r ->
+                    val time = LocalDateTime.ofInstant(r?.prTime?.toInstant(), ZoneId.systemDefault())
+                    val date = time.format(DateTimeFormatter.ofPattern("MM鏈坉d鏃�"))
+                    val stateTimes = MutableList<String?>(stateRange.size) { "" }
+                    // 褰撶姸鎬佷笉鏄叧闂椂锛岃〃绀鸿繖涓�缁勭姸鎬佽繕鏈畬鎴愶紝鍥犳娣诲姞鍒颁笂涓�鏉¤褰曚腑
+                    // 濡傛灉娌℃湁涓婁竴鏉¤褰曪紝鎴栬�呯姸鎬佷负闄や簡鍏抽棴鐨勭涓�涓姸鎬侊紝鍒欐柊澧炶褰�
+                    val record = if (records.isEmpty() || r?.prStateId == stateRange[1]) {
+                        val r = Record(deviceName, date, stateTimes)
+                        records.add(r)
+                        r
+                    } else {
+                        val last = records.last()
+                        // 鍒ゆ柇褰撳墠璁板綍鍜屼笂涓�鏉¤褰曟槸鍚﹀湪鍚屼竴澶�
+                        if (last.date == date) {
+                            last
+                        } else {
+                            val r1 = Record(deviceName, date, stateTimes)
+                            records.add(r1)
+                            r1
+                        }
+                    }
+                    var index = stateRange.indexOf(r?.prStateId)
+                    if (index != -1) {
+                        index -= 1
+                        if (index == -1) index = stateRange.lastIndex
+                        record.stateTimes[index] = DateUtil.DateToString(r?.prTime, DateUtil.DateStyle.HH_MM_SS)
+                    }
+                }
+            } else if (it.poStateRule == 1) {
+                // TODO: 2024/3/8
+            }
+        }
+        return records
+    }
+
+    /**
+     * 鐢ㄦ埛鍩烘湰淇℃伅
+     */
+    inner class UserBaseInfo(
+        val title: String?,
+        val userName: String?,
+        val timeStamp: String?,
+        val stateNames: List<String>,
+    )
+
+    /**
+     * 鍙拌处璁板綍
+     */
+    inner class Record(
+        val deviceName: String?,
+        val date: String?,
+        val stateTimes: MutableList<String?>,
+    )
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/creditcode/EnvCreditCode.kt b/src/main/kotlin/cn/flightfeather/supervision/common/creditcode/EnvCreditCode.kt
new file mode 100644
index 0000000..0223df0
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/creditcode/EnvCreditCode.kt
@@ -0,0 +1,123 @@
+package cn.flightfeather.supervision.common.creditcode
+
+import cn.flightfeather.supervision.infrastructure.utils.QRCodeUtil
+import java.awt.Color
+import java.awt.Font
+import java.awt.image.BufferedImage
+import java.io.*
+import javax.imageio.IIOImage
+import javax.imageio.ImageIO
+import javax.imageio.ImageTypeSpecifier
+import javax.imageio.metadata.IIOInvalidTreeException
+import javax.imageio.metadata.IIOMetadata
+import javax.imageio.metadata.IIOMetadataNode
+import javax.imageio.stream.ImageOutputStream
+
+/**
+ * 鐜俊鐮佺敓鎴愬伐鍏�
+ */
+object EnvCreditCode {
+
+    val templatePath =
+        (Thread.currentThread().contextClassLoader?.getResource("/")?.path ?: "src/main/resources") + "/templates/"
+    val templateName = "qr_code_bg.png"
+
+    fun createImage(userId: String, userName: String, company: String?, supply: String?, os: OutputStream) {
+        // 纭畾鍥剧墖瀹介珮浠ュ強浜岀淮鐮佺殑瀹藉害
+        val bgWidth = 1181
+        val bgHeight = 1654
+        val qrCodeWidth = 440
+
+        // 鐢熸垚浜岀淮鐮佸浘鐗�
+        val baseUrl = "http://47.100.191.150/ledger/page/qrcode.html"
+        val url = "$baseUrl?id=${userId}"
+        val qrCode = QRCodeUtil.createQRCodeBitmap2(url, userName, qrCodeWidth, qrCodeWidth)
+
+        // 鐢熸垚鐢诲竷
+        val bg = ImageIO.read(FileInputStream(templatePath + templateName))
+        val source = BufferedImage(bgWidth, bgHeight, BufferedImage.TYPE_INT_RGB)
+
+
+//        val f1 = Font("鎬濇簮榛戜綋 CN Medium", Font.PLAIN, 40)
+        val font = Font("寰蒋闆呴粦", Font.PLAIN, 40)
+
+        val graphics2D = source.graphics
+
+        // 缁樺埗浜岀淮鐮佸簳鍥�
+        graphics2D.drawImage(bg, 0, 0) { _, _, _, _, _, _ ->
+            true
+        }
+
+        // 缁樺埗椤堕儴灞呬腑鐨勫満鏅悕绉帮紙x鍧愭爣鏍规嵁鏂囨湰闀垮害鍔ㄦ�佽绠楋紝y鍧愭爣鏍规嵁璁捐鏂规鐩存帴瀹氫綅锛�
+        graphics2D.font = font
+        graphics2D.color = Color.BLACK
+        val w1 = graphics2D.fontMetrics.stringWidth(userName)
+        val x1 = (bgWidth - w1) / 2
+        graphics2D.drawString(userName, x1, 160 + graphics2D.fontMetrics.ascent)
+
+        // 缁樺埗鍦烘櫙鍚嶇О涓嬫柟灞呬腑鐨勬墍灞炰紒涓氬悕绉帮紙x鍧愭爣鏍规嵁鏂囨湰闀垮害鍔ㄦ�佽绠楋紝y鍧愭爣鏍规嵁璁捐鏂规鐩存帴瀹氫綅锛�
+        val c = company ?: ""
+        graphics2D.font = font
+        val w2 = graphics2D.fontMetrics.stringWidth(c)
+        val x2 = (bgWidth - w2) / 2
+        graphics2D.drawString(c, x2, 250 + graphics2D.fontMetrics.ascent)
+
+        // 缁樺埗涓績鐨勪簩缁寸爜鍥剧墖锛坸鍧愭爣鏍规嵁鏂囨湰闀垮害鍔ㄦ�佽绠楋紝y鍧愭爣鏍规嵁璁捐鏂规鐩存帴瀹氫綅锛�
+        val x3 = (bgWidth - qrCodeWidth) / 2
+        graphics2D.drawImage(qrCode, x3, 410) { img, infoflags, x, y, width, height ->
+            true
+        }
+
+        // 缁樺埗鏀寔鎻愪緵鏂�
+        val s = supply ?: ""
+        graphics2D.font = Font("寰蒋闆呴粦", Font.PLAIN, 30)
+        val w4 = graphics2D.fontMetrics.stringWidth(s)
+        val x4 = (bgWidth - w4) / 2
+        graphics2D.drawString(s, x4, 753 + graphics2D.fontMetrics.ascent)
+
+        val a = ImageIO.getImageWritersByFormatName("png")
+        while (a.hasNext()) {
+            val iw = a.next()
+            val writeParam = iw.defaultWriteParam
+            val typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB)
+            val metadata = iw.getDefaultImageMetadata(typeSpecifier, writeParam)
+            if (metadata.isReadOnly || !metadata.isStandardMetadataFormatSupported) {
+                continue
+            }
+
+            setDPI(metadata)
+
+            val stream = ImageIO.createImageOutputStream(os)
+//            val stream = ImageIO.createImageOutputStream(output)
+//            val stream = ImageIO.createImageOutputStream(File("C:/tools/${userName}.png"))
+            stream.use {
+                iw.output = it
+                iw.write(metadata, IIOImage(source, null, metadata), writeParam)
+            }
+            break
+        }
+//        ImageIO.write(source, "png", File("E:/qrcode/${it.second}.png"))
+    }
+
+    @Throws(IIOInvalidTreeException::class)
+    private fun setDPI(metadata: IIOMetadata) {
+
+        // for PMG, it's dots per millimeter
+        val dotsPerMilli = 1.0 * 300 / 10 / 2.54
+
+        val horiz = IIOMetadataNode("HorizontalPixelSize")
+        horiz.setAttribute("value", java.lang.Double.toString(dotsPerMilli))
+
+        val vert = IIOMetadataNode("VerticalPixelSize")
+        vert.setAttribute("value", java.lang.Double.toString(dotsPerMilli))
+
+        val dim = IIOMetadataNode("Dimension")
+        dim.appendChild(horiz)
+        dim.appendChild(vert)
+
+        val root = IIOMetadataNode("javax_imageio_1.0")
+        root.appendChild(dim)
+
+        metadata.mergeTree("javax_imageio_1.0", root)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/docimport/BaseExcelRule.kt b/src/main/kotlin/cn/flightfeather/supervision/common/docimport/BaseExcelRule.kt
new file mode 100644
index 0000000..684e501
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/docimport/BaseExcelRule.kt
@@ -0,0 +1,5 @@
+package cn.flightfeather.supervision.common.docimport
+
+abstract class BaseExcelRule {
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/docimport/ExcelImport.kt b/src/main/kotlin/cn/flightfeather/supervision/common/docimport/ExcelImport.kt
new file mode 100644
index 0000000..fdb571f
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/docimport/ExcelImport.kt
@@ -0,0 +1,42 @@
+@file:Suppress("UNCHECKED_CAST")
+
+package cn.flightfeather.supervision.common.docimport
+
+import org.apache.poi.hssf.usermodel.HSSFWorkbook
+import org.apache.poi.ss.usermodel.Row
+
+object ExcelImport {
+
+    fun <T : BaseExcelRule> parseToDataList(workbook: HSSFWorkbook, ruleClz: Class<T>, header: List<String>): List<T> {
+        if (!checkLegal(workbook, ruleClz, header)) return emptyList()
+
+        val result = mutableListOf<T>()
+        val sheet1 = workbook.getSheetAt(0)
+        val rowIterator = sheet1.rowIterator()
+        while (rowIterator.hasNext()) {
+            val row = rowIterator.next()
+            if (row.rowNum > 0) {
+                if (row.getCell(0).toString().trim().isNotBlank()) {
+                    val data = parseToData(row, ruleClz, header)
+                    result.add(data)
+                }
+            }
+        }
+
+        return result
+    }
+
+    private fun <T : BaseExcelRule> checkLegal(workbook: HSSFWorkbook, ruleClz: Class<T>, header:List<String>):
+            Boolean {
+        // TODO: 2023/8/30 琛ㄥご鍚堟硶鎬ф鏌�
+        return true
+    }
+
+    private fun <T : BaseExcelRule> parseToData(row: Row, ruleClz: Class<T>, header: List<String>): T {
+        val params = mutableListOf<String>()
+        repeat(header.size) {
+            params.add(row.getCell(it).toString().trim())
+        }
+        return ruleClz.constructors[0].newInstance(*params.toTypedArray()) as T
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/docimport/UserExcelRule.kt b/src/main/kotlin/cn/flightfeather/supervision/common/docimport/UserExcelRule.kt
new file mode 100644
index 0000000..c69d8fa
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/docimport/UserExcelRule.kt
@@ -0,0 +1,26 @@
+package cn.flightfeather.supervision.common.docimport
+
+/**
+ * 鐢ㄦ埛淇℃伅瀵煎叆瑙勫垯
+ */
+class UserExcelRule(
+    val name:String,
+    val provinceCode: String?,
+    val provinceName: String?,
+    val cityCode: String?,
+    val cityName: String?,
+    val districtCode: String?,
+    val districtName: String?,
+    val townCode: String?,
+    val townName: String?,
+    val areaCode: String?,
+    val area: String?,
+    val address:String?,
+    val contact:String?,
+    val telephone:String?
+):BaseExcelRule() {
+
+    companion object {
+        val header = listOf<String>()
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/exception/ResponseErrorException.kt b/src/main/kotlin/cn/flightfeather/supervision/common/exception/ResponseErrorException.kt
new file mode 100644
index 0000000..e01d06e
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/exception/ResponseErrorException.kt
@@ -0,0 +1,13 @@
+package cn.flightfeather.supervision.common.exception
+
+/**
+ * 鍏佽鎺ュ彛杩斿洖鐨勪笟鍔″眰闈㈢殑閿欒
+ */
+class ResponseErrorException : Exception {
+    constructor():super()
+    constructor(message: String) : super(message)
+    constructor(message: String, cause: Throwable) : super(message, cause)
+    constructor(cause: Throwable) : super(cause)
+    constructor(message: String, cause: Throwable, enableSuppression: Boolean, writableStackTrace: Boolean)
+            : super(message, cause, enableSuppression, writableStackTrace)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/net/FumeHttpService.kt b/src/main/kotlin/cn/flightfeather/supervision/common/net/FumeHttpService.kt
index 0104c3b..ba4f99d 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/common/net/FumeHttpService.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/net/FumeHttpService.kt
@@ -1,5 +1,7 @@
 package cn.flightfeather.supervision.common.net
 
+import cn.flightfeather.supervision.bgtask.TaskPushFume.Companion.HZY
+import cn.flightfeather.supervision.bgtask.TaskPushFume.Companion.ZQ
 import com.google.gson.Gson
 import com.google.gson.JsonObject
 import com.google.gson.JsonParser
@@ -13,37 +15,54 @@
 
     private val httpMethod = HttpMethod("xhhb-yy.senzly.top", 80)
 
-    data class PostData(
-            val apiKey: String = "hengzhiyuan",
-            val pwd: String = "123456",
-            val data: MutableList<FumeData> = mutableListOf()
-    )
+    class PostData private constructor(
+        val apiKey: String,
+        val pwd: String,
+        val data: MutableList<FumeData> = mutableListOf(),
+    ){
+        companion object {
+            fun newInstance(deviceType: String): PostData {
+                return when (deviceType) {
+                    HZY -> {
+                        PostData("hengzhiyuan", "123456")
+                    }
+                    ZQ -> {
+                        PostData("zhuoquan", "zq63618889")
+                    }
+                    else -> {
+                        PostData("", "")
+                    }
+                }
+            }
+        }
+    }
+
 
     data class FumeData(
-            //璁惧缂栧彿锛堜緵搴斿晢鑷畾涔夛紝鏈�澶ч暱搴︼細50锛屽繀椤荤‘淇濆敮涓�鎬э級
-            val equipmentShowId: String,
-            //鏁版嵁鏃堕棿锛屾牸寮忓繀椤绘槸yyyy/MM/dd HH:mm:ss鎴杫yyy-MM-dd HH:mm:ss
-            val dataTime: String?,
-            //褰撳墠杩涚儫娴撳害mg/m鲁锛屾暟鍊煎瀷锛屽厑璁稿皬鏁�
-            val valIn: Double,
-            //褰撳墠鎺掔儫娴撳害mg/m鲁锛屾暟鍊煎瀷锛屽厑璁稿皬鏁�
-            val valOut: Double,
-            //椋庢満鐘舵��:0:"鏃�",1:"鎹熷潖",2:"寰呮満",3:"鍚姩"
-            val fanStatus: Int,
-            //椋庢満宸ヤ綔鐢垫祦锛屾暟鍊硷紝鍏佽灏忔暟
-            val fanA: Double,
-            //椋庢満宸插惎鍔ㄦ椂闀�(鍒嗛挓)
-            val fanMinute: Int,
-            //鍑�鍖栧櫒鐘舵��:0:"鏃�",1:"鎹熷潖",2:"寰呮満",3:"鍚姩"
-            val purifyStatus: Int,
-            //鍑�鍖栧櫒宸ヤ綔鐢垫祦锛屾暟鍊硷紝鍏佽灏忔暟
-            val purifyA: Double,
-            //鍑�鍖栧櫒宸插惎鍔ㄦ椂闀�(鍒嗛挓)锛屾暟鍊硷紝蹇呴』鏁存暟
-            val purifyMinute: Int,
-            //娓呮磥搴︼紙鍋滅敤锛夛紝0-100鏁板�硷紝鍏佽灏忔暟
-            val cleanliness: Int,
-            //鍑�鍖栫巼锛�0-100鏁板�硷紝鍏佽灏忔暟
-            val purifyRate: Double
+        //璁惧缂栧彿锛堜緵搴斿晢鑷畾涔夛紝鏈�澶ч暱搴︼細50锛屽繀椤荤‘淇濆敮涓�鎬э級
+        val equipmentShowId: String,
+        //鏁版嵁鏃堕棿锛屾牸寮忓繀椤绘槸yyyy/MM/dd HH:mm:ss鎴杫yyy-MM-dd HH:mm:ss
+        val dataTime: String?,
+        //褰撳墠杩涚儫娴撳害mg/m鲁锛屾暟鍊煎瀷锛屽厑璁稿皬鏁�
+        val valIn: Double,
+        //褰撳墠鎺掔儫娴撳害mg/m鲁锛屾暟鍊煎瀷锛屽厑璁稿皬鏁�
+        val valOut: Double,
+        //椋庢満鐘舵��:0:"鏃�",1:"鎹熷潖",2:"寰呮満",3:"鍚姩"
+        val fanStatus: Int,
+        //椋庢満宸ヤ綔鐢垫祦锛屾暟鍊硷紝鍏佽灏忔暟
+        val fanA: Double,
+        //椋庢満宸插惎鍔ㄦ椂闀�(鍒嗛挓)
+        val fanMinute: Int,
+        //鍑�鍖栧櫒鐘舵��:0:"鏃�",1:"鎹熷潖",2:"寰呮満",3:"鍚姩"
+        val purifyStatus: Int,
+        //鍑�鍖栧櫒宸ヤ綔鐢垫祦锛屾暟鍊硷紝鍏佽灏忔暟
+        val purifyA: Double,
+        //鍑�鍖栧櫒宸插惎鍔ㄦ椂闀�(鍒嗛挓)锛屾暟鍊硷紝蹇呴』鏁存暟
+        val purifyMinute: Int,
+        //娓呮磥搴︼紙鍋滅敤锛夛紝0-100鏁板�硷紝鍏佽灏忔暟
+        val cleanliness: Int,
+        //鍑�鍖栫巼锛�0-100鏁板�硷紝鍏佽灏忔暟
+        val purifyRate: Double,
     )
 
     fun uploadData(postData: PostData): JsonObject? {
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/net/HttpMethod.kt b/src/main/kotlin/cn/flightfeather/supervision/common/net/HttpMethod.kt
index c526c76..f905a2c 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/common/net/HttpMethod.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/net/HttpMethod.kt
@@ -6,6 +6,8 @@
 import org.apache.commons.httpclient.methods.PostMethod
 import org.apache.commons.httpclient.methods.StringRequestEntity
 import org.apache.commons.httpclient.protocol.Protocol
+import org.apache.http.client.methods.HttpPost
+import org.slf4j.LoggerFactory
 
 /**
  * @author riku
@@ -14,6 +16,7 @@
 class HttpMethod(
         private val host: String, private val port: Int, private val isHttps: Boolean = false
 ) {
+    private val logger = LoggerFactory.getLogger(HttpMethod::class.java)
 
     data class MyResponse(
             val success: Boolean,
@@ -27,6 +30,7 @@
     private val httpClient = HttpClient()
 
     init {
+        Protocol.registerProtocol("https", Protocol("https", SkipCertificateValidation.MySecureProtocolSocketFactory(), port))
         if (isHttps) {
             httpClient.hostConfiguration.setHost(host, port, Protocol.getProtocol("https"))
         } else {
@@ -65,17 +69,25 @@
             postMethod.requestEntity = StringRequestEntity(data, "application/json", "utf-8")
         }
 
-        return when (httpClient.executeMethod(postMethod)) {
-            200 -> MyResponse(true, postMethod)
-            else -> MyResponse(false, postMethod)
+        return try {
+            when (httpClient.executeMethod(postMethod)) {
+                200 -> MyResponse(true, postMethod)
+                else -> MyResponse(false, postMethod)
+            }
+        } catch (e: Exception) {
+            logger.error(e.message)
+            MyResponse(false, postMethod)
         }
     }
 
     private fun defaultConfig(method: HttpMethodBase) {
-        method.setRequestHeader("accept", "*/*");
-        method.setRequestHeader("connection", "Keep-Alive");
-        method.setRequestHeader("Accept-Language", "zh-cn,zh;q=0.5");
-        method.setRequestHeader("Content-Type", "application/json;charset=utf-8")
+        method.setRequestHeader("Accept", "*/*");
+        method.setRequestHeader("Connection", "Keep-Alive");
+//        method.setRequestHeader("Accept-Language", "zh-cn,zh;q=0.5");
+        method.setRequestHeader("Accept-Encoding", "gzip,deflate,br");
+//        method.setRequestHeader("Content-Type", "application/json;charset=utf-8")
+        method.setRequestHeader("Content-Type", "application/json")
+//        method.setRequestHeader("Content-Type", "application/json;charset=GBK")
     }
 
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/net/JinAnLianTongHttpService.kt b/src/main/kotlin/cn/flightfeather/supervision/common/net/JinAnLianTongHttpService.kt
new file mode 100644
index 0000000..16e44ac
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/net/JinAnLianTongHttpService.kt
@@ -0,0 +1,199 @@
+package cn.flightfeather.supervision.common.net
+
+import cn.flightfeather.supervision.infrastructure.utils.DateUtil
+import cn.flightfeather.supervision.infrastructure.utils.GsonUtils
+import cn.flightfeather.supervision.lightshare.vo.JinAnConstructionInfo
+import cn.flightfeather.supervision.lightshare.vo.JinAnHourDustData
+import cn.flightfeather.supervision.lightshare.vo.JinAnLampDeviceData
+import cn.flightfeather.supervision.lightshare.vo.JinAnLampEnterBaseInfo
+import com.google.gson.*
+import org.apache.commons.codec.digest.DigestUtils
+import org.apache.commons.codec.digest.Md5Crypt
+import org.apache.tomcat.util.security.MD5Encoder
+import java.nio.charset.Charset
+import java.time.LocalDateTime
+import java.util.*
+import kotlin.time.seconds
+
+/**
+ * @author riku
+ * Date: 2022/11/15
+ * 闈欏畨鑱旈�氬叕鍙告彁渚涳紝宸ュ湴鍜岄楗洃娴嬫暟鎹姄鍙栨湇鍔℃帴鍙�
+ */
+object JinAnLianTongHttpService {
+
+    const val TAG = "JinAnLianTongHttpService"
+    private const val TOKEN = "e6dc8bb9e1ff0ce973fb92b4af2e4c3f"
+    private val httpMethod: HttpMethod = HttpMethod("101.230.224.77", 8088, true)
+
+    open class RequestData(
+        val current: Int = 1,
+        val size: Int = 30,
+    )
+
+    class LampRequestData(c: Int, s: Int, val smDate: String? = null, val emDate: String? = null) : RequestData(c, s)
+    class DustRequestData(c: Int, s: Int, val sdate: String? = null, val edate: String? = null) : RequestData(c, s)
+
+    init {
+        // FIXME: 2022/11/18 姝ゅ鐩墠閫氳繃蹇界暐SSL璇佷功楠岃瘉鐨勬柟寮忚繘琛岃闂�
+//        SkipCertificateValidation.ignoreSsl()
+    }
+
+    /**
+     * 缁熶竴璇锋眰澶�
+     */
+    fun headTimeStamp(): List<Pair<String, String>> {
+        val nowS = Date().time / 1000
+        val t = nowS - 200
+        val now = t.toString()
+        val key = "$now$TOKEN"
+        val sign = DigestUtils.md5Hex(key)
+        return listOf(
+            Pair("JA-TIMESTAMP", now),
+            Pair("JA-TOKEN", TOKEN),
+            Pair("JA-SIGN", sign)
+        )
+    }
+
+    /**
+     * 杩斿洖鏍¢獙缁撴灉
+     */
+    private fun resCheck(json: JsonElement): JsonObject {
+        if (!json.isJsonObject) throw IllegalStateException("${TAG}: 鑾峰彇宸ュ湴鎵皹鐩戞祴鐐逛俊鎭け璐ワ紝杩斿洖鍊间笉鏄竴涓猳bject")
+
+        val jo = json.asJsonObject
+        if (jo["code"].asInt != 20000) throw IllegalStateException("${TAG}: 鑾峰彇宸ュ湴鎵皹鐩戞祴鐐逛俊鎭け璐ワ紝閿欒${jo["message"]}")
+
+        if (!jo["data"].isJsonObject) throw IllegalStateException("${TAG}: 鑾峰彇宸ュ湴鎵皹鐩戞祴鐐逛俊鎭け璐ワ紝data瀛楁涓嶅瓨鍦ㄦ垨涓嶆槸object缁撴瀯")
+
+        val data = jo["data"].asJsonObject
+
+        if (!data["current"].isJsonPrimitive) throw IllegalStateException("${TAG}: 鑾峰彇宸ュ湴鎵皹鐩戞祴鐐逛俊鎭け璐ワ紝current瀛楁涓嶅瓨鍦ㄦ垨涓嶆槸鍩虹鏁版嵁缁撴瀯")
+        if (!data["pages"].isJsonPrimitive) throw IllegalStateException("${TAG}: 鑾峰彇宸ュ湴鎵皹鐩戞祴鐐逛俊鎭け璐ワ紝pages瀛楁涓嶅瓨鍦ㄦ垨涓嶆槸鍩虹鏁版嵁缁撴瀯")
+        if (!data["records"].isJsonArray) throw IllegalStateException("${TAG}: 鑾峰彇宸ュ湴鎵皹鐩戞祴鐐逛俊鎭け璐ワ紝records瀛楁涓嶅瓨鍦ㄦ垨涓嶆槸Array缁撴瀯")
+
+        return data
+    }
+
+    /**
+     * 鏍规嵁杩斿洖缁撴灉鍒ゆ柇鏄惁鏈変笅涓�鍒嗛〉
+     */
+    private fun nextPage(data: JsonObject):Boolean {
+        val current = data["current"].asInt
+        val pages = data["pages"].asInt
+        return current < pages
+    }
+
+    private inline fun <reified T> post(url: String, requestData: RequestData): Pair<Boolean, List<T>> {
+        val dataJson = Gson().toJson(requestData)
+        val res = httpMethod.post(url, dataJson, headTimeStamp())
+        return if (res.success) {
+            val str = if (res.m.responseCharSet == "utf-8") {
+                res.m.responseBodyAsString
+            } else {
+                String(res.m.responseBody, Charset.forName("utf-8"))
+            }
+            val json = JsonParser.parseString(str)
+            val data = resCheck(json)
+            val records = data["records"]
+            val next = nextPage(data)
+            val result = GsonUtils.parserJsonToArrayBeans(records.asJsonArray.toString(), T::class.java)
+            Pair(next, result)
+        } else {
+            throw IllegalStateException("缃戣矾閾炬帴閿欒锛岀姸鎬佺爜锛�${res.m.statusCode}")
+        }
+    }
+
+    /**
+     * 鎺ュ彛鏃堕棿閫傞厤
+     * 鏃堕棿瀛楁鐩墠鐢变簬鎺ュ彛鎻愪緵鏂圭殑鍘熷洜锛屽鑷存牸寮忎笉鍥哄畾
+     */
+    private fun dateAdapter(e: JsonElement): Date? {
+        if (e.isJsonNull) return null
+
+        // 灏濊瘯鏄惁鏄暟鍊兼牸寮�
+        try {
+            var d = e.asLong
+            // 鍙兘鏄�10浣嶆暟鐨勭鍊硷紝闇�瑕佽浆鎹负姣鍊�
+            if (d.toString().length == 10) {
+                d *= 1000
+            }
+            return Date(d)
+        } catch (e: Exception) {
+
+        }
+        // 灏濊瘯鏄惁鏄瓧绗︿覆鏍煎紡
+        try {
+            val d = e.asString
+            return DateUtil.StringToDate(d)
+        } catch (e: Exception) {
+
+        }
+        throw IllegalStateException("鏃堕棿瀛楁鐨勬牸寮忛�傞厤澶辫触")
+    }
+
+    /**
+     * 鑾峰彇宸ュ湴鎵皹鐩戞祴鐐逛俊鎭�
+     */
+    fun getConstructionDustMonitorSiteInfo(page: Int = 1): Pair<Boolean, List<JinAnConstructionInfo>> {
+        val requestData = RequestData(page, 100)
+        return post("/api/dust/v1/getConstructionDustMonitorSiteInfo", requestData)
+    }
+
+    /**
+     * 鏌ヨ宸ュ湴鎵皹鐩戞祴鐐瑰皬鏃舵暟鎹�
+     */
+    fun getHourlyDustData(page: Int = 1, sDate: Date?, eDate: Date?, perPage:Int = 5000): Pair<Boolean,
+            List<JinAnHourDustData>> {
+        val sStr = DateUtil.DateToString(sDate, DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS)
+        val eStr = DateUtil.DateToString(eDate, DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS)
+        val requestData = DustRequestData(page, perPage, sStr, eStr)
+//        return post("/api/dust/v1/getHourlyDustData", requestData)
+        val url = "/api/dust/v1/getHourlyDustData"
+        val dataJson = Gson().toJson(requestData)
+        val res = httpMethod.post(url, dataJson, headTimeStamp())
+        return if (res.success) {
+            val str = if (res.m.responseCharSet == "utf-8") {
+                res.m.responseBodyAsString
+            } else {
+                String(res.m.responseBody, Charset.forName("utf-8"))
+            }
+            val json = JsonParser.parseString(str)
+            val data = resCheck(json)
+            val records = data["records"]
+            val next = nextPage(data)
+
+            val jsonArray = records.asJsonArray
+            val beans = mutableListOf<JinAnHourDustData>()
+            jsonArray.forEach {
+                val bean = Gson().fromJson(it, JinAnHourDustData::class.java)
+                bean.createTime = dateAdapter(it.asJsonObject["inserttime"])
+                bean.stTime = dateAdapter(it.asJsonObject["lst"])
+                bean.etTime = dateAdapter(it.asJsonObject["lst_END"])
+                beans.add(bean)
+            }
+            Pair(next, beans)
+        } else {
+            throw IllegalStateException("缃戣矾閾炬帴閿欒锛岀姸鎬佺爜锛�${res.m.statusCode}")
+        }
+    }
+
+    /**
+     * 鏌ヨ娌圭儫鐩戞祴浼佷笟
+     */
+    fun getLampEnterBaseInfo(page: Int = 1): Pair<Boolean, List<JinAnLampEnterBaseInfo>> {
+        val requestData = RequestData(page, 1000)
+        return post("/api/lamp/v1/getLampEnterBaseInfo", requestData)
+    }
+
+    /**
+     * 鏌ヨ娌圭儫璁惧鏁版嵁
+     */
+    fun getLampDeviceData(page: Int = 1, smDate: Date?, emDate: Date?): Pair<Boolean, List<JinAnLampDeviceData>> {
+        val sStr = DateUtil.DateToString(smDate, DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS)
+        val eStr = DateUtil.DateToString(emDate, DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS)
+        val requestData = LampRequestData(page, 5000, sStr, eStr)
+        return post("/api/lamp/v1/getLampDeviceData", requestData)
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/net/SkipCertificateValidation.kt b/src/main/kotlin/cn/flightfeather/supervision/common/net/SkipCertificateValidation.kt
new file mode 100644
index 0000000..f3f5761
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/net/SkipCertificateValidation.kt
@@ -0,0 +1,150 @@
+package cn.flightfeather.supervision.common.net
+
+import org.apache.commons.httpclient.ConnectTimeoutException
+import org.apache.commons.httpclient.HttpClientError
+import org.apache.commons.httpclient.params.HttpConnectionParams
+import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory
+import org.apache.commons.httpclient.protocol.ProtocolSocketFactory
+import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory
+import java.io.IOException
+import java.net.InetAddress
+import java.net.Socket
+import java.net.UnknownHostException
+import java.security.cert.CertificateException
+import java.security.cert.X509Certificate
+import javax.net.ssl.*
+
+
+/**
+ * 閫氳繃java 杩涜璁块棶鏈夋椂鍊欎細鏈夎瘉涔﹁繘琛屾嫤鎴�
+ */
+object SkipCertificateValidation {
+    /**
+     * 蹇界暐HTTPS璇锋眰鐨凷SL璇佷功锛屽繀椤诲湪openConnection涔嬪墠璋冪敤
+     * @throws Exception
+     */
+    @Throws(Exception::class)
+    fun ignoreSsl() {
+        val hv = HostnameVerifier { urlHostName, session ->
+            println("Warning: URL Host: " + urlHostName + " vs. " + session.peerHost)
+            true
+        }
+        trustAllHttpsCertificates()
+        HttpsURLConnection.setDefaultHostnameVerifier(hv)
+    }
+
+    @Throws(Exception::class)
+    private fun trustAllHttpsCertificates() {
+        val trustAllCerts = arrayOfNulls<TrustManager>(1)
+        val tm: TrustManager = MiTM()
+        trustAllCerts[0] = tm
+        val sc = SSLContext.getInstance("SSL")
+        sc.init(null, trustAllCerts, null)
+        HttpsURLConnection.setDefaultSSLSocketFactory(sc.socketFactory)
+    }
+
+    internal class MiTM : X509TrustManager {
+        override fun getAcceptedIssuers(): Array<X509Certificate>? {
+            return null
+        }
+
+        @Throws(CertificateException::class)
+        override fun checkServerTrusted(certs: Array<X509Certificate>, authType: String) {
+            return
+        }
+
+        @Throws(CertificateException::class)
+        override fun checkClientTrusted(certs: Array<X509Certificate>, authType: String) {
+            return
+        }
+    }
+
+    class MySecureProtocolSocketFactory : ProtocolSocketFactory {
+        //杩欓噷娣诲姞涓�涓睘鎬э紝涓昏鐩殑灏辨槸鏉ヨ幏鍙杝sl璺宠繃楠岃瘉
+        private var sslContext: SSLContext? = null
+
+        /**
+         * 鍒ゆ柇鑾峰彇SSLContext
+         * @return
+         */
+        private val sSLContext: SSLContext?
+            get() {
+                if (sslContext == null) {
+                    sslContext = createEasySSLContext()
+                }
+                return sslContext
+            }
+
+        //鍚庨潰鐨勬柟娉曞熀鏈笂灏辨槸甯﹀叆鐩稿叧鍙傛暟灏卞彲浠ヤ簡
+        /*
+     * (non-Javadoc)
+     *
+     * @see org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket(java.lang.String,
+     *      int, java.net.InetAddress, int)
+     */
+        @Throws(IOException::class, UnknownHostException::class)
+        override fun createSocket(host: String, port: Int, clientHost: InetAddress?, clientPort: Int): Socket {
+            return sSLContext!!.socketFactory.createSocket(host, port, clientHost, clientPort)
+        }
+
+        /*
+     * (non-Javadoc)
+     *
+     * @see org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket(java.lang.String,
+     *      int, java.net.InetAddress, int,
+     *      org.apache.commons.httpclient.params.HttpConnectionParams)
+     */
+        @Throws(IOException::class, UnknownHostException::class, ConnectTimeoutException::class)
+        override fun createSocket(
+            host: String, port: Int, localAddress: InetAddress?, localPort: Int,
+            params: HttpConnectionParams?
+        ): Socket {
+            requireNotNull(params) { "Parameters may not be null" }
+            val timeout: Int = params.connectionTimeout
+            return if (timeout == 0) {
+                createSocket(host, port, localAddress, localPort)
+            } else {
+                ControllerThreadSocketFactory.createSocket(this, host, port, localAddress, localPort, timeout)
+            }
+        }
+
+        /*
+     * (non-Javadoc)
+     *
+     * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
+     */
+        @Throws(IOException::class, UnknownHostException::class)
+        override fun createSocket(host: String, port: Int): Socket {
+            return sSLContext!!.socketFactory.createSocket(host, port)
+        }
+
+        /*
+     * (non-Javadoc)
+     *
+     * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
+     */
+//        @Throws(IOException::class, UnknownHostException::class)
+//        override fun createSocket(socket: Socket?, host: String?, port: Int, autoClose: Boolean): Socket {
+//            return sSLContext!!.socketFactory.createSocket(socket, host, port, autoClose)
+//        }
+
+        companion object {
+            /**
+             * 杩欎釜鍒涘缓涓�涓幏鍙朣SLContext鐨勬柟娉曪紝瀵煎叆MyX509TrustManager杩涜鍒濆鍖�
+             * @return
+             */
+            private fun createEasySSLContext(): SSLContext {
+                return try {
+                    val context = SSLContext.getInstance("SSL")
+                    context.init(
+                        null, arrayOf(MiTM()),
+                        null
+                    )
+                    context
+                } catch (e: Exception) {
+                    throw HttpClientError(e.toString())
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/pdf/PdfUtil.kt b/src/main/kotlin/cn/flightfeather/supervision/common/pdf/PdfUtil.kt
index f85361f..106912d 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/common/pdf/PdfUtil.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/pdf/PdfUtil.kt
@@ -1,82 +1,96 @@
 package cn.flightfeather.supervision.common.pdf
 
-import org.apache.poi.util.Units
-import org.apache.poi.xwpf.usermodel.XWPFDocument
-import org.apache.poi.xwpf.usermodel.XWPFParagraph
-import java.io.File
-import java.io.FileInputStream
-import java.io.FileOutputStream
-import java.io.IOException
+import com.itextpdf.html2pdf.ConverterProperties
+import com.itextpdf.html2pdf.HtmlConverter
+import com.itextpdf.layout.font.FontProvider
+import com.itextpdf.text.Element
+import com.itextpdf.text.Font
+import com.itextpdf.text.FontFactory
+import com.itextpdf.text.pdf.BaseFont
+import com.itextpdf.text.pdf.PdfReader
+import com.itextpdf.text.pdf.PdfStamper
+import org.apache.pdfbox.pdmodel.PDDocument
+import org.apache.pdfbox.rendering.PDFRenderer
+import org.fit.pdfdom.PDFDomTree
+import org.fit.pdfdom.PDFDomTreeConfig
+import org.xhtmlrenderer.pdf.ITextRenderer
+import java.io.*
+import javax.imageio.ImageIO
+import javax.xml.parsers.ParserConfigurationException
 
 
 object PdfUtil {
 
-    fun generateContract(dynamicParam: DynamicParam): String {
-        val src = dynamicParam.templatePath+dynamicParam.templateName
-        val out = dynamicParam.outPath + dynamicParam.outName
+    private const val FONT1 = "/font/STSONG.TTF"
+    private const val FONT2 = "font/msyhbd.ttc"
+    private const val FONT3 = "font/msyhl.ttc"
 
-        val inputStream = FileInputStream(File(src))
-        val xwpfDocument = XWPFDocument(inputStream)
-
-        replace(xwpfDocument, dynamicParam.param)
-
-        output(xwpfDocument, out)
-
-        return out
+    @Throws(IOException::class, ParserConfigurationException::class)
+    fun parseWithPdfDomTree(`is`: InputStream?, startPage: Int, endPage: Int, config: PDFDomTreeConfig?): String? {
+        val pdf: PDDocument = PDDocument.load(`is`)
+        val parser = PDFDomTree(config)
+        parser.startPage = startPage
+        parser.endPage = endPage
+        val output: Writer = StringWriter()
+        parser.writeText(pdf, output)
+        pdf.close()
+        return output.toString()
     }
 
-    /**
-     * 鏇挎崲娈佃惤涓寚瀹氱殑鏂囨湰
-     */
-    fun replace(doc:XWPFDocument, params:Map<String, Any>) {
-        try {
-            setContent(doc.paragraphs, params)
+    fun htmlToPdf(content: String): ByteArray {
 
-            for (tab in doc.tables) {
-                for (row in tab.rows) {
-                    for (cell in row.tableCells) {
-                        //娉ㄦ剰锛実etParagraphs涓�瀹氫笉鑳芥紡鎺�
-                        //鍥犱负涓�涓〃鏍奸噷闈㈠彲鑳戒細鏈夊涓渶瑕佹浛鎹㈢殑鏂囧瓧
-                        //濡傛灉娌℃湁杩欎釜姝ラ閭d箞鏂囧瓧浼氭浛鎹笉浜�
-                        setContent(cell.paragraphs, params)
-                    }
-                }
-            }
-        } catch (e: IOException) {
-            e.printStackTrace()
+        val p = ConverterProperties()
+
+        p.fontProvider = FontProvider().apply {
+            addFont(FONT1)
         }
-    }
+        val outputStream = ByteArrayOutputStream()
+        HtmlConverter.convertToPdf(content, outputStream, p)
+        val inputStream = ByteArrayInputStream(outputStream.toByteArray())
+        val reader = PdfReader(inputStream)
+        val output = ByteArrayOutputStream()
+        val stamper = PdfStamper(reader, output)
 
-    private fun setContent(paragraphs: List<XWPFParagraph>, params: Map<String, Any>) {
-        for (p in paragraphs) {
-            for (r in p.runs) {
-                //闇�瑕佹浛鎹㈢殑鏂囨湰
-                val text = r.getText(0)
-                //鏇挎崲鎸囧畾鐨勬枃鏈�
-                for (key in params.keys) {
-                    if (text != null && text == key) {
-                        //鏇挎崲鐨勬椂鍊欒娉ㄦ剰锛宻etText鏄湁涓や釜鍙傛暟鐨�
-                        //绗竴涓槸鏇挎崲鐨勬枃鏈紝绗簩涓槸浠庡摢閲屽紑濮嬫浛鎹�
-                        //0鏄浛鎹㈠叏閮紝濡傛灉涓嶈缃偅涔堥粯璁ゅ氨鏄粠鍘熸枃瀛�
-                        //缁撳熬寮�濮嬭拷鍔�
-                        val v = params[key]
-                        when (v) {
-                            is String -> r.setText(v, 0)
-                            is File -> {
-                                val input = FileInputStream(v)
-                                val pic = r.addPicture(input, XWPFDocument.PICTURE_TYPE_JPEG, v.name, Units.toEMU(40.0), Units.toEMU(40.0))
+        val totalPages = reader.numberOfPages
+        val font = BaseFont.createFont(FONT1, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED)
+        for (i in 1..totalPages) {
+            // 璇诲彇绗琲椤靛唴瀹�
+            val page = stamper.getOverContent(i)
 
-                                input.close()
-                            }
-                        }
-                    }
-                }
+            val pageSize = reader.getPageSize(i)
+            page.run {
+                beginText()
+                setFontAndSize(font, 12F)
+                showTextAligned(Element.ALIGN_CENTER, "绗� ${i} 椤�", pageSize.width / 2, 20F, 0F)
+                endText()
             }
         }
+        stamper.close()
+        reader.close()
+
+//        val render = ITextRenderer()
+//        render.fontResolver.adF
+
+        return output.toByteArray()
+
+
     }
 
-    fun output(doc: XWPFDocument, outSrc: String) {
-        doc.write(FileOutputStream(outSrc))
+    fun pdfToPic(bytes: ByteArray): List<ByteArray> {
+        val picOutput = mutableListOf<ByteArrayOutputStream>()
+
+        val doc = PDDocument.load(bytes)
+        val renderer = PDFRenderer(doc)
+        val pageCount = doc.numberOfPages
+        for (i in 0 until pageCount) {
+            val output = ByteArrayOutputStream()
+            picOutput.add(output)
+            // dpi锛屽浘鐗囧儚绱犵偣锛宒pi瓒婇珮鍥剧墖浣撶Н瓒婂ぇ锛�216寰堟竻鏅帮紝105浣撶Н绋冲畾
+            val image = renderer.renderImageWithDPI(i, 216f)
+            // 鏍煎紡涓篔PG
+            ImageIO.write(image, "jpg", output)
+        }
         doc.close()
+        return picOutput.map { it.toByteArray() }
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/risk/DataSource.kt b/src/main/kotlin/cn/flightfeather/supervision/common/risk/DataSource.kt
new file mode 100644
index 0000000..5d515e4
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/risk/DataSource.kt
@@ -0,0 +1,61 @@
+package cn.flightfeather.supervision.common.risk
+
+import cn.flightfeather.supervision.domain.entity.BaseInfo
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.domain.enumeration.UserType
+import cn.flightfeather.supervision.domain.mapper.*
+import cn.flightfeather.supervision.lightshare.service.LedgerService
+import tk.mybatis.mapper.entity.Example
+
+class DataSource(val config: Config, val dbMapper: DbMapper) {
+    /**
+     * 鐢ㄦ埛绛涢�夋潯浠�
+     */
+    data class Config(
+        val district: String,
+        val sceneType: String,
+        val year: Int,
+        val month: Int,
+        val userConfigId: Int? = null,
+    ) {
+        // 鑱氶泦鍖哄悕绉�
+        var areaName: String? = null
+    }
+
+    private val sourceList = mutableListOf<Userinfo?>()
+
+    fun loop(callback: (user: Userinfo, config: Config, dbMapper: DbMapper) -> Unit) {
+        getUser()
+        sourceList.forEach {
+            it?.let { callback(it, config, dbMapper) }
+        }
+    }
+
+    private fun getUser() {
+        sourceList.clear()
+        var idList = emptyList<String>()
+        val c = dbMapper.userConfigMapper.selectByPrimaryKey(config.userConfigId)
+        c?.let {
+            config.areaName = c.ucArea
+            idList = dbMapper.baseInfoMapper.selectByExample(Example(BaseInfo::class.java).apply {
+                createCriteria().andEqualTo("biProvinceName", c.ucProvinceName)
+                    .andEqualTo("biCityName", c.ucCityName)
+                    .apply {
+                        c.ucDistrictName?.let { andEqualTo("biDistrictName", it) }
+                        c.ucTownName?.let { andEqualTo("biTownName", it) }
+                        c.ucArea?.let { andEqualTo("biArea", it) }
+                    }
+            }).map { it.biGuid }
+        }
+        dbMapper.userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
+            createCriteria().andEqualTo("extension1", config.district)
+                .andEqualTo("extension2", config.sceneType)
+                .andEqualTo("isenable", true)
+                .andEqualTo("usertypeid", UserType.Enterprise.value)
+                .apply {
+                    if (idList.isNotEmpty()) andIn("guid", idList)
+                }
+            and(createCriteria().orNotEqualTo("workno", "test").orIsNull("workno"))
+        }).let { sourceList.addAll(it) }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/risk/DbMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/common/risk/DbMapper.kt
new file mode 100644
index 0000000..cba34f7
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/risk/DbMapper.kt
@@ -0,0 +1,28 @@
+package cn.flightfeather.supervision.common.risk
+
+import cn.flightfeather.supervision.domain.mapper.*
+import cn.flightfeather.supervision.lightshare.service.LedgerService
+import org.springframework.stereotype.Component
+
+/**
+ *
+ * @date 2024/7/30
+ * @author feiyu02
+ */
+@Component
+class DbMapper(
+    val userinfoMapper: UserinfoMapper,
+    val userInfoWxMapper: UserInfoWxMapper,
+    val userConfigMapper: UserConfigMapper,
+    val userLoginLogMapper: UserLoginLogMapper,
+    val baseInfoMapper: BaseInfoMapper,
+    val companyMapper: CompanyMapper,
+    val personalInfoMapper: PersonalInfoMapper,
+    val ledgerRecordMapper: LedgerRecordMapper,
+    val ledgerSubTypeMapper: LedgerSubTypeMapper,
+    val ledgerService: LedgerService,
+    val evaluationMapper: EvaluationMapper,
+    val evaluationruleMapper: EvaluationruleMapper,
+    val commitmentMapper: CommitmentMapper,
+    val riskEvaluationMapper: RiskEvaluationMapper,
+)
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskAnalysis.kt b/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskAnalysis.kt
new file mode 100644
index 0000000..b7b644b
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskAnalysis.kt
@@ -0,0 +1,189 @@
+package cn.flightfeather.supervision.common.risk
+
+import cn.flightfeather.supervision.domain.entity.SceneType
+import java.io.OutputStream
+
+class RiskAnalysis(
+    private val dataSource: DataSource,
+    toDatabase: Boolean = false,
+    toFile: Boolean = false,
+) {
+
+    private val riskLedger = RiskLedger()
+    private val riskSelfLedger = RiskSelfLedger()
+    private val riskAssessment = RiskAssessment()
+    private val riskAuthenticated = RiskAuthenticated()
+    private val riskCommitment = RiskCommitment()
+    private var utilFile: UtilFile? = null
+    private var utilDatabase: UtilDatabase? = null
+
+    init {
+        if (toDatabase) utilDatabase = UtilDatabase(dataSource.dbMapper)
+        if (toFile) utilFile = UtilFile(dataSource.config)
+    }
+
+
+    // 鎬荤粨寮�澶�
+    private val summaryStart = listOf(
+        "绾夸笂绠$悊杈冭鑼冿紝涓嶅瓨鍦ㄤ笉瑙勮寖椤癸紝\n",
+        "绾夸笂绠$悊鐩稿瑙勮寖锛屼絾瀛樺湪灏戦噺涓嶈鑼冮」锛孿n",
+        "绾夸笂绠$悊涓嶈鑼冿紝瀛樺湪杈冨涓嶈鑼冮」锛孿n",
+        "绾夸笂绠$悊涓ラ噸涓嶈鑼冿紝瀛樺湪澶ч噺涓嶈鑼冮」锛孿n"
+    )
+
+    private val sEnd = listOf(
+        "寤鸿鐜板満鎵ф硶妫�鏌ユ牳瀹烇紝鑻ョ幇鍦虹‘瀹炶緝瑙勮寖锛屽彲浣滀负姝i潰瀹d紶鍏稿瀷銆�",
+        "寤鸿绾夸笂鎴栫幇鍦烘墽娉曟鏌ョ潱淇冩暣鏀广��",
+        "寤鸿寮�灞曠幇鍦烘墽娉曟鏌ョ潱淇冩暣鏀广��",
+        "寤鸿閲嶇偣寮�灞曠幇鍦烘墽娉曟鏌ョ潱淇冩暣鏀广��"
+    )
+    private val sEnd7 = listOf(
+        "寤鸿涓嶅畾鏈熻繘琛岀嚎涓婃娊鏌ユ垨鐜板満鏍告煡锛岃嫢绾夸笅鐜繚绠$悊涓庣嚎涓婂熀鏈竴鑷达紝鍙皢浼佷笟浣滀负姝i潰瀹d紶鍏稿瀷锛涜嫢绾夸笅鐜繚绠$悊涓庣嚎涓婂樊寮傝緝澶э紝鍒欏皢浼佷笟璋冩暣涓洪珮椋庨櫓骞舵寜楂橀闄╁缃��",
+        "寤鸿鐢熸�佺幆澧冧富绠¢儴闂ㄩ�氳繃鐢佃瘽銆佸井淇°�佸皬绋嬪簭绛夋柟寮忔彁閱掍紒涓氬畬鍠勮嚜韬幆淇濆畧娉曞悎瑙勭鐞嗐��",
+        "寤鸿鐢熸�佺幆澧冧富绠¢儴闂ㄩ�氳繃鐢佃瘽銆佸井淇°�佸皬绋嬪簭绛夋柟寮忔彁閱掍紒涓氬畬鍠勮嚜韬幆淇濆畧娉曞悎瑙勭鐞嗐��",
+        "寤鸿鐢熸�佺幆澧冧富绠¢儴闂ㄥ熀浜庣幆淇$爜灏忕▼搴忔寚瀵间紒涓氬紑灞曞簲鎬ヨ嚜宸℃煡锛屾垨鏈哄姩寮�灞曟墽娉曟鏌ャ�佷笓椤圭害璋堢瓑銆�"
+    )
+
+    // 鎬荤粨缁撳熬
+    private fun summaryEnd(index: Int) = when (dataSource.config.sceneType) {
+        cn.flightfeather.supervision.domain.enumeration.SceneType.VehicleRepair.value.toString() -> sEnd7[index]
+        else -> sEnd[index]
+    }
+
+    private fun exe() {
+        utilFile?.reset()
+        utilDatabase?.setConfig(dataSource.config.year, dataSource.config.month)
+        dataSource.loop { u, c, d ->
+            // 杞鍚勮瘎鍒ゆ爣鍑嗭紝寰楀嚭鍚勬爣鍑嗕笅鐨勯闄╃瓑绾�
+            val r1 = riskLedger.getResult(u, c, d)
+            val r2 = riskSelfLedger.getResult(u, c, d)
+            val r3 = riskAssessment.getResult(u, c, d)
+            val r4 = riskAuthenticated.getResult(u, c, d)
+            val r5 = riskCommitment.getResult(u, c, d)
+
+            // 鏍规嵁鍚勪釜瀛愰闄╃瓑绾э紝寰楀嚭缁煎悎椋庨櫓绛夌骇鍜屾�荤粨鎻忚堪
+            val riskLevel = judgeResult(r1, r2, r3.first, r4)
+            val summary = getSummary(riskLevel, r1, r2, r3.first, r4, r5)
+            utilDatabase?.insertToDataBase(u, riskLevel, summary)
+            utilFile?.parseRow(u, r1, r2, r3, r4, r5, riskLevel, summary)
+        }
+    }
+
+    fun execute() {
+        exe()
+        utilFile?.outPutToFile()
+    }
+
+    fun executeToStream(out: OutputStream) {
+        exe()
+        utilFile?.outPutToStream(out)
+    }
+
+    /**
+     * 鏍规嵁鍚勬爣鍑嗗畬鎴愭儏鍐碉紝寰楀嚭缁煎悎椋庨櫓绛夌骇鍙婂搴旇瘎璇�
+     * @return 椋庨櫓绛夌骇锛�0锛氫綆椋庨櫓锛�1锛氫腑椋庨櫓锛�2锛氶珮椋庨櫓
+     */
+    private fun judgeResult(r1: RiskLedger.Result, r2: RiskLedger.Result, r3: Boolean, r4: RiskAuthenticated.Result): Int {
+        when (dataSource.config.sceneType) {
+            cn.flightfeather.supervision.domain.enumeration.SceneType.VehicleRepair.value.toString() -> {
+                // 楂橀闄�
+                if (
+                    (r1.rate2 < .6 || r2.rate2 < .6)
+                    ||
+                    (r1.rate3 > .3 && r2.rate3 > .6)
+                    ||
+                    (r1.specialResult && r2.specialResult)
+                ) {
+                    return 2
+                }
+                // 浣庨闄�
+                else if (
+                    r1.rate2 >= .8
+                    && r2.rate2 >= .8
+                    && r3
+                    && r4.finished1
+                    && (r1.rate3 < .3 && r2.rate3 < .6)
+                ) {
+                    return 0
+                }
+                // 涓闄�
+                else {
+                    return 1
+                }
+            }
+            else -> {
+                // 楂橀闄�
+                if (
+                    (r1.rate2 == .0 || r2.rate2 == .0)
+                    ||
+                    (r1.rate2 < 0.6 || r2.rate2 < 0.6) && !r3
+                ) {
+                    return 2
+                }
+                // 浣庨闄�
+                else if (
+                    r1.rate2 >= .6
+                    && r2.rate2 >= .6
+                    && r3
+                    && r4.finished1
+                ) {
+                    return 0
+                }
+                // 涓闄�
+                else {
+                    return 1
+                }
+            }
+        }
+    }
+
+    /**
+     * 鏍规嵁缁煎悎椋庨櫓绛夌骇锛岀敓鎴愭�荤粨鎬ф弿杩�
+     */
+    private fun getSummary(
+        riskLevel: Int,
+        r1: RiskLedger.Result,
+        r2: RiskLedger.Result,
+        r3: Boolean,
+        r4: RiskAuthenticated.Result,
+        r5: Int
+    ): String {
+        val conclusion = StringBuilder()
+        when (riskLevel) {
+            0 -> {
+                if (r1.rate2 == 1.0 && r2.rate2 == 1.0 && r3 && r4.finished1 && r5 == 2) {
+                    conclusion.append(summaryStart[0])
+                    conclusion.append(getDetailSummary(riskLevel))
+                    conclusion.append(summaryEnd(0))
+                } else {
+                    conclusion.append(summaryStart[1])
+                    conclusion.append(getDetailSummary(riskLevel))
+                    conclusion.append(summaryEnd(1))
+                }
+            }
+            1 -> {
+                conclusion.append(summaryStart[2])
+                conclusion.append(getDetailSummary(riskLevel))
+                conclusion.append(summaryEnd(2))
+            }
+            2 -> {
+                conclusion.append(summaryStart[3])
+                conclusion.append(getDetailSummary(riskLevel))
+                conclusion.append(summaryEnd(3))
+            }
+        }
+
+        return conclusion.toString()
+    }
+
+    private fun getDetailSummary(riskLevel: Int):String {
+        val detail = StringBuilder()
+        detail.append(riskLedger.getSummary())
+        detail.append(riskSelfLedger.getSummary())
+        detail.append(riskAuthenticated.getSummary())
+        detail.append(riskCommitment.getSummary())
+        if (detail.isBlank()) detail.append("绾夸笂閰嶅悎搴﹂珮\n")
+        detail.append(riskAssessment.getSummary(riskLevel))
+        return detail.toString()
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskAssessment.kt b/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskAssessment.kt
new file mode 100644
index 0000000..37c82ac
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskAssessment.kt
@@ -0,0 +1,90 @@
+package cn.flightfeather.supervision.common.risk
+
+import cn.flightfeather.supervision.common.score.EvaluationUtil
+import cn.flightfeather.supervision.domain.entity.Evaluation
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.infrastructure.utils.DateUtil
+import com.github.pagehelper.PageHelper
+import tk.mybatis.mapper.entity.Example
+import java.time.LocalDateTime
+
+/**
+ * 鑾峰彇鑷瘎瀹屾垚鎯呭喌
+ */
+class RiskAssessment {
+
+    private val summary = listOf(
+        "鏈紑灞曡嚜璇勶紝\n",
+        "鑷瘎缁撴灉涓庣嚎涓婄鐞嗚鑼冩�у亸宸緝澶э紝\n",
+        "鑷瘎寰楀垎杈冮珮锛孿n",
+        "鑷瘎婊″垎锛孿n"
+    )
+
+    private var finished = false
+    private var score: Int? = null
+    private var totalScore = 0
+
+    private fun reset() {
+        finished = false
+        score = 0
+        totalScore = 0
+    }
+
+    fun getResult(user: Userinfo, config: DataSource.Config, dbMapper: DbMapper): Triple<Boolean, Int?, String> {
+        reset()
+
+        val sTime = LocalDateTime.of(config.year, config.month, 1, 0, 0, 0, 0)
+        val eTime = sTime.plusMonths(1)
+        PageHelper.startPage<Evaluation>(1, 1)
+        val result = dbMapper.evaluationMapper.selectByExample((Example(Evaluation::class.java).apply {
+            createCriteria().andEqualTo("evaluatorguid", user.guid)
+                .andEqualTo("ertype", 0)
+//                .andBetween("createdate", sTime, eTime)
+            orderBy("createdate").desc()
+        }))
+        if (result.isEmpty()) {
+            return Triple(false, null, "/")
+        } else {
+            val rule = dbMapper.evaluationruleMapper.selectByPrimaryKey(result[0].stguid)
+            totalScore = rule.resultrange?.toInt() ?: 0
+            // 鏍规嵁璇勪及鐨勬彁浜ゅ懆鏈燂紙鍗曚綅锛氭湀锛夛紝璁$畻瀵瑰簲鐨勬湀浠借寖鍥�
+            val period = rule.scensesubtypeid?.toInt() ?: 1
+            val startM = DateUtil.getStartMonthByPeriod(config.month, period)
+            val endM = startM?.plus(period)?.minus(1)
+
+            // 璁$畻璇勪及璁板綍瀵瑰簲鐨勫懆鏈燂紙鍝勾鐨勫嚑鏈堝埌鍑犳湀锛�
+            val list1 = result[0].scensename?.split("/") ?: return Triple(false, null, "/")
+            val year = list1[0]
+            val list2 = list1[1].split("-")
+            val sMonth = list2[0].toInt()
+            val eMonth = list2[1].toInt()
+
+            finished = if (startM != null && endM != null) {
+                year == config.year.toString() && sMonth >= startM && eMonth <= endM
+            } else {
+                year == config.year.toString()
+                        && config.month >= sMonth
+                        && config.month <= eMonth
+            }
+            score = result[0].resultscorebef?.toIntOrNull() ?: 0
+            val eRes = EvaluationUtil.getEvaluationLevel(score!!, rule)
+            return if (finished)
+                Triple(finished, score, eRes.evaluateLevel)
+            else
+                Triple(false, null, "/")
+        }
+    }
+
+    /**
+     * 鏍规嵁鏄惁瀹屾垚锛岃繑鍥炴�荤粨
+     * @param riskLevel 缁煎悎椋庨櫓绛夌骇
+     */
+    fun getSummary(riskLevel: Int): String {
+        return when {
+            !finished -> summary[0]
+            riskLevel == 2 -> summary[1]
+            riskLevel == 0 && score == totalScore -> summary[3]
+            else -> if (riskLevel == 0) summary[2] else ""
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskAuthenticated.kt b/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskAuthenticated.kt
new file mode 100644
index 0000000..61a8991
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskAuthenticated.kt
@@ -0,0 +1,101 @@
+package cn.flightfeather.supervision.common.risk
+
+import cn.flightfeather.supervision.domain.entity.*
+import cn.flightfeather.supervision.domain.enumeration.AuthenticationType
+import com.github.pagehelper.PageHelper
+import tk.mybatis.mapper.entity.Example
+import java.time.LocalDateTime
+import java.time.ZoneId
+
+/**
+ * 鑾峰彇璁よ瘉瀹屾垚鎯呭喌
+ */
+class RiskAuthenticated {
+
+    private val summary = listOf(
+        "浼佷笟鏈璇侊紝\n",
+        "绠$悊浜哄憳鏈璇侊紝\n",
+    )
+
+    inner class Result(){
+        // 灏忕▼搴忕櫥褰曟儏鍐�
+        var login = false
+        // 搴楅摵淇℃伅
+        var baseInfo: BaseInfo? = null
+        // 浼佷笟璁よ瘉鎯呭喌
+        var finished1 = false
+        // 涓汉璁よ瘉鎯呭喌
+        var finished2 = false
+        // 涓汉璁よ瘉浜烘暟
+        var count = 0
+        // 涓汉璁よ瘉绾у埆鏈�楂樿鑹�
+        var type = ""
+    }
+
+    private val result = Result()
+
+    private fun reset(){
+        result.apply {
+            login = false
+            baseInfo = null
+            finished1 = false
+            finished2 = false
+            count = 0
+            type = ""
+        }
+    }
+
+    fun getResult(user: Userinfo, config: DataSource.Config, dbMapper: DbMapper): Result {
+        reset()
+
+        val startTime = LocalDateTime.of(config.year, config.month, 1, 0, 0, 0)
+        val endTime = startTime.plusMonths(1).minusSeconds(1)
+//        dbMapper.userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
+//            createCriteria().andEqualTo("guid", user.guid)
+//                .andGreaterThanOrEqualTo("uiLoginTime", time)
+//        })?.run { if (isNotEmpty()) result.login = true }
+        PageHelper.startPage<UserLoginLog>(1, 1)
+        dbMapper.userLoginLogMapper.selectByExample(Example(UserLoginLog::class.java).apply {
+            createCriteria().andEqualTo("ulUserGuid", user.guid)
+                .andBetween("ulLoginTime", startTime, endTime)
+        })?.run { if (isNotEmpty()) result.login = true }
+        val baseInfo = dbMapper.baseInfoMapper.selectByPrimaryKey(user.guid)
+        result.baseInfo = baseInfo
+        val company = dbMapper.companyMapper.selectByPrimaryKey(baseInfo?.ciGuid)
+        val createTime = if (baseInfo.biCreateTime != null) {
+            LocalDateTime.ofInstant(baseInfo.biCreateTime.toInstant(), ZoneId.systemDefault())
+                .withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).plusSeconds(1)
+        } else {
+            // 濡傛灉鍦烘櫙娌℃湁濉啓鍒涘缓鏃堕棿锛屽垯榛樿宸插垱寤�
+            startTime.minusSeconds(1)
+        }
+        result.finished1 = company?.ciExtension3 == "authenticated" && startTime.isAfter(createTime)
+
+        val pList = dbMapper.personalInfoMapper.selectByExample(Example(PersonalInfo::class.java).apply {
+            createCriteria().andEqualTo("piSceneId", user.guid)
+        })
+        result.finished2 = pList.isNotEmpty() && startTime.isAfter(createTime)
+        if (result.finished2) {
+            result.count = pList.size
+            pList.forEach {
+                if (result.type.isBlank() || it?.piPosition == AuthenticationType.Admin.des) {
+                    result.type = it?.piPosition ?: ""
+                }
+            }
+        }
+
+        return result
+    }
+
+    /**
+     * 鏍规嵁鏄惁瀹屾垚锛岃繑鍥炴�荤粨
+     */
+    fun getSummary(): String {
+        val s = StringBuilder()
+        if (!result.finished1) {
+            s.append(summary[0])
+        }
+        if (result.type != AuthenticationType.Admin.des) s.append(summary[1])
+        return s.toString()
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskCommitment.kt b/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskCommitment.kt
new file mode 100644
index 0000000..85cc58b
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskCommitment.kt
@@ -0,0 +1,61 @@
+package cn.flightfeather.supervision.common.risk
+
+import cn.flightfeather.supervision.domain.entity.*
+import com.github.pagehelper.PageHelper
+import tk.mybatis.mapper.entity.Example
+import java.time.Duration
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.ZoneId
+import java.time.temporal.ChronoUnit
+
+/**
+ * 鑾峰彇瀹堟硶鎵胯瀹屾垚鎯呭喌
+ */
+class RiskCommitment {
+
+    private val summary = listOf(
+        "淇$敤/瀹堟硶鎵胯澶辨晥鏈強鏃舵洿鏂帮紝\n",
+    )
+
+    private var finished = false
+
+    private fun reset(){
+        finished = false
+    }
+
+    fun getResult(user: Userinfo, config: DataSource.Config, dbMapper: DbMapper): Int {
+        reset()
+
+        // 缁熻鏈堜唤鐨勬渶鍚庝竴澶╂渶鍚庝竴绉�
+        val time = LocalDateTime.of(config.year, config.month, 1, 0, 0, 0)
+            .plusMonths(1).minusSeconds(1)
+        // 鏌ヨ缁熻鏈堜唤涔嬪墠绛捐鐨勬渶鏂颁竴鏈熷畧娉曟壙璇�
+        PageHelper.startPage<Commitment>(1, 1)
+        val commitment = dbMapper.commitmentMapper.selectByExample(Example(Commitment::class.java).apply {
+            createCriteria().andEqualTo("uiGuid", user.guid)
+                .andLessThanOrEqualTo("cmCreateTime", time)
+            orderBy("cmCreateTime").desc()
+        })
+        return if (commitment.isEmpty()) {
+            0
+        } else {
+            // 鍒ゆ柇鎵胯绛捐鏃ユ湡鍜岀粺璁℃湀浠界殑鏃堕棿宸槸鍚﹁秴杩囨湁鏁堟椂闂达紙1骞达級
+            val date = commitment[0].cmCreateTime
+            val createTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault())
+            val days = ChronoUnit.DAYS.between(createTime, time)
+            finished = days <= 365
+            if (finished) 2 else 1
+        }
+    }
+
+    /**
+     * 鏍规嵁鏄惁瀹屾垚锛岃繑鍥炴�荤粨
+     */
+    fun getSummary(): String {
+        return when {
+            !finished -> summary[0]
+            else -> ""
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskLedger.kt b/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskLedger.kt
new file mode 100644
index 0000000..779b589
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskLedger.kt
@@ -0,0 +1,153 @@
+package cn.flightfeather.supervision.common.risk
+
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.domain.enumeration.SceneType
+import cn.flightfeather.supervision.lightshare.vo.LedgerSubTypeVo
+import java.time.LocalDate
+import java.time.format.DateTimeFormatter
+
+/**
+ * 鑾峰彇鍙拌处瀹屾垚鐜�
+ */
+open class RiskLedger {
+
+    open val summary = listOf(
+        "蹇呭~鍙拌处瀛樺湪閮ㄥ垎缂哄け椤癸紝\n",
+        "蹇呭~鍙拌处瀛樺湪杈冨缂哄け椤癸紝\n",
+        "蹇呭~鍙拌处缂哄け涓ラ噸锛孿n",
+        "蹇呭~鍙拌处鍏ㄧ被鍒己澶憋紝\n"
+    )
+
+    inner class Result() {
+        // 鎵�鏈夊彴璐︽彁浜ょ巼
+        var rate1: Double = .0
+        // 蹇呭~鍙拌处鎻愪氦鐜�
+        var rate2: Double = .0
+        // 蹇呭~椤逛腑涓嶆秹鍙婂彴璐﹀崰姣�
+        var rate3: Double = .0
+        // 缂哄け鍙拌处
+        var unSubmitLedger = ""
+        // 涓嶆秹鍙婂彴璐�
+        var notInvolvedLedger = ""
+        // 鐗规畩鎯呭喌鍒ゆ柇缁撴灉
+        var specialResult = false
+    }
+
+    private val result = Result()
+
+    protected var config: DataSource.Config? = null
+
+    private fun reset(){
+        result.apply {
+            rate1 = .0
+            rate2 = .0
+            unSubmitLedger = ""
+        }
+    }
+
+    fun getResult(user: Userinfo, config: DataSource.Config, dbMapper: DbMapper): Result {
+        this.config = config
+        reset()
+        return getLedger(user, config, dbMapper)
+    }
+
+    /**
+     * 鏍规嵁涓婁紶鐜囷紝杩斿洖鎬荤粨
+     */
+    fun getSummary(): String {
+        return result.run {
+            when {
+                rate2 >= 1.0 -> ""
+                rate2 >= .8 -> summary[0]
+                rate2 >= .6 && rate2 < .8 -> summary[1]
+                rate2 > 0 && rate2 < .6 -> summary[2]
+                else -> summary[3]
+            }
+        }
+    }
+
+    /**
+     * 鑾峰彇鍙拌处璁板綍
+     */
+    private fun getLedger(user: Userinfo, config: DataSource.Config, dbMapper: DbMapper): Result {
+        user.guid ?: return result
+        val time = LocalDate.of(config.year, config.month, 1).format(DateTimeFormatter.ofPattern("YYYY-MM-dd"))
+        val records = dbMapper.ledgerService.getUserLedgerSummary(user.guid!!, config.sceneType.toInt(), time)
+        return completionRate(records)
+    }
+
+    open fun isFit(ledgerSubTypeVo: LedgerSubTypeVo): Boolean {
+        return ledgerSubTypeVo.ledgerTypeId != -1
+    }
+
+    open fun specialCondition(records: List<LedgerSubTypeVo>): Boolean {
+        return when (this.config?.sceneType) {
+            // 鈥滃嵄闄╁簾鐗╄浆绉昏仈鍗曘�佸簾鏈烘补浜х敓閲忋�佸簾閾呴吀钃勭數姹犱骇鐢熼噺銆佸嵄闄╁簾鐗╄串瀛樺満鎵�鈥濇湁3绫诲強浠ヤ笂涓嶆甯告彁浜ゆ垨涓轰笉娑夊強鐨勶紱
+            SceneType.VehicleRepair.value.toString()->{
+                val ledgerTypeIds = listOf(2904, 2905, 2906, 2907)
+                val count = records.filter {
+                    return@filter ledgerTypeIds.contains(it.ledgerSubTypeId) && (!it.ledgerFinished || !it.involved)
+                }.size
+                count >= 3
+            }
+            else -> false
+        }
+    }
+
+    /**
+     * 璁$畻缁熻缁撴灉
+     */
+    private fun completionRate(records: List<LedgerSubTypeVo>): Result {
+        // 鎵�鏈夊彴璐﹁鏁�
+        var total1 = 0
+        var finished1 = 0
+        // 蹇呭~鍙拌处璁℃暟
+        var total2 = 0
+        var finished2 = 0
+        // 缂哄け鍙拌处
+        val list = mutableListOf<String>()
+        // 涓嶆秹鍙婂彴璐�
+        val list2 = mutableListOf<String>()
+
+        records.forEach {
+            if (!isFit(it)) return@forEach
+            //鎬绘暟
+            total1++
+            //瀹屾垚鏁�
+            if (it.ledgerFinished) {
+                finished1++
+            }
+            //蹇呭~椤�
+            if (it.needUpdate) {
+                total2++
+                if (it.ledgerFinished) {
+                    finished2++
+                } else {
+                    it.ledgerName?.let { n -> list.add(n) }
+                }
+                // 涓嶆秹鍙婇」
+                if (!it.involved) {
+                    it.ledgerName?.let { n -> list2.add(n) }
+                }
+            }
+        }
+        result.apply {
+            rate1 = finished1.toDouble().div(total1)
+            rate2 = finished2.toDouble().div(total2)
+            rate3 = list2.size.toDouble().div(total2)
+            unSubmitLedger = if (list.isNotEmpty()) {
+                "缂哄け锛歕"${list.joinToString("銆�")}\"锛屾�昏${list.size}椤�"
+            } else {
+                "鏃犵己澶遍」"
+            }
+            notInvolvedLedger = if (list2.isNotEmpty()) {
+                "涓嶆秹鍙婏細\"${list2.joinToString("銆�")}\"锛屾�昏${list2.size}椤�"
+            } else {
+                "鏃犱笉娑夊強椤�"
+            }
+            this.specialResult = specialCondition(records)
+        }
+
+        return result
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskSelfLedger.kt b/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskSelfLedger.kt
new file mode 100644
index 0000000..a6e3fc0
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/risk/RiskSelfLedger.kt
@@ -0,0 +1,38 @@
+package cn.flightfeather.supervision.common.risk
+
+import cn.flightfeather.supervision.domain.entity.LedgerSubType
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.domain.enumeration.SceneType
+import cn.flightfeather.supervision.lightshare.vo.LedgerSubTypeVo
+import tk.mybatis.mapper.entity.Example
+
+/**
+ * 鑾峰彇鑷贰鏌ュ畬鎴愮巼
+ */
+class RiskSelfLedger : RiskLedger() {
+
+    override val summary = listOf(
+        "鑷贰鏌ュ瓨鍦ㄩ儴鍒嗙己澶遍」锛孿n",
+        "鑷贰鏌ュ瓨鍦ㄨ緝澶氱己澶遍」锛孿n",
+        "鑷贰鏌ョ己澶变弗閲嶏紝\n",
+        "鑷贰鏌ュ叏绫诲埆缂哄け锛孿n"
+    )
+
+    override fun isFit(ledgerSubTypeVo: LedgerSubTypeVo): Boolean {
+        return ledgerSubTypeVo.ledgerTypeId == -1
+    }
+
+    override fun specialCondition(records: List<LedgerSubTypeVo>): Boolean {
+        return when (this.config?.sceneType) {
+            // 鈥滃嵄搴熻串瀛樺満鎵�鈥濇潗鏂欐甯告彁浜や笖闈炰笉娑夊強
+            SceneType.VehicleRepair.value.toString()->{
+                val ledgerTypeId = 3708
+                val r = records.find {
+                    return@find it.ledgerSubTypeId == ledgerTypeId && it.ledgerFinished && it.involved
+                }
+                r != null
+            }
+            else -> false
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/risk/UtilDatabase.kt b/src/main/kotlin/cn/flightfeather/supervision/common/risk/UtilDatabase.kt
new file mode 100644
index 0000000..85fffc4
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/risk/UtilDatabase.kt
@@ -0,0 +1,62 @@
+package cn.flightfeather.supervision.common.risk
+
+import cn.flightfeather.supervision.domain.entity.RiskEvaluation
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.domain.enumeration.SceneType
+import java.time.LocalDate
+import java.time.ZoneId
+import java.util.*
+
+class UtilDatabase(private val dbMapper: DbMapper) {
+    private var period: String? = null
+    private var startTime: Date? = null
+    private var endTime: Date? = null
+    private var publishTime: Date? = null
+
+    fun setConfig(year: Int, month: Int) {
+        setPeriod(year, month)
+        setDuration(year, month)
+    }
+
+    private fun setPeriod(year: Int, month: Int) {
+        period = "$year/$month-$month"
+    }
+
+    private fun setDuration(year: Int, month: Int) {
+        val s = LocalDate.of(year, month, 1)
+        val e = s.plusMonths(1).minusDays(1)
+        val p = s.plusMonths(1)
+        startTime = Date.from(s.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant())
+        endTime = Date.from(e.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant())
+        publishTime = Date.from(p.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant())
+    }
+
+    fun insertToDataBase(userinfo: Userinfo, riskLevel: Int, summary: String) {
+        val risk = RiskEvaluation().apply {
+            biGuid = userinfo.guid
+            rePeriod = period
+        }
+        val result = dbMapper.riskEvaluationMapper.selectOne(risk)
+        if (result == null) {
+            val vo = RiskEvaluation().apply {
+                biGuid = userinfo.guid
+                reRiskLevel = riskLevel
+                rePublishTime = publishTime
+                reSceneTypeId = userinfo.extension2?.toInt()
+                reSceneType = SceneType.getByValue(reSceneTypeId).des
+                rePeriod = period
+                reStartTime = startTime
+                reEndTime = endTime
+                reSummary = summary
+            }
+            dbMapper.riskEvaluationMapper.insert(vo)
+        } else {
+            result.apply {
+                reRiskLevel = riskLevel
+                reSummary = summary
+            }
+            dbMapper.riskEvaluationMapper.updateByPrimaryKeySelective(result)
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/risk/UtilFile.kt b/src/main/kotlin/cn/flightfeather/supervision/common/risk/UtilFile.kt
new file mode 100644
index 0000000..e721225
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/risk/UtilFile.kt
@@ -0,0 +1,148 @@
+package cn.flightfeather.supervision.common.risk
+
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.domain.enumeration.SceneType
+import cn.flightfeather.supervision.infrastructure.utils.DateUtil
+import cn.flightfeather.supervision.infrastructure.utils.ExcelUtil
+import org.apache.poi.hssf.usermodel.HSSFWorkbook
+import java.io.File
+import java.io.FileOutputStream
+import java.io.OutputStream
+import java.util.*
+import kotlin.math.round
+
+class UtilFile(private val config: DataSource.Config) {
+
+    private val heads = mutableListOf<Array<Any>>()
+    private val contents = mutableListOf<Array<Any>>()
+    private var index = 1
+    private var sceneType: String? = null
+
+    init {
+        sceneType = SceneType.getByValue(config.sceneType.toInt()).des
+        val h1 = listOf(
+            ExcelUtil.MyCell("${sceneType}鍗曚綅鍩烘湰淇℃伅", colSpan = 7),
+            ExcelUtil.MyCell("瀹堟硶甯壎寰俊灏忕▼搴忕櫥褰�", colSpan = 1),
+            ExcelUtil.MyCell("${sceneType}鍗曚綅璁よ瘉锛堝崟涓紒涓氬厑璁稿鐢ㄦ埛锛�", colSpan = 4),
+            ExcelUtil.MyCell("瀹堟硶鎵胯", colSpan = 1),
+            ExcelUtil.MyCell("鍙拌处瑙勮寖鎬�", colSpan = 4),
+            ExcelUtil.MyCell("鑷贰鏌ヨ鑼冩��", colSpan = 3),
+            ExcelUtil.MyCell("瀹堟硶鑷祴鑷瘎", colSpan = 3),
+            ExcelUtil.MyCell("绾夸笂鐩戠缁煎悎椋庨櫓鍒嗘瀽涓庡绛�", colSpan = 2),
+        )
+        val h2 = listOf(
+            ExcelUtil.MyCell("搴忓彿", colSpan = 1),
+            ExcelUtil.MyCell("璐﹀彿", colSpan = 1),
+            ExcelUtil.MyCell("鍗曚綅鍚嶇О", colSpan = 1),
+            ExcelUtil.MyCell("缁忚惀鐘舵��", colSpan = 1),
+            ExcelUtil.MyCell("鍗曚綅鍦板潃", colSpan = 1),
+            ExcelUtil.MyCell("甯哥敤鑱旂郴浜�", colSpan = 1),
+            ExcelUtil.MyCell("鑱旂郴鏂瑰紡", colSpan = 1),
+            ExcelUtil.MyCell("灏忕▼搴忕櫥褰曟儏鍐�", colSpan = 1),
+            ExcelUtil.MyCell("浼佷笟璁よ瘉", colSpan = 1),
+            ExcelUtil.MyCell("涓汉璁よ瘉", colSpan = 1),
+            ExcelUtil.MyCell("璁よ瘉浜烘暟", colSpan = 1),
+            ExcelUtil.MyCell("璁よ瘉瑙掕壊", colSpan = 1),
+            ExcelUtil.MyCell("鎵胯鎯呭喌", colSpan = 1),
+            ExcelUtil.MyCell("鍙拌处鎻愪氦鐜�", colSpan = 1),
+            ExcelUtil.MyCell("蹇呭~鍙拌处鎻愪氦鐜�", colSpan = 1),
+            ExcelUtil.MyCell("蹇呭~鍙拌处鎻愪氦缂哄け鎯呭喌", colSpan = 1),
+            ExcelUtil.MyCell("蹇呭~鍙拌处涓嶆秹鍙婃儏鍐�", colSpan = 1),
+            ExcelUtil.MyCell("鑷贰鏌ユ彁浜ょ巼", colSpan = 1),
+            ExcelUtil.MyCell("鑷贰鏌ユ彁浜ょ己澶辨儏鍐�", colSpan = 1),
+            ExcelUtil.MyCell("鑷贰鏌ヤ笉娑夊強鎯呭喌", colSpan = 1),
+            ExcelUtil.MyCell("鑷瘎鎯呭喌", colSpan = 1),
+            ExcelUtil.MyCell("鑷瘎鍒嗘暟", colSpan = 1),
+            ExcelUtil.MyCell("鑷瘎椋庨櫓绛夌骇", colSpan = 1),
+            ExcelUtil.MyCell("绾夸笂鐩戠椋庨櫓", colSpan = 1),
+            ExcelUtil.MyCell("鐩戠鎵ф硶寤鸿", colSpan = 1),
+        )
+        heads.add(h1.toTypedArray())
+        heads.add(h2.toTypedArray())
+    }
+
+    fun reset() {
+        index = 1
+        contents.clear()
+    }
+
+    /**
+     * 鐢熸垚涓�琛宔xcel鏁版嵁
+     */
+    fun parseRow(
+        u: Userinfo,
+        r1: RiskLedger.Result,
+        r2: RiskLedger.Result,
+        r3: Triple<Boolean, Int?, String>,
+        r4: RiskAuthenticated.Result,
+        r5: Int,
+        riskLevel: Int,
+        summary: String,
+    ) {
+        val row = listOf<Any>(
+            index.toDouble(),
+            u.acountname ?: "",
+            u.realname ?: "",
+            if (u.isenable == true) "姝e父缁忚惀" else "鍏冲仠",
+            r4.baseInfo?.biAddress ?: "",
+            r4.baseInfo?.biContact ?: "",
+            r4.baseInfo?.biTelephone ?: "",
+
+            if (r4.login) "宸茬櫥褰�" else "鏈櫥褰�",
+
+            // 璁よ瘉
+            if (r4.finished1) "宸茶璇�" else "鏈璇�",
+            if (r4.finished2) "宸茶璇�" else "鏈璇�",
+            r4.count,
+            r4.type,
+            // 瀹堟硶鎵胯
+            when (r5) {
+                0 -> "鏈壙璇�"
+                1 -> "宸插け鏁�"
+                else -> "鏈夋晥"
+            },
+            // 鍙拌处瑙勮寖鎬�
+            "${round(r1.rate1 * 10000) / 100}%",
+            "${round(r1.rate2 * 10000) / 100}%",
+            r1.unSubmitLedger,
+            r1.notInvolvedLedger,
+
+            "${round(r2.rate2 * 10000) / 100}%",
+            r2.unSubmitLedger,
+            r2.notInvolvedLedger,
+
+            if (r3.first) "宸茶嚜璇�" else "鏈嚜璇�",
+            r3.second?.toDouble() ?: "/",
+            r3.third,
+
+            parseRisk(riskLevel),
+            summary
+        )
+        contents.add(row.toTypedArray())
+        index++
+    }
+
+    private fun parseRisk(riskLevel: Int) = when (riskLevel) {
+        0->"浣庨闄�"
+        1->"涓闄�"
+        else->"楂橀闄�"
+    }
+
+    fun outPutToStream(out: OutputStream) {
+        val workbook = HSSFWorkbook()
+        ExcelUtil.write2(heads, contents, workbook)
+        workbook.write(out)
+        workbook.close()
+        out.flush()
+        out.close()
+    }
+
+    fun outPutToFile() {
+        val area = if (config.areaName != null) "-" + config.areaName else ""
+        val fileName = "缁煎悎椋庨櫓璇勪及-${config.district}-${sceneType}${area}-${config.year}骞�${config.month}鏈�-" +
+                "${DateUtil.DateToString(Date(), "yyyy-MM-dd-HHmmss")}.xls"
+        val filePath = "C:\\work\\宸ヤ綔\\椋炵窘鐜\\缁煎悎椋庨櫓\\$fileName"
+        val out = FileOutputStream(File(filePath))
+        outPutToStream(out)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/score/AutoScore.kt b/src/main/kotlin/cn/flightfeather/supervision/common/score/AutoScore.kt
index 29092cd..62138e6 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/common/score/AutoScore.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/score/AutoScore.kt
@@ -38,6 +38,8 @@
 
 //        private val SCENE_TYPE = SceneType.Restaurant
         private val SCENE_TYPE = SceneType.VehicleRepair
+
+        private val district = "寰愭眹鍖�"
     }
 
     @PostConstruct
@@ -94,7 +96,7 @@
     }
 
     fun go(_year: Int? = null, _month: Int? = null) {
-        val fileName = "${SCENE_TYPE.des}鑷姩璇勫垎-${DateUtil.DateToString(Date(), "yyyy-MM-ddhhmmss")}.xls"
+        val fileName = "${district}${SCENE_TYPE.des}鑷姩璇勫垎-${DateUtil.DateToString(Date(), "yyyy-MM-ddhhmmss")}.xls"
 //        val filePath = "E:\\宸ヤ綔\\寮�鍙慭\椋炵窘鐜app\\鑷姩璇勫垎\\${SCENE_TYPE.des}\\$fileName"
         val filePath = "C:\\work\\宸ヤ綔\\绗笁鏂圭洃绠\鑷姩璇勫垎\\${SCENE_TYPE.des}\\$fileName"
         val out = FileOutputStream(File(filePath))
@@ -103,9 +105,10 @@
 
         val userList = userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
             createCriteria().andEqualTo("usertypeid", UserType.Enterprise.value.toByte())
-                // FIXME: 2021/4/28 鍦烘櫙绫诲瀷 
+                .andEqualTo("extension1", district)
                 .andEqualTo("extension2", SCENE_TYPE.value.toString())
                 .andEqualTo("isenable", true)
+            and(createCriteria().orNotEqualTo("workno", "test").orIsNull("workno"))
 //            orderBy("workno")
         })
 
@@ -160,9 +163,9 @@
             }
 
             val info = Info(
-                it.guid,
-                it.acountname,
-                it.realname,
+                it?.guid,
+                it?.acountname,
+                it?.realname,
                 SCENE_TYPE,
                 year,
                 month,
@@ -375,47 +378,6 @@
         name = itemRule.itemname
         value = itemRule.extension1 ?: "0"
         extension1 = (itemRule.extension1 != null).toString()
-    }
-
-    private fun write2File(info: Info, evaluations: List<Evaluation>, topItems: MutableList<Evaluationsubrule>,
-                           rules: MutableList<Pair<Evaluationsubrule, MutableList<Evaluationsubrule>>>) {
-
-        val heads = mutableListOf<Array<String>>()
-        val contents = mutableListOf<Array<Any>>()
-        topItems.forEach {
-            val cList = mutableListOf<Any>()
-            cList.add(it.itemname ?: "")
-            val array1 = mutableListOf<ExcelUtil.MyCell>()
-            val array2 = mutableListOf<ExcelUtil.MyCell>()
-            val array3 = mutableListOf<ExcelUtil.MyCell>()
-            for (r in rules) {
-                if (r.first.fatherid == it.guid || r.first.guid == it.guid) {
-                    array1.add(ExcelUtil.MyCell(r.first.itemname?:"", 0))
-
-                    r.second.forEach { s ->
-                        if (s.fatherid == r.first.guid) {
-                            array2.add(ExcelUtil.MyCell(s.itemname?:"", 1))
-                            array3.add(ExcelUtil.MyCell(s.extension1?:"", 1))
-                            array1.last().rowSpan++
-                        }
-                    }
-                }
-            }
-            cList.add(array1.toTypedArray())
-            cList.add(array2.toTypedArray())
-            cList.add(array3.toTypedArray())
-            contents.add(cList.toTypedArray())
-        }
-        evaluations.forEach {
-            if ((it.ertype?.toInt() == 0)) {
-                val totalScoreList = mutableListOf<Any>()
-                totalScoreList.add("鎬诲垎")
-                totalScoreList.add(it.resultscorebef ?: "0")
-                contents.add(totalScoreList.toTypedArray())
-            }
-        }
-
-        ExcelUtil.write2(heads, contents, workbook!!, info.userName ?: "鏈煡鐢ㄦ埛")
     }
 
     private fun addToFile(contents: MutableList<Array<Any>>, info: Info, evaluations: List<Evaluation>, topItems: MutableList<Evaluationsubrule>,
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/score/EvaluationUtil.kt b/src/main/kotlin/cn/flightfeather/supervision/common/score/EvaluationUtil.kt
new file mode 100644
index 0000000..f03ee76
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/score/EvaluationUtil.kt
@@ -0,0 +1,46 @@
+package cn.flightfeather.supervision.common.score
+
+import cn.flightfeather.supervision.domain.entity.Evaluationrule
+
+object EvaluationUtil {
+
+    class EvaluationLevel {
+        var color: String = ""
+        var creditText: String = ""
+        var evaluateLevel: String = ""
+    }
+
+    fun getEvaluationLevel(totalPoint: Int, rule: Evaluationrule): EvaluationLevel {
+        val pointLevel = mutableListOf<Pair<Int, Int>>()
+        rule.extension1?.split("#")?.forEach {
+            val pStr = it.split(",")
+            pointLevel.add(Pair(pStr[0].toInt(), pStr[1].toInt()))
+        }
+        val evaluateLevel = rule.extension2?.split("#") ?: emptyList()
+        val creditTexts = rule.extension3?.split("#") ?: emptyList()
+        val levelColors = rule.remark?.split(";") ?: emptyList()
+
+        val result = EvaluationLevel()
+        if (pointLevel.isEmpty() || evaluateLevel.isEmpty() || creditTexts.isEmpty() || levelColors.isEmpty()) {
+            result.evaluateLevel = when (totalPoint) {
+                in 0..40 -> "鏋佸樊"
+                in 41..64 -> "杈冨樊"
+                in 65..79 -> "涓�鑸�"
+                in 80..94 -> "鑹ソ"
+                in 95..Int.MAX_VALUE -> "浼樼"
+                else -> "鏋佸樊"
+            }
+        } else {
+            for (i in pointLevel.indices) {
+                if (totalPoint in pointLevel[i].first..pointLevel[i].second ||
+                    (i == pointLevel.size - 1 && totalPoint > pointLevel[i].second)
+                ) {
+                    result.color = levelColors[i % levelColors.size]
+                    result.creditText = creditTexts[i % creditTexts.size]
+                    result.evaluateLevel = evaluateLevel[i % evaluateLevel.size]
+                }
+            }
+        }
+        return result
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/score/ScoreUtil.kt b/src/main/kotlin/cn/flightfeather/supervision/common/score/ScoreUtil.kt
new file mode 100644
index 0000000..e955060
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/score/ScoreUtil.kt
@@ -0,0 +1,226 @@
+package cn.flightfeather.supervision.common.score
+
+import cn.flightfeather.supervision.domain.entity.Evaluation
+import cn.flightfeather.supervision.domain.entity.Evaluationrule
+import cn.flightfeather.supervision.domain.entity.Evaluationsubrule
+import cn.flightfeather.supervision.domain.entity.Itemevaluation
+import cn.flightfeather.supervision.domain.enumeration.SceneType
+import cn.flightfeather.supervision.domain.mapper.*
+import cn.flightfeather.supervision.infrastructure.utils.DateUtil
+import cn.flightfeather.supervision.infrastructure.utils.ExcelUtil
+import org.apache.poi.hssf.usermodel.HSSFWorkbook
+import org.apache.poi.hssf.util.HSSFColor
+import org.springframework.stereotype.Component
+import tk.mybatis.mapper.entity.Example
+import java.io.File
+import java.io.FileOutputStream
+import java.util.*
+
+/**
+ * 鑷瘎寰楀垎瀵煎嚭
+ */
+@Component
+class ScoreUtil(
+    private val evaluationruleMapper: EvaluationruleMapper,
+    private val evaluationsubruleMapper: EvaluationsubruleMapper,
+    private val evaluationMapper: EvaluationMapper,
+    private val itemevaluationMapper: ItemevaluationMapper,
+    private val userinfoMapper: UserinfoMapper
+) {
+
+    var head3 = true
+
+    fun outPut() {
+        val scoreItem = getScoreItem()
+        val evaluations = getScoreResult()
+        val titles = genTitles(scoreItem.second, scoreItem.third)
+        val contents = genContents(evaluations, scoreItem.second, scoreItem.third)
+        titles.addAll(contents)
+        toFile(titles, SceneType.VehicleRepair)
+    }
+
+    /**
+     * 鑾峰彇璇勫垎瑙勫垯
+     */
+    fun getScoreItem(sceneType: Int = -7, districtCode: String = "310104")
+            : Triple<MutableList<Evaluationrule>,
+            MutableList<Evaluationsubrule>,
+            MutableList<Pair<Evaluationsubrule, MutableList<Evaluationsubrule>>>> {
+        val subRules = mutableListOf<Pair<Evaluationsubrule, MutableList<Evaluationsubrule>>>()
+        val baseRules = mutableListOf<Evaluationrule>()
+        val topItems = mutableListOf<Evaluationsubrule>()
+
+        val rule = evaluationruleMapper.selectByExample(Example(Evaluationrule::class.java).apply {
+            createCriteria()
+//                .andEqualTo("tasktypeid", 1)
+                .andEqualTo("scensetypeid", sceneType.toByte())
+                .andEqualTo("districtcode", districtCode)
+        })
+        if (rule.isNotEmpty()) {
+            baseRules.addAll(rule)
+
+            val ruleId = rule[0].guid
+            val rules = evaluationsubruleMapper.selectByExample(Example(Evaluationsubrule::class.java).apply {
+                createCriteria().andEqualTo("erguid", ruleId)
+            })
+            rules.forEach {
+                if (it.ertype == 2) {
+                    topItems.add(it)
+                }
+            }
+            topItems.sortBy { it.displayid }
+
+            var t = 0
+            topItems.forEach {
+                t += it.maxscore ?: 0
+                val tempRules = mutableListOf<Evaluationsubrule>()
+                for (i in rules) {
+                    if (i.fatherid == it.guid && i.ertype == 3) {
+                        tempRules.add(i)
+                    }
+                }
+                //璇勫垎澶ч」濡傛灉娌℃湁鎵惧埌璇勫垎灏忛」锛屽垯璇存槑鍏剁洿鎺ュ搴旀渶灏忚瘎鍒嗛」锛屽叾鏈韩鍙樻垚璇勫垎椤�
+                if (tempRules.isEmpty()) {
+                    tempRules.add(it)
+                }
+                tempRules.sortBy { t -> t.displayid }
+                tempRules.forEach { temp ->
+                    val tempSubRules = mutableListOf<Evaluationsubrule>()
+                    for (i in rules) {
+                        if (i.fatherid == temp.guid && i.ertype == 4) {
+                            tempSubRules.add(i)
+                        }
+                    }
+                    tempSubRules.sortBy { ts -> ts.displayid }
+                    subRules.add(Pair(temp, tempSubRules))
+                }
+            }
+        }
+
+        return Triple(baseRules, topItems, subRules)
+    }
+
+    fun getScoreResult(): List<Evaluation> {
+        return evaluationMapper.selectByExample(Example(Evaluation::class.java).apply {
+            createCriteria().andEqualTo("stguid", "3RNqhxpCe8lQoPss")
+        })
+    }
+
+    fun genTitles(topItems: List<Evaluationsubrule>, rules: List<Pair<Evaluationsubrule,
+            MutableList<Evaluationsubrule>>>): MutableList<Array<Any>> {
+        val contents = mutableListOf<Array<Any>>()
+        val h1 = mutableListOf<ExcelUtil.MyCell>()
+        h1.add(ExcelUtil.MyCell(""))
+        val h2 = mutableListOf<ExcelUtil.MyCell>()
+        h2.add(ExcelUtil.MyCell(""))
+        val h3 = mutableListOf<String>()
+        h3.add("")
+        topItems.forEach {
+            h1.add(ExcelUtil.MyCell(it.itemname ?: "", 1, 0))
+            for (r in rules) {
+                if (r.first.fatherid == it.guid || r.first.guid == it.guid) {
+                    h2.add(ExcelUtil.MyCell(r.first.itemname ?: "", 1, 0))
+                    // FIXME: 2021/4/25 鍐冲畾鏄惁鍐檋3
+                    if (head3) {
+                        r.second.forEach { s ->
+                            h3.add(s.itemname ?: "")
+                            h2.last().colSpan++
+                            h1.last().colSpan++
+                        }
+                    } else {
+                        h2.last().colSpan++
+                        h1.last().colSpan++
+                    }
+                }
+            }
+        }
+        // FIXME: 2021/4/25 鍐冲畾鏄惁鍐檋3
+        if (head3) {
+            h1.add(ExcelUtil.MyCell("鎬诲垎", 3, 1))
+            h1.add(ExcelUtil.MyCell("鐜俊鐮�", 3, 1))
+            h1.add(ExcelUtil.MyCell("鍛ㄦ湡", 3, 1))
+        } else {
+            h1.add(ExcelUtil.MyCell("鎬诲垎", 2, 1))
+            h1.add(ExcelUtil.MyCell("鐜俊鐮�", 2, 1))
+            h1.add(ExcelUtil.MyCell("鍛ㄦ湡", 2, 1))
+        }
+        contents.add(h1.toTypedArray())
+        contents.add(h2.toTypedArray())
+        // FIXME: 2021/4/25 鍐冲畾鏄惁鍐檋3
+        if (head3) contents.add(h3.toTypedArray())
+
+        return contents
+    }
+
+    fun genContents(
+        evaluations: List<Evaluation>, topItems: MutableList<Evaluationsubrule>,
+        rules: MutableList<Pair<Evaluationsubrule, MutableList<Evaluationsubrule>>>
+    ): List<Array<Any>> {
+        val contents = mutableListOf<Array<Any>>()
+        evaluations.forEach {
+            val cList = mutableListOf<Any>()
+            val user = userinfoMapper.selectByPrimaryKey(it.evaluatorguid)
+            cList.add("${user?.realname}")
+            val itemevaluations = itemevaluationMapper.selectByExample(Example(Itemevaluation::class.java).apply {
+                createCriteria().andEqualTo("sguid", it.guid)
+            })
+            //姣忎竴椤瑰叿浣撳緱鍒�
+            topItems.forEach {sr ->
+                for (r in rules) {
+                    if (r.first.fatherid == sr.guid || r.first.guid == sr.guid) {
+                        // FIXME: 2021/4/25 鍐冲畾鏄惁鍐檋3
+                        if (head3) {
+                            r.second.forEach { s ->
+                                val score = getScore(s.guid, itemevaluations)
+                                cList.add(score)
+                            }
+                        } else {
+                            val score = getScore(r.first.guid, itemevaluations)
+                            cList.add(score)
+                        }
+                    }
+                }
+            }
+
+            //鎬诲垎鍜岀幆淇$爜
+            cList.add(it.resultscorebef?.toDoubleOrNull() ?: -99.0)
+            val code = when (it.resultscorebef?.toIntOrNull() ?: 0) {
+                in 0..59 -> ExcelUtil.MyCell("绾㈢爜", fontColor = HSSFColor.HSSFColorPredefined.RED.index)
+                in 60..89 -> ExcelUtil.MyCell("榛勭爜", fontColor = HSSFColor.HSSFColorPredefined.GOLD.index)
+                in 90..120 -> ExcelUtil.MyCell("缁跨爜", fontColor = HSSFColor.HSSFColorPredefined.BRIGHT_GREEN.index)
+                else -> ExcelUtil.MyCell("瓒呭嚭鑼冨洿锛�${it.resultscoreaft}", fontColor = HSSFColor.HSSFColorPredefined.BLACK.index)
+            }
+            cList.add(code)
+            cList.add(it.scensename ?: "")
+
+            contents.add(cList.toTypedArray())
+        }
+        return contents
+    }
+
+    private fun getScore(subRuleId: String?, scoreList: List<Itemevaluation>): String{
+        val s = scoreList.find {
+            it.esrguid == subRuleId
+        }
+        return if (s?.extension1 == "true") s.value ?: "" else ""
+    }
+
+    fun toFile(contents: MutableList<Array<Any>>, sceneType: SceneType) {
+        // 鍐欏叆鏂囨。
+        val workbook = HSSFWorkbook()
+        val fileName = "${sceneType.des}璇勫垎-${DateUtil.DateToString(Date(), "yyyy-MM-ddhhmmss")}.xls"
+//        val filePath = "E:\\宸ヤ綔\\寮�鍙慭\椋炵窘鐜app\\鑷姩璇勫垎\\${SCENE_TYPE.des}\\$fileName"
+        val filePath = "C:\\work\\宸ヤ綔\\绗笁鏂圭洃绠\鐢ㄦ埛鑷瘎\\${sceneType.des}\\$fileName"
+        val file = File(filePath)
+        if (!file.parentFile.exists()) {
+            file.parentFile.mkdirs()
+        }
+        val out = FileOutputStream(file)
+
+        ExcelUtil.write2(emptyList(), contents, workbook)
+        workbook.write(out)
+        workbook.close()
+        out.flush()
+        out.close()
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/score/item/ScoreItem_13.kt b/src/main/kotlin/cn/flightfeather/supervision/common/score/item/ScoreItem_13.kt
index e0057c4..64513ed 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/common/score/item/ScoreItem_13.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/score/item/ScoreItem_13.kt
@@ -1,12 +1,9 @@
 package cn.flightfeather.supervision.common.score.item
 
-import cn.flightfeather.supervision.common.score.Info
 import cn.flightfeather.supervision.common.score.ScoreItem
-import cn.flightfeather.supervision.domain.entity.BaseInfo
 import cn.flightfeather.supervision.domain.mapper.BaseInfoMapper
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.stereotype.Component
-import tk.mybatis.mapper.entity.Example
 import javax.annotation.PostConstruct
 
 @Component
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/score/item/ScoreItem_14.kt b/src/main/kotlin/cn/flightfeather/supervision/common/score/item/ScoreItem_14.kt
deleted file mode 100644
index f705fd8..0000000
--- a/src/main/kotlin/cn/flightfeather/supervision/common/score/item/ScoreItem_14.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package cn.flightfeather.supervision.common.score.item
-
-import cn.flightfeather.supervision.common.score.Info
-import cn.flightfeather.supervision.common.score.ScoreItem
-
-class ScoreItem_14: ScoreItem() {
-    override var id: String = ""
-
-    override var name: String="鏈弬鍔犵幆淇濋儴闂紙鎴栧伐涓氬洯鍖烘垨琛楅晣锛夌粍缁囩殑绾夸笅鍩硅"
-
-    override var maxScore: Int = 2
-
-    override fun calScore(): Pair<Int, Int> {
-        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
-    }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/score/item/ScoreItem_15.kt b/src/main/kotlin/cn/flightfeather/supervision/common/score/item/ScoreItem_15.kt
deleted file mode 100644
index 7162a55..0000000
--- a/src/main/kotlin/cn/flightfeather/supervision/common/score/item/ScoreItem_15.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package cn.flightfeather.supervision.common.score.item
-
-import cn.flightfeather.supervision.common.score.Info
-import cn.flightfeather.supervision.common.score.ScoreItem
-
-class ScoreItem_15: ScoreItem() {
-    override var id: String = ""
-
-    override var name: String="浼佷笟淇$敤鎵胯锛堝湪绾裤�佷竴骞翠竴娆★級"
-
-    override var maxScore: Int = 5
-
-    override fun calScore(): Pair<Int, Int> {
-        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
-    }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/score/item/ScoreItem_16.kt b/src/main/kotlin/cn/flightfeather/supervision/common/score/item/ScoreItem_16.kt
deleted file mode 100644
index 25307f7..0000000
--- a/src/main/kotlin/cn/flightfeather/supervision/common/score/item/ScoreItem_16.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package cn.flightfeather.supervision.common.score.item
-
-import cn.flightfeather.supervision.common.score.Info
-import cn.flightfeather.supervision.common.score.ScoreItem
-
-class ScoreItem_16: ScoreItem() {
-    override var id: String = ""
-
-    override var name: String="浼佷笟淇$敤鑷瘎锛堝湪绾裤�佷竴鏈堜竴娆★級"
-
-    override var maxScore: Int = 10
-
-    override fun calScore(): Pair<Int, Int> {
-        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
-    }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/common/wx/TemplateManager.kt b/src/main/kotlin/cn/flightfeather/supervision/common/wx/TemplateManager.kt
index 29dbf57..7c884b9 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/common/wx/TemplateManager.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/common/wx/TemplateManager.kt
@@ -31,10 +31,12 @@
 
         //妯℃澘id鍜屽搴旂殑璺宠浆璺緞(宸叉湁椤哄簭灏介噺涓嶈淇敼锛屾柊妯℃澘寰�鍚庨『寤�)
         val templateList = listOf(
-            Pair(TEMPLATE_1,"pages/m_user/userlogin/userlogin"),
-            Pair(TEMPLATE_2,"pages/m_user/userlogin/userlogin"),
-            Pair(TEMPLATE_3,"pages/m_user/userlogin/userlogin"),
-            Pair(TEMPLATE_4,"pages/m_user/userlogin/userlogin"),
+//            Pair(TEMPLATE_1, "pages/mLedger/ledgerhome/ledgerhome"),
+//            Pair(TEMPLATE_2, "pages/mAssessment/assessment/assessment"),
+            Pair(TEMPLATE_1, "pages/mUser/userlogin/userlogin"),
+            Pair(TEMPLATE_2, "pages/mUser/userlogin/userlogin"),
+            Pair(TEMPLATE_3, "pages/mUser/userlogin/userlogin"),
+            Pair(TEMPLATE_4, "pages/mUser/userlogin/userlogin"),
         )
     }
 
@@ -104,6 +106,17 @@
                 }
                 msg.data = temp
             }
+            3 -> {
+                val temp = Template4()
+                if (dataList.size == 5) {
+                    temp.thing1.value = dataList[0]
+                    temp.thing3.value = dataList[1]
+                    temp.time2.value = dataList[2]
+                    temp.thing5.value = dataList[3]
+                    temp.thing4.value = dataList[4]
+                }
+                msg.data = temp
+            }
         }
         return msg
     }
diff --git a/src/main/kotlin/cn/flightfeather/supervision/config/AsyncConfig.kt b/src/main/kotlin/cn/flightfeather/supervision/config/AsyncConfig.kt
new file mode 100644
index 0000000..e4ca469
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/config/AsyncConfig.kt
@@ -0,0 +1,28 @@
+package cn.flightfeather.supervision.config
+
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.scheduling.annotation.EnableAsync
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
+import java.util.concurrent.Executor
+
+
+@Configuration
+@EnableAsync
+class AsyncConfig {
+    /*
+     *姝ゅ鎴愬憳鍙橀噺搴旇浣跨敤@Value浠庨厤缃腑璇诲彇
+    */
+    private val corePoolSize = 10
+    private val maxPoolSize = 200
+    private val queueCapacity = 10
+    @Bean
+    fun taskExecutor(): Executor {
+        val executor = ThreadPoolTaskExecutor()
+        executor.corePoolSize = corePoolSize
+        executor.maxPoolSize = maxPoolSize
+        executor.setQueueCapacity(queueCapacity)
+        executor.initialize()
+        return executor
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/config/FFInterceptor.kt b/src/main/kotlin/cn/flightfeather/supervision/config/FFInterceptor.kt
new file mode 100644
index 0000000..b3a35d7
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/config/FFInterceptor.kt
@@ -0,0 +1,35 @@
+package cn.flightfeather.supervision.config
+
+import org.springframework.web.servlet.HandlerInterceptor
+import org.springframework.web.servlet.ModelAndView
+import java.lang.Exception
+import javax.servlet.http.HttpServletRequest
+import javax.servlet.http.HttpServletResponse
+
+class FFInterceptor : HandlerInterceptor {
+
+    override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
+        // 鍏佽鍓嶇鑾峰彇鎵�鏈塰eader鍐呭瓧娈碉紙鍖呮嫭鑷畾涔夊瓧娈碉級
+        response.setHeader("Access-Control-Expose-Headers", "*")
+        return super.preHandle(request, response, handler)
+    }
+
+    override fun postHandle(
+        request: HttpServletRequest,
+        response: HttpServletResponse,
+        handler: Any,
+        modelAndView: ModelAndView?,
+    ) {
+        super.postHandle(request, response, handler, modelAndView)
+
+    }
+
+    override fun afterCompletion(
+        request: HttpServletRequest,
+        response: HttpServletResponse,
+        handler: Any,
+        ex: Exception?,
+    ) {
+        super.afterCompletion(request, response, handler, ex)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/config/Swagger2Configuration.kt b/src/main/kotlin/cn/flightfeather/supervision/config/Swagger2Configuration.kt
index 32a7522..9ba4105 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/config/Swagger2Configuration.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/config/Swagger2Configuration.kt
@@ -21,16 +21,15 @@
  */
 @Configuration
 @EnableOpenApi
-class Swagger2Configuration {
+class Swagger2Configuration(
+    @Value("\${springfox.documentation.swagger.v2.enabled}") var swagger2Enable: Boolean,
+) {
 
     companion object {
         const val SWAGGER_SCAN_BASE_PACKAGE = "cn.flightfeather.supervision"
 
         const val VERSION = "1.0.0"
     }
-
-    @Value("\${springfox.documentation.swagger.v2.enabled}")
-    var swagger2Enable: Boolean = true
 
     @Bean
     fun createRestApi(): Docket =
diff --git a/src/main/kotlin/cn/flightfeather/supervision/config/WebMvcConfig.kt b/src/main/kotlin/cn/flightfeather/supervision/config/WebMvcConfig.kt
new file mode 100644
index 0000000..0858240
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/config/WebMvcConfig.kt
@@ -0,0 +1,18 @@
+package cn.flightfeather.supervision.config
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
+
+/**
+ * web閰嶇疆
+ */
+@Configuration
+class WebMvcConfig : WebMvcConfigurer {
+
+    override fun addInterceptors(registry: InterceptorRegistry) {
+        super.addInterceptors(registry)
+        // 娣诲姞鑷畾涔夋嫤鎴櫒
+        registry.addInterceptor(FFInterceptor())
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/BaseInfo.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/BaseInfo.java
index 54a8c7a..a75649e 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/BaseInfo.java
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/BaseInfo.java
@@ -60,6 +60,12 @@
     @Column(name = "BI_Town_Name")
     private String biTownName;
 
+    @Column(name = "BI_Area_Code")
+    private String biAreaCode;
+
+    @Column(name = "BI_Area")
+    private String biArea;
+
     /**
      * 鎵�灞炵墿涓氬叕鍙稿悕绉癷d
      */
@@ -311,6 +317,34 @@
     }
 
     /**
+     * @return BI_Area_Code
+     */
+    public String getBiAreaCode() {
+        return biAreaCode;
+    }
+
+    /**
+     * @param biAreaCode
+     */
+    public void setBiAreaCode(String biAreaCode) {
+        this.biAreaCode = biAreaCode == null ? null : biAreaCode.trim();
+    }
+
+    /**
+     * @return UC_Area
+     */
+    public String getBiArea() {
+        return biArea;
+    }
+
+    /**
+     * @param biArea
+     */
+    public void setBiArea(String biArea) {
+        this.biArea = biArea == null ? null : biArea.trim();
+    }
+
+    /**
      * 鑾峰彇鎵�灞炵墿涓氬叕鍙稿悕绉癷d
      *
      * @return BI_Management_Company_Id - 鎵�灞炵墿涓氬叕鍙稿悕绉癷d
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/City.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/City.java
new file mode 100644
index 0000000..85cc879
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/City.java
@@ -0,0 +1,92 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import javax.persistence.*;
+
+@Table(name = "sm_t_city")
+public class City {
+    @Id
+    @Column(name = "C_CityID")
+    private Integer cCityid;
+
+    @Column(name = "P_PronvinceID")
+    private Integer pPronvinceid;
+
+    @Column(name = "C_CityCode")
+    private String cCitycode;
+
+    @Column(name = "C_CityName")
+    private String cCityname;
+
+    @Column(name = "C_Station")
+    private String cStation;
+
+    /**
+     * @return C_CityID
+     */
+    public Integer getcCityid() {
+        return cCityid;
+    }
+
+    /**
+     * @param cCityid
+     */
+    public void setcCityid(Integer cCityid) {
+        this.cCityid = cCityid;
+    }
+
+    /**
+     * @return P_PronvinceID
+     */
+    public Integer getpPronvinceid() {
+        return pPronvinceid;
+    }
+
+    /**
+     * @param pPronvinceid
+     */
+    public void setpPronvinceid(Integer pPronvinceid) {
+        this.pPronvinceid = pPronvinceid;
+    }
+
+    /**
+     * @return C_CityCode
+     */
+    public String getcCitycode() {
+        return cCitycode;
+    }
+
+    /**
+     * @param cCitycode
+     */
+    public void setcCitycode(String cCitycode) {
+        this.cCitycode = cCitycode == null ? null : cCitycode.trim();
+    }
+
+    /**
+     * @return C_CityName
+     */
+    public String getcCityname() {
+        return cCityname;
+    }
+
+    /**
+     * @param cCityname
+     */
+    public void setcCityname(String cCityname) {
+        this.cCityname = cCityname == null ? null : cCityname.trim();
+    }
+
+    /**
+     * @return C_Station
+     */
+    public String getcStation() {
+        return cStation;
+    }
+
+    /**
+     * @param cStation
+     */
+    public void setcStation(String cStation) {
+        this.cStation = cStation == null ? null : cStation.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/CommitmentTemplate.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/CommitmentTemplate.java
new file mode 100644
index 0000000..4cca857
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/CommitmentTemplate.java
@@ -0,0 +1,297 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "ea_t_commitment_template")
+public class CommitmentTemplate {
+    @Id
+    @Column(name = "CT_GUID")
+    private String ctGuid;
+
+    @Column(name = "CT_Scene_Type_Id")
+    private Integer ctSceneTypeId;
+
+    @Column(name = "CT_Province_Code")
+    private String ctProvinceCode;
+
+    @Column(name = "CT_Province_Name")
+    private String ctProvinceName;
+
+    @Column(name = "CT_City_Code")
+    private String ctCityCode;
+
+    @Column(name = "CT_City_Name")
+    private String ctCityName;
+
+    @Column(name = "CT_District_Code")
+    private String ctDistrictCode;
+
+    @Column(name = "CT_District_Name")
+    private String ctDistrictName;
+
+    @Column(name = "CT_Town_Code")
+    private String ctTownCode;
+
+    @Column(name = "CT_Town_Name")
+    private String ctTownName;
+
+    @Column(name = "CT_Create_Time")
+    private Date ctCreateTime;
+
+    @Column(name = "CT_Update_Time")
+    private Date ctUpdateTime;
+
+    @Column(name = "CT_Extension1")
+    private String ctExtension1;
+
+    @Column(name = "CT_Extension2")
+    private String ctExtension2;
+
+    @Column(name = "CT_Extension3")
+    private String ctExtension3;
+
+    @Column(name = "CT_Remark")
+    private String ctRemark;
+
+    @Column(name = "CT_Content")
+    private String ctContent;
+
+    /**
+     * @return CT_GUID
+     */
+    public String getCtGuid() {
+        return ctGuid;
+    }
+
+    /**
+     * @param ctGuid
+     */
+    public void setCtGuid(String ctGuid) {
+        this.ctGuid = ctGuid == null ? null : ctGuid.trim();
+    }
+
+    /**
+     * @return CT_Scene_Type_Id
+     */
+    public Integer getCtSceneTypeId() {
+        return ctSceneTypeId;
+    }
+
+    /**
+     * @param ctSceneTypeId
+     */
+    public void setCtSceneTypeId(Integer ctSceneTypeId) {
+        this.ctSceneTypeId = ctSceneTypeId;
+    }
+
+    /**
+     * @return CT_Province_Code
+     */
+    public String getCtProvinceCode() {
+        return ctProvinceCode;
+    }
+
+    /**
+     * @param ctProvinceCode
+     */
+    public void setCtProvinceCode(String ctProvinceCode) {
+        this.ctProvinceCode = ctProvinceCode == null ? null : ctProvinceCode.trim();
+    }
+
+    /**
+     * @return CT_Province_Name
+     */
+    public String getCtProvinceName() {
+        return ctProvinceName;
+    }
+
+    /**
+     * @param ctProvinceName
+     */
+    public void setCtProvinceName(String ctProvinceName) {
+        this.ctProvinceName = ctProvinceName == null ? null : ctProvinceName.trim();
+    }
+
+    /**
+     * @return CT_City_Code
+     */
+    public String getCtCityCode() {
+        return ctCityCode;
+    }
+
+    /**
+     * @param ctCityCode
+     */
+    public void setCtCityCode(String ctCityCode) {
+        this.ctCityCode = ctCityCode == null ? null : ctCityCode.trim();
+    }
+
+    /**
+     * @return CT_City_Name
+     */
+    public String getCtCityName() {
+        return ctCityName;
+    }
+
+    /**
+     * @param ctCityName
+     */
+    public void setCtCityName(String ctCityName) {
+        this.ctCityName = ctCityName == null ? null : ctCityName.trim();
+    }
+
+    /**
+     * @return CT_District_Code
+     */
+    public String getCtDistrictCode() {
+        return ctDistrictCode;
+    }
+
+    /**
+     * @param ctDistrictCode
+     */
+    public void setCtDistrictCode(String ctDistrictCode) {
+        this.ctDistrictCode = ctDistrictCode == null ? null : ctDistrictCode.trim();
+    }
+
+    /**
+     * @return CT_District_Name
+     */
+    public String getCtDistrictName() {
+        return ctDistrictName;
+    }
+
+    /**
+     * @param ctDistrictName
+     */
+    public void setCtDistrictName(String ctDistrictName) {
+        this.ctDistrictName = ctDistrictName == null ? null : ctDistrictName.trim();
+    }
+
+    /**
+     * @return CT_Town_Code
+     */
+    public String getCtTownCode() {
+        return ctTownCode;
+    }
+
+    /**
+     * @param ctTownCode
+     */
+    public void setCtTownCode(String ctTownCode) {
+        this.ctTownCode = ctTownCode == null ? null : ctTownCode.trim();
+    }
+
+    /**
+     * @return CT_Town_Name
+     */
+    public String getCtTownName() {
+        return ctTownName;
+    }
+
+    /**
+     * @param ctTownName
+     */
+    public void setCtTownName(String ctTownName) {
+        this.ctTownName = ctTownName == null ? null : ctTownName.trim();
+    }
+
+    /**
+     * @return CT_Create_Time
+     */
+    public Date getCtCreateTime() {
+        return ctCreateTime;
+    }
+
+    /**
+     * @param ctCreateTime
+     */
+    public void setCtCreateTime(Date ctCreateTime) {
+        this.ctCreateTime = ctCreateTime;
+    }
+
+    /**
+     * @return CT_Update_Time
+     */
+    public Date getCtUpdateTime() {
+        return ctUpdateTime;
+    }
+
+    /**
+     * @param ctUpdateTime
+     */
+    public void setCtUpdateTime(Date ctUpdateTime) {
+        this.ctUpdateTime = ctUpdateTime;
+    }
+
+    /**
+     * @return CT_Extension1
+     */
+    public String getCtExtension1() {
+        return ctExtension1;
+    }
+
+    /**
+     * @param ctExtension1
+     */
+    public void setCtExtension1(String ctExtension1) {
+        this.ctExtension1 = ctExtension1 == null ? null : ctExtension1.trim();
+    }
+
+    /**
+     * @return CT_Extension2
+     */
+    public String getCtExtension2() {
+        return ctExtension2;
+    }
+
+    /**
+     * @param ctExtension2
+     */
+    public void setCtExtension2(String ctExtension2) {
+        this.ctExtension2 = ctExtension2 == null ? null : ctExtension2.trim();
+    }
+
+    /**
+     * @return CT_Extension3
+     */
+    public String getCtExtension3() {
+        return ctExtension3;
+    }
+
+    /**
+     * @param ctExtension3
+     */
+    public void setCtExtension3(String ctExtension3) {
+        this.ctExtension3 = ctExtension3 == null ? null : ctExtension3.trim();
+    }
+
+    /**
+     * @return CT_Remark
+     */
+    public String getCtRemark() {
+        return ctRemark;
+    }
+
+    /**
+     * @param ctRemark
+     */
+    public void setCtRemark(String ctRemark) {
+        this.ctRemark = ctRemark == null ? null : ctRemark.trim();
+    }
+
+    /**
+     * @return CT_Content
+     */
+    public String getCtContent() {
+        return ctContent;
+    }
+
+    /**
+     * @param ctContent
+     */
+    public void setCtContent(String ctContent) {
+        this.ctContent = ctContent == null ? null : ctContent.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/DeviceInfo.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/DeviceInfo.java
index 63352f5..8fe3d5e 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/DeviceInfo.java
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/DeviceInfo.java
@@ -54,6 +54,12 @@
     private String diSupplier;
 
     /**
+     * 鏄惁鍦ㄧ嚎
+     */
+    @Column(name = "DI_Online")
+    private Boolean diOnline;
+
+    /**
      * @return DI_GUID
      */
     public String getDiGuid() {
@@ -266,4 +272,22 @@
     public void setDiSupplier(String diSupplier) {
         this.diSupplier = diSupplier == null ? null : diSupplier.trim();
     }
+
+    /**
+     * 鑾峰彇鏄惁鍦ㄧ嚎
+     *
+     * @return DI_Online - 鏄惁鍦ㄧ嚎
+     */
+    public Boolean getDiOnline() {
+        return diOnline;
+    }
+
+    /**
+     * 璁剧疆鏄惁鍦ㄧ嚎
+     *
+     * @param diOnline 鏄惁鍦ㄧ嚎
+     */
+    public void setDiOnline(Boolean diOnline) {
+        this.diOnline = diOnline;
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/District.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/District.java
new file mode 100644
index 0000000..755eb85
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/District.java
@@ -0,0 +1,109 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import javax.persistence.*;
+
+@Table(name = "sm_t_district")
+public class District {
+    @Id
+    @Column(name = "D_DistrictID")
+    private Integer dDistrictid;
+
+    @Column(name = "P_ProvinceID")
+    private Integer pProvinceid;
+
+    @Column(name = "C_CityID")
+    private Integer cCityid;
+
+    @Column(name = "D_DistrictCode")
+    private String dDistrictcode;
+
+    @Column(name = "D_DistrictName")
+    private String dDistrictname;
+
+    @Column(name = "D_Station")
+    private String dStation;
+
+    /**
+     * @return D_DistrictID
+     */
+    public Integer getdDistrictid() {
+        return dDistrictid;
+    }
+
+    /**
+     * @param dDistrictid
+     */
+    public void setdDistrictid(Integer dDistrictid) {
+        this.dDistrictid = dDistrictid;
+    }
+
+    /**
+     * @return P_ProvinceID
+     */
+    public Integer getpProvinceid() {
+        return pProvinceid;
+    }
+
+    /**
+     * @param pProvinceid
+     */
+    public void setpProvinceid(Integer pProvinceid) {
+        this.pProvinceid = pProvinceid;
+    }
+
+    /**
+     * @return C_CityID
+     */
+    public Integer getcCityid() {
+        return cCityid;
+    }
+
+    /**
+     * @param cCityid
+     */
+    public void setcCityid(Integer cCityid) {
+        this.cCityid = cCityid;
+    }
+
+    /**
+     * @return D_DistrictCode
+     */
+    public String getdDistrictcode() {
+        return dDistrictcode;
+    }
+
+    /**
+     * @param dDistrictcode
+     */
+    public void setdDistrictcode(String dDistrictcode) {
+        this.dDistrictcode = dDistrictcode == null ? null : dDistrictcode.trim();
+    }
+
+    /**
+     * @return D_DistrictName
+     */
+    public String getdDistrictname() {
+        return dDistrictname;
+    }
+
+    /**
+     * @param dDistrictname
+     */
+    public void setdDistrictname(String dDistrictname) {
+        this.dDistrictname = dDistrictname == null ? null : dDistrictname.trim();
+    }
+
+    /**
+     * @return D_Station
+     */
+    public String getdStation() {
+        return dStation;
+    }
+
+    /**
+     * @param dStation
+     */
+    public void setdStation(String dStation) {
+        this.dStation = dStation == null ? null : dStation.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/DustSiteInfo.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/DustSiteInfo.java
new file mode 100644
index 0000000..b441f68
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/DustSiteInfo.java
@@ -0,0 +1,1036 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "ja_t_dust_site_info")
+public class DustSiteInfo {
+    @Id
+    private String id;
+
+    /**
+     * 瀹夎鍦板潃
+     */
+    private String address;
+
+    /**
+     * 寮�宸ユ椂闂�
+     */
+    @Column(name = "begin_date")
+    private Date beginDate;
+
+    /**
+     * 寤虹瓚闈㈢Н
+     */
+    @Column(name = "build_area")
+    private String buildArea;
+
+    /**
+     * 閲囬泦鏃堕棿
+     */
+    @Column(name = "data_time")
+    private Date dataTime;
+
+    /**
+     * 娓呮礂鎺柦
+     */
+    @Column(name = "clean_measure")
+    private String cleanMeasure;
+
+    /**
+     * 绔欑偣缂栫爜
+     */
+    private String code;
+
+    /**
+     * 鏂藉伐鍗曚綅
+     */
+    @Column(name = "construction_unit")
+    private String constructionUnit;
+
+    /**
+     * 鐐逛綅鎺у埗绾�
+     */
+    @Column(name = "control_level")
+    private String controlLevel;
+
+    /**
+     * 寮�鍙戝晢
+     */
+    private String developers;
+
+    /**
+     * 鎵ц鏃堕棿
+     */
+    @Column(name = "do_time")
+    private Date doTime;
+
+    /**
+     * 杩愮淮鍟�
+     */
+    @Column(name = "duty_company")
+    private String dutyCompany;
+
+    /**
+     * 杩愮淮鍟唅d
+     */
+    @Column(name = "duty_company_id")
+    private String dutyCompanyId;
+
+    /**
+     * 缁撴潫鏃堕棿
+     */
+    @Column(name = "end_date")
+    private Date endDate;
+
+    /**
+     * 褰撳墠鏂藉伐闃舵
+     */
+    @Column(name = "engineering_stage")
+    private String engineeringStage;
+
+    /**
+     * 褰撳墠鏂藉伐闃舵缂栫爜
+     */
+    @Column(name = "engineering_stage_code")
+    private String engineeringStageCode;
+
+    /**
+     * 璁惧缂栫爜
+     */
+    @Column(name = "equipment_code")
+    private String equipmentCode;
+
+    /**
+     * 鍗犲湴闈㈢Н
+     */
+    @Column(name = "floor_area")
+    private String floorArea;
+
+    /**
+     * 鎵�灞炲尯鍘夸唬鐮�
+     */
+    @Column(name = "group_id")
+    private String groupId;
+
+    /**
+     * 鎵�灞炲尯鍘�
+     */
+    @Column(name = "group_name")
+    private String groupName;
+
+    /**
+     * 鏄惁鏈夌洃娴�
+     */
+    @Column(name = "has_monitor")
+    private String hasMonitor;
+
+    /**
+     * 鏄惁鍦ㄧ嚎
+     */
+    @Column(name = "is_online")
+    private String isOnline;
+
+    /**
+     * 璁惧鏄惁寮傚父
+     */
+    @Column(name = "is_trouble")
+    private String isTrouble;
+
+    /**
+     * 鍒犻櫎鏍囧織浣�
+     */
+    @Column(name = "jhpt_delete")
+    private String jhptDelete;
+
+    /**
+     * 鏇存柊鏃堕棿
+     */
+    @Column(name = "jhpt_update_time")
+    private String jhptUpdateTime;
+
+    private String kindex;
+
+    /**
+     * 绾害
+     */
+    private String latitude;
+
+    /**
+     * 鑱旂郴浜�
+     */
+    private String linkman;
+
+    /**
+     * 缁忓害
+     */
+    private String longitude;
+
+    /**
+     * 璁惧缂栫爜
+     */
+    @Column(name = "mn_code")
+    private String mnCode;
+
+    /**
+     * 绔欑偣鍚嶇О
+     */
+    private String name;
+
+    /**
+     * 鍣0鍔熻兘鍖�
+     */
+    @Column(name = "noise_region")
+    private String noiseRegion;
+
+    /**
+     * 鑱旂郴浜虹數璇�
+     */
+    private String phone;
+
+    /**
+     * 鎵�灞炵渷浠�
+     */
+    private String province;
+
+    /**
+     * 璐熻矗浜�
+     */
+    private String responsible;
+
+    /**
+     * 鍐呬腑澶栫幆缂栫爜
+     */
+    @Column(name = "ring_id")
+    private String ringId;
+
+    /**
+     * 闃舵寮�濮嬫棩鏈�
+     */
+    @Column(name = "stage_begin_date")
+    private Date stageBeginDate;
+
+    /**
+     * 鍋滄鏃堕棿
+     */
+    @Column(name = "stop_time")
+    private Date stopTime;
+
+    /**
+     * tsp娴撳害
+     */
+    private Double tsp;
+
+    /**
+     * 绫诲瀷缂栫爜
+     */
+    @Column(name = "type_id")
+    private String typeId;
+
+    /**
+     * 绫诲瀷鍚嶇О
+     */
+    private String typename;
+
+    /**
+     * 缁熻绫诲瀷缂栫爜
+     */
+    @Column(name = "union_type_id")
+    private String unionTypeId;
+
+    /**
+     * 鍥村楂樺害
+     */
+    @Column(name = "wall_height")
+    private String wallHeight;
+
+    /**
+     * 涓氬姟鏃堕棿
+     */
+    @Column(name = "ywsj_date")
+    private Date ywsjDate;
+
+    /**
+     * @return id
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(String id) {
+        this.id = id == null ? null : id.trim();
+    }
+
+    /**
+     * 鑾峰彇瀹夎鍦板潃
+     *
+     * @return address - 瀹夎鍦板潃
+     */
+    public String getAddress() {
+        return address;
+    }
+
+    /**
+     * 璁剧疆瀹夎鍦板潃
+     *
+     * @param address 瀹夎鍦板潃
+     */
+    public void setAddress(String address) {
+        this.address = address == null ? null : address.trim();
+    }
+
+    /**
+     * 鑾峰彇寮�宸ユ椂闂�
+     *
+     * @return begin_date - 寮�宸ユ椂闂�
+     */
+    public Date getBeginDate() {
+        return beginDate;
+    }
+
+    /**
+     * 璁剧疆寮�宸ユ椂闂�
+     *
+     * @param beginDate 寮�宸ユ椂闂�
+     */
+    public void setBeginDate(Date beginDate) {
+        this.beginDate = beginDate;
+    }
+
+    /**
+     * 鑾峰彇寤虹瓚闈㈢Н
+     *
+     * @return build_area - 寤虹瓚闈㈢Н
+     */
+    public String getBuildArea() {
+        return buildArea;
+    }
+
+    /**
+     * 璁剧疆寤虹瓚闈㈢Н
+     *
+     * @param buildArea 寤虹瓚闈㈢Н
+     */
+    public void setBuildArea(String buildArea) {
+        this.buildArea = buildArea == null ? null : buildArea.trim();
+    }
+
+    /**
+     * 鑾峰彇閲囬泦鏃堕棿
+     *
+     * @return data_time - 閲囬泦鏃堕棿
+     */
+    public Date getDataTime() {
+        return dataTime;
+    }
+
+    /**
+     * 璁剧疆閲囬泦鏃堕棿
+     *
+     * @param dataTime 閲囬泦鏃堕棿
+     */
+    public void setDataTime(Date dataTime) {
+        this.dataTime = dataTime;
+    }
+
+    /**
+     * 鑾峰彇娓呮礂鎺柦
+     *
+     * @return clean_measure - 娓呮礂鎺柦
+     */
+    public String getCleanMeasure() {
+        return cleanMeasure;
+    }
+
+    /**
+     * 璁剧疆娓呮礂鎺柦
+     *
+     * @param cleanMeasure 娓呮礂鎺柦
+     */
+    public void setCleanMeasure(String cleanMeasure) {
+        this.cleanMeasure = cleanMeasure == null ? null : cleanMeasure.trim();
+    }
+
+    /**
+     * 鑾峰彇绔欑偣缂栫爜
+     *
+     * @return code - 绔欑偣缂栫爜
+     */
+    public String getCode() {
+        return code;
+    }
+
+    /**
+     * 璁剧疆绔欑偣缂栫爜
+     *
+     * @param code 绔欑偣缂栫爜
+     */
+    public void setCode(String code) {
+        this.code = code == null ? null : code.trim();
+    }
+
+    /**
+     * 鑾峰彇鏂藉伐鍗曚綅
+     *
+     * @return construction_unit - 鏂藉伐鍗曚綅
+     */
+    public String getConstructionUnit() {
+        return constructionUnit;
+    }
+
+    /**
+     * 璁剧疆鏂藉伐鍗曚綅
+     *
+     * @param constructionUnit 鏂藉伐鍗曚綅
+     */
+    public void setConstructionUnit(String constructionUnit) {
+        this.constructionUnit = constructionUnit == null ? null : constructionUnit.trim();
+    }
+
+    /**
+     * 鑾峰彇鐐逛綅鎺у埗绾�
+     *
+     * @return control_level - 鐐逛綅鎺у埗绾�
+     */
+    public String getControlLevel() {
+        return controlLevel;
+    }
+
+    /**
+     * 璁剧疆鐐逛綅鎺у埗绾�
+     *
+     * @param controlLevel 鐐逛綅鎺у埗绾�
+     */
+    public void setControlLevel(String controlLevel) {
+        this.controlLevel = controlLevel == null ? null : controlLevel.trim();
+    }
+
+    /**
+     * 鑾峰彇寮�鍙戝晢
+     *
+     * @return developers - 寮�鍙戝晢
+     */
+    public String getDevelopers() {
+        return developers;
+    }
+
+    /**
+     * 璁剧疆寮�鍙戝晢
+     *
+     * @param developers 寮�鍙戝晢
+     */
+    public void setDevelopers(String developers) {
+        this.developers = developers == null ? null : developers.trim();
+    }
+
+    /**
+     * 鑾峰彇鎵ц鏃堕棿
+     *
+     * @return do_time - 鎵ц鏃堕棿
+     */
+    public Date getDoTime() {
+        return doTime;
+    }
+
+    /**
+     * 璁剧疆鎵ц鏃堕棿
+     *
+     * @param doTime 鎵ц鏃堕棿
+     */
+    public void setDoTime(Date doTime) {
+        this.doTime = doTime;
+    }
+
+    /**
+     * 鑾峰彇杩愮淮鍟�
+     *
+     * @return duty_company - 杩愮淮鍟�
+     */
+    public String getDutyCompany() {
+        return dutyCompany;
+    }
+
+    /**
+     * 璁剧疆杩愮淮鍟�
+     *
+     * @param dutyCompany 杩愮淮鍟�
+     */
+    public void setDutyCompany(String dutyCompany) {
+        this.dutyCompany = dutyCompany == null ? null : dutyCompany.trim();
+    }
+
+    /**
+     * 鑾峰彇杩愮淮鍟唅d
+     *
+     * @return duty_company_id - 杩愮淮鍟唅d
+     */
+    public String getDutyCompanyId() {
+        return dutyCompanyId;
+    }
+
+    /**
+     * 璁剧疆杩愮淮鍟唅d
+     *
+     * @param dutyCompanyId 杩愮淮鍟唅d
+     */
+    public void setDutyCompanyId(String dutyCompanyId) {
+        this.dutyCompanyId = dutyCompanyId == null ? null : dutyCompanyId.trim();
+    }
+
+    /**
+     * 鑾峰彇缁撴潫鏃堕棿
+     *
+     * @return end_date - 缁撴潫鏃堕棿
+     */
+    public Date getEndDate() {
+        return endDate;
+    }
+
+    /**
+     * 璁剧疆缁撴潫鏃堕棿
+     *
+     * @param endDate 缁撴潫鏃堕棿
+     */
+    public void setEndDate(Date endDate) {
+        this.endDate = endDate;
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鏂藉伐闃舵
+     *
+     * @return engineering_stage - 褰撳墠鏂藉伐闃舵
+     */
+    public String getEngineeringStage() {
+        return engineeringStage;
+    }
+
+    /**
+     * 璁剧疆褰撳墠鏂藉伐闃舵
+     *
+     * @param engineeringStage 褰撳墠鏂藉伐闃舵
+     */
+    public void setEngineeringStage(String engineeringStage) {
+        this.engineeringStage = engineeringStage == null ? null : engineeringStage.trim();
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鏂藉伐闃舵缂栫爜
+     *
+     * @return engineering_stage_code - 褰撳墠鏂藉伐闃舵缂栫爜
+     */
+    public String getEngineeringStageCode() {
+        return engineeringStageCode;
+    }
+
+    /**
+     * 璁剧疆褰撳墠鏂藉伐闃舵缂栫爜
+     *
+     * @param engineeringStageCode 褰撳墠鏂藉伐闃舵缂栫爜
+     */
+    public void setEngineeringStageCode(String engineeringStageCode) {
+        this.engineeringStageCode = engineeringStageCode == null ? null : engineeringStageCode.trim();
+    }
+
+    /**
+     * 鑾峰彇璁惧缂栫爜
+     *
+     * @return equipment_code - 璁惧缂栫爜
+     */
+    public String getEquipmentCode() {
+        return equipmentCode;
+    }
+
+    /**
+     * 璁剧疆璁惧缂栫爜
+     *
+     * @param equipmentCode 璁惧缂栫爜
+     */
+    public void setEquipmentCode(String equipmentCode) {
+        this.equipmentCode = equipmentCode == null ? null : equipmentCode.trim();
+    }
+
+    /**
+     * 鑾峰彇鍗犲湴闈㈢Н
+     *
+     * @return floor_area - 鍗犲湴闈㈢Н
+     */
+    public String getFloorArea() {
+        return floorArea;
+    }
+
+    /**
+     * 璁剧疆鍗犲湴闈㈢Н
+     *
+     * @param floorArea 鍗犲湴闈㈢Н
+     */
+    public void setFloorArea(String floorArea) {
+        this.floorArea = floorArea == null ? null : floorArea.trim();
+    }
+
+    /**
+     * 鑾峰彇鎵�灞炲尯鍘夸唬鐮�
+     *
+     * @return group_id - 鎵�灞炲尯鍘夸唬鐮�
+     */
+    public String getGroupId() {
+        return groupId;
+    }
+
+    /**
+     * 璁剧疆鎵�灞炲尯鍘夸唬鐮�
+     *
+     * @param groupId 鎵�灞炲尯鍘夸唬鐮�
+     */
+    public void setGroupId(String groupId) {
+        this.groupId = groupId == null ? null : groupId.trim();
+    }
+
+    /**
+     * 鑾峰彇鎵�灞炲尯鍘�
+     *
+     * @return group_name - 鎵�灞炲尯鍘�
+     */
+    public String getGroupName() {
+        return groupName;
+    }
+
+    /**
+     * 璁剧疆鎵�灞炲尯鍘�
+     *
+     * @param groupName 鎵�灞炲尯鍘�
+     */
+    public void setGroupName(String groupName) {
+        this.groupName = groupName == null ? null : groupName.trim();
+    }
+
+    /**
+     * 鑾峰彇鏄惁鏈夌洃娴�
+     *
+     * @return has_monitor - 鏄惁鏈夌洃娴�
+     */
+    public String getHasMonitor() {
+        return hasMonitor;
+    }
+
+    /**
+     * 璁剧疆鏄惁鏈夌洃娴�
+     *
+     * @param hasMonitor 鏄惁鏈夌洃娴�
+     */
+    public void setHasMonitor(String hasMonitor) {
+        this.hasMonitor = hasMonitor == null ? null : hasMonitor.trim();
+    }
+
+    /**
+     * 鑾峰彇鏄惁鍦ㄧ嚎
+     *
+     * @return is_online - 鏄惁鍦ㄧ嚎
+     */
+    public String getIsOnline() {
+        return isOnline;
+    }
+
+    /**
+     * 璁剧疆鏄惁鍦ㄧ嚎
+     *
+     * @param isOnline 鏄惁鍦ㄧ嚎
+     */
+    public void setIsOnline(String isOnline) {
+        this.isOnline = isOnline == null ? null : isOnline.trim();
+    }
+
+    /**
+     * 鑾峰彇璁惧鏄惁寮傚父
+     *
+     * @return is_trouble - 璁惧鏄惁寮傚父
+     */
+    public String getIsTrouble() {
+        return isTrouble;
+    }
+
+    /**
+     * 璁剧疆璁惧鏄惁寮傚父
+     *
+     * @param isTrouble 璁惧鏄惁寮傚父
+     */
+    public void setIsTrouble(String isTrouble) {
+        this.isTrouble = isTrouble == null ? null : isTrouble.trim();
+    }
+
+    /**
+     * 鑾峰彇鍒犻櫎鏍囧織浣�
+     *
+     * @return jhpt_delete - 鍒犻櫎鏍囧織浣�
+     */
+    public String getJhptDelete() {
+        return jhptDelete;
+    }
+
+    /**
+     * 璁剧疆鍒犻櫎鏍囧織浣�
+     *
+     * @param jhptDelete 鍒犻櫎鏍囧織浣�
+     */
+    public void setJhptDelete(String jhptDelete) {
+        this.jhptDelete = jhptDelete == null ? null : jhptDelete.trim();
+    }
+
+    /**
+     * 鑾峰彇鏇存柊鏃堕棿
+     *
+     * @return jhpt_update_time - 鏇存柊鏃堕棿
+     */
+    public String getJhptUpdateTime() {
+        return jhptUpdateTime;
+    }
+
+    /**
+     * 璁剧疆鏇存柊鏃堕棿
+     *
+     * @param jhptUpdateTime 鏇存柊鏃堕棿
+     */
+    public void setJhptUpdateTime(String jhptUpdateTime) {
+        this.jhptUpdateTime = jhptUpdateTime == null ? null : jhptUpdateTime.trim();
+    }
+
+    /**
+     * @return kindex
+     */
+    public String getKindex() {
+        return kindex;
+    }
+
+    /**
+     * @param kindex
+     */
+    public void setKindex(String kindex) {
+        this.kindex = kindex == null ? null : kindex.trim();
+    }
+
+    /**
+     * 鑾峰彇绾害
+     *
+     * @return latitude - 绾害
+     */
+    public String getLatitude() {
+        return latitude;
+    }
+
+    /**
+     * 璁剧疆绾害
+     *
+     * @param latitude 绾害
+     */
+    public void setLatitude(String latitude) {
+        this.latitude = latitude == null ? null : latitude.trim();
+    }
+
+    /**
+     * 鑾峰彇鑱旂郴浜�
+     *
+     * @return linkman - 鑱旂郴浜�
+     */
+    public String getLinkman() {
+        return linkman;
+    }
+
+    /**
+     * 璁剧疆鑱旂郴浜�
+     *
+     * @param linkman 鑱旂郴浜�
+     */
+    public void setLinkman(String linkman) {
+        this.linkman = linkman == null ? null : linkman.trim();
+    }
+
+    /**
+     * 鑾峰彇缁忓害
+     *
+     * @return longitude - 缁忓害
+     */
+    public String getLongitude() {
+        return longitude;
+    }
+
+    /**
+     * 璁剧疆缁忓害
+     *
+     * @param longitude 缁忓害
+     */
+    public void setLongitude(String longitude) {
+        this.longitude = longitude == null ? null : longitude.trim();
+    }
+
+    /**
+     * 鑾峰彇璁惧缂栫爜
+     *
+     * @return mn_code - 璁惧缂栫爜
+     */
+    public String getMnCode() {
+        return mnCode;
+    }
+
+    /**
+     * 璁剧疆璁惧缂栫爜
+     *
+     * @param mnCode 璁惧缂栫爜
+     */
+    public void setMnCode(String mnCode) {
+        this.mnCode = mnCode == null ? null : mnCode.trim();
+    }
+
+    /**
+     * 鑾峰彇绔欑偣鍚嶇О
+     *
+     * @return name - 绔欑偣鍚嶇О
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * 璁剧疆绔欑偣鍚嶇О
+     *
+     * @param name 绔欑偣鍚嶇О
+     */
+    public void setName(String name) {
+        this.name = name == null ? null : name.trim();
+    }
+
+    /**
+     * 鑾峰彇鍣0鍔熻兘鍖�
+     *
+     * @return noise_region - 鍣0鍔熻兘鍖�
+     */
+    public String getNoiseRegion() {
+        return noiseRegion;
+    }
+
+    /**
+     * 璁剧疆鍣0鍔熻兘鍖�
+     *
+     * @param noiseRegion 鍣0鍔熻兘鍖�
+     */
+    public void setNoiseRegion(String noiseRegion) {
+        this.noiseRegion = noiseRegion == null ? null : noiseRegion.trim();
+    }
+
+    /**
+     * 鑾峰彇鑱旂郴浜虹數璇�
+     *
+     * @return phone - 鑱旂郴浜虹數璇�
+     */
+    public String getPhone() {
+        return phone;
+    }
+
+    /**
+     * 璁剧疆鑱旂郴浜虹數璇�
+     *
+     * @param phone 鑱旂郴浜虹數璇�
+     */
+    public void setPhone(String phone) {
+        this.phone = phone == null ? null : phone.trim();
+    }
+
+    /**
+     * 鑾峰彇鎵�灞炵渷浠�
+     *
+     * @return province - 鎵�灞炵渷浠�
+     */
+    public String getProvince() {
+        return province;
+    }
+
+    /**
+     * 璁剧疆鎵�灞炵渷浠�
+     *
+     * @param province 鎵�灞炵渷浠�
+     */
+    public void setProvince(String province) {
+        this.province = province == null ? null : province.trim();
+    }
+
+    /**
+     * 鑾峰彇璐熻矗浜�
+     *
+     * @return responsible - 璐熻矗浜�
+     */
+    public String getResponsible() {
+        return responsible;
+    }
+
+    /**
+     * 璁剧疆璐熻矗浜�
+     *
+     * @param responsible 璐熻矗浜�
+     */
+    public void setResponsible(String responsible) {
+        this.responsible = responsible == null ? null : responsible.trim();
+    }
+
+    /**
+     * 鑾峰彇鍐呬腑澶栫幆缂栫爜
+     *
+     * @return ring_id - 鍐呬腑澶栫幆缂栫爜
+     */
+    public String getRingId() {
+        return ringId;
+    }
+
+    /**
+     * 璁剧疆鍐呬腑澶栫幆缂栫爜
+     *
+     * @param ringId 鍐呬腑澶栫幆缂栫爜
+     */
+    public void setRingId(String ringId) {
+        this.ringId = ringId == null ? null : ringId.trim();
+    }
+
+    /**
+     * 鑾峰彇闃舵寮�濮嬫棩鏈�
+     *
+     * @return stage_begin_date - 闃舵寮�濮嬫棩鏈�
+     */
+    public Date getStageBeginDate() {
+        return stageBeginDate;
+    }
+
+    /**
+     * 璁剧疆闃舵寮�濮嬫棩鏈�
+     *
+     * @param stageBeginDate 闃舵寮�濮嬫棩鏈�
+     */
+    public void setStageBeginDate(Date stageBeginDate) {
+        this.stageBeginDate = stageBeginDate;
+    }
+
+    /**
+     * 鑾峰彇鍋滄鏃堕棿
+     *
+     * @return stop_time - 鍋滄鏃堕棿
+     */
+    public Date getStopTime() {
+        return stopTime;
+    }
+
+    /**
+     * 璁剧疆鍋滄鏃堕棿
+     *
+     * @param stopTime 鍋滄鏃堕棿
+     */
+    public void setStopTime(Date stopTime) {
+        this.stopTime = stopTime;
+    }
+
+    /**
+     * 鑾峰彇tsp娴撳害
+     *
+     * @return tsp - tsp娴撳害
+     */
+    public Double getTsp() {
+        return tsp;
+    }
+
+    /**
+     * 璁剧疆tsp娴撳害
+     *
+     * @param tsp tsp娴撳害
+     */
+    public void setTsp(Double tsp) {
+        this.tsp = tsp;
+    }
+
+    /**
+     * 鑾峰彇绫诲瀷缂栫爜
+     *
+     * @return type_id - 绫诲瀷缂栫爜
+     */
+    public String getTypeId() {
+        return typeId;
+    }
+
+    /**
+     * 璁剧疆绫诲瀷缂栫爜
+     *
+     * @param typeId 绫诲瀷缂栫爜
+     */
+    public void setTypeId(String typeId) {
+        this.typeId = typeId == null ? null : typeId.trim();
+    }
+
+    /**
+     * 鑾峰彇绫诲瀷鍚嶇О
+     *
+     * @return typename - 绫诲瀷鍚嶇О
+     */
+    public String getTypename() {
+        return typename;
+    }
+
+    /**
+     * 璁剧疆绫诲瀷鍚嶇О
+     *
+     * @param typename 绫诲瀷鍚嶇О
+     */
+    public void setTypename(String typename) {
+        this.typename = typename == null ? null : typename.trim();
+    }
+
+    /**
+     * 鑾峰彇缁熻绫诲瀷缂栫爜
+     *
+     * @return union_type_id - 缁熻绫诲瀷缂栫爜
+     */
+    public String getUnionTypeId() {
+        return unionTypeId;
+    }
+
+    /**
+     * 璁剧疆缁熻绫诲瀷缂栫爜
+     *
+     * @param unionTypeId 缁熻绫诲瀷缂栫爜
+     */
+    public void setUnionTypeId(String unionTypeId) {
+        this.unionTypeId = unionTypeId == null ? null : unionTypeId.trim();
+    }
+
+    /**
+     * 鑾峰彇鍥村楂樺害
+     *
+     * @return wall_height - 鍥村楂樺害
+     */
+    public String getWallHeight() {
+        return wallHeight;
+    }
+
+    /**
+     * 璁剧疆鍥村楂樺害
+     *
+     * @param wallHeight 鍥村楂樺害
+     */
+    public void setWallHeight(String wallHeight) {
+        this.wallHeight = wallHeight == null ? null : wallHeight.trim();
+    }
+
+    /**
+     * 鑾峰彇涓氬姟鏃堕棿
+     *
+     * @return ywsj_date - 涓氬姟鏃堕棿
+     */
+    public Date getYwsjDate() {
+        return ywsjDate;
+    }
+
+    /**
+     * 璁剧疆涓氬姟鏃堕棿
+     *
+     * @param ywsjDate 涓氬姟鏃堕棿
+     */
+    public void setYwsjDate(Date ywsjDate) {
+        this.ywsjDate = ywsjDate;
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/DustSiteMap.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/DustSiteMap.java
new file mode 100644
index 0000000..e9a1126
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/DustSiteMap.java
@@ -0,0 +1,144 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "ja_t_dust_site_map")
+public class DustSiteMap {
+    @Id
+    @Column(name = "Id")
+    private Integer id;
+
+    @Column(name = "TZ_User_Id")
+    private String tzUserId;
+
+    @Column(name = "TZ_User_Name")
+    private String tzUserName;
+
+    @Column(name = "JA_MN_Code")
+    private String jaMnCode;
+
+    @Column(name = "JA_Scene_Name")
+    private String jaSceneName;
+
+    @Column(name = "SV_User_Id")
+    private String svUserId;
+
+    @Column(name = "SV_User_name")
+    private String svUserName;
+
+    @Column(name = "Create_Time")
+    private Date createTime;
+
+    /**
+     * @return Id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * @return TZ_User_Id
+     */
+    public String getTzUserId() {
+        return tzUserId;
+    }
+
+    /**
+     * @param tzUserId
+     */
+    public void setTzUserId(String tzUserId) {
+        this.tzUserId = tzUserId == null ? null : tzUserId.trim();
+    }
+
+    /**
+     * @return TZ_User_Name
+     */
+    public String getTzUserName() {
+        return tzUserName;
+    }
+
+    /**
+     * @param tzUserName
+     */
+    public void setTzUserName(String tzUserName) {
+        this.tzUserName = tzUserName == null ? null : tzUserName.trim();
+    }
+
+    /**
+     * @return JA_MN_Code
+     */
+    public String getJaMnCode() {
+        return jaMnCode;
+    }
+
+    /**
+     * @param jaMnCode
+     */
+    public void setJaMnCode(String jaMnCode) {
+        this.jaMnCode = jaMnCode == null ? null : jaMnCode.trim();
+    }
+
+    /**
+     * @return JA_Scene_Name
+     */
+    public String getJaSceneName() {
+        return jaSceneName;
+    }
+
+    /**
+     * @param jaSceneName
+     */
+    public void setJaSceneName(String jaSceneName) {
+        this.jaSceneName = jaSceneName == null ? null : jaSceneName.trim();
+    }
+
+    /**
+     * @return SV_User_Id
+     */
+    public String getSvUserId() {
+        return svUserId;
+    }
+
+    /**
+     * @param svUserId
+     */
+    public void setSvUserId(String svUserId) {
+        this.svUserId = svUserId == null ? null : svUserId.trim();
+    }
+
+    /**
+     * @return SV_User_name
+     */
+    public String getSvUserName() {
+        return svUserName;
+    }
+
+    /**
+     * @param svUserName
+     */
+    public void setSvUserName(String svUserName) {
+        this.svUserName = svUserName == null ? null : svUserName.trim();
+    }
+
+    /**
+     * @return Create_Time
+     */
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    /**
+     * @param createTime
+     */
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/EnvironmentalSchedule.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/EnvironmentalSchedule.java
new file mode 100644
index 0000000..fbf9e32
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/EnvironmentalSchedule.java
@@ -0,0 +1,409 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "ea_t_schedule")
+public class EnvironmentalSchedule {
+    @Id
+    @Column(name = "SC_ID")
+    private Integer scId;
+
+    /**
+     * 鏃ョ▼鏍囬
+     */
+    @Column(name = "SC_Title")
+    private String scTitle;
+
+    /**
+     * 鏃ョ▼姝ラ鍚嶇О鍒楄〃
+     */
+    @Column(name = "SC_Step_Name")
+    private String scStepName;
+
+    /**
+     * 鏃ョ▼绫诲瀷id锛�0锛氱郴缁熸棩绋嬶紱1锛氱敤鎴蜂笟鍔℃棩绋�
+     */
+    @Column(name = "SC_Type")
+    private Byte scType;
+
+    /**
+     * 鏃ョ▼绫诲瀷鍚嶇О
+     */
+    @Column(name = "SC_Type_Name")
+    private String scTypeName;
+
+    /**
+     * 鏃ョ▼鍛ㄦ湡绫诲瀷銆�0锛氭瘡鏃ワ紱1锛氭瘡鍛紱2锛氭瘡鏈堬紱3锛氭瘡骞达紱4锛氬浐瀹氭棩鏈�
+     */
+    @Column(name = "SC_Period_Type")
+    private Byte scPeriodType;
+
+    /**
+     * 鏃ョ▼鍛ㄦ湡绫诲瀷鍚嶇О
+     */
+    @Column(name = "SC_Period_Type_Name")
+    private String scPeriodTypeName;
+
+    /**
+     * 鏃ョ▼鍛ㄦ湡绫诲瀷涓烘瘡鍛ㄦ椂锛屽喅瀹氬懆鍑狅紝鍙栧�间负1鑷�7锛岀敤;鍒嗛殧
+     */
+    @Column(name = "SC_Every_Week")
+    private String scEveryWeek;
+
+    /**
+     * 鏃ョ▼鍛ㄦ湡绫诲瀷涓烘瘡鏈堟椂锛屽喅瀹氬摢鏃ワ紝鍙栧�间负1鑷�31锛岀敤;鍒嗛殧
+     */
+    @Column(name = "SC_Every_Month")
+    private String scEveryMonth;
+
+    /**
+     * 鏃ョ▼鍛ㄦ湡绫诲瀷涓烘瘡骞存椂锛屽喅瀹氬摢澶╋紝鍙栧�间负MM-DD锛岀敤;鍒嗛殧
+     */
+    @Column(name = "SC_Every_Year")
+    private String scEveryYear;
+
+    /**
+     * 瀵逛簬鍛ㄦ湡鎬х殑鏃ョ▼涓哄紑濮嬬敓鏁堟椂闂达紝瀵逛簬鍥哄畾鏃ョ▼涓哄搴旂殑鏃ョ▼鏃堕棿
+     */
+    @Column(name = "SC_Effective_Time")
+    private Date scEffectiveTime;
+
+    /**
+     * 鏃ョ▼鎵�灞炵敤鎴穒d锛屼笌鎵�灞炵敤鎴风被鍨嬩簰鏂�
+     */
+    @Column(name = "SC_User_ID")
+    private String scUserId;
+
+    /**
+     * 鏃ョ▼鎵�灞炵敤鎴风被鍨嬮厤缃〃id
+     */
+    @Column(name = "SC_User_Config_Id")
+    private Integer scUserConfigId;
+
+    /**
+     * 鍦烘櫙绫诲瀷id
+     */
+    @Column(name = "SC_Scene_Type")
+    private Integer scSceneType;
+
+    /**
+     * 鏄惁闇�瑕佺敤鎴风鏀讹紝绛炬敹鐢熸垚绛炬敹璁板綍
+     */
+    @Column(name = "SC_Need_Sign")
+    private Boolean scNeedSign;
+
+    /**
+     * 鏃ョ▼鍐呭
+     */
+    @Column(name = "SC_Content")
+    private String scContent;
+
+    /**
+     * 鏃ョ▼姝ラ鍐呭鍒楄〃
+     */
+    @Column(name = "SC_Step_Detail")
+    private String scStepDetail;
+
+    /**
+     * @return SC_ID
+     */
+    public Integer getScId() {
+        return scId;
+    }
+
+    /**
+     * @param scId
+     */
+    public void setScId(Integer scId) {
+        this.scId = scId;
+    }
+
+    /**
+     * 鑾峰彇鏃ョ▼鏍囬
+     *
+     * @return SC_Title - 鏃ョ▼鏍囬
+     */
+    public String getScTitle() {
+        return scTitle;
+    }
+
+    /**
+     * 璁剧疆鏃ョ▼鏍囬
+     *
+     * @param scTitle 鏃ョ▼鏍囬
+     */
+    public void setScTitle(String scTitle) {
+        this.scTitle = scTitle == null ? null : scTitle.trim();
+    }
+
+    /**
+     * 鑾峰彇鏃ョ▼姝ラ鍚嶇О鍒楄〃
+     *
+     * @return SC_Step_Name - 鏃ョ▼姝ラ鍚嶇О鍒楄〃
+     */
+    public String getScStepName() {
+        return scStepName;
+    }
+
+    /**
+     * 璁剧疆鏃ョ▼姝ラ鍚嶇О鍒楄〃
+     *
+     * @param scStepName 鏃ョ▼姝ラ鍚嶇О鍒楄〃
+     */
+    public void setScStepName(String scStepName) {
+        this.scStepName = scStepName == null ? null : scStepName.trim();
+    }
+
+    /**
+     * 鑾峰彇鏃ョ▼绫诲瀷id锛�0锛氱郴缁熸棩绋嬶紱1锛氱敤鎴蜂笟鍔℃棩绋�
+     *
+     * @return SC_Type - 鏃ョ▼绫诲瀷id锛�0锛氱郴缁熸棩绋嬶紱1锛氱敤鎴蜂笟鍔℃棩绋�
+     */
+    public Byte getScType() {
+        return scType;
+    }
+
+    /**
+     * 璁剧疆鏃ョ▼绫诲瀷id锛�0锛氱郴缁熸棩绋嬶紱1锛氱敤鎴蜂笟鍔℃棩绋�
+     *
+     * @param scType 鏃ョ▼绫诲瀷id锛�0锛氱郴缁熸棩绋嬶紱1锛氱敤鎴蜂笟鍔℃棩绋�
+     */
+    public void setScType(Byte scType) {
+        this.scType = scType;
+    }
+
+    /**
+     * 鑾峰彇鏃ョ▼绫诲瀷鍚嶇О
+     *
+     * @return SC_Type_Name - 鏃ョ▼绫诲瀷鍚嶇О
+     */
+    public String getScTypeName() {
+        return scTypeName;
+    }
+
+    /**
+     * 璁剧疆鏃ョ▼绫诲瀷鍚嶇О
+     *
+     * @param scTypeName 鏃ョ▼绫诲瀷鍚嶇О
+     */
+    public void setScTypeName(String scTypeName) {
+        this.scTypeName = scTypeName == null ? null : scTypeName.trim();
+    }
+
+    /**
+     * 鑾峰彇鏃ョ▼鍛ㄦ湡绫诲瀷銆�0锛氭瘡鏃ワ紱1锛氭瘡鍛紱2锛氭瘡鏈堬紱3锛氭瘡骞达紱4锛氬浐瀹氭棩鏈�
+     *
+     * @return SC_Period_Type - 鏃ョ▼鍛ㄦ湡绫诲瀷銆�0锛氭瘡鏃ワ紱1锛氭瘡鍛紱2锛氭瘡鏈堬紱3锛氭瘡骞达紱4锛氬浐瀹氭棩鏈�
+     */
+    public Byte getScPeriodType() {
+        return scPeriodType;
+    }
+
+    /**
+     * 璁剧疆鏃ョ▼鍛ㄦ湡绫诲瀷銆�0锛氭瘡鏃ワ紱1锛氭瘡鍛紱2锛氭瘡鏈堬紱3锛氭瘡骞达紱4锛氬浐瀹氭棩鏈�
+     *
+     * @param scPeriodType 鏃ョ▼鍛ㄦ湡绫诲瀷銆�0锛氭瘡鏃ワ紱1锛氭瘡鍛紱2锛氭瘡鏈堬紱3锛氭瘡骞达紱4锛氬浐瀹氭棩鏈�
+     */
+    public void setScPeriodType(Byte scPeriodType) {
+        this.scPeriodType = scPeriodType;
+    }
+
+    /**
+     * 鑾峰彇鏃ョ▼鍛ㄦ湡绫诲瀷鍚嶇О
+     *
+     * @return SC_Period_Type_Name - 鏃ョ▼鍛ㄦ湡绫诲瀷鍚嶇О
+     */
+    public String getScPeriodTypeName() {
+        return scPeriodTypeName;
+    }
+
+    /**
+     * 璁剧疆鏃ョ▼鍛ㄦ湡绫诲瀷鍚嶇О
+     *
+     * @param scPeriodTypeName 鏃ョ▼鍛ㄦ湡绫诲瀷鍚嶇О
+     */
+    public void setScPeriodTypeName(String scPeriodTypeName) {
+        this.scPeriodTypeName = scPeriodTypeName == null ? null : scPeriodTypeName.trim();
+    }
+
+    /**
+     * 鑾峰彇鏃ョ▼鍛ㄦ湡绫诲瀷涓烘瘡鍛ㄦ椂锛屽喅瀹氬懆鍑狅紝鍙栧�间负1鑷�7锛岀敤;鍒嗛殧
+     *
+     * @return SC_Every_Week - 鏃ョ▼鍛ㄦ湡绫诲瀷涓烘瘡鍛ㄦ椂锛屽喅瀹氬懆鍑狅紝鍙栧�间负1鑷�7锛岀敤;鍒嗛殧
+     */
+    public String getScEveryWeek() {
+        return scEveryWeek;
+    }
+
+    /**
+     * 璁剧疆鏃ョ▼鍛ㄦ湡绫诲瀷涓烘瘡鍛ㄦ椂锛屽喅瀹氬懆鍑狅紝鍙栧�间负1鑷�7锛岀敤;鍒嗛殧
+     *
+     * @param scEveryWeek 鏃ョ▼鍛ㄦ湡绫诲瀷涓烘瘡鍛ㄦ椂锛屽喅瀹氬懆鍑狅紝鍙栧�间负1鑷�7锛岀敤;鍒嗛殧
+     */
+    public void setScEveryWeek(String scEveryWeek) {
+        this.scEveryWeek = scEveryWeek == null ? null : scEveryWeek.trim();
+    }
+
+    /**
+     * 鑾峰彇鏃ョ▼鍛ㄦ湡绫诲瀷涓烘瘡鏈堟椂锛屽喅瀹氬摢鏃ワ紝鍙栧�间负1鑷�31锛岀敤;鍒嗛殧
+     *
+     * @return SC_Every_Month - 鏃ョ▼鍛ㄦ湡绫诲瀷涓烘瘡鏈堟椂锛屽喅瀹氬摢鏃ワ紝鍙栧�间负1鑷�31锛岀敤;鍒嗛殧
+     */
+    public String getScEveryMonth() {
+        return scEveryMonth;
+    }
+
+    /**
+     * 璁剧疆鏃ョ▼鍛ㄦ湡绫诲瀷涓烘瘡鏈堟椂锛屽喅瀹氬摢鏃ワ紝鍙栧�间负1鑷�31锛岀敤;鍒嗛殧
+     *
+     * @param scEveryMonth 鏃ョ▼鍛ㄦ湡绫诲瀷涓烘瘡鏈堟椂锛屽喅瀹氬摢鏃ワ紝鍙栧�间负1鑷�31锛岀敤;鍒嗛殧
+     */
+    public void setScEveryMonth(String scEveryMonth) {
+        this.scEveryMonth = scEveryMonth == null ? null : scEveryMonth.trim();
+    }
+
+    /**
+     * 鑾峰彇鏃ョ▼鍛ㄦ湡绫诲瀷涓烘瘡骞存椂锛屽喅瀹氬摢澶╋紝鍙栧�间负MM-DD锛岀敤;鍒嗛殧
+     *
+     * @return SC_Every_Year - 鏃ョ▼鍛ㄦ湡绫诲瀷涓烘瘡骞存椂锛屽喅瀹氬摢澶╋紝鍙栧�间负MM-DD锛岀敤;鍒嗛殧
+     */
+    public String getScEveryYear() {
+        return scEveryYear;
+    }
+
+    /**
+     * 璁剧疆鏃ョ▼鍛ㄦ湡绫诲瀷涓烘瘡骞存椂锛屽喅瀹氬摢澶╋紝鍙栧�间负MM-DD锛岀敤;鍒嗛殧
+     *
+     * @param scEveryYear 鏃ョ▼鍛ㄦ湡绫诲瀷涓烘瘡骞存椂锛屽喅瀹氬摢澶╋紝鍙栧�间负MM-DD锛岀敤;鍒嗛殧
+     */
+    public void setScEveryYear(String scEveryYear) {
+        this.scEveryYear = scEveryYear == null ? null : scEveryYear.trim();
+    }
+
+    /**
+     * 鑾峰彇瀵逛簬鍛ㄦ湡鎬х殑鏃ョ▼涓哄紑濮嬬敓鏁堟椂闂达紝瀵逛簬鍥哄畾鏃ョ▼涓哄搴旂殑鏃ョ▼鏃堕棿
+     *
+     * @return SC_Effective_Time - 瀵逛簬鍛ㄦ湡鎬х殑鏃ョ▼涓哄紑濮嬬敓鏁堟椂闂达紝瀵逛簬鍥哄畾鏃ョ▼涓哄搴旂殑鏃ョ▼鏃堕棿
+     */
+    public Date getScEffectiveTime() {
+        return scEffectiveTime;
+    }
+
+    /**
+     * 璁剧疆瀵逛簬鍛ㄦ湡鎬х殑鏃ョ▼涓哄紑濮嬬敓鏁堟椂闂达紝瀵逛簬鍥哄畾鏃ョ▼涓哄搴旂殑鏃ョ▼鏃堕棿
+     *
+     * @param scEffectiveTime 瀵逛簬鍛ㄦ湡鎬х殑鏃ョ▼涓哄紑濮嬬敓鏁堟椂闂达紝瀵逛簬鍥哄畾鏃ョ▼涓哄搴旂殑鏃ョ▼鏃堕棿
+     */
+    public void setScEffectiveTime(Date scEffectiveTime) {
+        this.scEffectiveTime = scEffectiveTime;
+    }
+
+    /**
+     * 鑾峰彇鏃ョ▼鎵�灞炵敤鎴穒d锛屼笌鎵�灞炵敤鎴风被鍨嬩簰鏂�
+     *
+     * @return SC_User_ID - 鏃ョ▼鎵�灞炵敤鎴穒d锛屼笌鎵�灞炵敤鎴风被鍨嬩簰鏂�
+     */
+    public String getScUserId() {
+        return scUserId;
+    }
+
+    /**
+     * 璁剧疆鏃ョ▼鎵�灞炵敤鎴穒d锛屼笌鎵�灞炵敤鎴风被鍨嬩簰鏂�
+     *
+     * @param scUserId 鏃ョ▼鎵�灞炵敤鎴穒d锛屼笌鎵�灞炵敤鎴风被鍨嬩簰鏂�
+     */
+    public void setScUserId(String scUserId) {
+        this.scUserId = scUserId == null ? null : scUserId.trim();
+    }
+
+    /**
+     * 鑾峰彇鏃ョ▼鎵�灞炵敤鎴风被鍨嬮厤缃〃id
+     *
+     * @return SC_User_Config_Id - 鏃ョ▼鎵�灞炵敤鎴风被鍨嬮厤缃〃id
+     */
+    public Integer getScUserConfigId() {
+        return scUserConfigId;
+    }
+
+    /**
+     * 璁剧疆鏃ョ▼鎵�灞炵敤鎴风被鍨嬮厤缃〃id
+     *
+     * @param scUserConfigId 鏃ョ▼鎵�灞炵敤鎴风被鍨嬮厤缃〃id
+     */
+    public void setScUserConfigId(Integer scUserConfigId) {
+        this.scUserConfigId = scUserConfigId;
+    }
+
+    /**
+     * 鑾峰彇鍦烘櫙绫诲瀷id
+     *
+     * @return SC_Scene_Type - 鍦烘櫙绫诲瀷id
+     */
+    public Integer getScSceneType() {
+        return scSceneType;
+    }
+
+    /**
+     * 璁剧疆鍦烘櫙绫诲瀷id
+     *
+     * @param scSceneType 鍦烘櫙绫诲瀷id
+     */
+    public void setScSceneType(Integer scSceneType) {
+        this.scSceneType = scSceneType;
+    }
+
+    /**
+     * 鑾峰彇鏄惁闇�瑕佺敤鎴风鏀讹紝绛炬敹鐢熸垚绛炬敹璁板綍
+     *
+     * @return SC_Need_Sign - 鏄惁闇�瑕佺敤鎴风鏀讹紝绛炬敹鐢熸垚绛炬敹璁板綍
+     */
+    public Boolean getScNeedSign() {
+        return scNeedSign;
+    }
+
+    /**
+     * 璁剧疆鏄惁闇�瑕佺敤鎴风鏀讹紝绛炬敹鐢熸垚绛炬敹璁板綍
+     *
+     * @param scNeedSign 鏄惁闇�瑕佺敤鎴风鏀讹紝绛炬敹鐢熸垚绛炬敹璁板綍
+     */
+    public void setScNeedSign(Boolean scNeedSign) {
+        this.scNeedSign = scNeedSign;
+    }
+
+    /**
+     * 鑾峰彇鏃ョ▼鍐呭
+     *
+     * @return SC_Content - 鏃ョ▼鍐呭
+     */
+    public String getScContent() {
+        return scContent;
+    }
+
+    /**
+     * 璁剧疆鏃ョ▼鍐呭
+     *
+     * @param scContent 鏃ョ▼鍐呭
+     */
+    public void setScContent(String scContent) {
+        this.scContent = scContent == null ? null : scContent.trim();
+    }
+
+    /**
+     * 鑾峰彇鏃ョ▼姝ラ鍐呭鍒楄〃
+     *
+     * @return SC_Step_Detail - 鏃ョ▼姝ラ鍐呭鍒楄〃
+     */
+    public String getScStepDetail() {
+        return scStepDetail;
+    }
+
+    /**
+     * 璁剧疆鏃ョ▼姝ラ鍐呭鍒楄〃
+     *
+     * @param scStepDetail 鏃ョ▼姝ラ鍐呭鍒楄〃
+     */
+    public void setScStepDetail(String scStepDetail) {
+        this.scStepDetail = scStepDetail == null ? null : scStepDetail.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Evaluationrule.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Evaluationrule.kt
index 88134e0..7054dac 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Evaluationrule.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Evaluationrule.kt
@@ -35,25 +35,25 @@
     var tasktype: String? = null
 
     /**
-     * 浠庡�煎煙琛ㄨ幏鍙�
+     * 鍦烘櫙绫诲瀷id
      */
     @Column(name = "ER_ScenseTypeID")
     var scensetypeid: Byte? = null
 
     /**
-     * 浠庡�煎煙琛ㄨ幏鍙�
+     * 鍦烘櫙绫诲瀷
      */
     @Column(name = "ER_ScenseType")
     var scensetype: String? = null
 
     /**
-     * 浠庡�煎煙琛ㄨ幏鍙�
+     * 璇勪及鍛ㄦ湡锛屽崟浣嶆湀锛岃寖鍥达細1-12
      */
     @Column(name = "ER_ScenseSubTypeID")
     var scensesubtypeid: Byte? = null
 
     /**
-     * 浠庡�煎煙琛ㄨ幏鍙�
+     *
      */
     @Column(name = "ER_ScenseSubType")
     var scensesubtype: String? = null
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/HourDustData.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/HourDustData.java
new file mode 100644
index 0000000..d16c21e
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/HourDustData.java
@@ -0,0 +1,324 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "ja_t_hour_dust_data")
+public class HourDustData {
+    @Id
+    private String id;
+
+    /**
+     * 鎵皹鍊�
+     */
+    private Double dustvalue;
+
+    /**
+     * FLAG
+     */
+    private String flag;
+
+    /**
+     * 绛夌骇
+     */
+    private String grade;
+
+    /**
+     * 鎵�灞炲尯鍘�
+     */
+    private String groupname;
+
+    /**
+     * 鍏ュ簱鏃堕棿
+     */
+    private Date inserttime;
+
+    /**
+     * 寮�濮嬫椂闂�
+     */
+    private Date lst;
+
+    /**
+     * 缁撴潫鏃堕棿
+     */
+    @Column(name = "lst_end")
+    private Date lstEnd;
+
+    /**
+     * 鐩戞祴璁惧缂栫爜
+     */
+    private String mncode;
+
+    /**
+     * 宸ョ▼鍚嶇О
+     */
+    private String name;
+
+    /**
+     * 鍣0鍊�
+     */
+    private String noisevalue;
+
+    /**
+     * 宸ョ▼ID
+     */
+    private String projectid;
+
+    /**
+     * 宸ョ▼绫诲埆ID
+     */
+    private String projecttypeid;
+
+    /**
+     * 璐ㄩ噺
+     */
+    private String quality;
+
+    /**
+     * @return id
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(String id) {
+        this.id = id == null ? null : id.trim();
+    }
+
+    /**
+     * 鑾峰彇鎵皹鍊�
+     *
+     * @return dustvalue - 鎵皹鍊�
+     */
+    public Double getDustvalue() {
+        return dustvalue;
+    }
+
+    /**
+     * 璁剧疆鎵皹鍊�
+     *
+     * @param dustvalue 鎵皹鍊�
+     */
+    public void setDustvalue(Double dustvalue) {
+        this.dustvalue = dustvalue;
+    }
+
+    /**
+     * 鑾峰彇FLAG
+     *
+     * @return flag - FLAG
+     */
+    public String getFlag() {
+        return flag;
+    }
+
+    /**
+     * 璁剧疆FLAG
+     *
+     * @param flag FLAG
+     */
+    public void setFlag(String flag) {
+        this.flag = flag == null ? null : flag.trim();
+    }
+
+    /**
+     * 鑾峰彇绛夌骇
+     *
+     * @return grade - 绛夌骇
+     */
+    public String getGrade() {
+        return grade;
+    }
+
+    /**
+     * 璁剧疆绛夌骇
+     *
+     * @param grade 绛夌骇
+     */
+    public void setGrade(String grade) {
+        this.grade = grade == null ? null : grade.trim();
+    }
+
+    /**
+     * 鑾峰彇鎵�灞炲尯鍘�
+     *
+     * @return groupname - 鎵�灞炲尯鍘�
+     */
+    public String getGroupname() {
+        return groupname;
+    }
+
+    /**
+     * 璁剧疆鎵�灞炲尯鍘�
+     *
+     * @param groupname 鎵�灞炲尯鍘�
+     */
+    public void setGroupname(String groupname) {
+        this.groupname = groupname == null ? null : groupname.trim();
+    }
+
+    /**
+     * 鑾峰彇鍏ュ簱鏃堕棿
+     *
+     * @return inserttime - 鍏ュ簱鏃堕棿
+     */
+    public Date getInserttime() {
+        return inserttime;
+    }
+
+    /**
+     * 璁剧疆鍏ュ簱鏃堕棿
+     *
+     * @param inserttime 鍏ュ簱鏃堕棿
+     */
+    public void setInserttime(Date inserttime) {
+        this.inserttime = inserttime;
+    }
+
+    /**
+     * 鑾峰彇寮�濮嬫椂闂�
+     *
+     * @return lst - 寮�濮嬫椂闂�
+     */
+    public Date getLst() {
+        return lst;
+    }
+
+    /**
+     * 璁剧疆寮�濮嬫椂闂�
+     *
+     * @param lst 寮�濮嬫椂闂�
+     */
+    public void setLst(Date lst) {
+        this.lst = lst;
+    }
+
+    /**
+     * 鑾峰彇缁撴潫鏃堕棿
+     *
+     * @return lst_end - 缁撴潫鏃堕棿
+     */
+    public Date getLstEnd() {
+        return lstEnd;
+    }
+
+    /**
+     * 璁剧疆缁撴潫鏃堕棿
+     *
+     * @param lstEnd 缁撴潫鏃堕棿
+     */
+    public void setLstEnd(Date lstEnd) {
+        this.lstEnd = lstEnd;
+    }
+
+    /**
+     * 鑾峰彇鐩戞祴璁惧缂栫爜
+     *
+     * @return mncode - 鐩戞祴璁惧缂栫爜
+     */
+    public String getMncode() {
+        return mncode;
+    }
+
+    /**
+     * 璁剧疆鐩戞祴璁惧缂栫爜
+     *
+     * @param mncode 鐩戞祴璁惧缂栫爜
+     */
+    public void setMncode(String mncode) {
+        this.mncode = mncode == null ? null : mncode.trim();
+    }
+
+    /**
+     * 鑾峰彇宸ョ▼鍚嶇О
+     *
+     * @return name - 宸ョ▼鍚嶇О
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * 璁剧疆宸ョ▼鍚嶇О
+     *
+     * @param name 宸ョ▼鍚嶇О
+     */
+    public void setName(String name) {
+        this.name = name == null ? null : name.trim();
+    }
+
+    /**
+     * 鑾峰彇鍣0鍊�
+     *
+     * @return noisevalue - 鍣0鍊�
+     */
+    public String getNoisevalue() {
+        return noisevalue;
+    }
+
+    /**
+     * 璁剧疆鍣0鍊�
+     *
+     * @param noisevalue 鍣0鍊�
+     */
+    public void setNoisevalue(String noisevalue) {
+        this.noisevalue = noisevalue == null ? null : noisevalue.trim();
+    }
+
+    /**
+     * 鑾峰彇宸ョ▼ID
+     *
+     * @return projectid - 宸ョ▼ID
+     */
+    public String getProjectid() {
+        return projectid;
+    }
+
+    /**
+     * 璁剧疆宸ョ▼ID
+     *
+     * @param projectid 宸ョ▼ID
+     */
+    public void setProjectid(String projectid) {
+        this.projectid = projectid == null ? null : projectid.trim();
+    }
+
+    /**
+     * 鑾峰彇宸ョ▼绫诲埆ID
+     *
+     * @return projecttypeid - 宸ョ▼绫诲埆ID
+     */
+    public String getProjecttypeid() {
+        return projecttypeid;
+    }
+
+    /**
+     * 璁剧疆宸ョ▼绫诲埆ID
+     *
+     * @param projecttypeid 宸ョ▼绫诲埆ID
+     */
+    public void setProjecttypeid(String projecttypeid) {
+        this.projecttypeid = projecttypeid == null ? null : projecttypeid.trim();
+    }
+
+    /**
+     * 鑾峰彇璐ㄩ噺
+     *
+     * @return quality - 璐ㄩ噺
+     */
+    public String getQuality() {
+        return quality;
+    }
+
+    /**
+     * 璁剧疆璐ㄩ噺
+     *
+     * @param quality 璐ㄩ噺
+     */
+    public void setQuality(String quality) {
+        this.quality = quality == null ? null : quality.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/IndustrialBaseInfo.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/IndustrialBaseInfo.java
new file mode 100644
index 0000000..dad4bf0
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/IndustrialBaseInfo.java
@@ -0,0 +1,234 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "ea_t_industrial_base_info")
+public class IndustrialBaseInfo  implements BaseSpecialInfo{
+    @Id
+    @Column(name = "IB_GUID")
+    private String ibGuid;
+
+    /**
+     * 浜х敓VOCs鐢熶骇宸ヨ壓
+     */
+    @Column(name = "IB_Production_Technique")
+    private String ibProductionTechnique;
+
+    /**
+     * 搴熸皵澶勭悊宸ヨ壓鍚嶇О
+     */
+    @Column(name = "IB_Waste_Gas_Technique")
+    private String ibWasteGasTechnique;
+
+    /**
+     * 搴熸皵澶勭悊鏈夋棤鐩戞帶鎺柦
+     */
+    @Column(name = "IB_Waste_Gas_Measure")
+    private String ibWasteGasMeasure;
+
+    /**
+     * 鏄惁閲囩敤鏇存崲寮忓惛闄勫鐞嗗伐鑹�
+     */
+    @Column(name = "IB_Has_Absorb_Technique")
+    private Boolean ibHasAbsorbTechnique;
+
+    /**
+     * 鍚搁檮鍓傚~鍏呴噺鏄惁绗﹀悎璁捐鏂囦欢
+     */
+    @Column(name = "IB_Adsorbent_Correct")
+    private Boolean ibAdsorbentCorrect;
+
+    /**
+     * 鍚搁檮鍓傛洿鎹㈠懆鏈熸槸鍚︾鍚堣璁℃枃浠�
+     */
+    @Column(name = "IB_Period_Correct")
+    private Boolean ibPeriodCorrect;
+
+    /**
+     * 鏄惁鏈夎喘涔板惛闄勫墏鍜屽簾鍚搁檮鍓傚鐞嗙殑鐩稿叧鍚堝悓銆佺エ鎹�
+     */
+    @Column(name = "IB_Has_Contract")
+    private Boolean ibHasContract;
+
+    /**
+     * 鐩稿叧鍚堝悓銆佺エ鎹槸鍚︿繚瀛�3骞�
+     */
+    @Column(name = "IB_Keep_Contract")
+    private Boolean ibKeepContract;
+
+    @Column(name = "IB_Create_Time")
+    private Date ibCreateTime;
+
+    /**
+     * @return IB_GUID
+     */
+    public String getIbGuid() {
+        return ibGuid;
+    }
+
+    /**
+     * @param ibGuid
+     */
+    public void setIbGuid(String ibGuid) {
+        this.ibGuid = ibGuid == null ? null : ibGuid.trim();
+    }
+
+    /**
+     * 鑾峰彇浜х敓VOCs鐢熶骇宸ヨ壓
+     *
+     * @return IB_Production_Technique - 浜х敓VOCs鐢熶骇宸ヨ壓
+     */
+    public String getIbProductionTechnique() {
+        return ibProductionTechnique;
+    }
+
+    /**
+     * 璁剧疆浜х敓VOCs鐢熶骇宸ヨ壓
+     *
+     * @param ibProductionTechnique 浜х敓VOCs鐢熶骇宸ヨ壓
+     */
+    public void setIbProductionTechnique(String ibProductionTechnique) {
+        this.ibProductionTechnique = ibProductionTechnique == null ? null : ibProductionTechnique.trim();
+    }
+
+    /**
+     * 鑾峰彇搴熸皵澶勭悊宸ヨ壓鍚嶇О
+     *
+     * @return IB_Waste_Gas_Technique - 搴熸皵澶勭悊宸ヨ壓鍚嶇О
+     */
+    public String getIbWasteGasTechnique() {
+        return ibWasteGasTechnique;
+    }
+
+    /**
+     * 璁剧疆搴熸皵澶勭悊宸ヨ壓鍚嶇О
+     *
+     * @param ibWasteGasTechnique 搴熸皵澶勭悊宸ヨ壓鍚嶇О
+     */
+    public void setIbWasteGasTechnique(String ibWasteGasTechnique) {
+        this.ibWasteGasTechnique = ibWasteGasTechnique == null ? null : ibWasteGasTechnique.trim();
+    }
+
+    /**
+     * 鑾峰彇搴熸皵澶勭悊鏈夋棤鐩戞帶鎺柦
+     *
+     * @return IB_Waste_Gas_Measure - 搴熸皵澶勭悊鏈夋棤鐩戞帶鎺柦
+     */
+    public String getIbWasteGasMeasure() {
+        return ibWasteGasMeasure;
+    }
+
+    /**
+     * 璁剧疆搴熸皵澶勭悊鏈夋棤鐩戞帶鎺柦
+     *
+     * @param ibWasteGasMeasure 搴熸皵澶勭悊鏈夋棤鐩戞帶鎺柦
+     */
+    public void setIbWasteGasMeasure(String ibWasteGasMeasure) {
+        this.ibWasteGasMeasure = ibWasteGasMeasure == null ? null : ibWasteGasMeasure.trim();
+    }
+
+    /**
+     * 鑾峰彇鏄惁閲囩敤鏇存崲寮忓惛闄勫鐞嗗伐鑹�
+     *
+     * @return IB_Has_Absorb_Technique - 鏄惁閲囩敤鏇存崲寮忓惛闄勫鐞嗗伐鑹�
+     */
+    public Boolean getIbHasAbsorbTechnique() {
+        return ibHasAbsorbTechnique;
+    }
+
+    /**
+     * 璁剧疆鏄惁閲囩敤鏇存崲寮忓惛闄勫鐞嗗伐鑹�
+     *
+     * @param ibHasAbsorbTechnique 鏄惁閲囩敤鏇存崲寮忓惛闄勫鐞嗗伐鑹�
+     */
+    public void setIbHasAbsorbTechnique(Boolean ibHasAbsorbTechnique) {
+        this.ibHasAbsorbTechnique = ibHasAbsorbTechnique;
+    }
+
+    /**
+     * 鑾峰彇鍚搁檮鍓傚~鍏呴噺鏄惁绗﹀悎璁捐鏂囦欢
+     *
+     * @return IB_Adsorbent_Correct - 鍚搁檮鍓傚~鍏呴噺鏄惁绗﹀悎璁捐鏂囦欢
+     */
+    public Boolean getIbAdsorbentCorrect() {
+        return ibAdsorbentCorrect;
+    }
+
+    /**
+     * 璁剧疆鍚搁檮鍓傚~鍏呴噺鏄惁绗﹀悎璁捐鏂囦欢
+     *
+     * @param ibAdsorbentCorrect 鍚搁檮鍓傚~鍏呴噺鏄惁绗﹀悎璁捐鏂囦欢
+     */
+    public void setIbAdsorbentCorrect(Boolean ibAdsorbentCorrect) {
+        this.ibAdsorbentCorrect = ibAdsorbentCorrect;
+    }
+
+    /**
+     * 鑾峰彇鍚搁檮鍓傛洿鎹㈠懆鏈熸槸鍚︾鍚堣璁℃枃浠�
+     *
+     * @return IB_Period_Correct - 鍚搁檮鍓傛洿鎹㈠懆鏈熸槸鍚︾鍚堣璁℃枃浠�
+     */
+    public Boolean getIbPeriodCorrect() {
+        return ibPeriodCorrect;
+    }
+
+    /**
+     * 璁剧疆鍚搁檮鍓傛洿鎹㈠懆鏈熸槸鍚︾鍚堣璁℃枃浠�
+     *
+     * @param ibPeriodCorrect 鍚搁檮鍓傛洿鎹㈠懆鏈熸槸鍚︾鍚堣璁℃枃浠�
+     */
+    public void setIbPeriodCorrect(Boolean ibPeriodCorrect) {
+        this.ibPeriodCorrect = ibPeriodCorrect;
+    }
+
+    /**
+     * 鑾峰彇鏄惁鏈夎喘涔板惛闄勫墏鍜屽簾鍚搁檮鍓傚鐞嗙殑鐩稿叧鍚堝悓銆佺エ鎹�
+     *
+     * @return IB_Has_Contract - 鏄惁鏈夎喘涔板惛闄勫墏鍜屽簾鍚搁檮鍓傚鐞嗙殑鐩稿叧鍚堝悓銆佺エ鎹�
+     */
+    public Boolean getIbHasContract() {
+        return ibHasContract;
+    }
+
+    /**
+     * 璁剧疆鏄惁鏈夎喘涔板惛闄勫墏鍜屽簾鍚搁檮鍓傚鐞嗙殑鐩稿叧鍚堝悓銆佺エ鎹�
+     *
+     * @param ibHasContract 鏄惁鏈夎喘涔板惛闄勫墏鍜屽簾鍚搁檮鍓傚鐞嗙殑鐩稿叧鍚堝悓銆佺エ鎹�
+     */
+    public void setIbHasContract(Boolean ibHasContract) {
+        this.ibHasContract = ibHasContract;
+    }
+
+    /**
+     * 鑾峰彇鐩稿叧鍚堝悓銆佺エ鎹槸鍚︿繚瀛�3骞�
+     *
+     * @return IB_Keep_Contract - 鐩稿叧鍚堝悓銆佺エ鎹槸鍚︿繚瀛�3骞�
+     */
+    public Boolean getIbKeepContract() {
+        return ibKeepContract;
+    }
+
+    /**
+     * 璁剧疆鐩稿叧鍚堝悓銆佺エ鎹槸鍚︿繚瀛�3骞�
+     *
+     * @param ibKeepContract 鐩稿叧鍚堝悓銆佺エ鎹槸鍚︿繚瀛�3骞�
+     */
+    public void setIbKeepContract(Boolean ibKeepContract) {
+        this.ibKeepContract = ibKeepContract;
+    }
+
+    /**
+     * @return IB_Create_Time
+     */
+    public Date getIbCreateTime() {
+        return ibCreateTime;
+    }
+
+    /**
+     * @param ibCreateTime
+     */
+    public void setIbCreateTime(Date ibCreateTime) {
+        this.ibCreateTime = ibCreateTime;
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Itemevaluation.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Itemevaluation.kt
index 5b3e046..89bd42f 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Itemevaluation.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Itemevaluation.kt
@@ -12,6 +12,9 @@
     @Column(name = "IE_GUID")
     var ieguid: String? = null
 
+    /**
+     * 鐢ㄦ埛id
+     */
     @Column(name = "I_GUID")
     var iguid: String? = null
 
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/LampDeviceData.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/LampDeviceData.java
new file mode 100644
index 0000000..2f60e08
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/LampDeviceData.java
@@ -0,0 +1,288 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "ja_t_lamp_device_data")
+public class LampDeviceData {
+    @Id
+    private Integer id;
+
+    /**
+     * 閫氶亾鍙�
+     */
+    @Column(name = "channel_num")
+    private String channelNum;
+
+    /**
+     * 娓呮磥搴�
+     */
+    @Column(name = "clean_liness")
+    private String cleanLiness;
+
+    /**
+     * 璁惧缂栧彿
+     */
+    @Column(name = "device_code")
+    private String deviceCode;
+
+    /**
+     * 璁惧鍚嶇О
+     */
+    @Column(name = "device_name")
+    private String deviceName;
+
+    /**
+     * 璁惧鐘舵��
+     */
+    @Column(name = "device_state")
+    private String deviceState;
+
+    /**
+     * 浼佷笟缂栧彿
+     */
+    @Column(name = "enter_id")
+    private String enterId;
+
+    /**
+     * 椋庢墖鐘舵��
+     */
+    @Column(name = "fan_state")
+    private String fanState;
+
+    /**
+     * 娌圭儫娴撳害
+     */
+    @Column(name = "lampblack_value")
+    private Double lampblackValue;
+
+    /**
+     * 鐩戞祴鏃堕棿
+     */
+    @Column(name = "monitor_time")
+    private Date monitorTime;
+
+    /**
+     * 鐢熶骇鏃堕棿
+     */
+    @Column(name = "production_date")
+    private Date productionDate;
+
+    /**
+     * 鍑�鍖栧櫒鐘舵��
+     */
+    @Column(name = "purifier_state")
+    private String purifierState;
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 鑾峰彇閫氶亾鍙�
+     *
+     * @return channel_num - 閫氶亾鍙�
+     */
+    public String getChannelNum() {
+        return channelNum;
+    }
+
+    /**
+     * 璁剧疆閫氶亾鍙�
+     *
+     * @param channelNum 閫氶亾鍙�
+     */
+    public void setChannelNum(String channelNum) {
+        this.channelNum = channelNum == null ? null : channelNum.trim();
+    }
+
+    /**
+     * 鑾峰彇娓呮磥搴�
+     *
+     * @return clean_liness - 娓呮磥搴�
+     */
+    public String getCleanLiness() {
+        return cleanLiness;
+    }
+
+    /**
+     * 璁剧疆娓呮磥搴�
+     *
+     * @param cleanLiness 娓呮磥搴�
+     */
+    public void setCleanLiness(String cleanLiness) {
+        this.cleanLiness = cleanLiness == null ? null : cleanLiness.trim();
+    }
+
+    /**
+     * 鑾峰彇璁惧缂栧彿
+     *
+     * @return device_code - 璁惧缂栧彿
+     */
+    public String getDeviceCode() {
+        return deviceCode;
+    }
+
+    /**
+     * 璁剧疆璁惧缂栧彿
+     *
+     * @param deviceCode 璁惧缂栧彿
+     */
+    public void setDeviceCode(String deviceCode) {
+        this.deviceCode = deviceCode == null ? null : deviceCode.trim();
+    }
+
+    /**
+     * 鑾峰彇璁惧鍚嶇О
+     *
+     * @return device_name - 璁惧鍚嶇О
+     */
+    public String getDeviceName() {
+        return deviceName;
+    }
+
+    /**
+     * 璁剧疆璁惧鍚嶇О
+     *
+     * @param deviceName 璁惧鍚嶇О
+     */
+    public void setDeviceName(String deviceName) {
+        this.deviceName = deviceName == null ? null : deviceName.trim();
+    }
+
+    /**
+     * 鑾峰彇璁惧鐘舵��
+     *
+     * @return device_state - 璁惧鐘舵��
+     */
+    public String getDeviceState() {
+        return deviceState;
+    }
+
+    /**
+     * 璁剧疆璁惧鐘舵��
+     *
+     * @param deviceState 璁惧鐘舵��
+     */
+    public void setDeviceState(String deviceState) {
+        this.deviceState = deviceState == null ? null : deviceState.trim();
+    }
+
+    /**
+     * 鑾峰彇浼佷笟缂栧彿
+     *
+     * @return enter_id - 浼佷笟缂栧彿
+     */
+    public String getEnterId() {
+        return enterId;
+    }
+
+    /**
+     * 璁剧疆浼佷笟缂栧彿
+     *
+     * @param enterId 浼佷笟缂栧彿
+     */
+    public void setEnterId(String enterId) {
+        this.enterId = enterId == null ? null : enterId.trim();
+    }
+
+    /**
+     * 鑾峰彇椋庢墖鐘舵��
+     *
+     * @return fan_state - 椋庢墖鐘舵��
+     */
+    public String getFanState() {
+        return fanState;
+    }
+
+    /**
+     * 璁剧疆椋庢墖鐘舵��
+     *
+     * @param fanState 椋庢墖鐘舵��
+     */
+    public void setFanState(String fanState) {
+        this.fanState = fanState == null ? null : fanState.trim();
+    }
+
+    /**
+     * 鑾峰彇娌圭儫娴撳害
+     *
+     * @return lampblack_value - 娌圭儫娴撳害
+     */
+    public Double getLampblackValue() {
+        return lampblackValue;
+    }
+
+    /**
+     * 璁剧疆娌圭儫娴撳害
+     *
+     * @param lampblackValue 娌圭儫娴撳害
+     */
+    public void setLampblackValue(Double lampblackValue) {
+        this.lampblackValue = lampblackValue;
+    }
+
+    /**
+     * 鑾峰彇鐩戞祴鏃堕棿
+     *
+     * @return monitor_time - 鐩戞祴鏃堕棿
+     */
+    public Date getMonitorTime() {
+        return monitorTime;
+    }
+
+    /**
+     * 璁剧疆鐩戞祴鏃堕棿
+     *
+     * @param monitorTime 鐩戞祴鏃堕棿
+     */
+    public void setMonitorTime(Date monitorTime) {
+        this.monitorTime = monitorTime;
+    }
+
+    /**
+     * 鑾峰彇鐢熶骇鏃堕棿
+     *
+     * @return production_date - 鐢熶骇鏃堕棿
+     */
+    public Date getProductionDate() {
+        return productionDate;
+    }
+
+    /**
+     * 璁剧疆鐢熶骇鏃堕棿
+     *
+     * @param productionDate 鐢熶骇鏃堕棿
+     */
+    public void setProductionDate(Date productionDate) {
+        this.productionDate = productionDate;
+    }
+
+    /**
+     * 鑾峰彇鍑�鍖栧櫒鐘舵��
+     *
+     * @return purifier_state - 鍑�鍖栧櫒鐘舵��
+     */
+    public String getPurifierState() {
+        return purifierState;
+    }
+
+    /**
+     * 璁剧疆鍑�鍖栧櫒鐘舵��
+     *
+     * @param purifierState 鍑�鍖栧櫒鐘舵��
+     */
+    public void setPurifierState(String purifierState) {
+        this.purifierState = purifierState == null ? null : purifierState.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/LampEnterBaseInfo.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/LampEnterBaseInfo.java
new file mode 100644
index 0000000..39bcfe2
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/LampEnterBaseInfo.java
@@ -0,0 +1,375 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "ja_t_lamp_enter_base_info")
+public class LampEnterBaseInfo {
+    /**
+     * 浼佷笟缂栫爜
+     */
+    @Id
+    @Column(name = "enter_id")
+    private String enterId;
+
+    /**
+     * 浼佷笟鍚嶇О
+     */
+    @Column(name = "enter_name")
+    private String enterName;
+
+    /**
+     * 浼佷笟鍦板潃
+     */
+    private String address;
+
+    /**
+     * 钀ヤ笟鏃堕棿
+     */
+    @Column(name = "business_date")
+    private String businessDate;
+
+    /**
+     * 鏁版嵁婧�
+     */
+    private String datasource;
+
+    /**
+     * 闆嗚仛鍖虹紪鐮�
+     */
+    @Column(name = "jjq_code")
+    private String jjqCode;
+
+    /**
+     * 闆嗚仛鍖哄悕绉�
+     */
+    @Column(name = "jjq_name")
+    private String jjqName;
+
+    /**
+     * 绾害
+     */
+    private Double latitude;
+
+    /**
+     * 鑱旂郴浜�
+     */
+    @Column(name = "link_man")
+    private String linkMan;
+
+    /**
+     * 鑱旂郴鐢佃瘽
+     */
+    @Column(name = "link_phone")
+    private String linkPhone;
+
+    /**
+     * 缁忓害
+     */
+    private Double longitude;
+
+    /**
+     * 琛屾斂鍖哄悕绉�
+     */
+    @Column(name = "region_name")
+    private String regionName;
+
+    /**
+     * 娉ㄥ唽鏃堕棿
+     */
+    @Column(name = "regist_date")
+    private Date registDate;
+
+    /**
+     * 鐘舵��
+     */
+    private String state;
+
+    /**
+     * 鎵�灞炶閬�
+     */
+    private String street;
+
+    /**
+     * 鎺掑彛绫诲瀷
+     */
+    private String outfallType;
+
+    /**
+     * 鑾峰彇浼佷笟缂栫爜
+     *
+     * @return enter_id - 浼佷笟缂栫爜
+     */
+    public String getEnterId() {
+        return enterId;
+    }
+
+    /**
+     * 璁剧疆浼佷笟缂栫爜
+     *
+     * @param enterId 浼佷笟缂栫爜
+     */
+    public void setEnterId(String enterId) {
+        this.enterId = enterId == null ? null : enterId.trim();
+    }
+
+    /**
+     * 鑾峰彇浼佷笟鍚嶇О
+     *
+     * @return enter_name - 浼佷笟鍚嶇О
+     */
+    public String getEnterName() {
+        return enterName;
+    }
+
+    /**
+     * 璁剧疆浼佷笟鍚嶇О
+     *
+     * @param enterName 浼佷笟鍚嶇О
+     */
+    public void setEnterName(String enterName) {
+        this.enterName = enterName == null ? null : enterName.trim();
+    }
+
+    /**
+     * 鑾峰彇浼佷笟鍦板潃
+     *
+     * @return address - 浼佷笟鍦板潃
+     */
+    public String getAddress() {
+        return address;
+    }
+
+    /**
+     * 璁剧疆浼佷笟鍦板潃
+     *
+     * @param address 浼佷笟鍦板潃
+     */
+    public void setAddress(String address) {
+        this.address = address == null ? null : address.trim();
+    }
+
+    /**
+     * 鑾峰彇钀ヤ笟鏃堕棿
+     *
+     * @return business_date - 钀ヤ笟鏃堕棿
+     */
+    public String getBusinessDate() {
+        return businessDate;
+    }
+
+    /**
+     * 璁剧疆钀ヤ笟鏃堕棿
+     *
+     * @param businessDate 钀ヤ笟鏃堕棿
+     */
+    public void setBusinessDate(String businessDate) {
+        this.businessDate = businessDate == null ? null : businessDate.trim();
+    }
+
+    /**
+     * 鑾峰彇鏁版嵁婧�
+     *
+     * @return datasource - 鏁版嵁婧�
+     */
+    public String getDatasource() {
+        return datasource;
+    }
+
+    /**
+     * 璁剧疆鏁版嵁婧�
+     *
+     * @param datasource 鏁版嵁婧�
+     */
+    public void setDatasource(String datasource) {
+        this.datasource = datasource == null ? null : datasource.trim();
+    }
+
+    /**
+     * 鑾峰彇闆嗚仛鍖虹紪鐮�
+     *
+     * @return jjq_code - 闆嗚仛鍖虹紪鐮�
+     */
+    public String getJjqCode() {
+        return jjqCode;
+    }
+
+    /**
+     * 璁剧疆闆嗚仛鍖虹紪鐮�
+     *
+     * @param jjqCode 闆嗚仛鍖虹紪鐮�
+     */
+    public void setJjqCode(String jjqCode) {
+        this.jjqCode = jjqCode == null ? null : jjqCode.trim();
+    }
+
+    /**
+     * 鑾峰彇闆嗚仛鍖哄悕绉�
+     *
+     * @return jjq_name - 闆嗚仛鍖哄悕绉�
+     */
+    public String getJjqName() {
+        return jjqName;
+    }
+
+    /**
+     * 璁剧疆闆嗚仛鍖哄悕绉�
+     *
+     * @param jjqName 闆嗚仛鍖哄悕绉�
+     */
+    public void setJjqName(String jjqName) {
+        this.jjqName = jjqName == null ? null : jjqName.trim();
+    }
+
+    /**
+     * 鑾峰彇绾害
+     *
+     * @return latitude - 绾害
+     */
+    public Double getLatitude() {
+        return latitude;
+    }
+
+    /**
+     * 璁剧疆绾害
+     *
+     * @param latitude 绾害
+     */
+    public void setLatitude(Double latitude) {
+        this.latitude = latitude;
+    }
+
+    /**
+     * 鑾峰彇鑱旂郴浜�
+     *
+     * @return link_man - 鑱旂郴浜�
+     */
+    public String getLinkMan() {
+        return linkMan;
+    }
+
+    /**
+     * 璁剧疆鑱旂郴浜�
+     *
+     * @param linkMan 鑱旂郴浜�
+     */
+    public void setLinkMan(String linkMan) {
+        this.linkMan = linkMan == null ? null : linkMan.trim();
+    }
+
+    /**
+     * 鑾峰彇鑱旂郴鐢佃瘽
+     *
+     * @return link_phone - 鑱旂郴鐢佃瘽
+     */
+    public String getLinkPhone() {
+        return linkPhone;
+    }
+
+    /**
+     * 璁剧疆鑱旂郴鐢佃瘽
+     *
+     * @param linkPhone 鑱旂郴鐢佃瘽
+     */
+    public void setLinkPhone(String linkPhone) {
+        this.linkPhone = linkPhone == null ? null : linkPhone.trim();
+    }
+
+    /**
+     * 鑾峰彇缁忓害
+     *
+     * @return longitude - 缁忓害
+     */
+    public Double getLongitude() {
+        return longitude;
+    }
+
+    /**
+     * 璁剧疆缁忓害
+     *
+     * @param longitude 缁忓害
+     */
+    public void setLongitude(Double longitude) {
+        this.longitude = longitude;
+    }
+
+    /**
+     * 鑾峰彇琛屾斂鍖哄悕绉�
+     *
+     * @return region_name - 琛屾斂鍖哄悕绉�
+     */
+    public String getRegionName() {
+        return regionName;
+    }
+
+    /**
+     * 璁剧疆琛屾斂鍖哄悕绉�
+     *
+     * @param regionName 琛屾斂鍖哄悕绉�
+     */
+    public void setRegionName(String regionName) {
+        this.regionName = regionName == null ? null : regionName.trim();
+    }
+
+    /**
+     * 鑾峰彇娉ㄥ唽鏃堕棿
+     *
+     * @return regist_date - 娉ㄥ唽鏃堕棿
+     */
+    public Date getRegistDate() {
+        return registDate;
+    }
+
+    /**
+     * 璁剧疆娉ㄥ唽鏃堕棿
+     *
+     * @param registDate 娉ㄥ唽鏃堕棿
+     */
+    public void setRegistDate(Date registDate) {
+        this.registDate = registDate;
+    }
+
+    /**
+     * 鑾峰彇鐘舵��
+     *
+     * @return state - 鐘舵��
+     */
+    public String getState() {
+        return state;
+    }
+
+    /**
+     * 璁剧疆鐘舵��
+     *
+     * @param state 鐘舵��
+     */
+    public void setState(String state) {
+        this.state = state == null ? null : state.trim();
+    }
+
+    /**
+     * 鑾峰彇鎵�灞炶閬�
+     *
+     * @return street - 鎵�灞炶閬�
+     */
+    public String getStreet() {
+        return street;
+    }
+
+    /**
+     * 璁剧疆鎵�灞炶閬�
+     *
+     * @param street 鎵�灞炶閬�
+     */
+    public void setStreet(String street) {
+        this.street = street == null ? null : street.trim();
+    }
+
+    public String getOutfallType() {
+        return outfallType;
+    }
+
+    public void setOutfallType(String outfallType) {
+        this.outfallType = outfallType;
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/LedgerSubType.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/LedgerSubType.java
index 871d948..90b90bf 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/LedgerSubType.java
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/LedgerSubType.java
@@ -42,6 +42,30 @@
     private Boolean lRealTime;
 
     /**
+     * 鍙板笎鏄惁鑷姩澶嶅埗
+     */
+    @Column(name = "L_Auto_Copy")
+    private Boolean lAutoCopy;
+
+    /**
+     * 鍙板笎瑙i噴
+     */
+    @Column(name = "L_Description")
+    private String lDescription;
+
+    /**
+     * 寮�鍏宠绫诲彴甯愭槸鍚﹀厑璁哥敤鎴烽�夋嫨涓嶆秹鍙婁笉涓婁紶
+     */
+    @Column(name = "L_Not_Related_Switch")
+    private Boolean lNotRelatedSwitch;
+
+    /**
+     * 鏄惁鍏佽璇ョ被鍙板笎鍚屼竴鏈熸彁浜ゅ缁勮褰�(鏌愪簺鍙板笎鍙兘鍑虹幇鍚屼竴绫诲埆澶氬浣嶇疆)
+     */
+    @Column(name = "L_Multi_Group")
+    private Boolean lMultiGroup;
+
+    /**
      * @return LS_SubTypeId
      */
     public Integer getLsSubtypeid() {
@@ -178,4 +202,76 @@
     public void setlRealTime(Boolean lRealTime) {
         this.lRealTime = lRealTime;
     }
+
+    /**
+     * 鑾峰彇鍙板笎鏄惁鑷姩澶嶅埗
+     *
+     * @return L_Auto_Copy - 鍙板笎鏄惁鑷姩澶嶅埗
+     */
+    public Boolean getlAutoCopy() {
+        return lAutoCopy;
+    }
+
+    /**
+     * 璁剧疆鍙板笎鏄惁鑷姩澶嶅埗
+     *
+     * @param lAutoCopy 鍙板笎鏄惁鑷姩澶嶅埗
+     */
+    public void setlAutoCopy(Boolean lAutoCopy) {
+        this.lAutoCopy = lAutoCopy;
+    }
+
+    /**
+     * 鑾峰彇鍙板笎瑙i噴
+     *
+     * @return L_Description - 鍙板笎瑙i噴
+     */
+    public String getlDescription() {
+        return lDescription;
+    }
+
+    /**
+     * 璁剧疆鍙板笎瑙i噴
+     *
+     * @param lDescription 鍙板笎瑙i噴
+     */
+    public void setlDescription(String lDescription) {
+        this.lDescription = lDescription == null ? null : lDescription.trim();
+    }
+
+    /**
+     * 鑾峰彇寮�鍏宠绫诲彴甯愭槸鍚﹀厑璁哥敤鎴烽�夋嫨涓嶆秹鍙婁笉涓婁紶
+     *
+     * @return L_Not_Related_Switch - 寮�鍏宠绫诲彴甯愭槸鍚﹀厑璁哥敤鎴烽�夋嫨涓嶆秹鍙婁笉涓婁紶
+     */
+    public Boolean getlNotRelatedSwitch() {
+        return lNotRelatedSwitch;
+    }
+
+    /**
+     * 璁剧疆寮�鍏宠绫诲彴甯愭槸鍚﹀厑璁哥敤鎴烽�夋嫨涓嶆秹鍙婁笉涓婁紶
+     *
+     * @param lNotRelatedSwitch 寮�鍏宠绫诲彴甯愭槸鍚﹀厑璁哥敤鎴烽�夋嫨涓嶆秹鍙婁笉涓婁紶
+     */
+    public void setlNotRelatedSwitch(Boolean lNotRelatedSwitch) {
+        this.lNotRelatedSwitch = lNotRelatedSwitch;
+    }
+
+    /**
+     * 鑾峰彇鏄惁鍏佽璇ョ被鍙板笎鍚屼竴鏈熸彁浜ゅ缁勮褰�(鏌愪簺鍙板笎鍙兘鍑虹幇鍚屼竴绫诲埆澶氬浣嶇疆)
+     *
+     * @return L_Multi_Group - 鏄惁鍏佽璇ョ被鍙板笎鍚屼竴鏈熸彁浜ゅ缁勮褰�(鏌愪簺鍙板笎鍙兘鍑虹幇鍚屼竴绫诲埆澶氬浣嶇疆)
+     */
+    public Boolean getlMultiGroup() {
+        return lMultiGroup;
+    }
+
+    /**
+     * 璁剧疆鏄惁鍏佽璇ョ被鍙板笎鍚屼竴鏈熸彁浜ゅ缁勮褰�(鏌愪簺鍙板笎鍙兘鍑虹幇鍚屼竴绫诲埆澶氬浣嶇疆)
+     *
+     * @param lMultiGroup 鏄惁鍏佽璇ョ被鍙板笎鍚屼竴鏈熸彁浜ゅ缁勮褰�(鏌愪簺鍙板笎鍙兘鍑虹幇鍚屼竴绫诲埆澶氬浣嶇疆)
+     */
+    public void setlMultiGroup(Boolean lMultiGroup) {
+        this.lMultiGroup = lMultiGroup;
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/NoticeConfig.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/NoticeConfig.kt
new file mode 100644
index 0000000..406f1bc
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/NoticeConfig.kt
@@ -0,0 +1,7 @@
+package cn.flightfeather.supervision.domain.entity
+
+class NoticeConfig {
+    val ecNoticetype: Int? = null
+
+    var ecNoticesubtype: Int? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/NoticeTemplate.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/NoticeTemplate.java
new file mode 100644
index 0000000..4c109f4
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/NoticeTemplate.java
@@ -0,0 +1,126 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import javax.persistence.*;
+
+@Table(name = "ec_t_notice_template")
+public class NoticeTemplate {
+    @Id
+    @Column(name = "NT_ID")
+    private Integer ntId;
+
+    @Column(name = "NT_Notice_Type")
+    private Integer ntNoticeType;
+
+    @Column(name = "NT_Notice_Type_Name")
+    private String ntNoticeTypeName;
+
+    @Column(name = "NT_Notice_Sub_Type")
+    private Integer ntNoticeSubType;
+
+    @Column(name = "NT_Notice_Sub_Type_Name")
+    private String ntNoticeSubTypeName;
+
+    @Column(name = "NT_Notice_Title")
+    private String ntNoticeTitle;
+
+    @Column(name = "NT_Notice_Template")
+    private String ntNoticeTemplate;
+
+    /**
+     * @return NT_ID
+     */
+    public Integer getNtId() {
+        return ntId;
+    }
+
+    /**
+     * @param ntId
+     */
+    public void setNtId(Integer ntId) {
+        this.ntId = ntId;
+    }
+
+    /**
+     * @return NT_Notice_Type
+     */
+    public Integer getNtNoticeType() {
+        return ntNoticeType;
+    }
+
+    /**
+     * @param ntNoticeType
+     */
+    public void setNtNoticeType(Integer ntNoticeType) {
+        this.ntNoticeType = ntNoticeType;
+    }
+
+    /**
+     * @return NT_Notice_Type_Name
+     */
+    public String getNtNoticeTypeName() {
+        return ntNoticeTypeName;
+    }
+
+    /**
+     * @param ntNoticeTypeName
+     */
+    public void setNtNoticeTypeName(String ntNoticeTypeName) {
+        this.ntNoticeTypeName = ntNoticeTypeName == null ? null : ntNoticeTypeName.trim();
+    }
+
+    /**
+     * @return NT_Notice_Sub_Type
+     */
+    public Integer getNtNoticeSubType() {
+        return ntNoticeSubType;
+    }
+
+    /**
+     * @param ntNoticeSubType
+     */
+    public void setNtNoticeSubType(Integer ntNoticeSubType) {
+        this.ntNoticeSubType = ntNoticeSubType;
+    }
+
+    /**
+     * @return NT_Notice_Sub_Type_Name
+     */
+    public String getNtNoticeSubTypeName() {
+        return ntNoticeSubTypeName;
+    }
+
+    /**
+     * @param ntNoticeSubTypeName
+     */
+    public void setNtNoticeSubTypeName(String ntNoticeSubTypeName) {
+        this.ntNoticeSubTypeName = ntNoticeSubTypeName == null ? null : ntNoticeSubTypeName.trim();
+    }
+
+    /**
+     * @return NT_Notice_Title
+     */
+    public String getNtNoticeTitle() {
+        return ntNoticeTitle;
+    }
+
+    /**
+     * @param ntNoticeTitle
+     */
+    public void setNtNoticeTitle(String ntNoticeTitle) {
+        this.ntNoticeTitle = ntNoticeTitle == null ? null : ntNoticeTitle.trim();
+    }
+
+    /**
+     * @return NT_Notice_Template
+     */
+    public String getNtNoticeTemplate() {
+        return ntNoticeTemplate;
+    }
+
+    /**
+     * @param ntNoticeTemplate
+     */
+    public void setNtNoticeTemplate(String ntNoticeTemplate) {
+        this.ntNoticeTemplate = ntNoticeTemplate == null ? null : ntNoticeTemplate.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/OverallEvaluation.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/OverallEvaluation.java
index 632fde8..4f8d316 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/OverallEvaluation.java
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/OverallEvaluation.java
@@ -9,53 +9,41 @@
     @Column(name = "OE_GUID")
     private Integer oeGuid;
 
-    /**
-     * 浼佷笟id
-     */
     @Column(name = "BI_GUID")
     private String biGuid;
 
-    /**
-     * 鏈�缁堣瘎鍒�
-     */
     @Column(name = "OE_Score")
     private Integer oeScore;
 
-    /**
-     * 鍙戝竷鏃堕棿
-     */
     @Column(name = "OE_Publish_Time")
     private Date oePublishTime;
 
-    /**
-     * 鏇存柊鏃堕棿
-     */
     @Column(name = "OE_Update_Time")
     private Date oeUpdateTime;
 
-    /**
-     * 浼佷笟绫诲瀷id
-     */
     @Column(name = "OE_Scene_Type_Id")
     private Byte oeSceneTypeId;
 
-    /**
-     * 浼佷笟绫诲瀷鍚嶇О
-     */
     @Column(name = "OE_Scene_Type")
     private String oeSceneType;
 
-    /**
-     * 璇勫垎鍛ㄦ湡锛孻YYY/M-M锛屾煇骞存煇鏈堣嚦鏌愭湀
-     */
     @Column(name = "OE_Period")
     private String oePeriod;
 
-    /**
-     * 鐜俊鐮佽瘎浼扮瓑绾э紝0: 缁跨爜锛�1: 榛勭爜锛�2: 绾㈢爜
-     */
     @Column(name = "OE_Code_Level")
     private Byte oeCodeLevel;
+
+    /**
+     * 鐢熸晥寮�濮嬫椂闂�
+     */
+    @Column(name = "OE_Start_Time")
+    private Date oeStartTime;
+
+    /**
+     * 鐢熸晥缁撴潫鏃堕棿
+     */
+    @Column(name = "OE_End_Time")
+    private Date oeEndTime;
 
     /**
      * @return OE_GUID
@@ -72,146 +60,150 @@
     }
 
     /**
-     * 鑾峰彇浼佷笟id
-     *
-     * @return CI_GUID - 浼佷笟id
+     * @return BI_GUID
      */
     public String getBiGuid() {
         return biGuid;
     }
 
     /**
-     * 璁剧疆浼佷笟id
-     *
-     * @param biGuid 浼佷笟id
+     * @param biGuid
      */
     public void setBiGuid(String biGuid) {
         this.biGuid = biGuid == null ? null : biGuid.trim();
     }
 
     /**
-     * 鑾峰彇鏈�缁堣瘎鍒�
-     *
-     * @return OE_Score - 鏈�缁堣瘎鍒�
+     * @return OE_Score
      */
     public Integer getOeScore() {
         return oeScore;
     }
 
     /**
-     * 璁剧疆鏈�缁堣瘎鍒�
-     *
-     * @param oeScore 鏈�缁堣瘎鍒�
+     * @param oeScore
      */
     public void setOeScore(Integer oeScore) {
         this.oeScore = oeScore;
     }
 
     /**
-     * 鑾峰彇鍙戝竷鏃堕棿
-     *
-     * @return OE_Publish_Time - 鍙戝竷鏃堕棿
+     * @return OE_Publish_Time
      */
     public Date getOePublishTime() {
         return oePublishTime;
     }
 
     /**
-     * 璁剧疆鍙戝竷鏃堕棿
-     *
-     * @param oePublishTime 鍙戝竷鏃堕棿
+     * @param oePublishTime
      */
     public void setOePublishTime(Date oePublishTime) {
         this.oePublishTime = oePublishTime;
     }
 
     /**
-     * 鑾峰彇鏇存柊鏃堕棿
-     *
-     * @return OE_Update_Time - 鏇存柊鏃堕棿
+     * @return OE_Update_Time
      */
     public Date getOeUpdateTime() {
         return oeUpdateTime;
     }
 
     /**
-     * 璁剧疆鏇存柊鏃堕棿
-     *
-     * @param oeUpdateTime 鏇存柊鏃堕棿
+     * @param oeUpdateTime
      */
     public void setOeUpdateTime(Date oeUpdateTime) {
         this.oeUpdateTime = oeUpdateTime;
     }
 
     /**
-     * 鑾峰彇浼佷笟绫诲瀷id
-     *
-     * @return OE_Scene_Type_Id - 浼佷笟绫诲瀷id
+     * @return OE_Scene_Type_Id
      */
     public Byte getOeSceneTypeId() {
         return oeSceneTypeId;
     }
 
     /**
-     * 璁剧疆浼佷笟绫诲瀷id
-     *
-     * @param oeSceneTypeId 浼佷笟绫诲瀷id
+     * @param oeSceneTypeId
      */
     public void setOeSceneTypeId(Byte oeSceneTypeId) {
         this.oeSceneTypeId = oeSceneTypeId;
     }
 
     /**
-     * 鑾峰彇浼佷笟绫诲瀷鍚嶇О
-     *
-     * @return OE_Scene_Type - 浼佷笟绫诲瀷鍚嶇О
+     * @return OE_Scene_Type
      */
     public String getOeSceneType() {
         return oeSceneType;
     }
 
     /**
-     * 璁剧疆浼佷笟绫诲瀷鍚嶇О
-     *
-     * @param oeSceneType 浼佷笟绫诲瀷鍚嶇О
+     * @param oeSceneType
      */
     public void setOeSceneType(String oeSceneType) {
         this.oeSceneType = oeSceneType == null ? null : oeSceneType.trim();
     }
 
     /**
-     * 鑾峰彇璇勫垎鍛ㄦ湡锛孻YYY/M-M锛屾煇骞存煇鏈堣嚦鏌愭湀
-     *
-     * @return OE_Period - 璇勫垎鍛ㄦ湡锛孻YYY/M-M锛屾煇骞存煇鏈堣嚦鏌愭湀
+     * @return OE_Period
      */
     public String getOePeriod() {
         return oePeriod;
     }
 
     /**
-     * 璁剧疆璇勫垎鍛ㄦ湡锛孻YYY/M-M锛屾煇骞存煇鏈堣嚦鏌愭湀
-     *
-     * @param oePeriod 璇勫垎鍛ㄦ湡锛孻YYY/M-M锛屾煇骞存煇鏈堣嚦鏌愭湀
+     * @param oePeriod
      */
     public void setOePeriod(String oePeriod) {
         this.oePeriod = oePeriod == null ? null : oePeriod.trim();
     }
 
     /**
-     * 鑾峰彇鐜俊鐮佽瘎浼扮瓑绾э紝0: 缁跨爜锛�1: 榛勭爜锛�2: 绾㈢爜
-     *
-     * @return OE_Code_Level - 鐜俊鐮佽瘎浼扮瓑绾э紝0: 缁跨爜锛�1: 榛勭爜锛�2: 绾㈢爜
+     * @return OE_Code_Level
      */
     public Byte getOeCodeLevel() {
         return oeCodeLevel;
     }
 
     /**
-     * 璁剧疆鐜俊鐮佽瘎浼扮瓑绾э紝0: 缁跨爜锛�1: 榛勭爜锛�2: 绾㈢爜
-     *
-     * @param oeCodeLevel 鐜俊鐮佽瘎浼扮瓑绾э紝0: 缁跨爜锛�1: 榛勭爜锛�2: 绾㈢爜
+     * @param oeCodeLevel
      */
     public void setOeCodeLevel(Byte oeCodeLevel) {
         this.oeCodeLevel = oeCodeLevel;
     }
+
+    /**
+     * 鑾峰彇鐢熸晥寮�濮嬫椂闂�
+     *
+     * @return RE_Start_Time - 鐢熸晥寮�濮嬫椂闂�
+     */
+    public Date getOeStartTime() {
+        return oeStartTime;
+    }
+
+    /**
+     * 璁剧疆鐢熸晥寮�濮嬫椂闂�
+     *
+     * @param oeStartTime 鐢熸晥寮�濮嬫椂闂�
+     */
+    public void setOeStartTime(Date oeStartTime) {
+        this.oeStartTime = oeStartTime;
+    }
+
+    /**
+     * 鑾峰彇鐢熸晥缁撴潫鏃堕棿
+     *
+     * @return RE_End_Time - 鐢熸晥缁撴潫鏃堕棿
+     */
+    public Date getOeEndTime() {
+        return oeEndTime;
+    }
+
+    /**
+     * 璁剧疆鐢熸晥缁撴潫鏃堕棿
+     *
+     * @param oeEndTime 鐢熸晥缁撴潫鏃堕棿
+     */
+    public void setOeEndTime(Date oeEndTime) {
+        this.oeEndTime = oeEndTime;
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/PersonalInfo.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/PersonalInfo.java
index 291f278..2de8a5d 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/PersonalInfo.java
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/PersonalInfo.java
@@ -47,6 +47,15 @@
     @Column(name = "PI_Position")
     private String piPosition;
 
+    /**
+     * 寰俊id
+     */
+    @Column(name = "PI_Wx_Id")
+    private String piWxId;
+
+    @Column(name = "PI_Scene_Id")
+    private String piSceneId;
+
     @Column(name = "PI_Extension1")
     private String piExtension1;
 
@@ -186,6 +195,38 @@
     }
 
     /**
+     * 鑾峰彇寰俊id
+     *
+     * @return PI_Wx_Id - 寰俊id
+     */
+    public String getPiWxId() {
+        return piWxId;
+    }
+
+    /**
+     * 璁剧疆寰俊id
+     *
+     * @param piWxId 寰俊id
+     */
+    public void setPiWxId(String piWxId) {
+        this.piWxId = piWxId == null ? null : piWxId.trim();
+    }
+
+    /**
+     * @return PI_Scene_Id
+     */
+    public String getPiSceneId() {
+        return piSceneId;
+    }
+
+    /**
+     * @param piSceneId
+     */
+    public void setPiSceneId(String piSceneId) {
+        this.piSceneId = piSceneId == null ? null : piSceneId.trim();
+    }
+
+    /**
      * @return PI_Extension1
      */
     public String getPiExtension1() {
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/PracticalOperation.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/PracticalOperation.java
new file mode 100644
index 0000000..bc0673a
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/PracticalOperation.java
@@ -0,0 +1,408 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import javax.persistence.*;
+
+@Table(name = "ea_t_practical_operation")
+public class PracticalOperation {
+    @Id
+    @Column(name = "PO_ID")
+    private Integer poId;
+
+    /**
+     * 鏉垮潡鍚嶇О锛堥粯璁よ澶囪繍琛岋級
+     */
+    @Column(name = "PO_Module_Name")
+    private String poModuleName;
+
+    /**
+     * 澶х被id
+     */
+    @Column(name = "PO_Type_Id")
+    private Integer poTypeId;
+
+    /**
+     * 澶х被鍚嶇О
+     */
+    @Column(name = "PO_Type_Name")
+    private String poTypeName;
+
+    /**
+     * 灏忕被id
+     */
+    @Column(name = "PO_Sub_Type_Id")
+    private Integer poSubTypeId;
+
+    /**
+     * 灏忕被鍚嶇О
+     */
+    @Column(name = "PO_Sub_Type_Name")
+    private String poSubTypeName;
+
+    /**
+     * 鏍囬
+     */
+    @Column(name = "PO_Title")
+    private String poTitle;
+
+    /**
+     * 鍐呭
+     */
+    @Column(name = "PO_Content")
+    private String poContent;
+
+    /**
+     * 璁惧缂栧彿锛堢敤 ; 鍒嗛殧锛�
+     */
+    @Column(name = "PO_Device_Code")
+    private String poDeviceCode;
+
+    /**
+     * 浜嬪姟鐘舵�佸彇鍊艰寖鍥磇d
+     */
+    @Column(name = "PO_State_Range_Id")
+    private String poStateRangeId;
+
+    /**
+     * 浜嬪姟鐘舵�佸彇鍊艰寖鍥磇d
+     */
+    @Column(name = "PO_State_Range")
+    private String poStateRange;
+
+    /**
+     * 浜嬪姟鍚勭姸鎬佺殑鎻愰啋淇℃伅鍙栧�艰寖鍥�
+     */
+    @Column(name = "PO_State_Remind_Range")
+    private String poStateRemindRange;
+
+    /**
+     * 浜嬪姟鐘舵�佺殑鍙樺寲瑙勫垯锛�0锛氱姸鎬佹湁鍏堝悗椤哄簭锛岄�愮骇鍙樺寲锛�1锛氱姸鎬佷负骞宠鐘舵�侊紝鏃犲厛鍚庨『搴忥級
+     */
+    @Column(name = "PO_State_Rule")
+    private Integer poStateRule;
+
+    /**
+     * 浜嬪姟瀵瑰簲鐨勯渶鑷姩鐢熸垚鐨勫彴璐︾被鍨媔d
+     */
+    @Column(name = "PO_Ledger_Type_Id")
+    private Integer poLedgerTypeId;
+
+    /**
+     * 鐢熸垚鐨勫彴甯愬悕绉�
+     */
+    @Column(name = "PO_Ledger_Type_Name")
+    private String poLedgerTypeName;
+
+    /**
+     * 褰掑睘鐨勭敤鎴烽厤缃紪鍙�
+     */
+    @Column(name = "PO_User_Config_Id")
+    private Integer poUserConfigId;
+
+    /**
+     * 褰掑睘鐨勭敤鎴穒d
+     */
+    @Column(name = "PO_User_Id")
+    private String poUserId;
+
+    /**
+     * @return PO_ID
+     */
+    public Integer getPoId() {
+        return poId;
+    }
+
+    /**
+     * @param poId
+     */
+    public void setPoId(Integer poId) {
+        this.poId = poId;
+    }
+
+    /**
+     * 鑾峰彇鏉垮潡鍚嶇О锛堥粯璁よ澶囪繍琛岋級
+     *
+     * @return PO_Module_Name - 鏉垮潡鍚嶇О锛堥粯璁よ澶囪繍琛岋級
+     */
+    public String getPoModuleName() {
+        return poModuleName;
+    }
+
+    /**
+     * 璁剧疆鏉垮潡鍚嶇О锛堥粯璁よ澶囪繍琛岋級
+     *
+     * @param poModuleName 鏉垮潡鍚嶇О锛堥粯璁よ澶囪繍琛岋級
+     */
+    public void setPoModuleName(String poModuleName) {
+        this.poModuleName = poModuleName == null ? null : poModuleName.trim();
+    }
+
+    /**
+     * 鑾峰彇澶х被id
+     *
+     * @return PO_Type_Id - 澶х被id
+     */
+    public Integer getPoTypeId() {
+        return poTypeId;
+    }
+
+    /**
+     * 璁剧疆澶х被id
+     *
+     * @param poTypeId 澶х被id
+     */
+    public void setPoTypeId(Integer poTypeId) {
+        this.poTypeId = poTypeId;
+    }
+
+    /**
+     * 鑾峰彇澶х被鍚嶇О
+     *
+     * @return PO_Type_Name - 澶х被鍚嶇О
+     */
+    public String getPoTypeName() {
+        return poTypeName;
+    }
+
+    /**
+     * 璁剧疆澶х被鍚嶇О
+     *
+     * @param poTypeName 澶х被鍚嶇О
+     */
+    public void setPoTypeName(String poTypeName) {
+        this.poTypeName = poTypeName == null ? null : poTypeName.trim();
+    }
+
+    /**
+     * 鑾峰彇灏忕被id
+     *
+     * @return PO_Sub_Type_Id - 灏忕被id
+     */
+    public Integer getPoSubTypeId() {
+        return poSubTypeId;
+    }
+
+    /**
+     * 璁剧疆灏忕被id
+     *
+     * @param poSubTypeId 灏忕被id
+     */
+    public void setPoSubTypeId(Integer poSubTypeId) {
+        this.poSubTypeId = poSubTypeId;
+    }
+
+    /**
+     * 鑾峰彇灏忕被鍚嶇О
+     *
+     * @return PO_Sub_Type_Name - 灏忕被鍚嶇О
+     */
+    public String getPoSubTypeName() {
+        return poSubTypeName;
+    }
+
+    /**
+     * 璁剧疆灏忕被鍚嶇О
+     *
+     * @param poSubTypeName 灏忕被鍚嶇О
+     */
+    public void setPoSubTypeName(String poSubTypeName) {
+        this.poSubTypeName = poSubTypeName == null ? null : poSubTypeName.trim();
+    }
+
+    /**
+     * 鑾峰彇鏍囬
+     *
+     * @return PO_Title - 鏍囬
+     */
+    public String getPoTitle() {
+        return poTitle;
+    }
+
+    /**
+     * 璁剧疆鏍囬
+     *
+     * @param poTitle 鏍囬
+     */
+    public void setPoTitle(String poTitle) {
+        this.poTitle = poTitle == null ? null : poTitle.trim();
+    }
+
+    /**
+     * 鑾峰彇鍐呭
+     *
+     * @return PO_Content - 鍐呭
+     */
+    public String getPoContent() {
+        return poContent;
+    }
+
+    /**
+     * 璁剧疆鍐呭
+     *
+     * @param poContent 鍐呭
+     */
+    public void setPoContent(String poContent) {
+        this.poContent = poContent == null ? null : poContent.trim();
+    }
+
+    /**
+     * 鑾峰彇璁惧缂栧彿锛堢敤 ; 鍒嗛殧锛�
+     *
+     * @return PO_Device_Code - 璁惧缂栧彿锛堢敤 ; 鍒嗛殧锛�
+     */
+    public String getPoDeviceCode() {
+        return poDeviceCode;
+    }
+
+    /**
+     * 璁剧疆璁惧缂栧彿锛堢敤 ; 鍒嗛殧锛�
+     *
+     * @param poDeviceCode 璁惧缂栧彿锛堢敤 ; 鍒嗛殧锛�
+     */
+    public void setPoDeviceCode(String poDeviceCode) {
+        this.poDeviceCode = poDeviceCode == null ? null : poDeviceCode.trim();
+    }
+
+    /**
+     * 鑾峰彇浜嬪姟鐘舵�佸彇鍊艰寖鍥磇d
+     *
+     * @return PO_State_Range_Id - 浜嬪姟鐘舵�佸彇鍊艰寖鍥磇d
+     */
+    public String getPoStateRangeId() {
+        return poStateRangeId;
+    }
+
+    /**
+     * 璁剧疆浜嬪姟鐘舵�佸彇鍊艰寖鍥磇d
+     *
+     * @param poStateRangeId 浜嬪姟鐘舵�佸彇鍊艰寖鍥磇d
+     */
+    public void setPoStateRangeId(String poStateRangeId) {
+        this.poStateRangeId = poStateRangeId == null ? null : poStateRangeId.trim();
+    }
+
+    /**
+     * 鑾峰彇浜嬪姟鐘舵�佸彇鍊艰寖鍥磇d
+     *
+     * @return PO_State_Range - 浜嬪姟鐘舵�佸彇鍊艰寖鍥磇d
+     */
+    public String getPoStateRange() {
+        return poStateRange;
+    }
+
+    /**
+     * 璁剧疆浜嬪姟鐘舵�佸彇鍊艰寖鍥磇d
+     *
+     * @param poStateRange 浜嬪姟鐘舵�佸彇鍊艰寖鍥磇d
+     */
+    public void setPoStateRange(String poStateRange) {
+        this.poStateRange = poStateRange == null ? null : poStateRange.trim();
+    }
+
+    /**
+     * 鑾峰彇浜嬪姟鍚勭姸鎬佺殑鎻愰啋淇℃伅鍙栧�艰寖鍥�
+     *
+     * @return PO_State_Remind_Range - 浜嬪姟鍚勭姸鎬佺殑鎻愰啋淇℃伅鍙栧�艰寖鍥�
+     */
+    public String getPoStateRemindRange() {
+        return poStateRemindRange;
+    }
+
+    /**
+     * 璁剧疆浜嬪姟鍚勭姸鎬佺殑鎻愰啋淇℃伅鍙栧�艰寖鍥�
+     *
+     * @param poStateRemindRange 浜嬪姟鍚勭姸鎬佺殑鎻愰啋淇℃伅鍙栧�艰寖鍥�
+     */
+    public void setPoStateRemindRange(String poStateRemindRange) {
+        this.poStateRemindRange = poStateRemindRange == null ? null : poStateRemindRange.trim();
+    }
+
+    /**
+     * 鑾峰彇浜嬪姟鐘舵�佺殑鍙樺寲瑙勫垯锛�0锛氱姸鎬佹湁鍏堝悗椤哄簭锛岄�愮骇鍙樺寲锛�1锛氱姸鎬佷负骞宠鐘舵�侊紝鏃犲厛鍚庨『搴忥級
+     *
+     * @return PO_State_Rule - 浜嬪姟鐘舵�佺殑鍙樺寲瑙勫垯锛�0锛氱姸鎬佹湁鍏堝悗椤哄簭锛岄�愮骇鍙樺寲锛�1锛氱姸鎬佷负骞宠鐘舵�侊紝鏃犲厛鍚庨『搴忥級
+     */
+    public Integer getPoStateRule() {
+        return poStateRule;
+    }
+
+    /**
+     * 璁剧疆浜嬪姟鐘舵�佺殑鍙樺寲瑙勫垯锛�0锛氱姸鎬佹湁鍏堝悗椤哄簭锛岄�愮骇鍙樺寲锛�1锛氱姸鎬佷负骞宠鐘舵�侊紝鏃犲厛鍚庨『搴忥級
+     *
+     * @param poStateRule 浜嬪姟鐘舵�佺殑鍙樺寲瑙勫垯锛�0锛氱姸鎬佹湁鍏堝悗椤哄簭锛岄�愮骇鍙樺寲锛�1锛氱姸鎬佷负骞宠鐘舵�侊紝鏃犲厛鍚庨『搴忥級
+     */
+    public void setPoStateRule(Integer poStateRule) {
+        this.poStateRule = poStateRule;
+    }
+
+    /**
+     * 鑾峰彇浜嬪姟瀵瑰簲鐨勯渶鑷姩鐢熸垚鐨勫彴璐︾被鍨媔d
+     *
+     * @return PO_Ledger_Type_Id - 浜嬪姟瀵瑰簲鐨勯渶鑷姩鐢熸垚鐨勫彴璐︾被鍨媔d
+     */
+    public Integer getPoLedgerTypeId() {
+        return poLedgerTypeId;
+    }
+
+    /**
+     * 璁剧疆浜嬪姟瀵瑰簲鐨勯渶鑷姩鐢熸垚鐨勫彴璐︾被鍨媔d
+     *
+     * @param poLedgerTypeId 浜嬪姟瀵瑰簲鐨勯渶鑷姩鐢熸垚鐨勫彴璐︾被鍨媔d
+     */
+    public void setPoLedgerTypeId(Integer poLedgerTypeId) {
+        this.poLedgerTypeId = poLedgerTypeId;
+    }
+
+    /**
+     * 鑾峰彇鐢熸垚鐨勫彴甯愬悕绉�
+     *
+     * @return PO_Ledger_Type_Name - 鐢熸垚鐨勫彴甯愬悕绉�
+     */
+    public String getPoLedgerTypeName() {
+        return poLedgerTypeName;
+    }
+
+    /**
+     * 璁剧疆鐢熸垚鐨勫彴甯愬悕绉�
+     *
+     * @param poLedgerTypeName 鐢熸垚鐨勫彴甯愬悕绉�
+     */
+    public void setPoLedgerTypeName(String poLedgerTypeName) {
+        this.poLedgerTypeName = poLedgerTypeName == null ? null : poLedgerTypeName.trim();
+    }
+
+    /**
+     * 鑾峰彇褰掑睘鐨勭敤鎴烽厤缃紪鍙�
+     *
+     * @return PO_User_Config_Id - 褰掑睘鐨勭敤鎴烽厤缃紪鍙�
+     */
+    public Integer getPoUserConfigId() {
+        return poUserConfigId;
+    }
+
+    /**
+     * 璁剧疆褰掑睘鐨勭敤鎴烽厤缃紪鍙�
+     *
+     * @param poUserConfigId 褰掑睘鐨勭敤鎴烽厤缃紪鍙�
+     */
+    public void setPoUserConfigId(Integer poUserConfigId) {
+        this.poUserConfigId = poUserConfigId;
+    }
+
+    /**
+     * 鑾峰彇褰掑睘鐨勭敤鎴穒d
+     *
+     * @return PO_User_Id - 褰掑睘鐨勭敤鎴穒d
+     */
+    public String getPoUserId() {
+        return poUserId;
+    }
+
+    /**
+     * 璁剧疆褰掑睘鐨勭敤鎴穒d
+     *
+     * @param poUserId 褰掑睘鐨勭敤鎴穒d
+     */
+    public void setPoUserId(String poUserId) {
+        this.poUserId = poUserId == null ? null : poUserId.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/PracticalOperationRecord.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/PracticalOperationRecord.java
new file mode 100644
index 0000000..97dec17
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/PracticalOperationRecord.java
@@ -0,0 +1,217 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "ea_t_practical_operation_record")
+public class PracticalOperationRecord {
+    @Id
+    @Column(name = "PR_Id")
+    private Integer prId;
+
+    /**
+     * 瀹炴搷鏉$洰鐨刬d
+     */
+    @Column(name = "PO_Id")
+    private Integer poId;
+
+    /**
+     * 瀹炴搷鏉$洰鏍囬
+     */
+    @Column(name = "PO_Title")
+    private String poTitle;
+
+    /**
+     * 鎵ц瀹炴搷鐨勭敤鎴穒d
+     */
+    @Column(name = "PR_User_Id")
+    private String prUserId;
+
+    /**
+     * 鎵ц瀹炴搷鐨勭敤鎴峰悕绉�
+     */
+    @Column(name = "PR_User_Name")
+    private String prUserName;
+
+    /**
+     * 鍦烘櫙绫诲瀷
+     */
+    @Column(name = "PR_User_Scene_Type")
+    private Integer prUserSceneType;
+
+    /**
+     * 瀹炴搷鎵ц鏃堕棿
+     */
+    @Column(name = "PR_Time")
+    private Date prTime;
+
+    /**
+     * 鎵ц缁撴灉鐨勭姸鎬乮d
+     */
+    @Column(name = "PR_State_Id")
+    private String prStateId;
+
+    /**
+     * 鎵ц缁撴灉鐨勭姸鎬佸悕绉�
+     */
+    @Column(name = "PR_State_Name")
+    private String prStateName;
+
+    /**
+     * @return PR_Id
+     */
+    public Integer getPrId() {
+        return prId;
+    }
+
+    /**
+     * @param prId
+     */
+    public void setPrId(Integer prId) {
+        this.prId = prId;
+    }
+
+    /**
+     * 鑾峰彇瀹炴搷鏉$洰鐨刬d
+     *
+     * @return PO_Id - 瀹炴搷鏉$洰鐨刬d
+     */
+    public Integer getPoId() {
+        return poId;
+    }
+
+    /**
+     * 璁剧疆瀹炴搷鏉$洰鐨刬d
+     *
+     * @param poId 瀹炴搷鏉$洰鐨刬d
+     */
+    public void setPoId(Integer poId) {
+        this.poId = poId;
+    }
+
+    /**
+     * 鑾峰彇瀹炴搷鏉$洰鏍囬
+     *
+     * @return PO_Title - 瀹炴搷鏉$洰鏍囬
+     */
+    public String getPoTitle() {
+        return poTitle;
+    }
+
+    /**
+     * 璁剧疆瀹炴搷鏉$洰鏍囬
+     *
+     * @param poTitle 瀹炴搷鏉$洰鏍囬
+     */
+    public void setPoTitle(String poTitle) {
+        this.poTitle = poTitle == null ? null : poTitle.trim();
+    }
+
+    /**
+     * 鑾峰彇鎵ц瀹炴搷鐨勭敤鎴穒d
+     *
+     * @return PR_User_Id - 鎵ц瀹炴搷鐨勭敤鎴穒d
+     */
+    public String getPrUserId() {
+        return prUserId;
+    }
+
+    /**
+     * 璁剧疆鎵ц瀹炴搷鐨勭敤鎴穒d
+     *
+     * @param prUserId 鎵ц瀹炴搷鐨勭敤鎴穒d
+     */
+    public void setPrUserId(String prUserId) {
+        this.prUserId = prUserId == null ? null : prUserId.trim();
+    }
+
+    /**
+     * 鑾峰彇鎵ц瀹炴搷鐨勭敤鎴峰悕绉�
+     *
+     * @return PR_User_Name - 鎵ц瀹炴搷鐨勭敤鎴峰悕绉�
+     */
+    public String getPrUserName() {
+        return prUserName;
+    }
+
+    /**
+     * 璁剧疆鎵ц瀹炴搷鐨勭敤鎴峰悕绉�
+     *
+     * @param prUserName 鎵ц瀹炴搷鐨勭敤鎴峰悕绉�
+     */
+    public void setPrUserName(String prUserName) {
+        this.prUserName = prUserName == null ? null : prUserName.trim();
+    }
+
+    /**
+     * 鑾峰彇鍦烘櫙绫诲瀷
+     *
+     * @return PR_User_Scene_Type - 鍦烘櫙绫诲瀷
+     */
+    public Integer getPrUserSceneType() {
+        return prUserSceneType;
+    }
+
+    /**
+     * 璁剧疆鍦烘櫙绫诲瀷
+     *
+     * @param prUserSceneType 鍦烘櫙绫诲瀷
+     */
+    public void setPrUserSceneType(Integer prUserSceneType) {
+        this.prUserSceneType = prUserSceneType;
+    }
+
+    /**
+     * 鑾峰彇瀹炴搷鎵ц鏃堕棿
+     *
+     * @return PR_Time - 瀹炴搷鎵ц鏃堕棿
+     */
+    public Date getPrTime() {
+        return prTime;
+    }
+
+    /**
+     * 璁剧疆瀹炴搷鎵ц鏃堕棿
+     *
+     * @param prTime 瀹炴搷鎵ц鏃堕棿
+     */
+    public void setPrTime(Date prTime) {
+        this.prTime = prTime;
+    }
+
+    /**
+     * 鑾峰彇鎵ц缁撴灉鐨勭姸鎬乮d
+     *
+     * @return PR_State_Id - 鎵ц缁撴灉鐨勭姸鎬乮d
+     */
+    public String getPrStateId() {
+        return prStateId;
+    }
+
+    /**
+     * 璁剧疆鎵ц缁撴灉鐨勭姸鎬乮d
+     *
+     * @param prStateId 鎵ц缁撴灉鐨勭姸鎬乮d
+     */
+    public void setPrStateId(String prStateId) {
+        this.prStateId = prStateId == null ? null : prStateId.trim();
+    }
+
+    /**
+     * 鑾峰彇鎵ц缁撴灉鐨勭姸鎬佸悕绉�
+     *
+     * @return PR_State_Name - 鎵ц缁撴灉鐨勭姸鎬佸悕绉�
+     */
+    public String getPrStateName() {
+        return prStateName;
+    }
+
+    /**
+     * 璁剧疆鎵ц缁撴灉鐨勭姸鎬佸悕绉�
+     *
+     * @param prStateName 鎵ц缁撴灉鐨勭姸鎬佸悕绉�
+     */
+    public void setPrStateName(String prStateName) {
+        this.prStateName = prStateName == null ? null : prStateName.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Province.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Province.java
new file mode 100644
index 0000000..d75fc41
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Province.java
@@ -0,0 +1,58 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import javax.persistence.*;
+
+@Table(name = "sm_t_province")
+public class Province {
+    @Id
+    @Column(name = "P_ProvinceID")
+    private Integer pProvinceid;
+
+    @Column(name = "P_ProvinceCode")
+    private String pProvincecode;
+
+    @Column(name = "P_ProvinceName")
+    private String pProvincename;
+
+    /**
+     * @return P_ProvinceID
+     */
+    public Integer getpProvinceid() {
+        return pProvinceid;
+    }
+
+    /**
+     * @param pProvinceid
+     */
+    public void setpProvinceid(Integer pProvinceid) {
+        this.pProvinceid = pProvinceid;
+    }
+
+    /**
+     * @return P_ProvinceCode
+     */
+    public String getpProvincecode() {
+        return pProvincecode;
+    }
+
+    /**
+     * @param pProvincecode
+     */
+    public void setpProvincecode(String pProvincecode) {
+        this.pProvincecode = pProvincecode == null ? null : pProvincecode.trim();
+    }
+
+    /**
+     * @return P_ProvinceName
+     */
+    public String getpProvincename() {
+        return pProvincename;
+    }
+
+    /**
+     * @param pProvincename
+     */
+    public void setpProvincename(String pProvincename) {
+        this.pProvincename = pProvincename == null ? null : pProvincename.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/RiskEvaluation.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/RiskEvaluation.java
new file mode 100644
index 0000000..0a2e31d
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/RiskEvaluation.java
@@ -0,0 +1,241 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "ea_t_risk_evaluation")
+public class RiskEvaluation {
+    @Id
+    @Column(name = "RE_ID")
+    private Integer reId;
+
+    /**
+     * 鐢ㄦ埛id
+     */
+    @Column(name = "BI_GUID")
+    private String biGuid;
+
+    /**
+     * 椋庨櫓绛夌骇锛�0锛氫綆椋庨櫓锛�1锛氫腑椋庨櫓锛�2锛氶珮椋庨櫓
+     */
+    @Column(name = "RE_Risk_Level")
+    private Integer reRiskLevel;
+
+    /**
+     * 鍙戝竷鏃堕棿
+     */
+    @Column(name = "RE_Publish_Time")
+    private Date rePublishTime;
+
+    /**
+     * 鍦烘櫙绫诲瀷id
+     */
+    @Column(name = "RE_Scene_Type_Id")
+    private Integer reSceneTypeId;
+
+    /**
+     * 鍦烘櫙绫诲瀷
+     */
+    @Column(name = "RE_Scene_Type")
+    private String reSceneType;
+
+    /**
+     * 鍛ㄦ湡
+     */
+    @Column(name = "RE_Period")
+    private String rePeriod;
+
+    /**
+     * 鐢熸晥寮�濮嬫椂闂�
+     */
+    @Column(name = "RE_Start_Time")
+    private Date reStartTime;
+
+    /**
+     * 鐢熸晥缁撴潫鏃堕棿
+     */
+    @Column(name = "RE_End_Time")
+    private Date reEndTime;
+
+    /**
+     * 椋庨櫓璇勪及鎬荤粨
+     */
+    @Column(name = "RE_Summary")
+    private String reSummary;
+
+    /**
+     * @return RE_ID
+     */
+    public Integer getReId() {
+        return reId;
+    }
+
+    /**
+     * @param reId
+     */
+    public void setReId(Integer reId) {
+        this.reId = reId;
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛id
+     *
+     * @return BI_GUID - 鐢ㄦ埛id
+     */
+    public String getBiGuid() {
+        return biGuid;
+    }
+
+    /**
+     * 璁剧疆鐢ㄦ埛id
+     *
+     * @param biGuid 鐢ㄦ埛id
+     */
+    public void setBiGuid(String biGuid) {
+        this.biGuid = biGuid == null ? null : biGuid.trim();
+    }
+
+    /**
+     * 鑾峰彇椋庨櫓绛夌骇锛�0锛氫綆椋庨櫓锛�1锛氫腑椋庨櫓锛�2锛氶珮椋庨櫓
+     *
+     * @return RE_Risk_Level - 椋庨櫓绛夌骇锛�0锛氫綆椋庨櫓锛�1锛氫腑椋庨櫓锛�2锛氶珮椋庨櫓
+     */
+    public Integer getReRiskLevel() {
+        return reRiskLevel;
+    }
+
+    /**
+     * 璁剧疆椋庨櫓绛夌骇锛�0锛氫綆椋庨櫓锛�1锛氫腑椋庨櫓锛�2锛氶珮椋庨櫓
+     *
+     * @param reRiskLevel 椋庨櫓绛夌骇锛�0锛氫綆椋庨櫓锛�1锛氫腑椋庨櫓锛�2锛氶珮椋庨櫓
+     */
+    public void setReRiskLevel(Integer reRiskLevel) {
+        this.reRiskLevel = reRiskLevel;
+    }
+
+    /**
+     * 鑾峰彇鍙戝竷鏃堕棿
+     *
+     * @return RE_Publish_Time - 鍙戝竷鏃堕棿
+     */
+    public Date getRePublishTime() {
+        return rePublishTime;
+    }
+
+    /**
+     * 璁剧疆鍙戝竷鏃堕棿
+     *
+     * @param rePublishTime 鍙戝竷鏃堕棿
+     */
+    public void setRePublishTime(Date rePublishTime) {
+        this.rePublishTime = rePublishTime;
+    }
+
+    /**
+     * 鑾峰彇鍦烘櫙绫诲瀷id
+     *
+     * @return RE_Scene_Type_Id - 鍦烘櫙绫诲瀷id
+     */
+    public Integer getReSceneTypeId() {
+        return reSceneTypeId;
+    }
+
+    /**
+     * 璁剧疆鍦烘櫙绫诲瀷id
+     *
+     * @param reSceneTypeId 鍦烘櫙绫诲瀷id
+     */
+    public void setReSceneTypeId(Integer reSceneTypeId) {
+        this.reSceneTypeId = reSceneTypeId;
+    }
+
+    /**
+     * 鑾峰彇鍦烘櫙绫诲瀷
+     *
+     * @return RE_Scene_Type - 鍦烘櫙绫诲瀷
+     */
+    public String getReSceneType() {
+        return reSceneType;
+    }
+
+    /**
+     * 璁剧疆鍦烘櫙绫诲瀷
+     *
+     * @param reSceneType 鍦烘櫙绫诲瀷
+     */
+    public void setReSceneType(String reSceneType) {
+        this.reSceneType = reSceneType == null ? null : reSceneType.trim();
+    }
+
+    /**
+     * 鑾峰彇鍛ㄦ湡
+     *
+     * @return RE_Period - 鍛ㄦ湡
+     */
+    public String getRePeriod() {
+        return rePeriod;
+    }
+
+    /**
+     * 璁剧疆鍛ㄦ湡
+     *
+     * @param rePeriod 鍛ㄦ湡
+     */
+    public void setRePeriod(String rePeriod) {
+        this.rePeriod = rePeriod == null ? null : rePeriod.trim();
+    }
+
+    /**
+     * 鑾峰彇鐢熸晥寮�濮嬫椂闂�
+     *
+     * @return RE_Start_Time - 鐢熸晥寮�濮嬫椂闂�
+     */
+    public Date getReStartTime() {
+        return reStartTime;
+    }
+
+    /**
+     * 璁剧疆鐢熸晥寮�濮嬫椂闂�
+     *
+     * @param reStartTime 鐢熸晥寮�濮嬫椂闂�
+     */
+    public void setReStartTime(Date reStartTime) {
+        this.reStartTime = reStartTime;
+    }
+
+    /**
+     * 鑾峰彇鐢熸晥缁撴潫鏃堕棿
+     *
+     * @return RE_End_Time - 鐢熸晥缁撴潫鏃堕棿
+     */
+    public Date getReEndTime() {
+        return reEndTime;
+    }
+
+    /**
+     * 璁剧疆鐢熸晥缁撴潫鏃堕棿
+     *
+     * @param reEndTime 鐢熸晥缁撴潫鏃堕棿
+     */
+    public void setReEndTime(Date reEndTime) {
+        this.reEndTime = reEndTime;
+    }
+
+    /**
+     * 鑾峰彇椋庨櫓璇勪及鎬荤粨
+     *
+     * @return RE_Summary - 椋庨櫓璇勪及鎬荤粨
+     */
+    public String getReSummary() {
+        return reSummary;
+    }
+
+    /**
+     * 璁剧疆椋庨櫓璇勪及鎬荤粨
+     *
+     * @param reSummary 椋庨櫓璇勪及鎬荤粨
+     */
+    public void setReSummary(String reSummary) {
+        this.reSummary = reSummary == null ? null : reSummary.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/SceneType.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/SceneType.java
new file mode 100644
index 0000000..5798d67
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/SceneType.java
@@ -0,0 +1,58 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import javax.persistence.*;
+
+@Table(name = "ea_t_scene_type")
+public class SceneType {
+    @Id
+    @Column(name = "SC_Id")
+    private Integer scId;
+
+    @Column(name = "SC_Name")
+    private String scName;
+
+    @Column(name = "SC_Tag")
+    private String scTag;
+
+    /**
+     * @return SC_Id
+     */
+    public Integer getScId() {
+        return scId;
+    }
+
+    /**
+     * @param scId
+     */
+    public void setScId(Integer scId) {
+        this.scId = scId;
+    }
+
+    /**
+     * @return SC_Name
+     */
+    public String getScName() {
+        return scName;
+    }
+
+    /**
+     * @param scName
+     */
+    public void setScName(String scName) {
+        this.scName = scName == null ? null : scName.trim();
+    }
+
+    /**
+     * @return SC_Tag
+     */
+    public String getScTag() {
+        return scTag;
+    }
+
+    /**
+     * @param scTag
+     */
+    public void setScTag(String scTag) {
+        this.scTag = scTag == null ? null : scTag.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/ScheduleSignRecord.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/ScheduleSignRecord.java
new file mode 100644
index 0000000..9036d65
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/ScheduleSignRecord.java
@@ -0,0 +1,121 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "ea_t_schedule_sign_record")
+public class ScheduleSignRecord {
+    @Id
+    @Column(name = "SR_ID")
+    private Integer srId;
+
+    /**
+     * 鏃ョ▼id
+     */
+    @Column(name = "SR_Schedule_Id")
+    private Integer srScheduleId;
+
+    /**
+     * 绛炬敹鐢ㄦ埛id
+     */
+    @Column(name = "SR_User_ID")
+    private String srUserId;
+
+    /**
+     * 绛炬敹鐘舵��
+     */
+    @Column(name = "SR_Sign_Status")
+    private Boolean srSignStatus;
+
+    /**
+     * 绛炬敹鏃堕棿
+     */
+    @Column(name = "SR_Sign_Time")
+    private Date srSignTime;
+
+    /**
+     * @return SR_ID
+     */
+    public Integer getSrId() {
+        return srId;
+    }
+
+    /**
+     * @param srId
+     */
+    public void setSrId(Integer srId) {
+        this.srId = srId;
+    }
+
+    /**
+     * 鑾峰彇鏃ョ▼id
+     *
+     * @return SR_Schedule_Id - 鏃ョ▼id
+     */
+    public Integer getSrScheduleId() {
+        return srScheduleId;
+    }
+
+    /**
+     * 璁剧疆鏃ョ▼id
+     *
+     * @param srScheduleId 鏃ョ▼id
+     */
+    public void setSrScheduleId(Integer srScheduleId) {
+        this.srScheduleId = srScheduleId;
+    }
+
+    /**
+     * 鑾峰彇绛炬敹鐢ㄦ埛id
+     *
+     * @return SR_User_ID - 绛炬敹鐢ㄦ埛id
+     */
+    public String getSrUserId() {
+        return srUserId;
+    }
+
+    /**
+     * 璁剧疆绛炬敹鐢ㄦ埛id
+     *
+     * @param srUserId 绛炬敹鐢ㄦ埛id
+     */
+    public void setSrUserId(String srUserId) {
+        this.srUserId = srUserId == null ? null : srUserId.trim();
+    }
+
+    /**
+     * 鑾峰彇绛炬敹鐘舵��
+     *
+     * @return SR_Sign_Status - 绛炬敹鐘舵��
+     */
+    public Boolean getSrSignStatus() {
+        return srSignStatus;
+    }
+
+    /**
+     * 璁剧疆绛炬敹鐘舵��
+     *
+     * @param srSignStatus 绛炬敹鐘舵��
+     */
+    public void setSrSignStatus(Boolean srSignStatus) {
+        this.srSignStatus = srSignStatus;
+    }
+
+    /**
+     * 鑾峰彇绛炬敹鏃堕棿
+     *
+     * @return SR_Sign_Time - 绛炬敹鏃堕棿
+     */
+    public Date getSrSignTime() {
+        return srSignTime;
+    }
+
+    /**
+     * 璁剧疆绛炬敹鏃堕棿
+     *
+     * @param srSignTime 绛炬敹鏃堕棿
+     */
+    public void setSrSignTime(Date srSignTime) {
+        this.srSignTime = srSignTime;
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/SelfPatrolMediaFile.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/SelfPatrolMediaFile.java
new file mode 100644
index 0000000..e3573ea
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/SelfPatrolMediaFile.java
@@ -0,0 +1,253 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "ea_t_self_patrol_media_file")
+public class SelfPatrolMediaFile {
+    @Id
+    @Column(name = "MF_GUID")
+    private String mfGuid;
+
+    @Column(name = "LR_GUID")
+    private String lrGuid;
+
+    @Column(name = "CI_GUID")
+    private String ciGuid;
+
+    /**
+     * 1锛氬浘鐗囷紱2锛氳棰戯紱3锛氶煶棰�
+     */
+    @Column(name = "MF_FileType")
+    private Integer mfFiletype;
+
+    @Column(name = "MF_SaveTime")
+    private Date mfSavetime;
+
+    @Column(name = "MF_IsDelete")
+    private Boolean mfIsdelete;
+
+    @Column(name = "MF_Extension1")
+    private String mfExtension1;
+
+    @Column(name = "MF_Extension2")
+    private String mfExtension2;
+
+    @Column(name = "MF_Extension3")
+    private String mfExtension3;
+
+    @Column(name = "MF_Remark")
+    private String mfRemark;
+
+    @Column(name = "MF_Path1")
+    private String mfPath1;
+
+    @Column(name = "MF_Description1")
+    private String mfDescription1;
+
+    @Column(name = "MF_Path2")
+    private String mfPath2;
+
+    @Column(name = "MF_Description2")
+    private String mfDescription2;
+
+    /**
+     * @return MF_GUID
+     */
+    public String getMfGuid() {
+        return mfGuid;
+    }
+
+    /**
+     * @param mfGuid
+     */
+    public void setMfGuid(String mfGuid) {
+        this.mfGuid = mfGuid == null ? null : mfGuid.trim();
+    }
+
+    /**
+     * @return LR_GUID
+     */
+    public String getLrGuid() {
+        return lrGuid;
+    }
+
+    /**
+     * @param lrGuid
+     */
+    public void setLrGuid(String lrGuid) {
+        this.lrGuid = lrGuid == null ? null : lrGuid.trim();
+    }
+
+    /**
+     * @return CI_GUID
+     */
+    public String getCiGuid() {
+        return ciGuid;
+    }
+
+    /**
+     * @param ciGuid
+     */
+    public void setCiGuid(String ciGuid) {
+        this.ciGuid = ciGuid == null ? null : ciGuid.trim();
+    }
+
+    /**
+     * 鑾峰彇1锛氬浘鐗囷紱2锛氳棰戯紱3锛氶煶棰�
+     *
+     * @return MF_FileType - 1锛氬浘鐗囷紱2锛氳棰戯紱3锛氶煶棰�
+     */
+    public Integer getMfFiletype() {
+        return mfFiletype;
+    }
+
+    /**
+     * 璁剧疆1锛氬浘鐗囷紱2锛氳棰戯紱3锛氶煶棰�
+     *
+     * @param mfFiletype 1锛氬浘鐗囷紱2锛氳棰戯紱3锛氶煶棰�
+     */
+    public void setMfFiletype(Integer mfFiletype) {
+        this.mfFiletype = mfFiletype;
+    }
+
+    /**
+     * @return MF_SaveTime
+     */
+    public Date getMfSavetime() {
+        return mfSavetime;
+    }
+
+    /**
+     * @param mfSavetime
+     */
+    public void setMfSavetime(Date mfSavetime) {
+        this.mfSavetime = mfSavetime;
+    }
+
+    /**
+     * @return MF_IsDelete
+     */
+    public Boolean getMfIsdelete() {
+        return mfIsdelete;
+    }
+
+    /**
+     * @param mfIsdelete
+     */
+    public void setMfIsdelete(Boolean mfIsdelete) {
+        this.mfIsdelete = mfIsdelete;
+    }
+
+    /**
+     * @return MF_Extension1
+     */
+    public String getMfExtension1() {
+        return mfExtension1;
+    }
+
+    /**
+     * @param mfExtension1
+     */
+    public void setMfExtension1(String mfExtension1) {
+        this.mfExtension1 = mfExtension1 == null ? null : mfExtension1.trim();
+    }
+
+    /**
+     * @return MF_Extension2
+     */
+    public String getMfExtension2() {
+        return mfExtension2;
+    }
+
+    /**
+     * @param mfExtension2
+     */
+    public void setMfExtension2(String mfExtension2) {
+        this.mfExtension2 = mfExtension2 == null ? null : mfExtension2.trim();
+    }
+
+    /**
+     * @return MF_Extension3
+     */
+    public String getMfExtension3() {
+        return mfExtension3;
+    }
+
+    /**
+     * @param mfExtension3
+     */
+    public void setMfExtension3(String mfExtension3) {
+        this.mfExtension3 = mfExtension3 == null ? null : mfExtension3.trim();
+    }
+
+    /**
+     * @return MF_Remark
+     */
+    public String getMfRemark() {
+        return mfRemark;
+    }
+
+    /**
+     * @param mfRemark
+     */
+    public void setMfRemark(String mfRemark) {
+        this.mfRemark = mfRemark == null ? null : mfRemark.trim();
+    }
+
+    /**
+     * @return MF_Path1
+     */
+    public String getMfPath1() {
+        return mfPath1;
+    }
+
+    /**
+     * @param mfPath1
+     */
+    public void setMfPath1(String mfPath1) {
+        this.mfPath1 = mfPath1 == null ? null : mfPath1.trim();
+    }
+
+    /**
+     * @return MF_Description1
+     */
+    public String getMfDescription1() {
+        return mfDescription1;
+    }
+
+    /**
+     * @param mfDescription1
+     */
+    public void setMfDescription1(String mfDescription1) {
+        this.mfDescription1 = mfDescription1 == null ? null : mfDescription1.trim();
+    }
+
+    /**
+     * @return MF_Path2
+     */
+    public String getMfPath2() {
+        return mfPath2;
+    }
+
+    /**
+     * @param mfPath2
+     */
+    public void setMfPath2(String mfPath2) {
+        this.mfPath2 = mfPath2 == null ? null : mfPath2.trim();
+    }
+
+    /**
+     * @return MF_Description2
+     */
+    public String getMfDescription2() {
+        return mfDescription2;
+    }
+
+    /**
+     * @param mfDescription2
+     */
+    public void setMfDescription2(String mfDescription2) {
+        this.mfDescription2 = mfDescription2 == null ? null : mfDescription2.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/SelfPatrolRecord.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/SelfPatrolRecord.java
new file mode 100644
index 0000000..57b8e9a
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/SelfPatrolRecord.java
@@ -0,0 +1,582 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "ea_t_self_patrol_record")
+public class SelfPatrolRecord {
+    @Id
+    @Column(name = "SR_GUID")
+    private String srGuid;
+
+    /**
+     * 搴旀�ヨ嚜宸℃煡浠诲姟id
+     */
+    @Column(name = "SP_GUID")
+    private String spGuid;
+
+    /**
+     * 鍙板笎绫诲瀷id
+     */
+    @Column(name = "LS_SubTypeId")
+    private Integer lsSubtypeid;
+
+    /**
+     * 鍙板笎绫诲瀷鍚嶇О
+     */
+    @Column(name = "LS_SubTypeName")
+    private String lsSubtypename;
+
+    /**
+     * 鍙板笎鎻愪氦骞翠唤
+     */
+    @Column(name = "SR_Year")
+    private Integer srYear;
+
+    /**
+     * 鍙板笎鎻愪氦鏈堜唤
+     */
+    @Column(name = "SR_Month")
+    private Byte srMonth;
+
+    /**
+     * 鍙板笎鎻愪氦鏃�
+     */
+    @Column(name = "SR_Day")
+    private Byte srDay;
+
+    /**
+     * 鍗曚綅GUID
+     */
+    @Column(name = "CI_GUID")
+    private String ciGuid;
+
+    /**
+     * 鍗曚綅鍚嶇О
+     */
+    @Column(name = "CI_Name")
+    private String ciName;
+
+    /**
+     * 鍙拌处鎻愪氦妯″紡1 鍥剧墖鎻愪氦锛�2 淇℃伅濉姤
+     */
+    @Column(name = "SR_EASubmitKind")
+    private Byte srEasubmitkind;
+
+    @Column(name = "SR_VerifierID")
+    private String srVerifierid;
+
+    @Column(name = "SR_VerifierRealName")
+    private String srVerifierrealname;
+
+    @Column(name = "SR_VerifyDate")
+    private Date srVerifydate;
+
+    @Column(name = "SR_IsVerify")
+    private Boolean srIsverify;
+
+    @Column(name = "SR_VerifyRst")
+    private String srVerifyrst;
+
+    @Column(name = "SR_AIVerifyTime")
+    private Integer srAiverifytime;
+
+    @Column(name = "SR_AIIsVerify")
+    private Boolean srAiisverify;
+
+    @Column(name = "SR_AIVerifyRst")
+    private String srAiverifyrst;
+
+    @Column(name = "SR_IsAI")
+    private Boolean srIsai;
+
+    /**
+     * 鎻愪氦浜篿d
+     */
+    @Column(name = "SR_SubmitID")
+    private String srSubmitid;
+
+    /**
+     * 鎻愪氦浜哄悕绉�
+     */
+    @Column(name = "SR_SubmitName")
+    private String srSubmitname;
+
+    /**
+     * 鏄惁鍙婃椂鎻愪氦
+     */
+    @Column(name = "SR_IsSubmitOnTime")
+    private Boolean srIssubmitontime;
+
+    /**
+     * 鎻愪氦鏃ユ湡
+     */
+    @Column(name = "SR_SubmitDate")
+    private Date srSubmitdate;
+
+    /**
+     * 閮ㄥ垎鏇存柊锛堥儴鍒嗙己澶便�侀仐澶憋級銆佸凡鏇存柊銆佹棤鏇存柊銆佺瓑
+     */
+    @Column(name = "SR_UpdateType")
+    private Byte srUpdatetype;
+
+    @Column(name = "SR_Extension1")
+    private String srExtension1;
+
+    @Column(name = "SR_Extension2")
+    private String srExtension2;
+
+    @Column(name = "SR_Extension3")
+    private String srExtension3;
+
+    @Column(name = "SR_Remark")
+    private String srRemark;
+
+    /**
+     * @return SR_GUID
+     */
+    public String getSrGuid() {
+        return srGuid;
+    }
+
+    /**
+     * @param srGuid
+     */
+    public void setSrGuid(String srGuid) {
+        this.srGuid = srGuid == null ? null : srGuid.trim();
+    }
+
+    /**
+     * 鑾峰彇搴旀�ヨ嚜宸℃煡浠诲姟id
+     *
+     * @return SP_GUID - 搴旀�ヨ嚜宸℃煡浠诲姟id
+     */
+    public String getSpGuid() {
+        return spGuid;
+    }
+
+    /**
+     * 璁剧疆搴旀�ヨ嚜宸℃煡浠诲姟id
+     *
+     * @param spGuid 搴旀�ヨ嚜宸℃煡浠诲姟id
+     */
+    public void setSpGuid(String spGuid) {
+        this.spGuid = spGuid == null ? null : spGuid.trim();
+    }
+
+    /**
+     * 鑾峰彇鍙板笎绫诲瀷id
+     *
+     * @return LS_SubTypeId - 鍙板笎绫诲瀷id
+     */
+    public Integer getLsSubtypeid() {
+        return lsSubtypeid;
+    }
+
+    /**
+     * 璁剧疆鍙板笎绫诲瀷id
+     *
+     * @param lsSubtypeid 鍙板笎绫诲瀷id
+     */
+    public void setLsSubtypeid(Integer lsSubtypeid) {
+        this.lsSubtypeid = lsSubtypeid;
+    }
+
+    /**
+     * 鑾峰彇鍙板笎绫诲瀷鍚嶇О
+     *
+     * @return LS_SubTypeName - 鍙板笎绫诲瀷鍚嶇О
+     */
+    public String getLsSubtypename() {
+        return lsSubtypename;
+    }
+
+    /**
+     * 璁剧疆鍙板笎绫诲瀷鍚嶇О
+     *
+     * @param lsSubtypename 鍙板笎绫诲瀷鍚嶇О
+     */
+    public void setLsSubtypename(String lsSubtypename) {
+        this.lsSubtypename = lsSubtypename == null ? null : lsSubtypename.trim();
+    }
+
+    /**
+     * 鑾峰彇鍙板笎鎻愪氦骞翠唤
+     *
+     * @return SR_Year - 鍙板笎鎻愪氦骞翠唤
+     */
+    public Integer getSrYear() {
+        return srYear;
+    }
+
+    /**
+     * 璁剧疆鍙板笎鎻愪氦骞翠唤
+     *
+     * @param srYear 鍙板笎鎻愪氦骞翠唤
+     */
+    public void setSrYear(Integer srYear) {
+        this.srYear = srYear;
+    }
+
+    /**
+     * 鑾峰彇鍙板笎鎻愪氦鏈堜唤
+     *
+     * @return SR_Month - 鍙板笎鎻愪氦鏈堜唤
+     */
+    public Byte getSrMonth() {
+        return srMonth;
+    }
+
+    /**
+     * 璁剧疆鍙板笎鎻愪氦鏈堜唤
+     *
+     * @param srMonth 鍙板笎鎻愪氦鏈堜唤
+     */
+    public void setSrMonth(Byte srMonth) {
+        this.srMonth = srMonth;
+    }
+
+    /**
+     * 鑾峰彇鍙板笎鎻愪氦鏃�
+     *
+     * @return SR_Day - 鍙板笎鎻愪氦鏃�
+     */
+    public Byte getSrDay() {
+        return srDay;
+    }
+
+    /**
+     * 璁剧疆鍙板笎鎻愪氦鏃�
+     *
+     * @param srDay 鍙板笎鎻愪氦鏃�
+     */
+    public void setSrDay(Byte srDay) {
+        this.srDay = srDay;
+    }
+
+    /**
+     * 鑾峰彇鍗曚綅GUID
+     *
+     * @return CI_GUID - 鍗曚綅GUID
+     */
+    public String getCiGuid() {
+        return ciGuid;
+    }
+
+    /**
+     * 璁剧疆鍗曚綅GUID
+     *
+     * @param ciGuid 鍗曚綅GUID
+     */
+    public void setCiGuid(String ciGuid) {
+        this.ciGuid = ciGuid == null ? null : ciGuid.trim();
+    }
+
+    /**
+     * 鑾峰彇鍗曚綅鍚嶇О
+     *
+     * @return CI_Name - 鍗曚綅鍚嶇О
+     */
+    public String getCiName() {
+        return ciName;
+    }
+
+    /**
+     * 璁剧疆鍗曚綅鍚嶇О
+     *
+     * @param ciName 鍗曚綅鍚嶇О
+     */
+    public void setCiName(String ciName) {
+        this.ciName = ciName == null ? null : ciName.trim();
+    }
+
+    /**
+     * 鑾峰彇鍙拌处鎻愪氦妯″紡1 鍥剧墖鎻愪氦锛�2 淇℃伅濉姤
+     *
+     * @return SR_EASubmitKind - 鍙拌处鎻愪氦妯″紡1 鍥剧墖鎻愪氦锛�2 淇℃伅濉姤
+     */
+    public Byte getSrEasubmitkind() {
+        return srEasubmitkind;
+    }
+
+    /**
+     * 璁剧疆鍙拌处鎻愪氦妯″紡1 鍥剧墖鎻愪氦锛�2 淇℃伅濉姤
+     *
+     * @param srEasubmitkind 鍙拌处鎻愪氦妯″紡1 鍥剧墖鎻愪氦锛�2 淇℃伅濉姤
+     */
+    public void setSrEasubmitkind(Byte srEasubmitkind) {
+        this.srEasubmitkind = srEasubmitkind;
+    }
+
+    /**
+     * @return SR_VerifierID
+     */
+    public String getSrVerifierid() {
+        return srVerifierid;
+    }
+
+    /**
+     * @param srVerifierid
+     */
+    public void setSrVerifierid(String srVerifierid) {
+        this.srVerifierid = srVerifierid == null ? null : srVerifierid.trim();
+    }
+
+    /**
+     * @return SR_VerifierRealName
+     */
+    public String getSrVerifierrealname() {
+        return srVerifierrealname;
+    }
+
+    /**
+     * @param srVerifierrealname
+     */
+    public void setSrVerifierrealname(String srVerifierrealname) {
+        this.srVerifierrealname = srVerifierrealname == null ? null : srVerifierrealname.trim();
+    }
+
+    /**
+     * @return SR_VerifyDate
+     */
+    public Date getSrVerifydate() {
+        return srVerifydate;
+    }
+
+    /**
+     * @param srVerifydate
+     */
+    public void setSrVerifydate(Date srVerifydate) {
+        this.srVerifydate = srVerifydate;
+    }
+
+    /**
+     * @return SR_IsVerify
+     */
+    public Boolean getSrIsverify() {
+        return srIsverify;
+    }
+
+    /**
+     * @param srIsverify
+     */
+    public void setSrIsverify(Boolean srIsverify) {
+        this.srIsverify = srIsverify;
+    }
+
+    /**
+     * @return SR_VerifyRst
+     */
+    public String getSrVerifyrst() {
+        return srVerifyrst;
+    }
+
+    /**
+     * @param srVerifyrst
+     */
+    public void setSrVerifyrst(String srVerifyrst) {
+        this.srVerifyrst = srVerifyrst == null ? null : srVerifyrst.trim();
+    }
+
+    /**
+     * @return SR_AIVerifyTime
+     */
+    public Integer getSrAiverifytime() {
+        return srAiverifytime;
+    }
+
+    /**
+     * @param srAiverifytime
+     */
+    public void setSrAiverifytime(Integer srAiverifytime) {
+        this.srAiverifytime = srAiverifytime;
+    }
+
+    /**
+     * @return SR_AIIsVerify
+     */
+    public Boolean getSrAiisverify() {
+        return srAiisverify;
+    }
+
+    /**
+     * @param srAiisverify
+     */
+    public void setSrAiisverify(Boolean srAiisverify) {
+        this.srAiisverify = srAiisverify;
+    }
+
+    /**
+     * @return SR_AIVerifyRst
+     */
+    public String getSrAiverifyrst() {
+        return srAiverifyrst;
+    }
+
+    /**
+     * @param srAiverifyrst
+     */
+    public void setSrAiverifyrst(String srAiverifyrst) {
+        this.srAiverifyrst = srAiverifyrst == null ? null : srAiverifyrst.trim();
+    }
+
+    /**
+     * @return SR_IsAI
+     */
+    public Boolean getSrIsai() {
+        return srIsai;
+    }
+
+    /**
+     * @param srIsai
+     */
+    public void setSrIsai(Boolean srIsai) {
+        this.srIsai = srIsai;
+    }
+
+    /**
+     * 鑾峰彇鎻愪氦浜篿d
+     *
+     * @return SR_SubmitID - 鎻愪氦浜篿d
+     */
+    public String getSrSubmitid() {
+        return srSubmitid;
+    }
+
+    /**
+     * 璁剧疆鎻愪氦浜篿d
+     *
+     * @param srSubmitid 鎻愪氦浜篿d
+     */
+    public void setSrSubmitid(String srSubmitid) {
+        this.srSubmitid = srSubmitid == null ? null : srSubmitid.trim();
+    }
+
+    /**
+     * 鑾峰彇鎻愪氦浜哄悕绉�
+     *
+     * @return SR_SubmitName - 鎻愪氦浜哄悕绉�
+     */
+    public String getSrSubmitname() {
+        return srSubmitname;
+    }
+
+    /**
+     * 璁剧疆鎻愪氦浜哄悕绉�
+     *
+     * @param srSubmitname 鎻愪氦浜哄悕绉�
+     */
+    public void setSrSubmitname(String srSubmitname) {
+        this.srSubmitname = srSubmitname == null ? null : srSubmitname.trim();
+    }
+
+    /**
+     * 鑾峰彇鏄惁鍙婃椂鎻愪氦
+     *
+     * @return SR_IsSubmitOnTime - 鏄惁鍙婃椂鎻愪氦
+     */
+    public Boolean getSrIssubmitontime() {
+        return srIssubmitontime;
+    }
+
+    /**
+     * 璁剧疆鏄惁鍙婃椂鎻愪氦
+     *
+     * @param srIssubmitontime 鏄惁鍙婃椂鎻愪氦
+     */
+    public void setSrIssubmitontime(Boolean srIssubmitontime) {
+        this.srIssubmitontime = srIssubmitontime;
+    }
+
+    /**
+     * 鑾峰彇鎻愪氦鏃ユ湡
+     *
+     * @return SR_SubmitDate - 鎻愪氦鏃ユ湡
+     */
+    public Date getSrSubmitdate() {
+        return srSubmitdate;
+    }
+
+    /**
+     * 璁剧疆鎻愪氦鏃ユ湡
+     *
+     * @param srSubmitdate 鎻愪氦鏃ユ湡
+     */
+    public void setSrSubmitdate(Date srSubmitdate) {
+        this.srSubmitdate = srSubmitdate;
+    }
+
+    /**
+     * 鑾峰彇閮ㄥ垎鏇存柊锛堥儴鍒嗙己澶便�侀仐澶憋級銆佸凡鏇存柊銆佹棤鏇存柊銆佺瓑
+     *
+     * @return SR_UpdateType - 閮ㄥ垎鏇存柊锛堥儴鍒嗙己澶便�侀仐澶憋級銆佸凡鏇存柊銆佹棤鏇存柊銆佺瓑
+     */
+    public Byte getSrUpdatetype() {
+        return srUpdatetype;
+    }
+
+    /**
+     * 璁剧疆閮ㄥ垎鏇存柊锛堥儴鍒嗙己澶便�侀仐澶憋級銆佸凡鏇存柊銆佹棤鏇存柊銆佺瓑
+     *
+     * @param srUpdatetype 閮ㄥ垎鏇存柊锛堥儴鍒嗙己澶便�侀仐澶憋級銆佸凡鏇存柊銆佹棤鏇存柊銆佺瓑
+     */
+    public void setSrUpdatetype(Byte srUpdatetype) {
+        this.srUpdatetype = srUpdatetype;
+    }
+
+    /**
+     * @return SR_Extension1
+     */
+    public String getSrExtension1() {
+        return srExtension1;
+    }
+
+    /**
+     * @param srExtension1
+     */
+    public void setSrExtension1(String srExtension1) {
+        this.srExtension1 = srExtension1 == null ? null : srExtension1.trim();
+    }
+
+    /**
+     * @return SR_Extension2
+     */
+    public String getSrExtension2() {
+        return srExtension2;
+    }
+
+    /**
+     * @param srExtension2
+     */
+    public void setSrExtension2(String srExtension2) {
+        this.srExtension2 = srExtension2 == null ? null : srExtension2.trim();
+    }
+
+    /**
+     * @return SR_Extension3
+     */
+    public String getSrExtension3() {
+        return srExtension3;
+    }
+
+    /**
+     * @param srExtension3
+     */
+    public void setSrExtension3(String srExtension3) {
+        this.srExtension3 = srExtension3 == null ? null : srExtension3.trim();
+    }
+
+    /**
+     * @return SR_Remark
+     */
+    public String getSrRemark() {
+        return srRemark;
+    }
+
+    /**
+     * @param srRemark
+     */
+    public void setSrRemark(String srRemark) {
+        this.srRemark = srRemark == null ? null : srRemark.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/SelfPatrolTask.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/SelfPatrolTask.java
new file mode 100644
index 0000000..25964cf
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/SelfPatrolTask.java
@@ -0,0 +1,219 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "ea_t_self_patrol_task")
+public class SelfPatrolTask {
+    @Id
+    @Column(name = "SP_GUID")
+    private String spGuid;
+
+    @Column(name = "SP_To_User_Id")
+    private String spToUserId;
+
+    @Column(name = "SP_From_User_Id")
+    private String spFromUserId;
+
+    @Column(name = "SP_Scene_Type_Id")
+    private Integer spSceneTypeId;
+
+    @Column(name = "SP_Ledger_Type_Id")
+    private String spLedgerTypeId;
+
+    @Column(name = "SP_Tag")
+    private String spTag;
+
+    /**
+     * 鍙戝竷鍗曚綅
+     */
+    @Column(name = "SP_Publish_Unit")
+    private String spPublishUnit;
+
+    @Column(name = "SP_Task_Year")
+    private Integer spTaskYear;
+
+    @Column(name = "SP_Task_Month")
+    private Integer spTaskMonth;
+
+    @Column(name = "SP_Create_Time")
+    private Date spCreateTime;
+
+    @Column(name = "SP_Deadline")
+    private Date spDeadline;
+
+    @Column(name = "SP_Task_Status")
+    private Integer spTaskStatus;
+
+    /**
+     * @return SP_GUID
+     */
+    public String getSpGuid() {
+        return spGuid;
+    }
+
+    /**
+     * @param spGuid
+     */
+    public void setSpGuid(String spGuid) {
+        this.spGuid = spGuid == null ? null : spGuid.trim();
+    }
+
+    /**
+     * @return SP_To_User_Id
+     */
+    public String getSpToUserId() {
+        return spToUserId;
+    }
+
+    /**
+     * @param spToUserId
+     */
+    public void setSpToUserId(String spToUserId) {
+        this.spToUserId = spToUserId == null ? null : spToUserId.trim();
+    }
+
+    /**
+     * @return SP_From_User_Id
+     */
+    public String getSpFromUserId() {
+        return spFromUserId;
+    }
+
+    /**
+     * @param spFromUserId
+     */
+    public void setSpFromUserId(String spFromUserId) {
+        this.spFromUserId = spFromUserId == null ? null : spFromUserId.trim();
+    }
+
+    /**
+     * @return SP_Scene_Type_Id
+     */
+    public Integer getSpSceneTypeId() {
+        return spSceneTypeId;
+    }
+
+    /**
+     * @param spSceneTypeId
+     */
+    public void setSpSceneTypeId(Integer spSceneTypeId) {
+        this.spSceneTypeId = spSceneTypeId;
+    }
+
+    /**
+     * @return SP_Ledger_Type_Id
+     */
+    public String getSpLedgerTypeId() {
+        return spLedgerTypeId;
+    }
+
+    /**
+     * @param spLedgerTypeId
+     */
+    public void setSpLedgerTypeId(String spLedgerTypeId) {
+        this.spLedgerTypeId = spLedgerTypeId == null ? null : spLedgerTypeId.trim();
+    }
+
+    /**
+     * @return SP_Tag
+     */
+    public String getSpTag() {
+        return spTag;
+    }
+
+    /**
+     * @param spTag
+     */
+    public void setSpTag(String spTag) {
+        this.spTag = spTag == null ? null : spTag.trim();
+    }
+
+    /**
+     * 鑾峰彇鍙戝竷鍗曚綅
+     *
+     * @return SP_Publish_Unit - 鍙戝竷鍗曚綅
+     */
+    public String getSpPublishUnit() {
+        return spPublishUnit;
+    }
+
+    /**
+     * 璁剧疆鍙戝竷鍗曚綅
+     *
+     * @param spPublishUnit 鍙戝竷鍗曚綅
+     */
+    public void setSpPublishUnit(String spPublishUnit) {
+        this.spPublishUnit = spPublishUnit == null ? null : spPublishUnit.trim();
+    }
+
+    /**
+     * @return SP_Task_Year
+     */
+    public Integer getSpTaskYear() {
+        return spTaskYear;
+    }
+
+    /**
+     * @param spTaskYear
+     */
+    public void setSpTaskYear(Integer spTaskYear) {
+        this.spTaskYear = spTaskYear;
+    }
+
+    /**
+     * @return SP_Task_Month
+     */
+    public Integer getSpTaskMonth() {
+        return spTaskMonth;
+    }
+
+    /**
+     * @param spTaskMonth
+     */
+    public void setSpTaskMonth(Integer spTaskMonth) {
+        this.spTaskMonth = spTaskMonth;
+    }
+
+    /**
+     * @return SP_Create_Time
+     */
+    public Date getSpCreateTime() {
+        return spCreateTime;
+    }
+
+    /**
+     * @param spCreateTime
+     */
+    public void setSpCreateTime(Date spCreateTime) {
+        this.spCreateTime = spCreateTime;
+    }
+
+    /**
+     * @return SP_Deadline
+     */
+    public Date getSpDeadline() {
+        return spDeadline;
+    }
+
+    /**
+     * @param spDeadline
+     */
+    public void setSpDeadline(Date spDeadline) {
+        this.spDeadline = spDeadline;
+    }
+
+    /**
+     * @return SP_Task_Status
+     */
+    public Integer getSpTaskStatus() {
+        return spTaskStatus;
+    }
+
+    /**
+     * @param spTaskStatus
+     */
+    public void setSpTaskStatus(Integer spTaskStatus) {
+        this.spTaskStatus = spTaskStatus;
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Town.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Town.java
new file mode 100644
index 0000000..7052198
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Town.java
@@ -0,0 +1,126 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import javax.persistence.*;
+
+@Table(name = "sm_t_town")
+public class Town {
+    @Id
+    @Column(name = "T_TownID")
+    private Integer tTownid;
+
+    @Column(name = "D_DistrictID")
+    private Integer dDistrictid;
+
+    @Column(name = "C_CityID")
+    private Integer cCityid;
+
+    @Column(name = "P_ProvinceID")
+    private Integer pProvinceid;
+
+    @Column(name = "T_TownCode")
+    private String tTowncode;
+
+    @Column(name = "T_TownName")
+    private String tTownname;
+
+    @Column(name = "T_Station")
+    private String tStation;
+
+    /**
+     * @return T_TownID
+     */
+    public Integer gettTownid() {
+        return tTownid;
+    }
+
+    /**
+     * @param tTownid
+     */
+    public void settTownid(Integer tTownid) {
+        this.tTownid = tTownid;
+    }
+
+    /**
+     * @return D_DistrictID
+     */
+    public Integer getdDistrictid() {
+        return dDistrictid;
+    }
+
+    /**
+     * @param dDistrictid
+     */
+    public void setdDistrictid(Integer dDistrictid) {
+        this.dDistrictid = dDistrictid;
+    }
+
+    /**
+     * @return C_CityID
+     */
+    public Integer getcCityid() {
+        return cCityid;
+    }
+
+    /**
+     * @param cCityid
+     */
+    public void setcCityid(Integer cCityid) {
+        this.cCityid = cCityid;
+    }
+
+    /**
+     * @return P_ProvinceID
+     */
+    public Integer getpProvinceid() {
+        return pProvinceid;
+    }
+
+    /**
+     * @param pProvinceid
+     */
+    public void setpProvinceid(Integer pProvinceid) {
+        this.pProvinceid = pProvinceid;
+    }
+
+    /**
+     * @return T_TownCode
+     */
+    public String gettTowncode() {
+        return tTowncode;
+    }
+
+    /**
+     * @param tTowncode
+     */
+    public void settTowncode(String tTowncode) {
+        this.tTowncode = tTowncode == null ? null : tTowncode.trim();
+    }
+
+    /**
+     * @return T_TownName
+     */
+    public String gettTownname() {
+        return tTownname;
+    }
+
+    /**
+     * @param tTownname
+     */
+    public void settTownname(String tTownname) {
+        this.tTownname = tTownname == null ? null : tTownname.trim();
+    }
+
+    /**
+     * @return T_Station
+     */
+    public String gettStation() {
+        return tStation;
+    }
+
+    /**
+     * @param tStation
+     */
+    public void settStation(String tStation) {
+        this.tStation = tStation == null ? null : tStation.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/UserConfig.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/UserConfig.java
new file mode 100644
index 0000000..a20ccf0
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/UserConfig.java
@@ -0,0 +1,430 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import javax.persistence.*;
+
+@Table(name = "sm_t_user_config")
+public class UserConfig {
+    @Id
+    @Column(name = "UC_Id")
+    private Integer ucId;
+
+    /**
+     * 鐢ㄦ埛绫诲瀷id
+     */
+    @Column(name = "UC_User_Type_Id")
+    private Integer ucUserTypeId;
+
+    /**
+     * 鐢ㄦ埛绫诲瀷
+     */
+    @Column(name = "UC_User_Type")
+    private String ucUserType;
+
+    /**
+     * 鐢ㄦ埛瀛愮被鍨媔d
+     */
+    @Column(name = "UC_User_SubType_Id")
+    private Integer ucUserSubtypeId;
+
+    /**
+     * 鐢ㄦ埛瀛愮被鍨�
+     */
+    @Column(name = "UC_User_SubType")
+    private String ucUserSubtype;
+
+    @Column(name = "UC_Province_Code")
+    private String ucProvinceCode;
+
+    @Column(name = "UC_Province_Name")
+    private String ucProvinceName;
+
+    @Column(name = "UC_City_Code")
+    private String ucCityCode;
+
+    @Column(name = "UC_City_Name")
+    private String ucCityName;
+
+    @Column(name = "UC_District_Code")
+    private String ucDistrictCode;
+
+    @Column(name = "UC_District_Name")
+    private String ucDistrictName;
+
+    @Column(name = "UC_Town_Code")
+    private String ucTownCode;
+
+    @Column(name = "UC_Town_Name")
+    private String ucTownName;
+
+    /**
+     * 闆嗕腑鍖虹紪鍙�
+     */
+    @Column(name = "UC_Area_Code")
+    private String ucAreaCode;
+
+    /**
+     * 闆嗕腑鍖�
+     */
+    @Column(name = "UC_Area")
+    private String ucArea;
+
+    @Column(name = "UC_Management_Company_Id")
+    private String ucManagementCompanyId;
+
+    @Column(name = "UC_Management_Company")
+    private String ucManagementCompany;
+
+    /**
+     * 鎷ユ湁鐨勫満鏅被鍨嬭寖鍥�
+     */
+    @Column(name = "UC_Scene_Range")
+    private String ucSceneRange;
+
+    @Column(name = "UC_Extension1")
+    private String ucExtension1;
+
+    @Column(name = "UC_Extension2")
+    private String ucExtension2;
+
+    @Column(name = "UC_Extension3")
+    private String ucExtension3;
+
+    @Column(name = "UC_Remark")
+    private String ucRemark;
+
+    /**
+     * @return UC_Id
+     */
+    public Integer getUcId() {
+        return ucId;
+    }
+
+    /**
+     * @param ucId
+     */
+    public void setUcId(Integer ucId) {
+        this.ucId = ucId;
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛绫诲瀷id
+     *
+     * @return UC_User_Type_Id - 鐢ㄦ埛绫诲瀷id
+     */
+    public Integer getUcUserTypeId() {
+        return ucUserTypeId;
+    }
+
+    /**
+     * 璁剧疆鐢ㄦ埛绫诲瀷id
+     *
+     * @param ucUserTypeId 鐢ㄦ埛绫诲瀷id
+     */
+    public void setUcUserTypeId(Integer ucUserTypeId) {
+        this.ucUserTypeId = ucUserTypeId;
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛绫诲瀷
+     *
+     * @return UC_User_Type - 鐢ㄦ埛绫诲瀷
+     */
+    public String getUcUserType() {
+        return ucUserType;
+    }
+
+    /**
+     * 璁剧疆鐢ㄦ埛绫诲瀷
+     *
+     * @param ucUserType 鐢ㄦ埛绫诲瀷
+     */
+    public void setUcUserType(String ucUserType) {
+        this.ucUserType = ucUserType == null ? null : ucUserType.trim();
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛瀛愮被鍨媔d
+     *
+     * @return UC_User_SubType_Id - 鐢ㄦ埛瀛愮被鍨媔d
+     */
+    public Integer getUcUserSubtypeId() {
+        return ucUserSubtypeId;
+    }
+
+    /**
+     * 璁剧疆鐢ㄦ埛瀛愮被鍨媔d
+     *
+     * @param ucUserSubtypeId 鐢ㄦ埛瀛愮被鍨媔d
+     */
+    public void setUcUserSubtypeId(Integer ucUserSubtypeId) {
+        this.ucUserSubtypeId = ucUserSubtypeId;
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛瀛愮被鍨�
+     *
+     * @return UC_User_SubType - 鐢ㄦ埛瀛愮被鍨�
+     */
+    public String getUcUserSubtype() {
+        return ucUserSubtype;
+    }
+
+    /**
+     * 璁剧疆鐢ㄦ埛瀛愮被鍨�
+     *
+     * @param ucUserSubtype 鐢ㄦ埛瀛愮被鍨�
+     */
+    public void setUcUserSubtype(String ucUserSubtype) {
+        this.ucUserSubtype = ucUserSubtype == null ? null : ucUserSubtype.trim();
+    }
+
+    /**
+     * @return UC_Province_Code
+     */
+    public String getUcProvinceCode() {
+        return ucProvinceCode;
+    }
+
+    /**
+     * @param ucProvinceCode
+     */
+    public void setUcProvinceCode(String ucProvinceCode) {
+        this.ucProvinceCode = ucProvinceCode == null ? null : ucProvinceCode.trim();
+    }
+
+    /**
+     * @return UC_Province_Name
+     */
+    public String getUcProvinceName() {
+        return ucProvinceName;
+    }
+
+    /**
+     * @param ucProvinceName
+     */
+    public void setUcProvinceName(String ucProvinceName) {
+        this.ucProvinceName = ucProvinceName == null ? null : ucProvinceName.trim();
+    }
+
+    /**
+     * @return UC_City_Code
+     */
+    public String getUcCityCode() {
+        return ucCityCode;
+    }
+
+    /**
+     * @param ucCityCode
+     */
+    public void setUcCityCode(String ucCityCode) {
+        this.ucCityCode = ucCityCode == null ? null : ucCityCode.trim();
+    }
+
+    /**
+     * @return UC_City_Name
+     */
+    public String getUcCityName() {
+        return ucCityName;
+    }
+
+    /**
+     * @param ucCityName
+     */
+    public void setUcCityName(String ucCityName) {
+        this.ucCityName = ucCityName == null ? null : ucCityName.trim();
+    }
+
+    /**
+     * @return UC_District_Code
+     */
+    public String getUcDistrictCode() {
+        return ucDistrictCode;
+    }
+
+    /**
+     * @param ucDistrictCode
+     */
+    public void setUcDistrictCode(String ucDistrictCode) {
+        this.ucDistrictCode = ucDistrictCode == null ? null : ucDistrictCode.trim();
+    }
+
+    /**
+     * @return UC_District_Name
+     */
+    public String getUcDistrictName() {
+        return ucDistrictName;
+    }
+
+    /**
+     * @param ucDistrictName
+     */
+    public void setUcDistrictName(String ucDistrictName) {
+        this.ucDistrictName = ucDistrictName == null ? null : ucDistrictName.trim();
+    }
+
+    /**
+     * @return UC_Town_Code
+     */
+    public String getUcTownCode() {
+        return ucTownCode;
+    }
+
+    /**
+     * @param ucTownCode
+     */
+    public void setUcTownCode(String ucTownCode) {
+        this.ucTownCode = ucTownCode == null ? null : ucTownCode.trim();
+    }
+
+    /**
+     * @return UC_Town_Name
+     */
+    public String getUcTownName() {
+        return ucTownName;
+    }
+
+    /**
+     * @param ucTownName
+     */
+    public void setUcTownName(String ucTownName) {
+        this.ucTownName = ucTownName == null ? null : ucTownName.trim();
+    }
+
+    /**
+     * 鑾峰彇闆嗕腑鍖虹紪鍙�
+     *
+     * @return UC_Area_Code - 闆嗕腑鍖虹紪鍙�
+     */
+    public String getUcAreaCode() {
+        return ucAreaCode;
+    }
+
+    /**
+     * 璁剧疆闆嗕腑鍖虹紪鍙�
+     *
+     * @param ucAreaCode 闆嗕腑鍖虹紪鍙�
+     */
+    public void setUcAreaCode(String ucAreaCode) {
+        this.ucAreaCode = ucAreaCode == null ? null : ucAreaCode.trim();
+    }
+
+    /**
+     * 鑾峰彇闆嗕腑鍖�
+     *
+     * @return UC_Area - 闆嗕腑鍖�
+     */
+    public String getUcArea() {
+        return ucArea;
+    }
+
+    /**
+     * 璁剧疆闆嗕腑鍖�
+     *
+     * @param ucArea 闆嗕腑鍖�
+     */
+    public void setUcArea(String ucArea) {
+        this.ucArea = ucArea == null ? null : ucArea.trim();
+    }
+
+    /**
+     * @return UC_Management_Company_Id
+     */
+    public String getUcManagementCompanyId() {
+        return ucManagementCompanyId;
+    }
+
+    /**
+     * @param ucManagementCompanyId
+     */
+    public void setUcManagementCompanyId(String ucManagementCompanyId) {
+        this.ucManagementCompanyId = ucManagementCompanyId == null ? null : ucManagementCompanyId.trim();
+    }
+
+    /**
+     * @return UC_Management_Company
+     */
+    public String getUcManagementCompany() {
+        return ucManagementCompany;
+    }
+
+    /**
+     * @param ucManagementCompany
+     */
+    public void setUcManagementCompany(String ucManagementCompany) {
+        this.ucManagementCompany = ucManagementCompany == null ? null : ucManagementCompany.trim();
+    }
+
+    /**
+     * 鑾峰彇鎷ユ湁鐨勫満鏅被鍨嬭寖鍥�
+     *
+     * @return UC_Scene_Range - 鎷ユ湁鐨勫満鏅被鍨嬭寖鍥�
+     */
+    public String getUcSceneRange() {
+        return ucSceneRange;
+    }
+
+    /**
+     * 璁剧疆鎷ユ湁鐨勫満鏅被鍨嬭寖鍥�
+     *
+     * @param ucSceneRange 鎷ユ湁鐨勫満鏅被鍨嬭寖鍥�
+     */
+    public void setUcSceneRange(String ucSceneRange) {
+        this.ucSceneRange = ucSceneRange == null ? null : ucSceneRange.trim();
+    }
+
+    /**
+     * @return UC_Extension1
+     */
+    public String getUcExtension1() {
+        return ucExtension1;
+    }
+
+    /**
+     * @param ucExtension1
+     */
+    public void setUcExtension1(String ucExtension1) {
+        this.ucExtension1 = ucExtension1 == null ? null : ucExtension1.trim();
+    }
+
+    /**
+     * @return UC_Extension2
+     */
+    public String getUcExtension2() {
+        return ucExtension2;
+    }
+
+    /**
+     * @param ucExtension2
+     */
+    public void setUcExtension2(String ucExtension2) {
+        this.ucExtension2 = ucExtension2 == null ? null : ucExtension2.trim();
+    }
+
+    /**
+     * @return UC_Extension3
+     */
+    public String getUcExtension3() {
+        return ucExtension3;
+    }
+
+    /**
+     * @param ucExtension3
+     */
+    public void setUcExtension3(String ucExtension3) {
+        this.ucExtension3 = ucExtension3 == null ? null : ucExtension3.trim();
+    }
+
+    /**
+     * @return UC_Remark
+     */
+    public String getUcRemark() {
+        return ucRemark;
+    }
+
+    /**
+     * @param ucRemark
+     */
+    public void setUcRemark(String ucRemark) {
+        this.ucRemark = ucRemark == null ? null : ucRemark.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/UserLoginLog.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/UserLoginLog.java
new file mode 100644
index 0000000..9985a9c
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/UserLoginLog.java
@@ -0,0 +1,66 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "sm_t_user_login_log")
+public class UserLoginLog {
+    @Id
+    @Column(name = "UL_Id")
+    private Integer ulId;
+
+    /**
+     * 鐢ㄦ埛id
+     */
+    @Column(name = "UL_User_GUID")
+    private String ulUserGuid;
+
+    @Column(name = "UL_Login_Time")
+    private Date ulLoginTime;
+
+    /**
+     * @return UL_Id
+     */
+    public Integer getUlId() {
+        return ulId;
+    }
+
+    /**
+     * @param ulId
+     */
+    public void setUlId(Integer ulId) {
+        this.ulId = ulId;
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛id
+     *
+     * @return UL_User_GUID - 鐢ㄦ埛id
+     */
+    public String getUlUserGuid() {
+        return ulUserGuid;
+    }
+
+    /**
+     * 璁剧疆鐢ㄦ埛id
+     *
+     * @param ulUserGuid 鐢ㄦ埛id
+     */
+    public void setUlUserGuid(String ulUserGuid) {
+        this.ulUserGuid = ulUserGuid == null ? null : ulUserGuid.trim();
+    }
+
+    /**
+     * @return UL_Login_Time
+     */
+    public Date getUlLoginTime() {
+        return ulLoginTime;
+    }
+
+    /**
+     * @param ulLoginTime
+     */
+    public void setUlLoginTime(Date ulLoginTime) {
+        this.ulLoginTime = ulLoginTime;
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/UserMap.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/UserMap.java
index 32b29e6..ce20cdf 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/UserMap.java
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/UserMap.java
@@ -1,5 +1,6 @@
 package cn.flightfeather.supervision.domain.entity;
 
+import java.util.Date;
 import javax.persistence.*;
 
 @Table(name = "ts_t_user_map")
@@ -28,6 +29,9 @@
      */
     @Column(name = "SV_User_Name")
     private String svUserName;
+
+    @Column(name = "UM_Create_Time")
+    private Date umCreateTime;
 
     /**
      * 鑾峰彇椋炵窘鐜鐢ㄦ埛id
@@ -100,4 +104,18 @@
     public void setSvUserName(String svUserName) {
         this.svUserName = svUserName == null ? null : svUserName.trim();
     }
+
+    /**
+     * @return UM_Create_Time
+     */
+    public Date getUmCreateTime() {
+        return umCreateTime;
+    }
+
+    /**
+     * @param umCreateTime
+     */
+    public void setUmCreateTime(Date umCreateTime) {
+        this.umCreateTime = umCreateTime;
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Userinfo.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Userinfo.kt
index 9342e1b..12ad17d 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Userinfo.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/Userinfo.kt
@@ -40,6 +40,12 @@
     @Column(name = "UI_UserType")
     var usertype: String? = null
 
+    @Column(name = "UI_User_SubType_Id")
+    var userSubTypeId: Int? = null
+
+    @Column(name = "UI_User_SubType")
+    var userSubType: String? = null
+
     @Column(name = "D_GUID")
     var dGuid: String? = null
 
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/VOCHourValue.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/VOCHourValue.java
index e54d1a8..ebf7bd2 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/VOCHourValue.java
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/VOCHourValue.java
@@ -9,9 +9,6 @@
     @Column(name = "VOC_ID")
     private Integer vocId;
 
-    /**
-     * 璁惧缂栧彿
-     */
     @Column(name = "VOC_Stat_Code")
     private String vocStatCode;
 
@@ -22,44 +19,44 @@
     private Date vocDataTime;
 
     /**
-     * VOC娴撳害 mg/m3
+     * VOC鍊�
      */
     @Column(name = "VOC_Value")
     private Double vocValue;
 
     /**
-     * e70201 椋庢満鐢垫祦-A
+     * VOC鍗曚綅
      */
+    @Column(name = "VOC_Unit")
+    private String vocUnit;
+
+    /**
+     * 娓╁害
+     */
+    @Column(name = "VOC_Temperature")
+    private Double vocTemperature;
+
+    /**
+     * 婀垮害
+     */
+    @Column(name = "VOC_RH")
+    private Double vocRh;
+
     @Column(name = "VOC_Fan_Electricity_1")
     private Double vocFanElectricity1;
 
-    /**
-     * e70202 椋庢満鐢垫祦-A
-     */
     @Column(name = "VOC_Fan_Electricity_2")
     private Double vocFanElectricity2;
 
-    /**
-     * e70203 椋庢満鐢垫祦-A
-     */
     @Column(name = "VOC_Fan_Electricity_3")
     private Double vocFanElectricity3;
 
-    /**
-     * e70204 椋庢満鐢垫祦-A
-     */
     @Column(name = "VOC_Fan_Electricity_4")
     private Double vocFanElectricity4;
 
-    /**
-     * e70205 椋庢満鐢垫祦-A
-     */
     @Column(name = "VOC_Fan_Electricity_5")
     private Double vocFanElectricity5;
 
-    /**
-     * e70206 椋庢満鐢垫祦-A
-     */
     @Column(name = "VOC_Fan_Electricity_6")
     private Double vocFanElectricity6;
 
@@ -78,18 +75,14 @@
     }
 
     /**
-     * 鑾峰彇璁惧缂栧彿
-     *
-     * @return VOC_Stat_Code - 璁惧缂栧彿
+     * @return VOC_Stat_Code
      */
     public String getVocStatCode() {
         return vocStatCode;
     }
 
     /**
-     * 璁剧疆璁惧缂栧彿
-     *
-     * @param vocStatCode 璁惧缂栧彿
+     * @param vocStatCode
      */
     public void setVocStatCode(String vocStatCode) {
         this.vocStatCode = vocStatCode == null ? null : vocStatCode.trim();
@@ -124,126 +117,156 @@
     }
 
     /**
-     * 鑾峰彇VOC娴撳害
+     * 鑾峰彇VOC鍊�
      *
-     * @return VOC_Value - VOC娴撳害
+     * @return VOC_Value - VOC鍊�
      */
     public Double getVocValue() {
         return vocValue;
     }
 
     /**
-     * 璁剧疆VOC娴撳害
+     * 璁剧疆VOC鍊�
      *
-     * @param vocValue VOC娴撳害
+     * @param vocValue VOC鍊�
      */
     public void setVocValue(Double vocValue) {
         this.vocValue = vocValue;
     }
 
     /**
-     * 鑾峰彇e70201 椋庢満鐢垫祦-A
+     * 鑾峰彇VOC鍗曚綅
      *
-     * @return VOC_Fan_Electricity_1 - e70201 椋庢満鐢垫祦-A
+     * @return VOC_Unit - VOC鍗曚綅
+     */
+    public String getVocUnit() {
+        return vocUnit;
+    }
+
+    /**
+     * 璁剧疆VOC鍗曚綅
+     *
+     * @param vocUnit VOC鍗曚綅
+     */
+    public void setVocUnit(String vocUnit) {
+        this.vocUnit = vocUnit == null ? null : vocUnit.trim();
+    }
+
+    /**
+     * 鑾峰彇娓╁害
+     *
+     * @return VOC_Temperature - 娓╁害
+     */
+    public Double getVocTemperature() {
+        return vocTemperature;
+    }
+
+    /**
+     * 璁剧疆娓╁害
+     *
+     * @param vocTemperature 娓╁害
+     */
+    public void setVocTemperature(Double vocTemperature) {
+        this.vocTemperature = vocTemperature;
+    }
+
+    /**
+     * 鑾峰彇婀垮害
+     *
+     * @return VOC_RH - 婀垮害
+     */
+    public Double getVocRh() {
+        return vocRh;
+    }
+
+    /**
+     * 璁剧疆婀垮害
+     *
+     * @param vocRh 婀垮害
+     */
+    public void setVocRh(Double vocRh) {
+        this.vocRh = vocRh;
+    }
+
+    /**
+     * @return VOC_Fan_Electricity_1
      */
     public Double getVocFanElectricity1() {
         return vocFanElectricity1;
     }
 
     /**
-     * 璁剧疆e70201 椋庢満鐢垫祦-A
-     *
-     * @param vocFanElectricity1 e70201 椋庢満鐢垫祦-A
+     * @param vocFanElectricity1
      */
     public void setVocFanElectricity1(Double vocFanElectricity1) {
         this.vocFanElectricity1 = vocFanElectricity1;
     }
 
     /**
-     * 鑾峰彇e70202 椋庢満鐢垫祦-A
-     *
-     * @return VOC_Fan_Electricity_2 - e70202 椋庢満鐢垫祦-A
+     * @return VOC_Fan_Electricity_2
      */
     public Double getVocFanElectricity2() {
         return vocFanElectricity2;
     }
 
     /**
-     * 璁剧疆e70202 椋庢満鐢垫祦-A
-     *
-     * @param vocFanElectricity2 e70202 椋庢満鐢垫祦-A
+     * @param vocFanElectricity2
      */
     public void setVocFanElectricity2(Double vocFanElectricity2) {
         this.vocFanElectricity2 = vocFanElectricity2;
     }
 
     /**
-     * 鑾峰彇e70203 椋庢満鐢垫祦-A
-     *
-     * @return VOC_Fan_Electricity_3 - e70203 椋庢満鐢垫祦-A
+     * @return VOC_Fan_Electricity_3
      */
     public Double getVocFanElectricity3() {
         return vocFanElectricity3;
     }
 
     /**
-     * 璁剧疆e70203 椋庢満鐢垫祦-A
-     *
-     * @param vocFanElectricity3 e70203 椋庢満鐢垫祦-A
+     * @param vocFanElectricity3
      */
     public void setVocFanElectricity3(Double vocFanElectricity3) {
         this.vocFanElectricity3 = vocFanElectricity3;
     }
 
     /**
-     * 鑾峰彇e70204 椋庢満鐢垫祦-A
-     *
-     * @return VOC_Fan_Electricity_4 - e70204 椋庢満鐢垫祦-A
+     * @return VOC_Fan_Electricity_4
      */
     public Double getVocFanElectricity4() {
         return vocFanElectricity4;
     }
 
     /**
-     * 璁剧疆e70204 椋庢満鐢垫祦-A
-     *
-     * @param vocFanElectricity4 e70204 椋庢満鐢垫祦-A
+     * @param vocFanElectricity4
      */
     public void setVocFanElectricity4(Double vocFanElectricity4) {
         this.vocFanElectricity4 = vocFanElectricity4;
     }
 
     /**
-     * 鑾峰彇e70205 椋庢満鐢垫祦-A
-     *
-     * @return VOC_Fan_Electricity_5 - e70205 椋庢満鐢垫祦-A
+     * @return VOC_Fan_Electricity_5
      */
     public Double getVocFanElectricity5() {
         return vocFanElectricity5;
     }
 
     /**
-     * 璁剧疆e70205 椋庢満鐢垫祦-A
-     *
-     * @param vocFanElectricity5 e70205 椋庢満鐢垫祦-A
+     * @param vocFanElectricity5
      */
     public void setVocFanElectricity5(Double vocFanElectricity5) {
         this.vocFanElectricity5 = vocFanElectricity5;
     }
 
     /**
-     * 鑾峰彇e70206 椋庢満鐢垫祦-A
-     *
-     * @return VOC_Fan_Electricity_6 - e70206 椋庢満鐢垫祦-A
+     * @return VOC_Fan_Electricity_6
      */
     public Double getVocFanElectricity6() {
         return vocFanElectricity6;
     }
 
     /**
-     * 璁剧疆e70206 椋庢満鐢垫祦-A
-     *
-     * @param vocFanElectricity6 e70206 椋庢満鐢垫祦-A
+     * @param vocFanElectricity6
      */
     public void setVocFanElectricity6(Double vocFanElectricity6) {
         this.vocFanElectricity6 = vocFanElectricity6;
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/entity/VocPurifyDevice.java b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/VocPurifyDevice.java
new file mode 100644
index 0000000..0e8be0e
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/entity/VocPurifyDevice.java
@@ -0,0 +1,227 @@
+package cn.flightfeather.supervision.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "ea_t_voc_purify_device")
+public class VocPurifyDevice {
+    @Id
+    @Column(name = "VP_Id")
+    private Integer vpId;
+
+    @Column(name = "IB_GUID")
+    private String ibGuid;
+
+    /**
+     * 璁捐椋庨噺
+     */
+    @Column(name = "VP_Air_Volume")
+    private Integer vpAirVolume;
+
+    /**
+     * 鍚搁檮鍓傚悕绉�
+     */
+    @Column(name = "VP_Absorbent_Name")
+    private String vpAbsorbentName;
+
+    /**
+     * 鍚搁檮鍓傚~鍏呴噺
+     */
+    @Column(name = "VP_Absorbent_Amount")
+    private Integer vpAbsorbentAmount;
+
+    /**
+     * 鍚搁檮鍓傛洿鎹㈠懆鏈熷崟浣嶏紝鏃ャ�佸懆銆佹湀銆佸勾
+     */
+    @Column(name = "VP_Period_Unit")
+    private String vpPeriodUnit;
+
+    /**
+     * 姣忎釜鍛ㄦ湡鏇存崲娆℃暟
+     */
+    @Column(name = "VP_Period_Count")
+    private Integer vpPeriodCount;
+
+    /**
+     * 鍚搁檮鍓傛瘡娆℃洿鎹㈤噸閲忥紝鍗曚綅鍏枻
+     */
+    @Column(name = "VP_Period_Weight")
+    private Double vpPeriodWeight;
+
+    @Column(name = "VP_Create_Time")
+    private Date vpCreateTime;
+
+    /**
+     * 鏈�鏂版洿鎹㈡椂闂�
+     */
+    @Column(name = "VP_Change_Time")
+    private Date vpChangeTime;
+
+    /**
+     * @return VP_Id
+     */
+    public Integer getVpId() {
+        return vpId;
+    }
+
+    /**
+     * @param vpId
+     */
+    public void setVpId(Integer vpId) {
+        this.vpId = vpId;
+    }
+
+    /**
+     * @return IB_GUID
+     */
+    public String getIbGuid() {
+        return ibGuid;
+    }
+
+    /**
+     * @param ibGuid
+     */
+    public void setIbGuid(String ibGuid) {
+        this.ibGuid = ibGuid == null ? null : ibGuid.trim();
+    }
+
+    /**
+     * 鑾峰彇璁捐椋庨噺
+     *
+     * @return VP_Air_Volume - 璁捐椋庨噺
+     */
+    public Integer getVpAirVolume() {
+        return vpAirVolume;
+    }
+
+    /**
+     * 璁剧疆璁捐椋庨噺
+     *
+     * @param vpAirVolume 璁捐椋庨噺
+     */
+    public void setVpAirVolume(Integer vpAirVolume) {
+        this.vpAirVolume = vpAirVolume;
+    }
+
+    /**
+     * 鑾峰彇鍚搁檮鍓傚悕绉�
+     *
+     * @return VP_Absorbent_Name - 鍚搁檮鍓傚悕绉�
+     */
+    public String getVpAbsorbentName() {
+        return vpAbsorbentName;
+    }
+
+    /**
+     * 璁剧疆鍚搁檮鍓傚悕绉�
+     *
+     * @param vpAbsorbentName 鍚搁檮鍓傚悕绉�
+     */
+    public void setVpAbsorbentName(String vpAbsorbentName) {
+        this.vpAbsorbentName = vpAbsorbentName == null ? null : vpAbsorbentName.trim();
+    }
+
+    /**
+     * 鑾峰彇鍚搁檮鍓傚~鍏呴噺
+     *
+     * @return VP_Absorbent_Amount - 鍚搁檮鍓傚~鍏呴噺
+     */
+    public Integer getVpAbsorbentAmount() {
+        return vpAbsorbentAmount;
+    }
+
+    /**
+     * 璁剧疆鍚搁檮鍓傚~鍏呴噺
+     *
+     * @param vpAbsorbentAmount 鍚搁檮鍓傚~鍏呴噺
+     */
+    public void setVpAbsorbentAmount(Integer vpAbsorbentAmount) {
+        this.vpAbsorbentAmount = vpAbsorbentAmount;
+    }
+
+    /**
+     * 鑾峰彇鍚搁檮鍓傛洿鎹㈠懆鏈熷崟浣嶏紝鏃ャ�佸懆銆佹湀銆佸勾
+     *
+     * @return VP_Period_Unit - 鍚搁檮鍓傛洿鎹㈠懆鏈熷崟浣嶏紝鏃ャ�佸懆銆佹湀銆佸勾
+     */
+    public String getVpPeriodUnit() {
+        return vpPeriodUnit;
+    }
+
+    /**
+     * 璁剧疆鍚搁檮鍓傛洿鎹㈠懆鏈熷崟浣嶏紝鏃ャ�佸懆銆佹湀銆佸勾
+     *
+     * @param vpPeriodUnit 鍚搁檮鍓傛洿鎹㈠懆鏈熷崟浣嶏紝鏃ャ�佸懆銆佹湀銆佸勾
+     */
+    public void setVpPeriodUnit(String vpPeriodUnit) {
+        this.vpPeriodUnit = vpPeriodUnit == null ? null : vpPeriodUnit.trim();
+    }
+
+    /**
+     * 鑾峰彇姣忎釜鍛ㄦ湡鏇存崲娆℃暟
+     *
+     * @return VP_Period_Count - 姣忎釜鍛ㄦ湡鏇存崲娆℃暟
+     */
+    public Integer getVpPeriodCount() {
+        return vpPeriodCount;
+    }
+
+    /**
+     * 璁剧疆姣忎釜鍛ㄦ湡鏇存崲娆℃暟
+     *
+     * @param vpPeriodCount 姣忎釜鍛ㄦ湡鏇存崲娆℃暟
+     */
+    public void setVpPeriodCount(Integer vpPeriodCount) {
+        this.vpPeriodCount = vpPeriodCount;
+    }
+
+    /**
+     * 鑾峰彇鍚搁檮鍓傛瘡娆℃洿鎹㈤噸閲忥紝鍗曚綅鍏枻
+     *
+     * @return VP_Period_Weight - 鍚搁檮鍓傛瘡娆℃洿鎹㈤噸閲忥紝鍗曚綅鍏枻
+     */
+    public Double getVpPeriodWeight() {
+        return vpPeriodWeight;
+    }
+
+    /**
+     * 璁剧疆鍚搁檮鍓傛瘡娆℃洿鎹㈤噸閲忥紝鍗曚綅鍏枻
+     *
+     * @param vpPeriodWeight 鍚搁檮鍓傛瘡娆℃洿鎹㈤噸閲忥紝鍗曚綅鍏枻
+     */
+    public void setVpPeriodWeight(Double vpPeriodWeight) {
+        this.vpPeriodWeight = vpPeriodWeight;
+    }
+
+    /**
+     * @return VP_Create_Time
+     */
+    public Date getVpCreateTime() {
+        return vpCreateTime;
+    }
+
+    /**
+     * @param vpCreateTime
+     */
+    public void setVpCreateTime(Date vpCreateTime) {
+        this.vpCreateTime = vpCreateTime;
+    }
+
+    /**
+     * 鑾峰彇鏈�鏂版洿鎹㈡椂闂�
+     *
+     * @return VP_Change_Time - 鏈�鏂版洿鎹㈡椂闂�
+     */
+    public Date getVpChangeTime() {
+        return vpChangeTime;
+    }
+
+    /**
+     * 璁剧疆鏈�鏂版洿鎹㈡椂闂�
+     *
+     * @param vpChangeTime 鏈�鏂版洿鎹㈡椂闂�
+     */
+    public void setVpChangeTime(Date vpChangeTime) {
+        this.vpChangeTime = vpChangeTime;
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/AssessmentRuleType.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/AssessmentRuleType.kt
index dbf22c2..58d36bc 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/AssessmentRuleType.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/AssessmentRuleType.kt
@@ -5,7 +5,7 @@
  */
 enum class AssessmentRuleType(val value: Int, val des: String) {
     Total(0, "鎬昏瘎鍒嗚〃"),
-    Compliance(1, "鐜繚鍚堣鎬ц瘎浼�"),
-    Risk(2,"鐜椋庨櫓鍔ㄦ�佽瘎浼�"),
-    GreenProduction(3, "缁胯壊鐢熶骇璇勪及")
+    Compliance(1, "璇勫垎瀛愯〃涓�"),
+    Risk(2,"璇勫垎瀛愯〃浜�"),
+    GreenProduction(3, "璇勫垎瀛愯〃涓�")
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/AuthenticationType.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/AuthenticationType.kt
new file mode 100644
index 0000000..4988b2f
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/AuthenticationType.kt
@@ -0,0 +1,9 @@
+package cn.flightfeather.supervision.domain.enumeration
+
+/**
+ * 鐢ㄦ埛璁よ瘉浜哄憳绫诲瀷
+ */
+enum class AuthenticationType(val value: Byte, val des: String) {
+    Admin(1, "绠$悊鍛�"),
+    Staff(0, "鑱屽憳")
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/NotificationType.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/NotificationType.kt
index 5b14e94..0a73cf4 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/NotificationType.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/NotificationType.kt
@@ -7,12 +7,36 @@
 enum class NotificationType(val value: Int, val des: String) {
     System(1, "绯荤粺閫氱煡"),
     Work(2, "宸ヤ綔閫氱煡"),
-    Alarm(3, "璀︽姤淇℃伅")
+    Alarm(3, "璀︽姤淇℃伅");
+
+    companion object {
+        fun getByValue(value1: Int) = when (value1) {
+            System.value -> System.des
+            Work.value -> Work.des
+            Alarm.value -> Alarm.des
+            else -> ""
+        }
+    }
+
 }
 
 enum class WorkSubType(val value: Int, val des: String) {
+    All(0, "鍏ㄩ儴"),
     Requirement(1, "宸ヤ綔瑕佹眰"),
     Law(2, "鎵ф硶閫氱煡"),
     Supervision(3, "鐩戠閫氱煡"),
-    Meeting(4, "浼氳閫氱煡")
+    Meeting(4, "浼氳閫氱煡");
+
+    companion object {
+        fun getByValue(value1: Int, value2: Int) = when (value1) {
+            NotificationType.Work.value -> when (value2) {
+                Requirement.value -> Requirement.des
+                Law.value -> Law.des
+                Supervision.value -> Supervision.des
+                Meeting.value -> Meeting.des
+                else -> All.des
+            }
+            else -> NotificationType.getByValue(value1)
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/SceneType.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/SceneType.kt
index 5fb37a2..35dc598 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/SceneType.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/SceneType.kt
@@ -1,6 +1,6 @@
 package cn.flightfeather.supervision.domain.enumeration
 
-enum class SceneType(val value: Int, val des: String) {
+enum class  SceneType(val value: Int, val des: String) {
     NoType(0, "鏃犵被鍨�"),
     Restaurant(1, "椁愰ギ"),
     Construction(2, "宸ュ湴"),
@@ -8,19 +8,35 @@
     StorageYard(4, "鍫嗗満"),
     MixingPlant(5, "鎼呮媽绔�"),
     Industrial(6, "宸ヤ笟浼佷笟"),
-    VehicleRepair(7, "姹戒慨");
+    VehicleRepair(7, "姹戒慨"),
+    Laboratory(8, "瀹為獙瀹�"),
+    MedicalInstitution(9, "鍖荤枟鏈烘瀯");
 
     companion object {
-        fun getNameByValue(value: Int): String = when (value) {
-            0 -> NoType.des
-            1 -> Restaurant.des
-            2 -> Construction.des
-            3 -> Wharf.des
-            4 -> StorageYard.des
-            5 -> MixingPlant.des
-            6 -> Industrial.des
-            7 -> VehicleRepair.des
-            else -> NoType.des
+        fun getByValue(value: Int?): SceneType = when (value) {
+            0 -> NoType
+            1 -> Restaurant
+            2 -> Construction
+            3 -> Wharf
+            4 -> StorageYard
+            5 -> MixingPlant
+            6 -> Industrial
+            7 -> VehicleRepair
+            8 -> Laboratory
+            9 -> MedicalInstitution
+            else -> NoType
         }
+
+        fun toPairList() = listOf(
+            Pair(Restaurant.value.toString(), Restaurant.des),
+            Pair(Construction.value.toString(), Construction.des),
+            Pair(Wharf.value.toString(), Wharf.des),
+            Pair(StorageYard.value.toString(), StorageYard.des),
+            Pair(MixingPlant.value.toString(), MixingPlant.des),
+            Pair(Industrial.value.toString(), Industrial.des),
+            Pair(VehicleRepair.value.toString(), VehicleRepair.des),
+            Pair(Laboratory.value.toString(), Laboratory.des),
+            Pair(MedicalInstitution.value.toString(), MedicalInstitution.des),
+        )
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/SelfPatrolTaskStatus.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/SelfPatrolTaskStatus.kt
new file mode 100644
index 0000000..6d42fc8
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/SelfPatrolTaskStatus.kt
@@ -0,0 +1,15 @@
+package cn.flightfeather.supervision.domain.enumeration
+
+/**
+ * @author riku
+ * Date: 2023/6/11
+ * 搴旀�ヨ嚜宸℃煡浠诲姟鐘舵��
+ */
+enum class SelfPatrolTaskStatus constructor(val value: Int, val des: String){
+    UnPublish(0,"鏈彂甯�"),
+    Published(1,"宸插彂甯冨緟瀹屾垚"),
+    Finished(2,"宸插畬鎴愬緟瀹℃牳"),
+    Pass(3, "瀹℃牳閫氳繃"),
+    UnPass(4, "瀹℃牳涓嶉�氳繃寰呮暣鏀�"),
+    Changed(5, "宸叉暣鏀瑰緟閲嶆柊瀹℃牳"),
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/UserType.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/UserType.kt
index 12f11bd..d91fcca 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/UserType.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/enumeration/UserType.kt
@@ -6,4 +6,13 @@
     Insider(1, "鍐呴儴浜哄憳"),
     Gov(2, "鏀垮簻閮ㄩ棬"),
     Enterprise(3, "浼佷笟")
+}
+
+enum class SubUserType(val value: Int, val des: String) {
+    Province(20, "鐪佺骇鏀垮簻"),
+    City(21, "甯傜骇鏀垮簻"),
+    District(22, "鍖虹骇鏀垮簻"),
+    Town(23, "闀囩骇鏀垮簻"),
+    Area(24, "闆嗕腑鍖�"),
+    Pollutant(30, "鎺掓薄浼佷笟"),
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/BaseInfoMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/BaseInfoMapper.kt
index 22a820e..ee3fc32 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/BaseInfoMapper.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/BaseInfoMapper.kt
@@ -1,8 +1,15 @@
 package cn.flightfeather.supervision.domain.mapper
 
 import cn.flightfeather.supervision.domain.entity.BaseInfo
+import cn.flightfeather.supervision.domain.entity.Userinfo
 import cn.flightfeather.supervision.domain.util.MyMapper
+import cn.flightfeather.supervision.lightshare.vo.BaseInfoVo
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
 import org.apache.ibatis.annotations.Mapper
 
 @Mapper
-interface BaseInfoMapper : MyMapper<BaseInfo>
\ No newline at end of file
+interface BaseInfoMapper : MyMapper<BaseInfo> {
+
+    fun searchUser(condition: UserSearchCondition): List<BaseInfoVo>
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/CityMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/CityMapper.kt
new file mode 100644
index 0000000..8c447ba
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/CityMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.util.MyMapper
+import cn.flightfeather.supervision.domain.entity.City
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface CityMapper : MyMapper<City?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/CommitmentTemplateMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/CommitmentTemplateMapper.kt
new file mode 100644
index 0000000..8e0246d
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/CommitmentTemplateMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.CommitmentTemplate
+import cn.flightfeather.supervision.domain.util.MyMapper
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface CommitmentTemplateMapper : MyMapper<CommitmentTemplate?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/DistrictMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/DistrictMapper.kt
new file mode 100644
index 0000000..6a2e4b9
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/DistrictMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.util.MyMapper
+import cn.flightfeather.supervision.domain.entity.District
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface DistrictMapper : MyMapper<District?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/DustSiteInfoMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/DustSiteInfoMapper.kt
new file mode 100644
index 0000000..9be73bf
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/DustSiteInfoMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.DustSiteInfo
+import cn.flightfeather.supervision.domain.util.MyMapper
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface DustSiteInfoMapper : MyMapper<DustSiteInfo?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/DustSiteMapMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/DustSiteMapMapper.kt
new file mode 100644
index 0000000..73e34d2
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/DustSiteMapMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.DustSiteMap
+import cn.flightfeather.supervision.domain.util.MyMapper
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface DustSiteMapMapper : MyMapper<DustSiteMap?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/EnvironmentalScheduleMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/EnvironmentalScheduleMapper.kt
new file mode 100644
index 0000000..19fe74f
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/EnvironmentalScheduleMapper.kt
@@ -0,0 +1,11 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.EnvironmentalSchedule
+import cn.flightfeather.supervision.domain.util.MyMapper
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface EnvironmentalScheduleMapper : MyMapper<EnvironmentalSchedule?>{
+
+    fun getSchedules(userId: String, configId: List<Int>, sceneType: String, type: Int?): List<EnvironmentalSchedule>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/EvaluationMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/EvaluationMapper.kt
index c498fa8..e17d4ae 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/EvaluationMapper.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/EvaluationMapper.kt
@@ -1,6 +1,8 @@
 package cn.flightfeather.supervision.domain.mapper
 
 import cn.flightfeather.supervision.domain.entity.Evaluation
+import cn.flightfeather.supervision.lightshare.vo.CreditInfoVo
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
 import org.apache.ibatis.annotations.Param
 import tk.mybatis.mapper.common.Mapper
 import kotlin.reflect.jvm.internal.impl.load.kotlin.JvmType
@@ -9,4 +11,6 @@
 interface EvaluationMapper: Mapper<Evaluation> {
 
     fun getAssessments(district: String, realName: String, town:String, @Param("sceneTypes") sceneTypes: List<String>): List<Map<String, JvmType.Object>>
+
+    fun searchGradeList(condition: UserSearchCondition): List<CreditInfoVo>
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/HourDustDataMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/HourDustDataMapper.kt
new file mode 100644
index 0000000..b941ce3
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/HourDustDataMapper.kt
@@ -0,0 +1,13 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.HourDustData
+import cn.flightfeather.supervision.domain.util.MyMapper
+import cn.flightfeather.supervision.lightshare.vo.DataCategoryCountVo
+import org.apache.ibatis.annotations.Mapper
+import java.time.LocalDateTime
+
+@Mapper
+interface HourDustDataMapper : MyMapper<HourDustData?> {
+
+    fun findDataCountEachDay(startTime:LocalDateTime, endTime:LocalDateTime):List<DataCategoryCountVo>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/IndustrialBaseInfoMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/IndustrialBaseInfoMapper.kt
new file mode 100644
index 0000000..874635f
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/IndustrialBaseInfoMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.IndustrialBaseInfo
+import cn.flightfeather.supervision.domain.util.MyMapper
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface IndustrialBaseInfoMapper : MyMapper<IndustrialBaseInfo?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/LampDeviceDataMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/LampDeviceDataMapper.kt
new file mode 100644
index 0000000..553f5c7
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/LampDeviceDataMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.LampDeviceData
+import cn.flightfeather.supervision.domain.util.MyMapper
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface LampDeviceDataMapper : MyMapper<LampDeviceData?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/LampEnterBaseInfoMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/LampEnterBaseInfoMapper.kt
new file mode 100644
index 0000000..f2d3b74
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/LampEnterBaseInfoMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.LampEnterBaseInfo
+import cn.flightfeather.supervision.domain.util.MyMapper
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface LampEnterBaseInfoMapper : MyMapper<LampEnterBaseInfo?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/NoticeMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/NoticeMapper.kt
index ac34a25..29a3a71 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/NoticeMapper.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/NoticeMapper.kt
@@ -10,5 +10,6 @@
 
     fun selectByUser(userTypeId: String, userId: String, startIndex: Int, perPage: Int): List<Notice>
 
-    fun getUnReadNotification(userId: String, districtCode: String?, sceneTypeId: String?):List<NotificationVo>
+    fun getUnReadNotification(userId: String, districtCode: String?, sceneTypeId: String?, userTypeId: Byte?)
+            : List<NotificationVo>
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/NoticeTemplateMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/NoticeTemplateMapper.kt
new file mode 100644
index 0000000..d0942b7
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/NoticeTemplateMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.NoticeTemplate
+import cn.flightfeather.supervision.domain.util.MyMapper
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface NoticeTemplateMapper : MyMapper<NoticeTemplate?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/OverallEvaluationMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/OverallEvaluationMapper.kt
index 1d1e8e9..180de28 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/OverallEvaluationMapper.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/OverallEvaluationMapper.kt
@@ -2,7 +2,16 @@
 
 import cn.flightfeather.supervision.domain.entity.OverallEvaluation
 import cn.flightfeather.supervision.domain.util.MyMapper
+import cn.flightfeather.supervision.lightshare.vo.CreditInfoVo
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
 import org.apache.ibatis.annotations.Mapper
 
 @Mapper
-interface OverallEvaluationMapper : MyMapper<OverallEvaluation>
\ No newline at end of file
+interface OverallEvaluationMapper : MyMapper<OverallEvaluation> {
+
+    fun getLatestPeriod(condition: UserSearchCondition): String?
+
+    fun getCreditCount(condition: UserSearchCondition): List<OverallEvaluation>
+
+    fun searchEcCodeList(condition: UserSearchCondition): List<CreditInfoVo>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/PracticalOperationMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/PracticalOperationMapper.kt
new file mode 100644
index 0000000..7189f5a
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/PracticalOperationMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.util.MyMapper
+import cn.flightfeather.supervision.domain.entity.PracticalOperation
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface PracticalOperationMapper : MyMapper<PracticalOperation?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/PracticalOperationRecordMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/PracticalOperationRecordMapper.kt
new file mode 100644
index 0000000..7aa6aad
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/PracticalOperationRecordMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.util.MyMapper
+import cn.flightfeather.supervision.domain.entity.PracticalOperationRecord
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface PracticalOperationRecordMapper : MyMapper<PracticalOperationRecord?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/ProvinceMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/ProvinceMapper.kt
new file mode 100644
index 0000000..5669fb0
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/ProvinceMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.util.MyMapper
+import cn.flightfeather.supervision.domain.entity.Province
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface ProvinceMapper : MyMapper<Province?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/RiskEvaluationMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/RiskEvaluationMapper.kt
new file mode 100644
index 0000000..c9d25da
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/RiskEvaluationMapper.kt
@@ -0,0 +1,17 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.RiskEvaluation
+import cn.flightfeather.supervision.domain.util.MyMapper
+import cn.flightfeather.supervision.lightshare.vo.CreditInfoVo
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface RiskEvaluationMapper : MyMapper<RiskEvaluation?>{
+
+    fun getLatestPeriod(condition: UserSearchCondition): String?
+
+    fun getRiskCount(condition: UserSearchCondition): List<RiskEvaluation>
+
+    fun searchRiskList(condition: UserSearchCondition): List<CreditInfoVo>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SceneTypeMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SceneTypeMapper.kt
new file mode 100644
index 0000000..aa61186
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SceneTypeMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.SceneType
+import cn.flightfeather.supervision.domain.util.MyMapper
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface SceneTypeMapper : MyMapper<SceneType?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/ScheduleSignRecordMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/ScheduleSignRecordMapper.kt
new file mode 100644
index 0000000..5636afe
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/ScheduleSignRecordMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.ScheduleSignRecord
+import cn.flightfeather.supervision.domain.util.MyMapper
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface ScheduleSignRecordMapper : MyMapper<ScheduleSignRecord?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SelfPatrolMediaFileMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SelfPatrolMediaFileMapper.kt
new file mode 100644
index 0000000..ef0c7b5
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SelfPatrolMediaFileMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.SelfPatrolMediaFile
+import cn.flightfeather.supervision.domain.util.MyMapper
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface SelfPatrolMediaFileMapper : MyMapper<SelfPatrolMediaFile?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SelfPatrolRecordMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SelfPatrolRecordMapper.kt
new file mode 100644
index 0000000..e9be91f
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SelfPatrolRecordMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.SelfPatrolRecord
+import cn.flightfeather.supervision.domain.util.MyMapper
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface SelfPatrolRecordMapper : MyMapper<SelfPatrolRecord?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SelfPatrolTaskMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SelfPatrolTaskMapper.kt
new file mode 100644
index 0000000..f76d23a
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/SelfPatrolTaskMapper.kt
@@ -0,0 +1,27 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.SelfPatrolTask
+import cn.flightfeather.supervision.domain.util.MyMapper
+import cn.flightfeather.supervision.lightshare.vo.SelfPatrolTaskVo
+import org.apache.ibatis.annotations.InsertProvider
+import org.apache.ibatis.annotations.Mapper
+import org.apache.ibatis.annotations.Options
+import tk.mybatis.mapper.provider.SpecialProvider
+
+@Mapper
+interface SelfPatrolTaskMapper : MyMapper<SelfPatrolTask?> {
+
+    fun getPublishedTask(userId: String, year: Int?, month: Int?): List<SelfPatrolTaskVo>
+
+}
+
+/**
+ * 鎵归噺鎻掑叆鎺ュ彛
+ */
+@Mapper
+interface InsertUidListMapper<T> {
+
+    @Options(useGeneratedKeys = true, keyProperty = "spGuid")
+    @InsertProvider(type = SpecialProvider::class, method = "dynamicSQL")
+    fun insertUidList(recordList: List<T>?): Int
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/TownMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/TownMapper.kt
new file mode 100644
index 0000000..14d5076
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/TownMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.util.MyMapper
+import cn.flightfeather.supervision.domain.entity.Town
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface TownMapper : MyMapper<Town?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/UserConfigMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/UserConfigMapper.kt
new file mode 100644
index 0000000..cdcd4bd
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/UserConfigMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.UserConfig
+import cn.flightfeather.supervision.domain.util.MyMapper
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface UserConfigMapper : MyMapper<UserConfig?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/UserLoginLogMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/UserLoginLogMapper.kt
new file mode 100644
index 0000000..403a2bf
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/UserLoginLogMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.util.MyMapper
+import cn.flightfeather.supervision.domain.entity.UserLoginLog
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface UserLoginLogMapper : MyMapper<UserLoginLog?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/UserinfoMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/UserinfoMapper.kt
index ed30985..237159a 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/UserinfoMapper.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/UserinfoMapper.kt
@@ -2,9 +2,13 @@
 
 import cn.flightfeather.supervision.domain.entity.Userinfo
 import cn.flightfeather.supervision.domain.util.MyMapper
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
 import org.apache.ibatis.annotations.Mapper
 
 @Mapper
-interface UserinfoMapper:MyMapper<Userinfo> {
+interface UserinfoMapper:MyMapper<Userinfo?> {
 
+    fun searchUser(condition: UserSearchCondition): List<Userinfo>
+
+    fun getUnAuthedUsers(): List<Userinfo?>
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/VocPurifyDeviceMapper.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/VocPurifyDeviceMapper.kt
new file mode 100644
index 0000000..76963cc
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/mapper/VocPurifyDeviceMapper.kt
@@ -0,0 +1,8 @@
+package cn.flightfeather.supervision.domain.mapper
+
+import cn.flightfeather.supervision.domain.entity.VocPurifyDevice
+import cn.flightfeather.supervision.domain.util.MyMapper
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface VocPurifyDeviceMapper : MyMapper<VocPurifyDevice?>
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/repository/EvaluationRep.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/repository/EvaluationRep.kt
new file mode 100644
index 0000000..ee16551
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/repository/EvaluationRep.kt
@@ -0,0 +1,57 @@
+package cn.flightfeather.supervision.domain.repository
+
+import cn.flightfeather.supervision.domain.entity.Evaluation
+import cn.flightfeather.supervision.domain.entity.Evaluationrule
+import cn.flightfeather.supervision.domain.enumeration.AssessmentRuleType
+import cn.flightfeather.supervision.domain.enumeration.SceneType
+import cn.flightfeather.supervision.domain.mapper.EvaluationMapper
+import cn.flightfeather.supervision.domain.mapper.EvaluationruleMapper
+import org.springframework.stereotype.Repository
+import tk.mybatis.mapper.entity.Example
+import java.time.LocalDateTime
+
+/**
+ * 璇勪及鐩稿叧鏁版嵁搴撴搷浣�
+ */
+@Repository
+class EvaluationRep(
+    private val evaluationruleMapper: EvaluationruleMapper,
+    private val evaluationMapper: EvaluationMapper,
+) {
+
+    /**
+     * 鑾峰彇璇勪及鍩烘湰瑙勫垯锛堥潪鑷瘎锛�
+     */
+    fun findRule(sceneType: SceneType, ruleType: AssessmentRuleType = AssessmentRuleType.Total): Evaluationrule? {
+        val list = evaluationruleMapper.selectByExample(Example(Evaluationrule::class.java).apply {
+            createCriteria().andEqualTo("scensetypeid", sceneType.value)
+                .andEqualTo("ruletype", ruleType.value)
+            and(createCriteria().orIsNull("tasktypeid").orNotEqualTo("tasktypeid", 1))
+        })
+        return if (list.isNotEmpty()) {
+            list[0]
+        } else {
+            null
+        }
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛璇勪及鍛ㄦ湡鍐呮渶鏂颁竴鏈熻瘎浼版�诲垎
+     */
+    fun findLatest(ruleId: String?, userId: String, period: String, st: LocalDateTime, et: LocalDateTime): Evaluation? {
+        val r = evaluationMapper.selectByExample(Example(Evaluation::class.java).apply {
+            createCriteria().andEqualTo("iguid", userId)
+                .andEqualTo("stguid", ruleId)
+            and(
+                createCriteria().orEqualTo("scensename", period)
+                    .orBetween("createdate", st, et)
+            )
+            orderBy("createdate").desc()
+        })
+        return if (r.isNotEmpty()) {
+            r[0]
+        } else {
+            null
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/repository/LedgerMediaFileRep.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/repository/LedgerMediaFileRep.kt
new file mode 100644
index 0000000..24ecfd9
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/repository/LedgerMediaFileRep.kt
@@ -0,0 +1,69 @@
+package cn.flightfeather.supervision.domain.repository
+
+import cn.flightfeather.supervision.domain.entity.LedgerMediaFile
+import cn.flightfeather.supervision.domain.mapper.LedgerMediaFileMapper
+import cn.flightfeather.supervision.infrastructure.utils.DateUtil
+import cn.flightfeather.supervision.infrastructure.utils.FileUtil
+import cn.flightfeather.supervision.infrastructure.utils.UUIDGenerator
+import cn.flightfeather.supervision.lightshare.vo.LedgerVo
+import org.springframework.beans.factory.annotation.Value
+import org.springframework.stereotype.Repository
+import java.io.FileNotFoundException
+import java.util.*
+
+@Repository
+class LedgerMediaFileRep(private val ledgerMediaFileMapper: LedgerMediaFileMapper) {
+
+    @Value("\${imgPath}")
+    lateinit var imgPath: String
+
+    /**
+     * 鏌ヨ
+     * @param lrGuid 鍙拌处璁板綍id
+     */
+    fun select(lrGuid: String): LedgerMediaFile? {
+        return ledgerMediaFileMapper.selectOne(LedgerMediaFile().apply { this.lrGuid = lrGuid })
+    }
+
+    fun saveFile(userId: String, ledgerVo: LedgerVo, files: List<Pair<ByteArray, String>>): String {
+        var picPath = ""
+        val time = DateUtil.DateToString(ledgerVo.updateDate, DateUtil.DateStyle.YYYY_MM)
+
+        files.forEachIndexed { index, file ->
+            val fileName = "${ledgerVo.ledgerSubTypeId}-${index + 1}.${file.second}"
+            val basePath = imgPath
+            val path = "$time/$userId/${ledgerVo.ledgerName}/"
+            picPath += if (picPath.isEmpty()) {
+                "$path$fileName"
+            } else {
+                ";$path$fileName"
+            }
+            try {
+                //璋冪敤鏂囦欢淇濆瓨鏂规硶
+                FileUtil.uploadFile(file.first, basePath + path, fileName!!)
+            } catch (e: FileNotFoundException) {
+                e.printStackTrace()
+            }
+        }
+        return picPath
+    }
+
+    fun insert(ledgerVo: LedgerVo, picPath: String) {
+        val ledgerMedia = LedgerMediaFile().apply {
+            mfGuid = UUIDGenerator.generate16ShortUUID()
+            lrGuid = ledgerVo.id
+            mfFiletype = ledgerVo.fileType
+            mfPath1 = picPath
+            mfDescription1 = ledgerVo.remark1
+            mfSavetime = Date()
+            mfIsdelete = false
+        }
+        //鎻掑叆鏂扮殑澶氬獟浣撴枃浠惰褰曟暟鎹�
+        ledgerMediaFileMapper.insert(ledgerMedia)
+    }
+
+    fun update(ledgerMedia: LedgerMediaFile?) {
+        //鏇存柊鐨勫濯掍綋鏂囦欢璁板綍鏁版嵁
+        ledgerMediaFileMapper.updateByPrimaryKey(ledgerMedia)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/repository/LedgerRep.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/repository/LedgerRep.kt
new file mode 100644
index 0000000..140e842
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/repository/LedgerRep.kt
@@ -0,0 +1,46 @@
+package cn.flightfeather.supervision.domain.repository
+
+import cn.flightfeather.supervision.domain.entity.LedgerRecord
+import cn.flightfeather.supervision.domain.entity.LedgerSubType
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.domain.mapper.LedgerRecordMapper
+import cn.flightfeather.supervision.domain.mapper.LedgerSubTypeMapper
+import org.springframework.stereotype.Repository
+import tk.mybatis.mapper.entity.Example
+import java.time.LocalDateTime
+import java.time.ZoneId
+import java.util.*
+
+@Repository
+class LedgerRep(
+    private val ledgerSubTypeMapper: LedgerSubTypeMapper,
+    private val ledgerRecordMapper: LedgerRecordMapper,
+) {
+    fun selectLedger(ledgerSubTypeId: Int?): LedgerSubType? {
+        return ledgerSubTypeMapper.selectByPrimaryKey(ledgerSubTypeId)
+    }
+
+    fun insertRecord(ledgerRecord: LedgerRecord?) {
+        ledgerRecord?.let { ledgerRecordMapper.insert(it) }
+    }
+
+    fun updateRecord(ledgerRecord: LedgerRecord?) {
+        ledgerRecord?.let { ledgerRecordMapper.updateByPrimaryKey(it) }
+    }
+
+    fun selectRecord(userId: String, ledgerSubTypeId: Int?, time: Date?): LedgerRecord? {
+        val updateTime = LocalDateTime.ofInstant(time?.toInstant(), ZoneId.systemDefault())
+        return selectRecord(userId, ledgerSubTypeId, updateTime)
+    }
+
+    fun selectRecord(userId: String, ledgerSubTypeId: Int?, time: LocalDateTime?): LedgerRecord? {
+        val year = time?.year
+        val month = time?.monthValue
+        return ledgerRecordMapper.selectOne(LedgerRecord().apply {
+            lsSubtypeid = ledgerSubTypeId
+            year?.let { lrYear = it }
+            month?.let { lrMonth = it.toByte() }
+            lrSubmitid = userId
+        })
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/repository/PracticalOperationRep.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/repository/PracticalOperationRep.kt
new file mode 100644
index 0000000..f50322b
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/repository/PracticalOperationRep.kt
@@ -0,0 +1,107 @@
+package cn.flightfeather.supervision.domain.repository
+
+import cn.flightfeather.supervision.common.exception.ResponseErrorException
+import cn.flightfeather.supervision.domain.entity.PracticalOperation
+import cn.flightfeather.supervision.domain.entity.PracticalOperationRecord
+import cn.flightfeather.supervision.domain.mapper.PracticalOperationMapper
+import cn.flightfeather.supervision.domain.mapper.PracticalOperationRecordMapper
+import com.github.pagehelper.PageHelper
+import org.springframework.stereotype.Repository
+import tk.mybatis.mapper.entity.Example
+import java.time.LocalDateTime
+import java.util.*
+
+@Repository
+class PracticalOperationRep(
+    private val practicalOperationMapper: PracticalOperationMapper,
+    private val practicalOperationRecordMapper: PracticalOperationRecordMapper,
+    private val userInfoRep: UserInfoRep,
+) {
+
+    /**
+     * 鏍规嵁鐢ㄦ埛閰嶇疆id鑾峰彇瀹炴搷浜嬪姟
+     * @param configIds 鐢ㄦ埛閰嶇疆鐨勪富閿甶d
+     */
+    fun getOperation(configIds: List<Int>): List<PracticalOperation?> {
+        return practicalOperationMapper.selectByExample(Example(PracticalOperation::class.java).apply {
+            createCriteria().andIn("poUserConfigId", configIds)
+        })
+    }
+
+    /**
+     * 鏍规嵁鐢ㄦ埛id鑾峰彇瀹炴搷浜嬪姟
+     * @param userId 鐢ㄦ埛id
+     */
+    fun getOperation(userId: String): List<PracticalOperation?> {
+        return practicalOperationMapper.selectByExample(Example(PracticalOperation::class.java).apply {
+            createCriteria().andEqualTo("poUserId", userId)
+        })
+    }
+
+    /**
+     * 鎵ц涓�浠跺疄鎿嶄簨鍔★紝璁板綍鎵ц鐘舵�佺粨鏋�
+     * @param userId 鎵ц浜篿d
+     * @param operationId 浜嬪姟id
+     * @param stateId 浜嬪姟鐨勭粨鏋滅姸鎬乮d锛堟牴鎹瘡涓簨鍔$殑瀹氫箟鍐冲畾锛�
+     */
+    fun executeOperation(userId: String, operationId: Int, stateId: String): PracticalOperationRecord? {
+        val userInfo = userInfoRep.getUser(userId) ?: throw ResponseErrorException("鐢ㄦ埛涓嶅瓨鍦紝鏃犳硶鎿嶄綔")
+        val operation =
+            practicalOperationMapper.selectByPrimaryKey(operationId) ?: throw ResponseErrorException("璇ュ疄鎿嶄簨鍔′笉瀛樺湪")
+        val stateRangeIds = operation.poStateRangeId.split(";")
+        val stateRangeNames = operation.poStateRange.split(";")
+        if (stateRangeIds.size != stateRangeNames.size) throw ResponseErrorException("浜嬪姟鎵ц缁撴灉鐨勫彲閫夌姸鎬侀厤缃敊璇紒")
+        val index = stateRangeIds.indexOf(stateId)
+        if (index == -1) throw ResponseErrorException("浜嬪姟鎵ц鐨勭姸鎬佹棤鏁�")
+        val record = PracticalOperationRecord().apply {
+            poId = operationId
+            poTitle = operation.poTitle
+            prUserId = userId
+            prUserName = userInfo.realname
+            prUserSceneType = userInfo.extension2?.toIntOrNull()
+            prTime = Date()
+            prStateId = stateId
+            prStateName = stateRangeNames[index]
+        }
+        practicalOperationRecordMapper.insert(record)
+        return record
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛瀹炴搷浜嬪姟鎿嶄綔璁板綍
+     * @param userId
+     * @param operationId
+     * @param page
+     * @param perPage
+     */
+    fun getRecords(userId: String, operationId: Int, page: Int = 1, perPage: Int = 30):
+            List<PracticalOperationRecord?> {
+        PageHelper.startPage<PracticalOperationRecord>(page, perPage)
+        return getRecords(userId, listOf(operationId))
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛瀹炴搷浜嬪姟鎿嶄綔璁板綍
+     * @param userId
+     * @param operationIds
+     * @param sT
+     * @param eT
+     * @param isAsc 鏄惁鎸変笂浼犳椂闂存搴忔帓鍒楋紝榛樿false
+     */
+    fun getRecords(
+        userId: String?, operationIds: List<Int?>, sT: LocalDateTime? = null, eT: LocalDateTime? = null,
+        isAsc: Boolean = false,
+    )
+            : List<PracticalOperationRecord?> {
+        return practicalOperationRecordMapper.selectByExample(Example(PracticalOperationRecord::class.java).apply {
+            createCriteria().andIn("poId", operationIds)
+                .andEqualTo("prUserId", userId)
+                .andGreaterThanOrEqualTo("prTime", sT)
+                .andLessThanOrEqualTo("prTime", eT)
+            orderBy("poId").asc()
+                .orderBy("prTime").apply {
+                    if (isAsc) asc() else desc()
+                }
+        })
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/repository/UserConfigRep.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/repository/UserConfigRep.kt
new file mode 100644
index 0000000..ac1f61b
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/repository/UserConfigRep.kt
@@ -0,0 +1,82 @@
+package cn.flightfeather.supervision.domain.repository
+
+import cn.flightfeather.supervision.domain.entity.BaseInfo
+import cn.flightfeather.supervision.domain.entity.UserConfig
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.domain.mapper.BaseInfoMapper
+import cn.flightfeather.supervision.domain.mapper.UserConfigMapper
+import cn.flightfeather.supervision.domain.mapper.UserinfoMapper
+import org.springframework.stereotype.Repository
+import tk.mybatis.mapper.entity.Example
+
+@Repository
+class UserConfigRep(
+    private val userConfigMapper: UserConfigMapper,
+    private val userinfoMapper: UserinfoMapper,
+    private val baseInfoMapper: BaseInfoMapper,
+) {
+
+    fun select(configId: Int): UserConfig? {
+        return userConfigMapper.selectByPrimaryKey(configId)
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛瀵瑰簲鐨勭敤鎴烽厤缃俊鎭�
+     * 閽堝浼佷笟鐢ㄦ埛
+     */
+    fun getUserConfig(userInfo: Userinfo, baseInfo: BaseInfo?): List<UserConfig?> {
+        val res = userConfigMapper.selectByExample(Example(UserConfig::class.java).apply {
+            createCriteria().andEqualTo("ucUserTypeId", userInfo.usertypeid)
+            userInfo.userSubTypeId?.let {
+                and(createCriteria().orEqualTo("ucUserSubtypeId", it)
+                    .orIsNull("ucUserSubtypeId"))
+            }
+            userInfo.extension1?.let {
+                and(createCriteria().orEqualTo("ucDistrictName", it)
+                    .orIsNull("ucDistrictName"))
+            }
+            userInfo.extension2?.let {
+                and(createCriteria().orEqualTo("ucSceneRange", it)
+                    .orIsNull("ucSceneRange"))
+            }
+            baseInfo?.biProvinceCode?.let {
+                and(createCriteria().orEqualTo("ucProvinceCode", it)
+                    .orIsNull("ucProvinceCode"))
+            }
+            baseInfo?.biCityCode?.let {
+                and(createCriteria().orEqualTo("ucCityCode", it)
+                    .orIsNull("ucCityCode"))
+            }
+            baseInfo?.biDistrictCode?.let {
+                and(createCriteria().orEqualTo("ucDistrictCode", it)
+                    .orIsNull("ucDistrictCode"))
+            }
+            baseInfo?.biTownCode?.let {
+                and(createCriteria().orEqualTo("ucTownCode", it)
+                    .orIsNull("ucTownCode"))
+            }
+            baseInfo?.biAreaCode?.let {
+                and(createCriteria().orEqualTo("ucAreaCode", it)
+                    .orIsNull("ucAreaCode"))
+            }
+            baseInfo?.biManagementCompanyId?.let {
+                and(createCriteria().orEqualTo("ucManagementCompanyId", it)
+                    .orIsNull("ucManagementCompanyId"))
+            }
+        })
+//        return if (res.isNotEmpty()) res[0] else null
+        return res
+    }
+
+    fun getUserConfig(userId: String): List<UserConfig?> {
+        val userInfo = userinfoMapper.selectByPrimaryKey(userId) ?: return emptyList()
+        val baseInfo = baseInfoMapper.selectByPrimaryKey(userId)
+        return getUserConfig(userInfo, baseInfo)
+    }
+
+    fun getUserConfigBySubType(userId: String): UserConfig? {
+        val configId = userinfoMapper.selectByPrimaryKey(userId)?.userSubTypeId ?: return null
+        return userConfigMapper.selectByPrimaryKey(configId)
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/repository/UserInfoRep.kt b/src/main/kotlin/cn/flightfeather/supervision/domain/repository/UserInfoRep.kt
new file mode 100644
index 0000000..bee8134
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/repository/UserInfoRep.kt
@@ -0,0 +1,70 @@
+package cn.flightfeather.supervision.domain.repository
+
+import cn.flightfeather.supervision.domain.entity.UserLoginLog
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.domain.enumeration.UserType
+import cn.flightfeather.supervision.domain.mapper.BaseInfoMapper
+import cn.flightfeather.supervision.domain.mapper.UserLoginLogMapper
+import cn.flightfeather.supervision.domain.mapper.UserinfoMapper
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+import org.springframework.stereotype.Repository
+import tk.mybatis.mapper.entity.Example
+import java.util.*
+
+@Repository
+class UserInfoRep(
+    private val userinfoMapper: UserinfoMapper,
+    private val baseInfoMapper: BaseInfoMapper,
+    private val userLoginLogMapper: UserLoginLogMapper,
+) {
+
+    /**
+     * 鎼滅储鐢ㄦ埛
+     */
+    fun searchUser(condition: UserSearchCondition): List<Userinfo> {
+        return userinfoMapper.searchUser(condition)
+    }
+
+    /**
+     * 鐧诲綍鏃ュ織璁板綍
+     */
+    fun loginLog(userId: String?) {
+        userId?.let {
+            userLoginLogMapper.insert(UserLoginLog().apply {
+                ulUserGuid = userId
+                ulLoginTime = Date()
+            })
+        }
+    }
+
+    /**
+     * 鍒濆瀵嗙爜鏈慨鏀圭殑娲昏穬涓殑浼佷笟鐢ㄦ埛
+     */
+    fun pdUnChangeUsers(): List<Userinfo?> {
+        return userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
+            createCriteria().andEqualTo("usertypeid", UserType.Enterprise.value)
+                .andEqualTo("isenable", true)
+            and(createCriteria().orIsNull("remark").orNotEqualTo("remark", "pwChanged"))
+            and(createCriteria().orIsNull("workno").orNotEqualTo("workno", "test"))
+        })
+    }
+
+    /**
+     * 妫�鏌ョ敤鎴蜂俊鎭槸鍚﹂噸澶�
+     */
+    fun checkIsRepeat(userinfo: Userinfo): Pair<Boolean, String> {
+        userinfoMapper.selectByPrimaryKey(userinfo.guid)?.run { return Pair(true, "鐢ㄦ埛id宸插瓨鍦�") }
+        userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
+            createCriteria().andEqualTo("acountname", userinfo.acountname)
+        }).run { if (isNotEmpty()) return Pair(true, "鐢ㄦ埛璐︽埛宸插瓨鍦�") }
+        userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
+            createCriteria().andEqualTo("realname", userinfo.realname)
+        }).run { if (isNotEmpty()) return Pair(true, "鐢ㄦ埛鏄电О宸插瓨鍦�") }
+        return Pair(false, "鐢ㄦ埛鏈噸澶�")
+    }
+
+    fun getUser(userId: String): Userinfo? {
+        return userinfoMapper.selectByPrimaryKey(userId)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/domain/util/MyMapper.java b/src/main/kotlin/cn/flightfeather/supervision/domain/util/MyMapper.java
index c298a95..9fb2894 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/domain/util/MyMapper.java
+++ b/src/main/kotlin/cn/flightfeather/supervision/domain/util/MyMapper.java
@@ -30,9 +30,9 @@
 /**
  * 缁ф壙鑷繁鐨凪yMapper
  *
-         * @author liuzh
-        * @since 2015-09-06 21:53
-        */
+ * @author liuzh
+ * @since 2015-09-06 21:53
+ */
 public interface MyMapper<T> extends Mapper<T>, MySqlMapper<T> {
     //TODO
     //FIXME 鐗瑰埆娉ㄦ剰锛岃鎺ュ彛涓嶈兘琚壂鎻忓埌锛屽惁鍒欎細鍑洪敊
diff --git a/src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/DateUtil.kt b/src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/DateUtil.kt
index bf4b724..f19633a 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/DateUtil.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/DateUtil.kt
@@ -714,6 +714,31 @@
         }
     }
 
+    /**
+     * 鏍规嵁缁欏畾鐨勫懆鏈燂紝杩斿洖鎵�鏈夊彲鑳藉湪鍛ㄦ湡鍐呯殑鍛ㄦ湡缁勫悎
+     * @param period YYYY/M-M
+     */
+    fun getSuitablePeriod(period: String?):List<String> {
+        var year:Int? = null
+        var sMonth:Int? = null
+        var eMonth:Int? = null
+        period?.split("/")?.takeIf { it.size == 2 }?.let { p ->
+            year = p[0].toIntOrNull()
+            p[1].split("-").takeIf { it.size == 2 }?.let { m->
+                sMonth = m[0].toIntOrNull()
+                eMonth = m[1].toIntOrNull()
+            }
+        }
+        val result = mutableListOf<String>()
+        if (year != null && sMonth != null && eMonth != null) {
+            repeat(eMonth!! - sMonth!! + 1) {
+                result.add("${year}/${sMonth}-${sMonth}")
+            }
+            if (sMonth != eMonth) period?.let { result.add(it) }
+        }
+        return  result
+    }
+
     enum class DateStyle private constructor(val value: String, val isShowOnly: Boolean) {
 
         YYYYMMDD("yyyyMMdd", false),
diff --git a/src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/ExcelUtil.kt b/src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/ExcelUtil.kt
index 6a3d664..4bc2b71 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/ExcelUtil.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/ExcelUtil.kt
@@ -22,19 +22,20 @@
     /**
      * 鑷姩澶勭悊琛屽悎骞舵暟鎹�
      */
-    fun write2(heads: List<Array<String>>, contents: List<Array<Any>>, workbook: HSSFWorkbook, sheetName: String = "sheet1") {
+    fun write2(heads: List<Array<Any>>, contents: MutableList<Array<Any>>, workbook: HSSFWorkbook, sheetName: String = "sheet1") {
 
         val sheet = workbook.createSheet(sheetName)
 
         var rowIndex = 0
 
-        heads.forEach {
-            val rows = sheet.createRow(rowIndex)
-            for (i in it.indices) {
-                rows.createCell(i).setCellValue(it[i])
-            }
-            rowIndex++
-        }
+//        heads.forEach {
+//            val rows = sheet.createRow(rowIndex)
+//            for (i in it.indices) {
+//                rows.createCell(i).setCellValue(it[i])
+//            }
+//            rowIndex++
+//        }
+        contents.addAll(0, heads)
 
         contents.forEach {
             val maxRow = getMaxRows(it)
@@ -101,6 +102,7 @@
                         rows.createCell(col).setCellValue(c)
                         println("write1-2: ${c};($rowIndex, ${col})")
                     }
+                    is Int -> rows.createCell(col).setCellValue(c.toDouble())
                     is Double -> rows.createCell(col).setCellValue(c)
                     is Boolean -> rows.createCell(col).setCellValue(c)
                     is Date -> rows.createCell(col).setCellValue(c)
@@ -151,6 +153,7 @@
                                 rows.createCell(map.key).setCellValue(c)
                                 println("write2-2: ${c};($_rowIndex, ${map.key})")
                             }
+                            is Int -> rows.createCell(col).setCellValue(c.toDouble())
                             is Double -> rows.createCell(map.key).setCellValue(c)
                             is Boolean -> rows.createCell(map.key).setCellValue(c)
                             is Date -> rows.createCell(map.key).setCellValue(c)
diff --git a/src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/FileUtil.kt b/src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/FileUtil.kt
index 2c14d00..d52a0a0 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/FileUtil.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/FileUtil.kt
@@ -5,10 +5,7 @@
 import org.springframework.util.Base64Utils
 import java.awt.Image
 import java.awt.image.BufferedImage
-import java.io.ByteArrayInputStream
-import java.io.ByteArrayOutputStream
-import java.io.File
-import java.io.FileOutputStream
+import java.io.*
 import java.util.*
 import javax.imageio.ImageIO
 
@@ -16,7 +13,7 @@
 object FileUtil {
     private const val SCHEME_PNG = "data:image/png;base64,"
 
-    @Throws(Exception::class)
+    @Throws(FileNotFoundException::class)
     fun uploadFile(file: ByteArray, filePath: String, fileName: String) {
         val targetFile = File(filePath)
         if (!targetFile.exists()) {
@@ -28,6 +25,17 @@
         out.close()
     }
 
+    fun deleteFile(path: String) {
+        val targetFile = File(path)
+        if (targetFile.exists()) {
+            try {
+                targetFile.delete()
+            } catch (e: SecurityException) {
+                e.printStackTrace()
+            }
+        }
+    }
+
     /**
      * 鑾峰彇鏂囦欢鍚�
      */
diff --git a/src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/QRCodeUtil.kt b/src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/QRCodeUtil.kt
new file mode 100644
index 0000000..b31d375
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/infrastructure/utils/QRCodeUtil.kt
@@ -0,0 +1,88 @@
+package cn.flightfeather.supervision.infrastructure.utils
+
+import com.google.zxing.BarcodeFormat
+import com.google.zxing.EncodeHintType
+import com.google.zxing.WriterException
+import com.google.zxing.common.CharacterSetECI
+import com.google.zxing.qrcode.QRCodeWriter
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
+import java.awt.Color
+import java.awt.image.BufferedImage
+import java.io.File
+import java.util.*
+import javax.imageio.ImageIO
+
+
+/**
+ * @author riku
+ * Date: 2020/5/21
+ * 浜岀淮鐮佺敓鎴�
+ */
+object QRCodeUtil {
+
+    private var picName = "default"
+
+    /**
+     * 鍒涘缓浜岀淮鐮佷綅鍥� (鏀寔鑷畾涔夐厤缃拰鑷畾涔夋牱寮�)
+     *
+     * @param content 瀛楃涓插唴瀹�
+     * @param width 浣嶅浘瀹藉害,瑕佹眰>=0(鍗曚綅:px)
+     * @param height 浣嶅浘楂樺害,瑕佹眰>=0(鍗曚綅:px)
+     * @param character_set 瀛楃闆�/瀛楃杞爜鏍煎紡 (鏀寔鏍煎紡:[CharacterSetECI])銆備紶null鏃�,zxing婧愮爜榛樿浣跨敤 "ISO-8859-1"
+     * @param error_correction 瀹归敊绾у埆 (鏀寔绾у埆:[ErrorCorrectionLevel])銆備紶null鏃�,zxing婧愮爜榛樿浣跨敤 "L"
+     * @param margin 绌虹櫧杈硅窛 (鍙慨鏀�,瑕佹眰:鏁村瀷涓�>=0), 浼爊ull鏃�,zxing婧愮爜榛樿浣跨敤"4"銆�
+     * @param color_black 榛戣壊鑹插潡鐨勮嚜瀹氫箟棰滆壊鍊�
+     * @param color_white 鐧借壊鑹插潡鐨勮嚜瀹氫箟棰滆壊鍊�
+     * @return
+     */
+    fun createQRCodeBitmap2(
+        content: String?, pName: String = picName, width: Int = 480, height: Int = 480,
+        character_set: String = "UTF-8", error_correction: String = "H", margin: String = "2",
+        color_black: Color = Color.BLACK, color_white: Color = Color.WHITE
+    ): BufferedImage? {
+
+        /** 1.鍙傛暟鍚堟硶鎬у垽鏂�  */
+        if (content.isNullOrEmpty()) { // 瀛楃涓插唴瀹瑰垽绌�
+            return null
+        }
+        if (width < 0 || height < 0) { // 瀹藉拰楂橀兘闇�瑕�>=0
+            return null
+        }
+        try {
+            /** 2.璁剧疆浜岀淮鐮佺浉鍏抽厤缃�,鐢熸垚BitMatrix(浣嶇煩闃�)瀵硅薄  */
+            val hints: Hashtable<EncodeHintType, String?> = Hashtable()
+            if (character_set.isNotEmpty()) {
+                hints[EncodeHintType.CHARACTER_SET] = character_set // 瀛楃杞爜鏍煎紡璁剧疆
+            }
+            if (error_correction.isNotEmpty()) {
+                hints[EncodeHintType.ERROR_CORRECTION] = error_correction // 瀹归敊绾у埆璁剧疆
+            }
+            if (margin.isNotEmpty()) {
+                hints[EncodeHintType.MARGIN] = margin // 绌虹櫧杈硅窛璁剧疆
+            }
+            val bitMatrix = QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints)
+
+            /** 3.鍒涘缓鍍忕礌鏁扮粍,骞舵牴鎹瓸itMatrix(浣嶇煩闃�)瀵硅薄涓烘暟缁勫厓绱犺祴棰滆壊鍊�  */
+            val pixels = IntArray(width * height)
+            for (y in 0 until height) {
+                for (x in 0 until width) {
+                    if (bitMatrix[x, y]) {
+                        pixels[y * width + x] = color_black.rgb // 榛戣壊鑹插潡鍍忕礌璁剧疆
+                    } else {
+                        pixels[y * width + x] = color_white.rgb // 鐧借壊鑹插潡鍍忕礌璁剧疆
+                    }
+                }
+            }
+            /** 4.鍒涘缓Bitmap瀵硅薄,鏍规嵁鍍忕礌鏁扮粍璁剧疆Bitmap姣忎釜鍍忕礌鐐圭殑棰滆壊鍊�,涔嬪悗杩斿洖Bitmap瀵硅薄  */
+            val image = BufferedImage(width, height, BufferedImage.TYPE_INT_RGB)
+            image.raster.setDataElements(0, 0, width, height, pixels)
+
+//            ImageIO.write(image, "png", File("$basePath$pName.png"))
+
+            return image
+        } catch (e: WriterException) {
+            e.printStackTrace()
+        }
+        return null
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/ScheduleRepository.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/ScheduleRepository.kt
new file mode 100644
index 0000000..c4c04ae
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/ScheduleRepository.kt
@@ -0,0 +1,19 @@
+package cn.flightfeather.supervision.lightshare.repository
+
+import cn.flightfeather.supervision.domain.entity.BaseInfo
+import cn.flightfeather.supervision.domain.entity.EnvironmentalSchedule
+import cn.flightfeather.supervision.domain.entity.UserConfig
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.lightshare.vo.ScheduleOption
+
+interface ScheduleRepository {
+
+    /**
+     * 鑾峰彇鐢ㄦ埛鐨勬棩绋�
+     */
+    fun getSchedules(userInfo: Userinfo, config: List<UserConfig?>, option: ScheduleOption): List<EnvironmentalSchedule?>
+
+    /**
+     * 鎸夌収鏃堕棿鑾峰彇瀵瑰簲鐨勬棩绋嬬鏀惰褰�
+     */
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/ScheduleSignRecordRepository.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/ScheduleSignRecordRepository.kt
new file mode 100644
index 0000000..fc9f10c
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/ScheduleSignRecordRepository.kt
@@ -0,0 +1,12 @@
+package cn.flightfeather.supervision.lightshare.repository
+
+import cn.flightfeather.supervision.domain.entity.ScheduleSignRecord
+import java.util.*
+
+interface ScheduleSignRecordRepository {
+
+    /**
+     * 鎸夌収鏃堕棿鑾峰彇瀵瑰簲鐨勬棩绋嬬鏀惰褰�
+     */
+    fun getRecord(userId: String?, scheduleId: Int?, sTime: Date?, eTime: Date?): List<ScheduleSignRecord?>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/MeetingVMRoomRepositoryImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/MeetingVMRoomRepositoryImpl.kt
index 4cc23b1..895001d 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/MeetingVMRoomRepositoryImpl.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/MeetingVMRoomRepositoryImpl.kt
@@ -32,10 +32,10 @@
             vmrCreateentguid = company.ciGuid
             vmrCreateentname=company.ciName
             vmrCreatorid = userId
-            vmrCreator = user.acountname
+            vmrCreator = user?.acountname
             vmrUpdatedate= Date()
             vmrModifierid = userId
-            vmrModifier = user.acountname
+            vmrModifier = user?.acountname
 
             vmrRoomcode=UUIDGenerator.generateShortUUID()
         }
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/ScheduleRepositoryImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/ScheduleRepositoryImpl.kt
new file mode 100644
index 0000000..4f1de9c
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/ScheduleRepositoryImpl.kt
@@ -0,0 +1,24 @@
+package cn.flightfeather.supervision.lightshare.repository.impl
+
+import cn.flightfeather.supervision.domain.entity.EnvironmentalSchedule
+import cn.flightfeather.supervision.domain.entity.UserConfig
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.domain.mapper.EnvironmentalScheduleMapper
+import cn.flightfeather.supervision.lightshare.repository.ScheduleRepository
+import cn.flightfeather.supervision.lightshare.vo.ScheduleOption
+import org.springframework.stereotype.Repository
+
+@Repository
+class ScheduleRepositoryImpl(private val scheduleMapper: EnvironmentalScheduleMapper) : ScheduleRepository {
+
+    override fun getSchedules(
+        userInfo: Userinfo,
+        configs: List<UserConfig?>,
+        option: ScheduleOption,
+    ): List<EnvironmentalSchedule?> {
+        if (userInfo.guid == null || configs.isEmpty() || userInfo.extension2 == null) return emptyList()
+        val configId = mutableListOf<Int>()
+        configs.forEach { it?.let { configId.add(it.ucId) } }
+        return scheduleMapper.getSchedules(userInfo.guid!!, configId, userInfo.extension2!!, option.type)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/ScheduleSignRecordRepositoryImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/ScheduleSignRecordRepositoryImpl.kt
new file mode 100644
index 0000000..62e0718
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/ScheduleSignRecordRepositoryImpl.kt
@@ -0,0 +1,21 @@
+package cn.flightfeather.supervision.lightshare.repository.impl
+
+import cn.flightfeather.supervision.domain.entity.ScheduleSignRecord
+import cn.flightfeather.supervision.domain.mapper.ScheduleSignRecordMapper
+import cn.flightfeather.supervision.lightshare.repository.ScheduleSignRecordRepository
+import org.springframework.stereotype.Repository
+import tk.mybatis.mapper.entity.Example
+import java.util.*
+
+@Repository
+class ScheduleSignRecordRepositoryImpl(private val scheduleSignRecordMapper: ScheduleSignRecordMapper) :
+    ScheduleSignRecordRepository {
+
+    override fun getRecord(userId: String?, scheduleId: Int?, sTime: Date?, eTime: Date?): List<ScheduleSignRecord?> {
+        return scheduleSignRecordMapper.selectByExample(Example(ScheduleSignRecord::class.java).apply {
+            createCriteria().andEqualTo("srScheduleId", scheduleId)
+                .andEqualTo("srUserId", userId)
+                .andBetween("srSignTime", sTime, eTime)
+        })
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/AuthService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/AuthService.kt
index 40102da..3e57984 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/AuthService.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/AuthService.kt
@@ -2,6 +2,7 @@
 
 import cn.flightfeather.supervision.domain.entity.Company
 import cn.flightfeather.supervision.domain.entity.PersonalInfo
+import cn.flightfeather.supervision.domain.entity.Userinfo
 import cn.flightfeather.supervision.domain.enumeration.SceneType
 import cn.flightfeather.supervision.lightshare.vo.AuthSceneVo
 import cn.flightfeather.supervision.lightshare.vo.BaseResponse
@@ -30,4 +31,13 @@
      * @return 璁よ瘉鐘舵�侊紝 [浼佷笟璁よ瘉鐘舵��, 鍦烘櫙璁よ瘉鐘舵��, 涓汉璁よ瘉鐘舵�乚
      */
     fun authStatus(wxUserId: String?, userId: String?): BaseResponse<List<Boolean>>
+
+    /**
+     * 鑾峰彇浼佷笟璁よ瘉鐘舵��
+     * @param userId 鍦烘櫙鐢ㄦ埛id
+     * @return 璁よ瘉鐘舵�侊紝 [浼佷笟璁よ瘉鐘舵��, 鍦烘櫙璁よ瘉鐘舵��, 涓汉璁よ瘉鐘舵�乚
+     */
+    fun sceneAuthStatus(userId: String?): BaseResponse<List<Boolean>>
+
+    fun getUnAuthedUsers(): BaseResponse<List<Userinfo?>>
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/BaseInfoService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/BaseInfoService.kt
new file mode 100644
index 0000000..8f3b5fb
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/BaseInfoService.kt
@@ -0,0 +1,17 @@
+package cn.flightfeather.supervision.lightshare.service
+
+import cn.flightfeather.supervision.domain.entity.BaseInfo
+import cn.flightfeather.supervision.lightshare.vo.BaseInfoVo
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+
+interface BaseInfoService {
+
+    fun findOne(id: String): BaseResponse<BaseInfo>
+
+    fun save(info: BaseInfo): BaseResponse<Int>
+
+    fun update(info: BaseInfo): BaseResponse<Int>
+
+    fun searchUser(condition: UserSearchCondition, page: Int, perPage: Int): BaseResponse<List<BaseInfoVo?>>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/CommitmentService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/CommitmentService.kt
index ad58d5b..89b9776 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/CommitmentService.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/CommitmentService.kt
@@ -1,6 +1,7 @@
 package cn.flightfeather.supervision.lightshare.service
 
 import cn.flightfeather.supervision.domain.entity.Commitment
+import cn.flightfeather.supervision.domain.entity.CommitmentTemplate
 import cn.flightfeather.supervision.lightshare.vo.BaseResponse
 import cn.flightfeather.supervision.lightshare.vo.CommitmentVo
 import org.springframework.web.multipart.MultipartFile
@@ -10,6 +11,8 @@
 
     fun getLetterOfCommitment(userId: String, page: Int, perPage: Int, response: HttpServletResponse): List<Commitment>
 
+    fun getTemplateOfCommitment(userId: String): BaseResponse<CommitmentTemplate>
+
     fun uploadLetterOfCommitment(userId: String, commitmentVoList: String, files: Array<MultipartFile>): Boolean
 
     fun createLetterOfCommitment(userId: String, info: String, sign: MultipartFile?, seal: MultipartFile?): BaseResponse<List<String>>
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/CompanyService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/CompanyService.kt
new file mode 100644
index 0000000..fe55939
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/CompanyService.kt
@@ -0,0 +1,13 @@
+package cn.flightfeather.supervision.lightshare.service
+
+import cn.flightfeather.supervision.domain.entity.Company
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+
+interface CompanyService {
+
+    fun findOne(id: String): BaseResponse<Company>
+
+    fun save(userId:String, info: Company): BaseResponse<Int>
+
+    fun update(userId: String, info: Company): BaseResponse<Int>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ComplaintService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ComplaintService.kt
index aaeda5c..7ca6f5d 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ComplaintService.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ComplaintService.kt
@@ -5,7 +5,17 @@
 
 interface ComplaintService {
 
+    // 淇¤鎶曡瘔
     fun getComplaints(userId: String): List<Complaint>
 
+    fun saveComplaint(info: Complaint): Int
+
+    fun updateComplaint(info: Complaint): Int
+
+    // 琛屾斂澶勭綒
     fun getPunishment(userId: String): List<Punishment>
+
+    fun savePunishment(info: Punishment): Int
+
+    fun updatePunishment(info: Punishment): Int
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ConfigService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ConfigService.kt
new file mode 100644
index 0000000..7325099
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ConfigService.kt
@@ -0,0 +1,24 @@
+package cn.flightfeather.supervision.lightshare.service
+
+import cn.flightfeather.supervision.domain.entity.CommitmentTemplate
+import cn.flightfeather.supervision.domain.entity.UserConfig
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+
+interface ConfigService {
+
+    /**
+     * 鏍规嵁鐢ㄦ埛鑾峰彇瀵瑰簲鍙敤鍦烘櫙绫诲瀷
+     * @param userId 璇锋眰鐢ㄦ埛id
+     */
+    fun getSceneRange(userId: String): List<Pair<String?, String?>>?
+
+    /**
+     * 鏍规嵁鍦烘櫙绫诲瀷鍜岃鏀垮尯鍒掕幏鍙栨壙璇烘ā鏉夸俊鎭�
+     * @param condition 鏌ヨ鏉′欢锛屼娇鐢ㄤ簡鍏朵腑鐨刐UserSearchCondition.sceneTypes],[UserSearchCondition.provinceCode]
+     * [UserSearchCondition.cityCode],[UserSearchCondition.districtCode],[[UserSearchCondition.townCode]]
+     */
+    fun getCommitmentTemplate(condition: UserSearchCondition): CommitmentTemplate?
+
+    fun getUserConfig(userId: String): UserConfig?
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/CreditService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/CreditService.kt
new file mode 100644
index 0000000..0d99b2e
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/CreditService.kt
@@ -0,0 +1,13 @@
+package cn.flightfeather.supervision.lightshare.service
+
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import cn.flightfeather.supervision.lightshare.vo.CreditInfoVo
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+import javax.servlet.http.HttpServletResponse
+
+interface CreditService {
+
+    fun searchEcCodeList(userId: String, condition: UserSearchCondition, page: Int, perPage: Int): BaseResponse<List<CreditInfoVo>>
+
+    fun downloadEcCodeImg(userId: String, response: HttpServletResponse): BaseResponse<Boolean>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/DeviceService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/DeviceService.kt
index 9bffdc7..a0f402b 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/DeviceService.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/DeviceService.kt
@@ -2,6 +2,7 @@
 
 import cn.flightfeather.supervision.domain.entity.FumePurifyDevice
 import cn.flightfeather.supervision.domain.entity.MonitorDevice
+import cn.flightfeather.supervision.domain.entity.VocPurifyDevice
 import cn.flightfeather.supervision.lightshare.vo.BaseResponse
 import cn.flightfeather.supervision.lightshare.vo.DataVo
 import cn.flightfeather.supervision.lightshare.vo.DateVo
@@ -11,7 +12,15 @@
 
     fun getPurifyDeviceInfo(userId: String): List<FumePurifyDevice>
 
+    fun saveFumePurifyDevice(info: FumePurifyDevice): Int
+
+    fun updateFumePurifyDevice(info: FumePurifyDevice): Int
+
     fun getMonitorDeviceInfo(userId: String): List<MonitorDevice>
+
+    fun saveMonitorDevice(info: MonitorDevice): Int
+
+    fun updateMonitorDevice(info: MonitorDevice): Int
 
     fun getLatestMinuteValue(userId: String):List<DataVo>
 
@@ -22,4 +31,15 @@
     fun getHistoryValue(userId: String, startTime: String, endTime: String, period: Byte): List<DataVo>
 
     fun getRealTimeData(page: Int, perPage: Int): BaseResponse<List<DataVo>>
+
+    fun getJingAnDustHourValue(userId: String, startTime: String?, endTime: String?): List<DataVo>
+
+    fun getJingAnFumeValue(userId: String, startTime: String?, endTime: String?): List<DataVo>
+
+    fun getDeviceInfo(userId: String)
+
+    fun saveVOCPurifyDevice(userId: String, infoList: List<VocPurifyDevice>): Int
+
+    fun getVOCPurifyDevice(userId: String): List<VocPurifyDevice?>
+
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/EnforceCaseService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/EnforceCaseService.kt
new file mode 100644
index 0000000..396c586
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/EnforceCaseService.kt
@@ -0,0 +1,10 @@
+package cn.flightfeather.supervision.lightshare.service
+
+import cn.flightfeather.supervision.domain.entity.EnforceCase
+
+interface EnforceCaseService {
+
+    fun addCase(userId: String, enforceCase: EnforceCase): Int
+
+    fun updateCase(userId: String, enforceCase: EnforceCase): Int
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/EvaluationService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/EvaluationService.kt
index 315e1d2..02e417c 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/EvaluationService.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/EvaluationService.kt
@@ -1,10 +1,7 @@
 package cn.flightfeather.supervision.lightshare.service
 
 import cn.flightfeather.supervision.domain.entity.Evaluation
-import cn.flightfeather.supervision.lightshare.vo.AssessmentGradeVo
-import cn.flightfeather.supervision.lightshare.vo.AssessmentSearchCondition
-import cn.flightfeather.supervision.lightshare.vo.CreditInfoVo
-import cn.flightfeather.supervision.lightshare.vo.GradeDetailVo
+import cn.flightfeather.supervision.lightshare.vo.*
 import javax.servlet.http.HttpServletResponse
 
 
@@ -21,9 +18,11 @@
 
     fun getTotalPoints(userId: String, evaluatorType: Int, startTime: String, endTime: String, sceneTypeId: Int? = null, erGuid: String? = null, eId: String? = null): List<Evaluation>
 
-    fun getHistoryPoint(userId: String, page: Int, per_page: Int, platform:String?, response: HttpServletResponse): List<AssessmentGradeVo>
+    fun getHistoryPoint(userId: String, page: Int, per_page: Int, platform: String?, period: String?, response: HttpServletResponse): List<AssessmentGradeVo>
 
-    fun getCreditInfo(userId: String): CreditInfoVo
+    fun getCreditInfo(userId: String, period: String?): CreditInfoVo
+
+    fun getCreditCount(userId: String, condition: UserSearchCondition): BaseResponse<CountVo>
 
     fun getAssessments(userId: String, condition: AssessmentSearchCondition, page: Int, perPage: Int, response: HttpServletResponse): List<AssessmentGradeVo>
 
@@ -31,5 +30,9 @@
 
     fun uploadScore(userId: String, period: String, ruleId: String?, itemList: List<Pair<String, String>>): Boolean
 
+    fun updateScore(userId: String, period: String, ruleId: String?, itemList: List<Pair<String, String>>): Boolean
+
     fun getDetail(userId: String, period: String): GradeDetailVo
+
+    fun searchGradeList(userId: String, condition: UserSearchCondition, page: Int, perPage: Int): BaseResponse<List<CreditInfoVo>>
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/HazardousWasteService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/HazardousWasteService.kt
index 42a63a2..fef7369 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/HazardousWasteService.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/HazardousWasteService.kt
@@ -2,11 +2,18 @@
 
 import cn.flightfeather.supervision.domain.entity.HWFile
 import cn.flightfeather.supervision.domain.entity.HWRecord
-import cn.flightfeather.supervision.lightshare.vo.BaseResponse
 
 interface HazardousWasteService {
 
     fun getFile(userId: String): List<HWFile?>
 
+    fun saveHWFile(info: HWFile): Int
+
+    fun updateHWFile(info: HWFile): Int
+
     fun getRecord(userId: String, year: String?): List<HWRecord?>
+
+    fun saveHWRecord(info: HWRecord): Int
+
+    fun updateHWRecord(info: HWRecord): Int
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/AuthServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/AuthServiceImpl.kt
index 7262457..c4828eb 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/AuthServiceImpl.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/AuthServiceImpl.kt
@@ -7,6 +7,7 @@
 import cn.flightfeather.supervision.infrastructure.utils.PinYin
 import cn.flightfeather.supervision.infrastructure.utils.UUIDGenerator
 import cn.flightfeather.supervision.lightshare.service.AuthService
+import cn.flightfeather.supervision.lightshare.vo.AuthSceneIndVo
 import cn.flightfeather.supervision.lightshare.vo.AuthSceneRestVo
 import cn.flightfeather.supervision.lightshare.vo.AuthSceneVo
 import cn.flightfeather.supervision.lightshare.vo.BaseResponse
@@ -14,6 +15,7 @@
 import org.springframework.stereotype.Service
 import org.springframework.transaction.annotation.Transactional
 import tk.mybatis.mapper.entity.Example
+import java.util.*
 
 @Service
 class AuthServiceImpl(
@@ -25,7 +27,9 @@
     private val fumePurifyDeviceMapper: FumePurifyDeviceMapper,
     private val monitorDeviceMapper: MonitorDeviceMapper,
     private val restaurantBaseInfoMapper: RestaurantBaseInfoMapper,
-    private val vehicleBaseInfoMapper: VehicleBaseInfoMapper
+    private val vehicleBaseInfoMapper: VehicleBaseInfoMapper,
+    private val industrialBaseInfoMapper: IndustrialBaseInfoMapper,
+    private val vocPurifyDeviceMapper: VocPurifyDeviceMapper,
 ): AuthService {
 
     @Transactional
@@ -43,6 +47,17 @@
             bInfo.ciGuid = company.ciGuid
             bInfo.ciName = company.ciName
             baseInfoMapper.updateByPrimaryKeySelective(bInfo)
+        } else {
+            val userInfo = userinfoMapper.selectByPrimaryKey(wxUser.uiGuid)
+            val baseInfo = BaseInfo().apply {
+                biGuid = wxUser.uiGuid
+                biName = userInfo?.realname
+                ciGuid = company.ciGuid
+                ciName = company.ciName
+                biCreateTime = Date()
+                biExtension1 = userInfo?.acountname
+            }
+            baseInfoMapper.insertSelective(baseInfo)
         }
         if (wxUser.ciGuid != company.ciGuid) {
             wxUser.ciGuid = company.ciGuid
@@ -61,25 +76,34 @@
         var bInfo = if (wxUser.uiGuid == null) null else baseInfoMapper.selectByPrimaryKey(wxUser.uiGuid)
         if (bInfo == null) {
             val cInfo = if (wxUser.ciGuid == null) null else companyMapper.selectByPrimaryKey(wxUser.ciGuid)
-            val name = getUName(asVo.biName ?: "")
-            //鏂板缓鍦烘櫙璐﹀彿鍙婂満鏅俊鎭�
-            val newUser = Userinfo().apply {
-                guid = UUIDGenerator.generate16ShortUUID()
-                acountname = name
-                realname = asVo.biName
-                password = "123456"
-                usertypeid = 3
-                usertype = "浼佷笟"
-                isenable = true
-                if (asVo.biLocation.isNotEmpty()) extension1 = asVo.biLocation[2]
-                extension2 = sceneType.toString()
+            val user = userinfoMapper.selectByPrimaryKey(wxUser.uiGuid)
+            if (user == null) {
+                val name = getUName(asVo.biName ?: "")
+                //鏂板缓鍦烘櫙璐﹀彿鍙婂満鏅俊鎭�
+                val user = Userinfo().apply {
+                    guid = UUIDGenerator.generate16ShortUUID()
+                    acountname = name
+                    realname = asVo.biName
+                    password = "123456"
+                    usertypeid = 3
+                    usertype = "浼佷笟"
+                    isenable = true
+                    if (asVo.biLocation.isNotEmpty()) extension1 = asVo.biLocation[2]
+                    extension2 = sceneType.toString()
+                }
+                userinfoMapper.insert(user)
+            } else {
+                user.apply {
+                    realname = asVo.biName
+                    if (asVo.biLocation.isNotEmpty()) extension1 = asVo.biLocation[2]
+                }
+                userinfoMapper.updateByPrimaryKeySelective(user)
             }
-            bInfo = asVo.toNewBaseInfo(newUser, cInfo)
-            userinfoMapper.insert(newUser)
+            bInfo = asVo.toNewBaseInfo(user, cInfo)
             baseInfoMapper.insert(bInfo)
         } else {
             val userInfo = userinfoMapper.selectByPrimaryKey(bInfo.biGuid)
-            userInfo.apply {
+            userInfo?.apply {
                 realname = asVo.biName
                 if (asVo.biLocation.isNotEmpty()) extension1 = asVo.biLocation[2]
             }
@@ -136,7 +160,18 @@
                 val info = gson.fromJson(sceneInfo, AuthSceneVo::class.java)
             }
             SceneType.Industrial.value -> {
-                val info = gson.fromJson(sceneInfo, AuthSceneVo::class.java)
+                val info = gson.fromJson(sceneInfo, AuthSceneIndVo::class.java)
+                //宸ヤ笟浼佷笟鍩烘湰淇℃伅褰曞叆
+                var rbInfo = industrialBaseInfoMapper.selectByPrimaryKey(userId)
+                if (rbInfo == null) {
+                    rbInfo = info.toNewIndInfo(userId)
+                    industrialBaseInfoMapper.insert(rbInfo)
+                } else {
+                    info.updateIndInfo(rbInfo)
+                    industrialBaseInfoMapper.updateByPrimaryKeySelective(rbInfo)
+                }
+//                industrialBaseInfoMapper
+//                vocPurifyDeviceMapper
             }
             SceneType.VehicleRepair.value -> {
                 val info = gson.fromJson(sceneInfo, AuthSceneVo::class.java)
@@ -150,6 +185,8 @@
     override fun authPersonal(wxUserId: String, personalInfo: PersonalInfo): BaseResponse<String> {
         val wxUser = userInfoWxMapper.selectByPrimaryKey(wxUserId) ?: return BaseResponse(false, "鐢ㄦ埛寰俊id涓嶅瓨鍦�")
         personalInfo.piExtension3 = AuthenticationStatus.YES.des
+        personalInfo.piWxId = wxUserId
+        personalInfo.piSceneId = wxUser.uiGuid
         if (personalInfo.piGuid == null) {
             personalInfo.piGuid = UUIDGenerator.generate16ShortUUID()
             personalInfoMapper.insert(personalInfo)
@@ -180,12 +217,16 @@
                 }
             }
             //鍒ゆ柇涓汉淇℃伅鏄惁璁よ瘉
-            if (wxUser.piGuid != null) {
-                personalInfoMapper.selectByPrimaryKey(wxUser.piGuid)?.let { p ->
+            if (wxUser.uiGuid != null) {
+                personalInfoMapper.selectByExample(Example(PersonalInfo::class.java).apply {
+                    createCriteria().andEqualTo("piSceneId", wxUser.uiGuid)
+                        .andEqualTo("piWxId", wxUser.uiOpenId)
+                })?.takeIf { it.isNotEmpty() }?.get(0)?.let { p ->
                     if (p.piExtension3 == AuthenticationStatus.YES.des) status[2] = true
                 }
             }
-        }else if (userId != null) {
+        }
+        if (userId != null) {
             val user = userinfoMapper.selectByPrimaryKey(userId) ?: return BaseResponse(false, "璇ュ満鏅处鎴蜂笉瀛樺湪")
             val baseInfo = baseInfoMapper.selectByPrimaryKey(userId)
             //鍒ゆ柇浼佷笟淇℃伅鏄惁璁よ瘉
@@ -197,7 +238,37 @@
             //鍒ゆ柇鍦烘櫙淇℃伅鏄惁璁よ瘉
             if (baseInfo?.biExtension3 == AuthenticationStatus.YES.des) status[1] = true
             //鍒ゆ柇涓汉淇℃伅鏄惁璁よ瘉
-            // TODO: 2022/10/11 姝ゅ垎鏀笅鏆傛椂鏃犱釜浜鸿璇�
+            userInfoWxMapper.selectByExample(Example(UserInfoWx::class.java).apply {
+                createCriteria().andEqualTo("uiGuid", userId)
+            })?.takeIf { it.isNotEmpty() }?.get(0)?.let {
+                personalInfoMapper.selectByExample(Example(PersonalInfo::class.java).apply {
+                    createCriteria().andEqualTo("piSceneId", it.uiGuid)
+                        .andEqualTo("piWxId", it.uiOpenId)
+                })?.takeIf { it.isNotEmpty() }?.get(0)?.let { p ->
+                    if (p.piExtension3 == AuthenticationStatus.YES.des) status[2] = true
+                }
+            }
+        }
+
+        return BaseResponse(true, data = status)
+    }
+
+    override fun sceneAuthStatus(userId: String?): BaseResponse<List<Boolean>> {
+        val status = mutableListOf(false, false, false)
+        val base = baseInfoMapper.selectByPrimaryKey(userId) ?: return BaseResponse(false, "璇ュ井淇¤处鎴蜂笉瀛樺湪")
+        //鍒ゆ柇浼佷笟淇℃伅鏄惁璁よ瘉
+        if (base.ciGuid != null) {
+            companyMapper.selectByPrimaryKey(base.ciGuid)?.let { c ->
+                if (c.ciExtension3 == AuthenticationStatus.YES.des) status[0] = true
+            }
+        }
+        //鍒ゆ柇鍦烘櫙淇℃伅鏄惁璁よ瘉
+        if (base.biExtension3 == AuthenticationStatus.YES.des) status[1] = true
+        //鍒ゆ柇涓汉淇℃伅鏄惁璁よ瘉
+        personalInfoMapper.selectByExample(Example(PersonalInfo::class.java).apply {
+            createCriteria().andEqualTo("piSceneId", base.biGuid)
+        })?.takeIf { it.isNotEmpty() }?.get(0)?.let { p ->
+            if (p.piExtension3 == AuthenticationStatus.YES.des) status[2] = true
         }
 
         return BaseResponse(true, data = status)
@@ -221,4 +292,9 @@
         if (repeated) uName = UUIDGenerator.generateShortUUID()
         return uName
     }
+
+    override fun getUnAuthedUsers(): BaseResponse<List<Userinfo?>> {
+        val res = userinfoMapper.getUnAuthedUsers()
+        return BaseResponse(true, data = res)
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/BaseInfoServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/BaseInfoServiceImpl.kt
new file mode 100644
index 0000000..d180905
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/BaseInfoServiceImpl.kt
@@ -0,0 +1,56 @@
+package cn.flightfeather.supervision.lightshare.service.Impl
+
+import cn.flightfeather.supervision.domain.entity.BaseInfo
+import cn.flightfeather.supervision.domain.mapper.BaseInfoMapper
+import cn.flightfeather.supervision.domain.mapper.UserinfoMapper
+import cn.flightfeather.supervision.infrastructure.utils.UUIDGenerator
+import cn.flightfeather.supervision.lightshare.service.BaseInfoService
+import cn.flightfeather.supervision.lightshare.vo.BaseInfoVo
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import cn.flightfeather.supervision.lightshare.vo.DataHead
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+import com.github.pagehelper.PageHelper
+import org.springframework.stereotype.Service
+import java.util.*
+
+@Service
+class BaseInfoServiceImpl(
+    private val baseInfoMapper: BaseInfoMapper,
+    private val userinfoMapper: UserinfoMapper,
+) : BaseInfoService {
+
+    override fun findOne(id: String): BaseResponse<BaseInfo> {
+        val res = baseInfoMapper.selectByPrimaryKey(id) ?: return BaseResponse(false, "鐢ㄦ埛id涓嶅瓨鍦�")
+        return BaseResponse(true, data = res)
+    }
+
+    override fun save(info: BaseInfo): BaseResponse<Int> {
+        if (info.biGuid == null) return BaseResponse(false, "鐢ㄦ埛涓婚敭涓嶈兘涓虹┖")
+        baseInfoMapper.selectByPrimaryKey(info.biGuid)?.run { return BaseResponse(false, "鐢ㄦ埛鍩烘湰淇℃伅涓嶈兘閲嶅鍒涘缓") }
+        userinfoMapper.selectByPrimaryKey(info.biGuid) ?: return BaseResponse(false, "璇ョ敤鎴穒d璐﹀彿涓嶅瓨鍦�")
+        info.biCreateTime = Date()
+        info.biUpdateTime = info.biCreateTime
+        val res = baseInfoMapper.insert(info)
+        return if (res == 1) {
+            BaseResponse(true, data = res)
+        } else {
+            BaseResponse(false, "鎻掑叆鏁版嵁搴撳け璐�", data = res)
+        }
+    }
+
+    override fun update(info: BaseInfo): BaseResponse<Int> {
+        info.biUpdateTime = Date()
+        val res = baseInfoMapper.updateByPrimaryKeySelective(info)
+        return if (res == 1) {
+            BaseResponse(true, data = res)
+        } else {
+            BaseResponse(false, "鏇存柊鏁版嵁搴撳け璐�", data = res)
+        }
+    }
+
+    override fun searchUser(condition: UserSearchCondition, page: Int, perPage: Int,): BaseResponse<List<BaseInfoVo?>> {
+        val p = PageHelper.startPage<BaseInfoVo>(page, perPage)
+        baseInfoMapper.searchUser(condition)
+        return BaseResponse(true, head = DataHead(p.pageNum, p.pages, p.total), data = p.result)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/CommitmentServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/CommitmentServiceImpl.kt
index 693e017..a52c293 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/CommitmentServiceImpl.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/CommitmentServiceImpl.kt
@@ -3,6 +3,7 @@
 import cn.flightfeather.supervision.common.pdf.DynamicParam
 import cn.flightfeather.supervision.common.pdf.GeneratePdfUtil
 import cn.flightfeather.supervision.domain.entity.Commitment
+import cn.flightfeather.supervision.domain.entity.CommitmentTemplate
 import cn.flightfeather.supervision.domain.enumeration.SceneType
 import cn.flightfeather.supervision.domain.mapper.CommitmentMapper
 import cn.flightfeather.supervision.domain.mapper.UserinfoMapper
@@ -46,6 +47,10 @@
         response.setIntHeader("totalPage", p.pages)
         response.setIntHeader("currentPage", p.pageNum)
         return result
+    }
+
+    override fun getTemplateOfCommitment(userId: String): BaseResponse<CommitmentTemplate> {
+        TODO("Not yet implemented")
     }
 
     override fun uploadLetterOfCommitment(userId: String, commitmentVoList: String, files: Array<MultipartFile>): Boolean {
@@ -116,15 +121,22 @@
             SceneType.Construction.value,
             SceneType.Wharf.value,
             SceneType.StorageYard.value,
-            SceneType.MixingPlant.value,
-            SceneType.Industrial.value -> {
+            SceneType.MixingPlant.value -> {
                 templateName = "commitment-construction.ftl"
                 contractName = "commitment-construction-${now.time}.pdf"
+            }
+            SceneType.Industrial.value->{
+                templateName = "commitment-industrial.ftl"
+                contractName = "commitment-industrial-${now.time}.pdf"
             }
             SceneType.VehicleRepair.value -> {
                 templateName = "commitment-vehicle.ftl"
                 contractName = "commitment-vehicle-${now.time}.pdf"
             }
+            SceneType.Laboratory.value -> {
+                templateName = "commitment-laboratory.ftl"
+                contractName = "commitment-laboratory-${now.time}.pdf"
+            }
         }
 //        val picName = contractName.replace("pdf", "jpg")
 
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/CompanyServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/CompanyServiceImpl.kt
new file mode 100644
index 0000000..011b46c
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/CompanyServiceImpl.kt
@@ -0,0 +1,50 @@
+package cn.flightfeather.supervision.lightshare.service.Impl
+
+import cn.flightfeather.supervision.domain.entity.Company
+import cn.flightfeather.supervision.domain.mapper.BaseInfoMapper
+import cn.flightfeather.supervision.domain.mapper.CompanyMapper
+import cn.flightfeather.supervision.infrastructure.utils.UUIDGenerator
+import cn.flightfeather.supervision.lightshare.service.CompanyService
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import org.springframework.stereotype.Service
+
+@Service
+class CompanyServiceImpl(
+    private val companyMapper: CompanyMapper,
+    private val baseInfoMapper: BaseInfoMapper,
+) : CompanyService {
+
+    override fun findOne(id: String): BaseResponse<Company> {
+        val res = companyMapper.selectByPrimaryKey(id) ?: return BaseResponse(false, "鐢ㄦ埛id涓嶅瓨鍦�")
+        return BaseResponse(true, data = res)
+    }
+
+    override fun save(userId: String, info: Company): BaseResponse<Int> {
+        if (info.ciGuid != null) return BaseResponse(false, "鐢ㄦ埛浼佷笟涓婚敭涓嶈兘鑷鍒涘缓")
+        val baseInfo = baseInfoMapper.selectByPrimaryKey(userId) ?: return BaseResponse(false, "鍒涘缓鍏徃淇℃伅涔嬪墠璇峰厛鍒涘缓鐢ㄦ埛鍩烘湰淇℃伅")
+        info.ciGuid = UUIDGenerator.generate16ShortUUID()
+        baseInfo.ciGuid = info.ciGuid
+        baseInfo.ciName = info.ciName
+        baseInfoMapper.updateByPrimaryKeySelective(baseInfo)
+        val res = companyMapper.insert(info)
+        return if (res == 1) {
+            BaseResponse(true, data = res)
+        } else {
+            BaseResponse(false, "鎻掑叆鏁版嵁搴撳け璐�", data = res)
+        }
+    }
+
+    override fun update(userId: String, info: Company): BaseResponse<Int> {
+        val baseInfo = baseInfoMapper.selectByPrimaryKey(userId)
+        if (baseInfo.ciGuid == info.ciGuid) {
+            baseInfo.ciName = info.ciName
+            baseInfoMapper.updateByPrimaryKeySelective(baseInfo)
+        }
+        val res = companyMapper.updateByPrimaryKeySelective(info)
+        return if (res == 1) {
+            BaseResponse(true, data = res)
+        } else {
+            BaseResponse(false, "鏇存柊鏁版嵁搴撳け璐�", data = res)
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ComplaintServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ComplaintServiceImpl.kt
index a7f61d1..d773ece 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ComplaintServiceImpl.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ComplaintServiceImpl.kt
@@ -21,10 +21,30 @@
         })
     }
 
+    override fun saveComplaint(info: Complaint): Int {
+        // TODO: 2023/3/20 not yet implemented
+        return 0
+    }
+
+    override fun updateComplaint(info: Complaint): Int {
+        // TODO: 2023/3/20 not yet implemented
+        return 0
+    }
+
     override fun getPunishment(userId: String): List<Punishment> {
         return punishmentMapper.selectByExample(Example(Punishment::class.java).apply {
             createCriteria().andEqualTo("pmSceneId", userId)
             orderBy("pmTime").desc()
         })
     }
+
+    override fun savePunishment(info: Punishment): Int {
+        // TODO: 2023/3/20 not yet implemented
+        return 0
+    }
+
+    override fun updatePunishment(info: Punishment): Int {
+        // TODO: 2023/3/20 not yet implemented
+        return 0
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ConfigServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ConfigServiceImpl.kt
new file mode 100644
index 0000000..96887b0
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ConfigServiceImpl.kt
@@ -0,0 +1,68 @@
+package cn.flightfeather.supervision.lightshare.service.Impl
+
+import cn.flightfeather.supervision.common.exception.ResponseErrorException
+import cn.flightfeather.supervision.domain.entity.CommitmentTemplate
+import cn.flightfeather.supervision.domain.entity.SceneType
+import cn.flightfeather.supervision.domain.entity.UserConfig
+import cn.flightfeather.supervision.domain.mapper.*
+import cn.flightfeather.supervision.domain.repository.UserConfigRep
+import cn.flightfeather.supervision.lightshare.service.ConfigService
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+import org.springframework.stereotype.Service
+import tk.mybatis.mapper.entity.Example
+
+@Service
+class ConfigServiceImpl(
+    private val userinfoMapper: UserinfoMapper,
+    private val userConfigMapper: UserConfigMapper,
+    private val baseInfoMapper: BaseInfoMapper,
+    private val commitmentTemplateMapper: CommitmentTemplateMapper,
+    private val sceneTypeMapper: SceneTypeMapper,
+    private val userConfigRep: UserConfigRep
+) : ConfigService {
+
+    override fun getSceneRange(userId: String): List<Pair<String?, String?>>? {
+        val config = userConfigRep.getUserConfigBySubType(userId)
+        // 鐢ㄦ埛娌℃湁鍏宠仈閰嶇疆鎴栬�呴厤缃腑鍙闂殑鍦烘櫙绫诲瀷涓虹┖鏃讹紝杩斿洖鎵�鏈夌被鍨�
+        val result = if (config == null || config.ucSceneRange == null) {
+            val types = sceneTypeMapper.selectByExample(Example(SceneType::class.java).apply {
+                createCriteria().andIsNull("scTag")
+            })
+            if (types.isNotEmpty()) {
+                types.map { Pair(it?.scId.toString(), it?.scName) }
+            } else {
+                cn.flightfeather.supervision.domain.enumeration.SceneType.toPairList()
+            }
+        } else {
+            config.ucSceneRange?.split(";")?.let {sr ->
+                sceneTypeMapper.selectByExample(Example(SceneType::class.java).apply {
+                    createCriteria().andIn("scId", sr)
+                }).map { Pair(it?.scId.toString(), it?.scName) }
+            }
+        }
+        return result
+    }
+
+    override fun getCommitmentTemplate(condition: UserSearchCondition): CommitmentTemplate? {
+        commitmentTemplateMapper.selectByExample(Example(CommitmentTemplate::class.java).apply {
+            createCriteria().andEqualTo("ctProvinceCode", condition.provinceCode)
+                .andEqualTo("ctProvinceName", condition.provinceName)
+                .andEqualTo("ctCityCode", condition.cityCode)
+                .andEqualTo("ctCityName", condition.cityName)
+                .andEqualTo("ctDistrictCode", condition.districtCode)
+                .andEqualTo("ctDistrictName", condition.districtName)
+                .andEqualTo("ctTownCode", condition.townCode)
+                .andEqualTo("ctTownName", condition.townName)
+                .andIn("ctSceneTypeId", condition.sceneTypes)
+        }).let {
+            if (it.isEmpty()) {
+                throw ResponseErrorException("鏃犵浉鍏虫壙璇轰功妯℃澘")
+            }
+            return it[0]
+        }
+    }
+
+    override fun getUserConfig(userId: String): UserConfig? {
+        return userConfigRep.getUserConfigBySubType(userId)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/CreditServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/CreditServiceImpl.kt
new file mode 100644
index 0000000..1564758
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/CreditServiceImpl.kt
@@ -0,0 +1,59 @@
+package cn.flightfeather.supervision.lightshare.service.Impl
+
+import cn.flightfeather.supervision.common.creditcode.EnvCreditCode
+import cn.flightfeather.supervision.domain.entity.Evaluation
+import cn.flightfeather.supervision.domain.mapper.BaseInfoMapper
+import cn.flightfeather.supervision.domain.mapper.OverallEvaluationMapper
+import cn.flightfeather.supervision.domain.mapper.UserinfoMapper
+import cn.flightfeather.supervision.domain.repository.UserConfigRep
+import cn.flightfeather.supervision.lightshare.service.CreditService
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import cn.flightfeather.supervision.lightshare.vo.CreditInfoVo
+import cn.flightfeather.supervision.lightshare.vo.DataHead
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+import com.github.pagehelper.PageHelper
+import org.springframework.stereotype.Service
+import java.util.*
+import javax.servlet.http.HttpServletResponse
+
+@Service
+class CreditServiceImpl(
+    private val overallEvaluationMapper: OverallEvaluationMapper,
+    private val userinfoMapper: UserinfoMapper,
+    private val userConfigRep: UserConfigRep,
+    private val baseInfoMapper: BaseInfoMapper,
+) : CreditService {
+
+    override fun searchEcCodeList(
+        userId: String,
+        condition: UserSearchCondition,
+        page: Int,
+        perPage: Int,
+    ): BaseResponse<List<CreditInfoVo>> {
+        if (condition.period == null) return BaseResponse(false, "蹇呴』閫夋嫨鍛ㄦ湡")
+        if (condition.sceneTypes.size > 2) return BaseResponse(false, "鍦烘櫙绫诲瀷鍙敮鎸佷竴绉�")
+        val config = userConfigRep.getUserConfigBySubType(userId)
+        val condition2 = UserSearchCondition.fromUserConfig(config, condition)
+        val p = PageHelper.startPage<Evaluation>(page, perPage)
+        val result = overallEvaluationMapper.searchEcCodeList(condition2)
+        return BaseResponse(true, head = DataHead(p.pageNum, p.pages, p.total), data = result)
+    }
+
+    override fun downloadEcCodeImg(userId: String, response: HttpServletResponse): BaseResponse<Boolean> {
+//        val info = baseInfoMapper.selectByPrimaryKey(userId)?.let { Triple(it.biGuid, it.biName ?: "", it.ciName) }
+//            ?: userinfoMapper.selectByPrimaryKey(userId)?.let { Triple(it.guid, it.realname ?: "", "") }
+//            ?: return BaseResponse(false, "鐢ㄦ埛涓嶅瓨鍦�")
+        val info = baseInfoMapper.selectByPrimaryKey(userId) ?: return BaseResponse(false, "鐢ㄦ埛涓嶅瓨鍦�")
+        val supply = "${info.biCityName}${info.biDistrictName}鐢熸�佺幆澧冨眬"
+        return try {
+            response.contentType = "image/png;charset=utf-8"
+            val name = Base64.getEncoder().encodeToString("${info.biName}.png".toByteArray())
+            response.setHeader("fileName", name)
+            EnvCreditCode.createImage(info.biGuid, info.biName, info.ciName, supply, response.outputStream)
+//            response.outputStream.write(output.toByteArray())
+            BaseResponse(true)
+        } catch (e: Exception) {
+            BaseResponse(false, "鐜俊鐮佸浘鐗囩敓鎴愬紓甯革細${e.message}")
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/DeviceServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/DeviceServiceImpl.kt
index 67a4645..defc570 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/DeviceServiceImpl.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/DeviceServiceImpl.kt
@@ -21,7 +21,11 @@
         val baseInfoMapper: BaseInfoMapper,
         val deviceInfoMapper: DeviceInfoMapper,
         val vocHourValueMapper: VOCHourValueMapper,
-        val userinfoMapper: UserinfoMapper
+        val userinfoMapper: UserinfoMapper,
+        val hourDustDataMapper: HourDustDataMapper,
+        val lampDeviceDataMapper: LampDeviceDataMapper,
+        val lampEnterBaseInfoMapper: LampEnterBaseInfoMapper,
+        val vocPurifyDeviceMapper: VocPurifyDeviceMapper
 ) : DeviceService {
 
     override fun getPurifyDeviceInfo(userId: String): List<FumePurifyDevice> {
@@ -71,7 +75,7 @@
                 })?.takeIf { it.isNotEmpty() }?.get(0)?.let {
                     when (it.diSceneTypeId) {
                         SceneType.Restaurant.value -> {
-                            PageHelper.startPage<FumeMinuteValue>(1, 1)
+                            PageHelper.startPage<FumeMinuteValue>(1, 15)
                             val latest = fumeMinuteValueMapper.selectByExample(Example(FumeMinuteValue::class.java).apply {
                                 createCriteria().andEqualTo("mvStatCode", mn)
                                 orderBy("mvDataTime").desc()
@@ -242,23 +246,169 @@
 
     override fun getRealTimeData(page: Int, perPage: Int): BaseResponse<List<DataVo>> {
         val deviceList = mutableListOf<String>()
+        val deviceMap = mutableMapOf<String, Pair<String?, String?>>()
+        val deviceInfoList = deviceInfoMapper.selectAll()
         baseInfoMapper.selectByExample(Example(BaseInfo::class.java).apply {
             createCriteria().andIsNotNull("biExtension2")
                     .andNotEqualTo("biExtension2", "")
             orderBy("biExtension2")
         }).forEach {
+            val device = deviceInfoList.find { d-> it.biExtension2 == d?.diCode }
             deviceList.add(it.biExtension2)
+            deviceMap[it.biExtension2] = Pair(it.biName, device?.diSupplier)
         }
         val resultList = mutableListOf<DataVo>()
         val p = PageHelper.startPage<FumeMinuteValue>(page, perPage)
         fumeMinuteValueMapper.getRealTimeData().forEach {
             resultList.add(DataVo(
-                    DateUtil.DateToString(it.mvDataTime, DateUtil.DateStyle.YYYY_MM_DD_HH_MM),
-                    if (it.mvFumeConcentration < 0) it.mvFumeConcentration2 else it.mvFumeConcentration,
-                    it.mvStatCode
+                DateUtil.DateToString(it.mvDataTime, DateUtil.DateStyle.YYYY_MM_DD_HH_MM),
+                if (it.mvFumeConcentration < 0) it.mvFumeConcentration2 else it.mvFumeConcentration,
+                it.mvStatCode,
+                deviceMap[it.mvStatCode]?.first,
+                deviceMap[it.mvStatCode]?.second,
             ))
         }
 
         return BaseResponse(true, head = DataHead(p.pageNum, p.pages), data = resultList)
     }
+
+    override fun getJingAnDustHourValue(userId: String, startTime: String?, endTime: String?): List<DataVo> {
+        val result = mutableListOf<DataVo>()
+        val baseInfo = baseInfoMapper.selectByPrimaryKey(userId)
+        val sT = startTime?.let { DateUtil.StringToDate(it) }
+        val eT = endTime?.let { DateUtil.StringToDate(it) }
+
+        if (baseInfo != null) {
+            val mn = baseInfo.biExtension2
+            if (!mn.isNullOrBlank()) {
+                if (sT == null || eT == null) {
+                    PageHelper.startPage<HourDustData>(1, 60)
+                }
+                hourDustDataMapper.selectByExample(Example(HourDustData::class.java).apply {
+                    createCriteria().andEqualTo("mncode", mn)
+                        .apply {
+                            sT?.let {
+                                andGreaterThanOrEqualTo("lst", sT)
+                            }
+                            eT?.let {
+                                andLessThanOrEqualTo("lst", eT)
+                            }
+                        }
+                    orderBy("mvDataTime").desc()
+                }).map {
+                    DataVo(DateUtil.DateToString(it?.lst, DateUtil.DateStyle.YYYY_MM_DD_HH_MM), it?.dustvalue ?: 0.0, it?.mncode)
+                }.also {
+                    result.addAll(it.asReversed())
+                }
+            }
+        }
+
+        return result
+    }
+
+    override fun getJingAnFumeValue(userId: String, startTime: String?, endTime: String?): List<DataVo> {
+        val result = mutableListOf<DataVo>()
+        val baseInfo = baseInfoMapper.selectByPrimaryKey(userId)
+        val sT = startTime?.let { DateUtil.StringToDate(it) }
+        val eT = endTime?.let { DateUtil.StringToDate(it) }
+
+        if (baseInfo != null) {
+            val mn = baseInfo.biExtension2
+            if (!mn.isNullOrBlank()) {
+                if (sT == null || eT == null) {
+                    PageHelper.startPage<LampDeviceData>(1, 60)
+                }
+                lampDeviceDataMapper.selectByExample(Example(LampDeviceData::class.java).apply {
+                    createCriteria().andEqualTo("enterId", mn)
+                        .apply {
+                            sT?.let {
+                                andGreaterThanOrEqualTo("monitorTime", sT)
+                            }
+                            eT?.let {
+                                andLessThanOrEqualTo("monitorTime", eT)
+                            }
+                        }
+                    orderBy("monitorTime").desc()
+                }).map {
+                    DataVo(DateUtil.DateToString(it?.monitorTime, DateUtil.DateStyle.YYYY_MM_DD_HH_MM), it?.lampblackValue ?: 0.0, it?.deviceCode)
+                }.also {
+                    result.addAll(it.asReversed())
+                }
+            }
+        }
+
+        return result
+    }
+
+    override fun getDeviceInfo(userId: String) {
+        val userInfo = userinfoMapper.selectByPrimaryKey(userId)
+        val baseInfo = baseInfoMapper.selectByPrimaryKey(userId)
+        if (baseInfo?.biExtension2?.isNotBlank() == true) {
+            when (userInfo?.extension2) {
+                SceneType.Restaurant.value.toString() -> {
+                    val lamp = lampEnterBaseInfoMapper.selectByPrimaryKey(baseInfo.biExtension2)
+                }
+                SceneType.Construction.value.toString(),
+                SceneType.Wharf.value.toString(),
+                SceneType.StorageYard.value.toString(),
+                SceneType.MixingPlant.value.toString(),
+                SceneType.Industrial.value.toString(),
+                SceneType.VehicleRepair.value.toString()->{
+
+                }
+            }
+        }
+    }
+
+    override fun saveFumePurifyDevice(info: FumePurifyDevice): Int {
+        // TODO: 2023/3/20 not yet implemented
+        return 0
+    }
+
+    override fun updateFumePurifyDevice(info: FumePurifyDevice): Int {
+        // TODO: 2023/3/20 not yet implemented
+        return 0
+    }
+
+    override fun saveMonitorDevice(info: MonitorDevice): Int {
+        // TODO: 2023/3/20 not yet implemented
+        return 0
+    }
+
+    override fun updateMonitorDevice(info: MonitorDevice): Int {
+        // TODO: 2023/3/20 not yet implemented
+        return 0
+    }
+
+    override fun saveVOCPurifyDevice(userId: String, infoList: List<VocPurifyDevice>): Int {
+        var res = 0
+        val infoList2 = mutableListOf<VocPurifyDevice>().apply { addAll(infoList) }
+        vocPurifyDeviceMapper.selectByExample(Example(VocPurifyDevice::class.java).apply {
+            createCriteria().andEqualTo("ibGuid", userId)
+        }).forEach { d ->
+            val info = infoList2.find { i-> i.vpId == d?.vpId }
+            if (info != null) {
+                info.ibGuid = userId
+                info.vpCreateTime = d?.vpCreateTime
+                res += vocPurifyDeviceMapper.updateByPrimaryKey(info)
+                infoList2.remove(info)
+            } else {
+                vocPurifyDeviceMapper.delete(d)
+//                print("delete: ")
+//                println(info)
+            }
+        }
+        infoList2.forEach {
+            it.ibGuid = userId
+            it.vpCreateTime = Date()
+            res += vocPurifyDeviceMapper.insert(it)
+        }
+        return res
+    }
+
+    override fun getVOCPurifyDevice(userId: String): List<VocPurifyDevice?> {
+        return vocPurifyDeviceMapper.selectByExample(Example(VocPurifyDevice::class.java).apply {
+            createCriteria().andEqualTo("ibGuid", userId)
+        })
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EnforceCaseServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EnforceCaseServiceImpl.kt
new file mode 100644
index 0000000..96cc7b6
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EnforceCaseServiceImpl.kt
@@ -0,0 +1,17 @@
+package cn.flightfeather.supervision.lightshare.service.Impl
+
+import cn.flightfeather.supervision.domain.entity.EnforceCase
+import cn.flightfeather.supervision.lightshare.service.EnforceCaseService
+import org.springframework.stereotype.Service
+
+@Service
+class EnforceCaseServiceImpl : EnforceCaseService {
+
+    override fun addCase(userId: String, enforceCase: EnforceCase): Int {
+        TODO("Not yet implemented")
+    }
+
+    override fun updateCase(userId: String, enforceCase: EnforceCase): Int {
+        TODO("Not yet implemented")
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EvaluationServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EvaluationServiceImpl.kt
index a37458b..a2f7cb1 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EvaluationServiceImpl.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EvaluationServiceImpl.kt
@@ -5,14 +5,13 @@
 import cn.flightfeather.supervision.domain.enumeration.AssessmentRuleType
 import cn.flightfeather.supervision.domain.enumeration.SceneType
 import cn.flightfeather.supervision.domain.mapper.*
+import cn.flightfeather.supervision.domain.repository.EvaluationRep
 import cn.flightfeather.supervision.infrastructure.utils.DateUtil
 import cn.flightfeather.supervision.infrastructure.utils.UUIDGenerator
+import cn.flightfeather.supervision.domain.repository.UserConfigRep
 import cn.flightfeather.supervision.lightshare.service.EvaluationService
 import cn.flightfeather.supervision.lightshare.service.ItemevaluationService
-import cn.flightfeather.supervision.lightshare.vo.AssessmentGradeVo
-import cn.flightfeather.supervision.lightshare.vo.AssessmentSearchCondition
-import cn.flightfeather.supervision.lightshare.vo.CreditInfoVo
-import cn.flightfeather.supervision.lightshare.vo.GradeDetailVo
+import cn.flightfeather.supervision.lightshare.vo.*
 import com.github.pagehelper.PageHelper
 import org.springframework.stereotype.Service
 import tk.mybatis.mapper.entity.Example
@@ -22,15 +21,17 @@
 
 @Service
 class EvaluationServiceImpl(
-        val evaluationMapper: EvaluationMapper,
-        val evaluationruleMapper: EvaluationruleMapper,
-        val evaluationsubruleMapper: EvaluationsubruleMapper,
-        val userinfoMapper: UserinfoMapper,
-        val baseInfoMapper: BaseInfoMapper,
-        val companyMapper: CompanyMapper,
-        val overallEvaluationMapper: OverallEvaluationMapper,
-        val autoScore: AutoScore,
-        val itemevaluationService: ItemevaluationService
+    val evaluationMapper: EvaluationMapper,
+    val evaluationruleMapper: EvaluationruleMapper,
+    val evaluationsubruleMapper: EvaluationsubruleMapper,
+    val userinfoMapper: UserinfoMapper,
+    val baseInfoMapper: BaseInfoMapper,
+    val companyMapper: CompanyMapper,
+    val overallEvaluationMapper: OverallEvaluationMapper,
+    val autoScore: AutoScore,
+    val itemevaluationService: ItemevaluationService,
+    private val userConfigRep: UserConfigRep,
+    private val evaluationRep: EvaluationRep,
 ) : EvaluationService {
 
     override fun findOne(id: String): Evaluation = evaluationMapper.selectByPrimaryKey(id)
@@ -39,7 +40,7 @@
 
     override fun save(evaluation: Evaluation): Int {
         updateRank(evaluation, true)
-        return  evaluationMapper.insert(evaluation)
+        return evaluationMapper.insert(evaluation)
     }
 
     override fun update(evaluation: Evaluation): Int {
@@ -49,17 +50,25 @@
 
     override fun delete(id: String): Int = evaluationMapper.deleteByPrimaryKey(id)
 
-    override fun getTotalPoints(userId: String, evaluatorType: Int, startTime: String, endTime: String, sceneTypeId: Int?, erGuid: String?, eId: String?): List<Evaluation> {
+    override fun getTotalPoints(
+        userId: String,
+        evaluatorType: Int,
+        startTime: String,
+        endTime: String,
+        sceneTypeId: Int?,
+        erGuid: String?,
+        eId: String?,
+    ): List<Evaluation> {
         val example = Example(Evaluation::class.java)
         val criteria = example.createCriteria()
         val startDate = DateUtil.StringToDate(startTime)
         val endDate = DateUtil.StringToDate(endTime)
         criteria.andEqualTo("iguid", userId)
-                .andBetween("createdate", startDate, endDate)
+            .andBetween("createdate", startDate, endDate)
         example.and(example.createCriteria().apply {
             if (evaluatorType == 0) {
                 orEqualTo("evaluatorrealname", evaluatorType.toString())
-                        .orIsNull("evaluatorrealname")
+                    .orIsNull("evaluatorrealname")
             } else {
                 andEqualTo("evaluatorrealname", evaluatorType.toString())
             }
@@ -68,15 +77,22 @@
         eId?.let { criteria.andEqualTo("guid", eId) }
         sceneTypeId?.let {
             example.and(example.createCriteria()
-                    .orEqualTo("scensetypeid", sceneTypeId.toByte())
-                    .orIsNull("scensetypeid")
+                .orEqualTo("scensetypeid", sceneTypeId.toByte())
+                .orIsNull("scensetypeid")
             )
         }
 
         return evaluationMapper.selectByExample(example)
     }
 
-    override fun getHistoryPoint(userId: String, page: Int, per_page: Int, platform:String?, response: HttpServletResponse): List<AssessmentGradeVo> {
+    override fun getHistoryPoint(
+        userId: String,
+        page: Int,
+        per_page: Int,
+        platform: String?,
+        period: String?,
+        response: HttpServletResponse,
+    ): List<AssessmentGradeVo> {
         val userInfo = userinfoMapper.selectByPrimaryKey(userId) ?: return emptyList()
         // FIXME: 2022/11/8 涓存椂娣诲姞杩囧害鍔熻兘锛屾彁渚涘井淇″皬绋嬪簭鍓嶇姹戒慨绫诲瀷鐨勫満鏅崟鐙殑璇勪及娓呭崟 锛屽満鏅被鍨嬩负 -7
         var sceneType = userInfo.extension2
@@ -110,10 +126,15 @@
         }
         val example = Example(Evaluation::class.java).apply {
             createCriteria().andEqualTo("iguid", userId)
-                    .andEqualTo("ertype", AssessmentRuleType.Total.value.toByte())
+                .andEqualTo("ertype", AssessmentRuleType.Total.value.toByte())
+                .apply {
+                    period?.let { andEqualTo("scensename", it) }
+                }
             //鏍规嵁璇勪及浜虹殑绫诲瀷杩涜绛涢�夛紝鑷瘎鍜屽畼鏂硅瘎鍒嗗垎寮�鎺掑悕
-            and(createCriteria().orIsNull("evaluatorrealname")
-                    .orEqualTo("evaluatorrealname", 0))
+            and(
+                createCriteria().orIsNull("evaluatorrealname")
+                    .orEqualTo("evaluatorrealname", 0)
+            )
             orderBy("createdate").desc()
         }
         val counts = evaluationMapper.selectCountByExample(example)
@@ -139,49 +160,52 @@
                 creditText = l["creditText"]
                 rank = it.promissednum ?: 1
                 updateDate = it.createdate
-                period = it.scensename
+                this.period = it.scensename
             })
         }
 
         return resultList
     }
 
-    override fun getCreditInfo(userId: String): CreditInfoVo {
-        val userinfo = userinfoMapper.selectByPrimaryKey(userId)
+    override fun getCreditInfo(userId: String, period: String?): CreditInfoVo {
+        val userinfo = userinfoMapper.selectByPrimaryKey(userId) ?: return CreditInfoVo()
         val baseInfo = baseInfoMapper.selectByPrimaryKey(userId)
-            ?: return CreditInfoVo(
-                userId, userinfo.realname,userinfo.extension2?.toIntOrNull() ?: SceneType.NoType.value)
-        val company = companyMapper.selectByPrimaryKey(baseInfo.ciGuid)
-
+        val company = baseInfo?.let { companyMapper.selectByPrimaryKey(it.ciGuid) }
 
         val result = CreditInfoVo(
-                userId,
-                baseInfo?.biName,
-                userinfo.extension2?.toIntOrNull() ?: SceneType.NoType.value,
-                baseInfo?.ciName,
-                baseInfo?.biManagementCompany,
-                baseInfo?.biContact,
-                baseInfo?.biTelephone,
-                baseInfo?.biAddress,
-                district = company?.ciDistrictName,
-                town = company?.ciTownName
+            userId,
+            baseInfo?.biName,
+            userinfo?.extension2?.toIntOrNull() ?: SceneType.NoType.value,
+            baseInfo?.ciName,
+            baseInfo?.biManagementCompany,
+            baseInfo?.biContact,
+            baseInfo?.biTelephone,
+            baseInfo?.biAddress,
+            district = company?.ciDistrictName,
+            town = company?.ciTownName
         )
 
         val rule = evaluationruleMapper.selectByExample(Example(Evaluationrule::class.java).apply {
             val c = createCriteria()
-            userinfo.extension2?.toByteOrNull()?.let {
+            userinfo?.extension2?.toByteOrNull()?.let {
                 c.andEqualTo("scensetypeid", it)
-                        .andEqualTo("ruletype", "0")
+                    .andEqualTo("ruletype", "0")
             }
         }).takeIf { it.isNotEmpty() }?.get(0) ?: return result
 
+        val periodList = DateUtil.getSuitablePeriod(period)
         val overallEvaluation = overallEvaluationMapper.selectByExample(Example(OverallEvaluation::class.java).apply {
-            createCriteria().andEqualTo("biGuid", baseInfo?.biGuid)
+            createCriteria().andEqualTo("biGuid", userinfo?.guid)
+                .apply {
+                    if (periodList.isNotEmpty()) {
+                        andIn("oePeriod", periodList)
+                    }
+                }
             orderBy("oePublishTime").desc()
         }).takeIf { it.isNotEmpty() }?.get(0) ?: return result
 
         //璇勫垎璁板綍瀵瑰簲 鐨勬墦鍒嗗懆鏈� 锛屾牸寮忎负 YYYY/M-M锛屾煇骞存煇鏈堣嚦鏌愭湀
-        val period = overallEvaluation.oePeriod
+//        val period = overallEvaluation.oePeriod
         //璇勫垎绛夌骇鍒嗘暟鐣岄檺锛屾牸寮忎负  0,59#60,89#90,100锛岃〃绀烘湁涓変釜鍒嗘暟娈�
         val levels = rule.extension1?.split("#")?.asReversed()
         //璇勫垎绛夌骇瀵瑰簲鐨勬弿杩帮紝鏍煎紡涓� 杈冨樊#涓�鑸�#浼樼锛屽搴斾笁涓垎鏁版鐨勬弿杩�
@@ -223,15 +247,51 @@
         return result
     }
 
+    override fun getCreditCount(userId: String, condition: UserSearchCondition): BaseResponse<CountVo> {
+        if (condition.sceneTypes.size != 1) return BaseResponse(false, "鍙敮鎸佸崟涓満鏅被鍨嬬殑鏌ヨ")
 
-    override fun getAssessments(userId: String, condition: AssessmentSearchCondition, page: Int, perPage: Int, response: HttpServletResponse): List<AssessmentGradeVo> {
+        val config = userConfigRep.getUserConfigBySubType(userId)
+        val condition2 = UserSearchCondition.fromUserConfig(config, condition)
+
+        // 缁跨爜
+        var level0 = 0
+        // 榛勭爜
+        var level1 = 0
+        // 绾㈢爜
+        var level2 = 0
+        condition2.period = condition2.period
+            ?: overallEvaluationMapper.getLatestPeriod(condition2)
+                    ?: return BaseResponse(false, "鏃犺褰�")
+
+        overallEvaluationMapper.getCreditCount(condition2).forEach {
+            when (it.oeCodeLevel?.toInt()) {
+                0 -> level0++
+                1 -> level1++
+                2 -> level2++
+            }
+        }
+        val result = CountVo().apply {
+            tag = condition2.period
+            countList.addAll(listOf(level0, level1, level2))
+        }
+
+        return BaseResponse(true, data = result)
+    }
+
+    override fun getAssessments(
+        userId: String,
+        condition: AssessmentSearchCondition,
+        page: Int,
+        perPage: Int,
+        response: HttpServletResponse,
+    ): List<AssessmentGradeVo> {
         val user = userinfoMapper.selectByPrimaryKey(userId)
-        val districtName = user.extension1
+        val districtName = user?.extension1
 
         val p = PageHelper.startPage<Evaluation>(page, perPage)
 
         val result = mutableListOf<AssessmentGradeVo>()
-        evaluationMapper.getAssessments(districtName?:"", condition.searchText, "", condition.sceneTypes).forEach {
+        evaluationMapper.getAssessments(districtName ?: "", condition.searchText, "", condition.sceneTypes).forEach {
             //姝ゅ鐢变簬 PageHelper 鐨勫垎椤垫搷浣滐紝浼氬鑷寸粨鏋滅殑鏁伴噺寮哄埗涓� perPage鐨勫�硷紝鍖呮嫭null
             if (it != null) {
                 result.add(AssessmentGradeVo().apply {
@@ -259,7 +319,12 @@
         return response
     }
 
-    override fun uploadScore(userId: String, period: String, ruleId: String?, itemList: List<Pair<String, String>>): Boolean {
+    override fun uploadScore(
+        userId: String,
+        period: String,
+        ruleId: String?,
+        itemList: List<Pair<String, String>>,
+    ): Boolean {
         val userinfo = userinfoMapper.selectByPrimaryKey(userId) ?: return false
         var sceneType = userinfo.extension2
 
@@ -278,20 +343,11 @@
         var totalPoint = 0
         var tEvaluation = Evaluation()
 
-        //涓婁紶鐨勫緱鍒嗚鍒�
-//        var rule = Evaluationrule()
-//        val subRules:List<Evaluationsubrule> = if (ruleId != null) {
-//            rule = evaluationruleMapper.selectByPrimaryKey(ruleId)
-//            evaluationsubruleMapper.selectByExample(Example(Evaluationsubrule::class.java).apply {
-//                createCriteria().andEqualTo("erguid", ruleId)
-//            })
-//        }
-
-        val ruleList = evaluationruleMapper.selectByExample(Example(Evaluationrule::class.java).apply {
+        evaluationruleMapper.selectByExample(Example(Evaluationrule::class.java).apply {
             createCriteria().andEqualTo("scensetypeid", sceneType)
-                    .andNotEqualTo("ruletype", AssessmentRuleType.Total.value)
+                .andNotEqualTo("ruletype", AssessmentRuleType.Total.value)
                 .andIsNull("tasktypeid")
-        }).forEach {rule->
+        }).forEach { rule ->
             val subRules = evaluationsubruleMapper.selectByExample(Example(Evaluationsubrule::class.java).apply {
                 createCriteria().andEqualTo("erguid", rule.guid)
             })
@@ -310,12 +366,14 @@
                         var fatherId: String?
                         var subRule = s
                         var score = it.second
+                        // 鏍规嵁涓婁紶鐨勬潯鐩敓鎴愬搴旂殑璇ユ潯鐩緱鍒嗚褰曚互鍙婂叾鎵�鏈夌殑鐖堕」鏉$洰鐨勫緱鍒嗚褰�
                         do {
-                            val result = calculateScore(rule, evaluation.guid!!, userId, subRule, score, itemEvaluationList)
+                            val result =
+                                calculateScore(rule, evaluation.guid!!, userId, subRule, score, itemEvaluationList)
                             fatherId = result.first
-                            for (s in subRules) {
-                                if (s.guid == fatherId) {
-                                    subRule = s
+                            for (s1 in subRules) {
+                                if (s1.guid == fatherId) {
+                                    subRule = s1
                                     score = result.second ?: "0"
                                     break
                                 }
@@ -326,15 +384,15 @@
                 }
             }
 
-            //鎬诲垎
+            //瑙勫垯璁惧畾鐨勬渶澶у垎鍊�
             var maxScore = 0
-            subRules.forEach subRules@{s ->
+            subRules.forEach subRules@{ s ->
                 //璁$畻搴斿緱鎬诲垎锛宐asic_score锛氳〃绀哄熀纭�鍒嗭紝璁$畻鍦ㄥ簲寰楁�诲垎鍐咃紱addition_score琛ㄧず鍔犲垎锛屼笉璁$畻鍦ㄥ唴
                 if (s.ertype == 2 && s.extension1 != "addition_score") {
                     maxScore += s.maxscore ?: 0
                 }
                 //瑙勫垯宸茬粡鎵撳垎瀹屾瘯锛屽垯璺宠繃
-                itemEvaluationList.forEach {i ->
+                itemEvaluationList.forEach { i ->
                     if (i.esrguid == s.guid) {
                         //濡傛灉鏄渶澶х殑2绾ц瘎浼拌鍒欙紝璁$畻宸茶幏寰楃殑鎬诲垎
                         if (s.ertype == 2) {
@@ -392,47 +450,55 @@
         return true
     }
 
+    override fun updateScore(
+        userId: String,
+        period: String,
+        ruleId: String?,
+        itemList: List<Pair<String, String>>,
+    ): Boolean {
+        TODO("Not yet implemented")
+    }
+
     override fun getDetail(userId: String, period: String): GradeDetailVo {
         val list = period.split("-")
-        val endM = list[1].toInt()
+        var endM = list[1].toInt()
         val list2 = list[0].split("/")
         val year = list2[0].toInt()
-        val startM = list2[1].toInt()
-        val st = LocalDateTime.of(year, startM, 1, 0, 0, 0, 0)
-        val et = LocalDateTime.of(year, endM, 1, 0, 0, 0, 0).plusMonths(1)
+        var startM = list2[1].toInt()
+        var st = LocalDateTime.of(year, startM, 1, 0, 0, 0, 0)
+        var et = LocalDateTime.of(year, endM, 1, 0, 0, 0, 0).plusMonths(1)
 
         val result = GradeDetailVo()
 
         val userinfo = userinfoMapper.selectByPrimaryKey(userId) ?: return result
-        var sceneType = userinfo.extension2
+        var sceneType = SceneType.getByValue(userinfo.extension2?.toIntOrNull())
         // FIXME: 2022/11/8 涓存椂娣诲姞杩囧害鍔熻兘锛屾彁渚涘井淇″皬绋嬪簭鍓嶇姹戒慨绫诲瀷鐨勫満鏅崟鐙殑璇勪及娓呭崟 锛屽満鏅被鍨嬩负 -7
-        if (sceneType == SceneType.VehicleRepair.value.toString()) {
-            sceneType = "-7"
+        if (sceneType == SceneType.VehicleRepair) {
+            sceneType = SceneType.VehicleRepair
         }
 
         //璇ュ満鏅被鍨嬩笅鐨勬墍鏈夊緱鍒嗚鍒�
-//        var rule0: Evaluationrule? = null
-//        val rule1List = mutableListOf<Evaluationrule>()
-//        evaluationruleMapper.selectByExample(Example(Evaluationrule::class.java).apply {
-//            createCriteria().andEqualTo("scensetypeid", sceneType)
-//                and(createCriteria().orIsNull("tasktypeid").orNotEqualTo("tasktypeid", 1))
-//        }).forEach {
-//            if (it.ruletype == AssessmentRuleType.Total.value.toString()) {
-//                rule0 = it
-//            } else {
-//                rule1List.add(it)
-//            }
-//        }
-//        if (rule0 == null) return result
-        //寰楀垎瑙h鍜屽緱鍒嗚鎯�
-        evaluationMapper.selectByExample(Example(Evaluation::class.java).apply {
+        val rule0 = evaluationRep.findRule(sceneType) ?: return result
+        //鑾峰緱寰楀垎瑙勫垯涓畾涔夌殑璇勪及鍛ㄦ湡锛堝崟浣嶏細鏈堬級
+        val rulePeriod = rule0.scensesubtypeid?.toInt() ?: 1
+        DateUtil.getStartMonthByPeriod(startM, rulePeriod)?.let {
+            startM = it
+            endM = startM + rulePeriod - 1
+            st = LocalDateTime.of(year, startM, 1, 0, 0, 0, 0)
+            et = LocalDateTime.of(year, endM, 1, 0, 0, 0, 0).plusMonths(1)
+        }
+        //鑾峰彇鏈�鏂颁竴鏈熺殑鎬诲垎
+        val latestEva = evaluationRep.findLatest(rule0.guid, userId, period, st, et)
+        //鏍规嵁鎬诲垎鍛ㄦ湡鑾峰彇鐩稿悓鍛ㄦ湡鍐呯殑瀛愯瘎鍒�
+        val latestSubEva = evaluationMapper.selectByExample(Example(Evaluation::class.java).apply {
             createCriteria().andEqualTo("iguid", userId)
-//                    .andEqualTo("ertype", AssessmentRuleType.Total.value.toByte())
-            and(
-                    createCriteria().orEqualTo("scensename", period)
-                            .orBetween("createdate", st, et)
-            )
-        }).forEach {e ->
+                .andEqualTo("scensename", latestEva?.scensename)
+                .andNotEqualTo("ertype", AssessmentRuleType.Total.value.toByte())
+        })
+        latestEva?.let {
+            latestSubEva.add(it)
+        }
+        latestSubEva.forEach { e ->
             val rule = evaluationruleMapper.selectByPrimaryKey(e.stguid)
             //鎬诲垎瑙勫垯锛岀敓鎴愭�讳綋璇勪环
             if (rule.ruletype == AssessmentRuleType.Total.value.toString()) {
@@ -456,13 +522,13 @@
                     }
 
                     val l = getEvaluationLevel(e.resultscorebef?.toInt()
-                            ?: 0, pointLevel, evaluateLevel, creditTexts, levelColors)
+                        ?: 0, pointLevel, evaluateLevel, creditTexts, levelColors)
                     result.apply {
                         creditText = l["creditText"]
                         score = e.resultscorebef?.toInt() ?: 0
                         rank = e.promissednum
                         level = l["evaluateLevel"]
-                        this.period = period
+                        this.period = latestEva?.scensename
                         time = e.createdate
 //                    color = l["color"]
                     }
@@ -475,65 +541,72 @@
                 })
                 val itemEvaluations = itemevaluationService.getItemEvaluationList(e.guid!!)
                 val ruleMap = result.loseScore
+                val ruleMap2 = result.scoring
                 //鍒嗙被鍒殑寰楀垎(姣忎釜璇勫垎琛ㄧ殑璇勫垎澶ч」鐨勫緱鍒�)鍜屽け鍒嗘潯鐩�
-                itemEvaluations.sortedBy { it.ertype }.forEach {item ->
+                itemEvaluations.sortedBy { it.ertype }.forEach { item ->
+                    val value = item.value?.toInt() ?: 0
                     when (item.ertype) {
                         //鍒嗙被鍒殑寰楀垎
                         2 -> {
                             ruleMap[item.name] = mutableMapOf()
+                            ruleMap2[item.name] = mutableMapOf()
                             for (s in subRules) {
                                 if (s.guid == item.esrguid) {
-                                    val score = if ((item.value?.toInt() ?: 0) <= 0) {
-                                        s.maxscore?.plus(item.value?.toInt() ?: 0)
+                                    val score = if (value <= 0) {
+                                        s.maxscore?.plus(value)
                                     } else {
-                                        item.value?.toInt() ?: 0
+                                        value
                                     }
-                                    result.classScore.add(Triple(item.name ?: "", s.maxscore?.toString()?:"0", score.toString()))
+                                    result.classScore.add(Triple(item.name ?: "",
+                                        s.maxscore?.toString() ?: "0",
+                                        score.toString()))
                                     break
                                 }
                             }
                         }
                         3 -> {
-                            if ((item.value?.toInt() ?: 0) != 0 && item.extension1 == "true") {
+                            if (value != 0 && item.extension1 == "true") {
+                                val map = if (value > 0) ruleMap2 else ruleMap
                                 for (s in subRules) {
                                     if (s.guid == item.esrguid) {
-                                        if (!ruleMap.containsKey(s.fathername)) {
-                                            ruleMap[s.fathername] = mutableMapOf()
+                                        if (!map.containsKey(s.fathername)) {
+                                            map[s.fathername] = mutableMapOf()
                                         }
-                                        ruleMap[s.fathername]?.put(item.name, mutableListOf())
+                                        map[s.fathername]?.put(item.name, mutableListOf())
                                         break
                                     }
                                 }
                             }
                         }
-                        //澶卞垎鏉$洰
+                        //澶卞垎鎴栧緱鍒嗘潯鐩�
                         4 -> {
-                            if ((item.value?.toInt() ?: 0) != 0 && item.extension1 == "true") {
+                            if (value != 0 && item.extension1 == "true") {
+                                val map = if (value > 0) ruleMap2 else ruleMap
                                 for (s in subRules) {
                                     if (s.guid == item.esrguid) {
                                         val d =
-                                                Triple(
-                                                        item.name ?: "",
+                                            Triple(
+                                                item.name ?: "",
 //                                                if ((item.value?.toInt() ?: 0) < 0) {
 //                                                    item.value ?: "0"
 //                                                } else {
 //                                                    (item.value?.toInt() ?: 0).minus(s.maxscore ?: 0).toString()
 //                                                },
-                                                        item.value ?: "0",
-                                                        s.remark ?: ""
-                                                )
+                                                item.value ?: "0",
+                                                s.remark ?: ""
+                                            )
                                         val rule3Name = s.fathername
                                         for (s1 in subRules) {
                                             if (s1.itemname == rule3Name) {
                                                 val rule2Name =
-                                                //鐖秈d涓虹┖锛岃鏄庢4绾ц瘎浼伴」鐩存帴闄勫睘浜�2绾ц瘎浼伴」
-                                                if (s1.fathername.isNullOrBlank()) {
-                                                    ruleMap[rule3Name]?.put(rule3Name, mutableListOf())
-                                                    rule3Name
-                                                } else {
-                                                    s1.fathername
-                                                }
-                                                ruleMap[rule2Name]?.get(rule3Name)?.add(d)
+                                                    //鐖秈d涓虹┖锛岃鏄庢4绾ц瘎浼伴」鐩存帴闄勫睘浜�2绾ц瘎浼伴」
+                                                    if (s1.fathername.isNullOrBlank()) {
+                                                        map[rule3Name]?.put(rule3Name, mutableListOf())
+                                                        rule3Name
+                                                    } else {
+                                                        s1.fathername
+                                                    }
+                                                map[rule2Name]?.get(rule3Name)?.add(d)
                                                 break
                                             }
                                         }
@@ -553,6 +626,34 @@
         return result
     }
 
+    override fun searchGradeList(
+        userId: String,
+        condition: UserSearchCondition,
+        page: Int,
+        perPage: Int,
+    ): BaseResponse<List<CreditInfoVo>> {
+        if (condition.period == null) return BaseResponse(false, "蹇呴』閫夋嫨鍛ㄦ湡")
+        if (condition.sceneTypes.size > 2) return BaseResponse(false, "鍦烘櫙绫诲瀷鍙敮鎸佷竴绉�")
+
+        val config = userConfigRep.getUserConfigBySubType(userId)
+        val condition2 = UserSearchCondition.fromUserConfig(config, condition)
+
+//        val period = condition.period!!
+//        val sceneType = condition.sceneTypes[0]
+//        var district = condition.districtName
+//        val sort = condition.sorts
+//
+//        if (district == null) {
+//            val userInfo = userinfoMapper.selectByPrimaryKey(userId)
+//            district = userInfo?.extension1
+//        }
+        val p = PageHelper.startPage<Evaluation>(page, perPage)
+        val result = evaluationMapper.searchGradeList(condition2).onEach {
+                if (it.score == null) it.score = "/"
+            }
+        return BaseResponse(true, head = DataHead(p.pageNum, p.pages, p.total), data = result)
+    }
+
     /**
      * 鏍规嵁涓婁紶鐨勫瓙瑙勫垯鎵e垎鎯呭喌锛岀敓鎴愬瓙椤瑰緱鍒嗚褰�
      * @param rule 鎬昏鍒�
@@ -563,7 +664,14 @@
      * @param itemEvaluationList 寰楀垎璁板綍琛�
      * @return 璇勫垎椤圭殑鐖秈d鍜屽緱鍒�
      */
-    private fun calculateScore(rule:Evaluationrule, eGuid: String, userId: String, subRule: Evaluationsubrule, score: String, itemEvaluationList: MutableList<Itemevaluation>): Pair<String?, String?> {
+    private fun calculateScore(
+        rule: Evaluationrule,
+        eGuid: String,
+        userId: String,
+        subRule: Evaluationsubrule,
+        score: String,
+        itemEvaluationList: MutableList<Itemevaluation>,
+    ): Pair<String?, String?> {
         var result: Pair<String?, String?> = Pair(null, null)
         var exist = false
         for (i in itemEvaluationList) {
@@ -621,11 +729,11 @@
         pointLevel: MutableList<Pair<Int, Int>> = mutableListOf(),
         evaluateLevel: MutableList<String> = mutableListOf(),
         creditTexts: MutableList<String> = mutableListOf(),
-        levelColors: MutableList<String> = mutableListOf()
+        levelColors: MutableList<String> = mutableListOf(),
     ): Map<String, String> {
         val result = mutableMapOf<String, String>()
         if (pointLevel.isEmpty() || evaluateLevel.isEmpty() || creditTexts.isEmpty() || levelColors.isEmpty()) {
-            result["evaluateLevel"] =  when (score) {
+            result["evaluateLevel"] = when (score) {
                 in 0..40 -> "鏋佸樊"
                 in 41..64 -> "杈冨樊"
                 in 65..79 -> "涓�鑸�"
@@ -636,7 +744,8 @@
         } else {
             for (i in pointLevel.indices) {
                 if (score in pointLevel[i].first..pointLevel[i].second ||
-                        (i == pointLevel.size - 1 && score > pointLevel[i].second)) {
+                    (i == pointLevel.size - 1 && score > pointLevel[i].second)
+                ) {
                     result["color"] = levelColors[i % levelColors.size]
                     result["creditText"] = creditTexts[i % creditTexts.size]
                     result["evaluateLevel"] = evaluateLevel[i % evaluateLevel.size]
@@ -651,12 +760,12 @@
         if (evaluation.ertype == AssessmentRuleType.Total.value.toByte()) {
             val eList = evaluationMapper.selectByExample(Example(Evaluation::class.java).apply {
                 createCriteria().andEqualTo("scensename", evaluation.scensename)
-                        .andIsNotNull("scensename")
+                    .andIsNotNull("scensename")
                     .andEqualTo("ertype", AssessmentRuleType.Total.value)
                 //鏍规嵁璇勪及浜虹殑绫诲瀷杩涜绛涢�夛紝鑷瘎鍜屽畼鏂硅瘎鍒嗗皝闈㈠紑鎺掑悕
                 if (evaluation.evaluatorrealname == null || evaluation.evaluatorrealname == "0") {
                     and(createCriteria().orIsNull("evaluatorrealname")
-                            .orEqualTo("evaluatorrealname", evaluation.evaluatorrealname))
+                        .orEqualTo("evaluatorrealname", evaluation.evaluatorrealname))
                 } else {
                     and(createCriteria().andEqualTo("evaluatorrealname", evaluation.evaluatorrealname))
                 }
@@ -676,10 +785,9 @@
             }
             val updateList = mutableListOf<Evaluation>()
             for (i in eList.indices) {
-                if (eList[i].guid == evaluation.guid){
+                if (eList[i].guid == evaluation.guid) {
                     evaluation.promissednum = i + 1
-                }
-                else if (eList[i].promissednum != i + 1) {
+                } else if (eList[i].promissednum != i + 1) {
                     eList[i].promissednum = i + 1
                     updateList.add(eList[i])
                 }
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EvaluationsubruleServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EvaluationsubruleServiceImpl.kt
index 199bea0..7abce00 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EvaluationsubruleServiceImpl.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EvaluationsubruleServiceImpl.kt
@@ -4,14 +4,17 @@
 import cn.flightfeather.supervision.domain.entity.Evaluationrule
 import cn.flightfeather.supervision.domain.entity.Evaluationsubrule
 import cn.flightfeather.supervision.domain.entity.Itemevaluation
+import cn.flightfeather.supervision.domain.enumeration.AssessmentRuleType
 import cn.flightfeather.supervision.domain.enumeration.SceneType
 import cn.flightfeather.supervision.domain.mapper.*
+import cn.flightfeather.supervision.infrastructure.utils.DateUtil
 import cn.flightfeather.supervision.lightshare.service.EvaluationsubruleService
 import cn.flightfeather.supervision.lightshare.vo.EvaluationVo
 import cn.flightfeather.supervision.lightshare.vo.SubEvaluationVo
 import cn.flightfeather.supervision.lightshare.vo.ThirdEvaluationVo
 import org.springframework.stereotype.Service
 import tk.mybatis.mapper.entity.Example
+import java.time.LocalDateTime
 
 @Service
 class EvaluationsubruleServiceImpl(
@@ -40,6 +43,14 @@
     }
 
     override fun getScore(userId: String, time: String, platform:String?): List<EvaluationVo> {
+        val list = time.split("-")
+        var endM = list[1].toInt()
+        val list2 = list[0].split("/")
+        val year = list2[0].toInt()
+        var startM = list2[1].toInt()
+        var st = LocalDateTime.of(year, startM, 1, 0, 0, 0, 0)
+        var et = LocalDateTime.of(year, endM, 1, 0, 0, 0, 0).plusMonths(1)
+
         val userinfo = userinfoMapper.selectByPrimaryKey(userId) ?: return emptyList()
         var sceneType = userinfo.extension2
         // FIXME: 2022/11/8 涓存椂娣诲姞杩囧害鍔熻兘锛屾彁渚涘井淇″皬绋嬪簭鍓嶇姹戒慨绫诲瀷鐨勫満鏅崟鐙殑璇勪及娓呭崟 锛屽満鏅被鍨嬩负 -7
@@ -56,6 +67,16 @@
 
         val rIdList = mutableListOf<String?>()
         rules.forEach {
+            // 鎵惧埌鎬昏鍒�
+            if (it.ruletype == AssessmentRuleType.Total.value.toString()) {
+                val rulePeriod = it.scensesubtypeid?.toInt() ?: 1
+                DateUtil.getStartMonthByPeriod(startM, rulePeriod)?.let {s ->
+                    startM = s
+                    endM = startM + rulePeriod - 1
+                    st = LocalDateTime.of(year, startM, 1, 0, 0, 0, 0)
+                    et = LocalDateTime.of(year, endM, 1, 0, 0, 0, 0).plusMonths(1)
+                }
+            }
             rIdList.add(it.guid)
         }
 
@@ -72,7 +93,11 @@
         val ruleScore = evaluationMapper.selectByExample(Example(Evaluation::class.java).apply {
             createCriteria().andIn("stguid", rIdList)//瑙勫垯id
                     .andEqualTo("evaluatorguid", userId)//鐢ㄦ埛id
-                    .andEqualTo("scensename", time)//璇勪及鍛ㄦ湡锛屼緥锛�2020/6-6
+            and(
+                createCriteria().orEqualTo("scensename", time)//璇勪及鍛ㄦ湡锛屼緥锛�2020/6-6
+                    .orBetween("createdate", st, et)
+            )
+            orderBy("createdate").desc()
         })
         //瀛愯鍒欓�愭潯寰楀垎
         val subRuleScores = if (ruleScore.isEmpty()) {
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/HazardousWasteServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/HazardousWasteServiceImpl.kt
index 5e56e85..ede7924 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/HazardousWasteServiceImpl.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/HazardousWasteServiceImpl.kt
@@ -49,4 +49,24 @@
         }
         return result
     }
+
+    override fun saveHWFile(info: HWFile): Int {
+        // TODO: 2023/3/20 not yet implemented
+        return 0
+    }
+
+    override fun updateHWFile(info: HWFile): Int {
+        // TODO: 2023/3/20 not yet implemented
+        return 0
+    }
+
+    override fun saveHWRecord(info: HWRecord): Int {
+        // TODO: 2023/3/20 not yet implemented
+        return 0
+    }
+
+    override fun updateHWRecord(info: HWRecord): Int {
+        // TODO: 2023/3/20 not yet implemented
+        return 0
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/LedgerServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/LedgerServiceImpl.kt
index c9521ac..96ca914 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/LedgerServiceImpl.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/LedgerServiceImpl.kt
@@ -3,12 +3,14 @@
 import cn.flightfeather.supervision.domain.entity.LedgerMediaFile
 import cn.flightfeather.supervision.domain.entity.LedgerRecord
 import cn.flightfeather.supervision.domain.entity.LedgerSubType
-import cn.flightfeather.supervision.domain.enumeration.LedgerCheckStatus
 import cn.flightfeather.supervision.domain.enumeration.SceneType
 import cn.flightfeather.supervision.domain.mapper.LedgerMediaFileMapper
 import cn.flightfeather.supervision.domain.mapper.LedgerRecordMapper
 import cn.flightfeather.supervision.domain.mapper.LedgerSubTypeMapper
 import cn.flightfeather.supervision.domain.mapper.UserinfoMapper
+import cn.flightfeather.supervision.domain.repository.LedgerMediaFileRep
+import cn.flightfeather.supervision.domain.repository.LedgerRep
+import cn.flightfeather.supervision.domain.repository.UserInfoRep
 import cn.flightfeather.supervision.infrastructure.utils.DateUtil
 import cn.flightfeather.supervision.infrastructure.utils.FileUtil
 import cn.flightfeather.supervision.infrastructure.utils.UUIDGenerator
@@ -17,9 +19,16 @@
 import com.fasterxml.jackson.core.type.TypeReference
 import com.fasterxml.jackson.databind.ObjectMapper
 import com.github.pagehelper.PageHelper
+import org.springframework.beans.factory.annotation.Value
 import org.springframework.stereotype.Service
 import org.springframework.web.multipart.MultipartFile
 import tk.mybatis.mapper.entity.Example
+import java.io.File
+import java.io.FileNotFoundException
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.ZoneId
+import java.time.format.DateTimeFormatter
 import java.util.*
 import javax.servlet.http.HttpServletResponse
 import kotlin.collections.ArrayList
@@ -27,11 +36,19 @@
 
 @Service
 class LedgerServiceImpl(
-        val ledgerSubTypeMapper: LedgerSubTypeMapper,
-        val userinfoMapper: UserinfoMapper,
-        val ledgerRecordMapper: LedgerRecordMapper,
-        val ledgerMediaFileMapper: LedgerMediaFileMapper
-):LedgerService {
+    val ledgerSubTypeMapper: LedgerSubTypeMapper,
+    val userinfoMapper: UserinfoMapper,
+    val ledgerRecordMapper: LedgerRecordMapper,
+    val ledgerMediaFileMapper: LedgerMediaFileMapper,
+    private val ledgerMediaFileRep: LedgerMediaFileRep,
+    private val userInfoRep: UserInfoRep,
+    private val ledgerRep: LedgerRep,
+) : LedgerService {
+
+    @Value("\${imgPath}")
+    lateinit var imgPath: String
+
+    private val notInvolvedPath = "ledgerIcons/ledger_not_involved.jpg"
 
     override fun getLedgerType(sceneType: Int): ArrayList<LedgerSubTypeVo> {
         val ledgerSubTypes = ledgerSubTypeMapper.selectByExample(Example(LedgerSubType::class.java).apply {
@@ -42,13 +59,13 @@
         val resultList = ArrayList<LedgerSubTypeVo>()
         ledgerSubTypes.forEach {
             val l = LedgerSubTypeVo(
-                    it.lsSubtypeid,
-                    it.lsName,
-                    it.getlTypeid(),
-                    it.getlTypename(),
-                    needUpdate = it.getlNeedupdate(),
-                    sceneType = it.getlScenetype(),
-                    iconUrl = it.getlIconurl()
+                it.lsSubtypeid,
+                it.lsName,
+                it.getlTypeid(),
+                it.getlTypename(),
+                needUpdate = it.getlNeedupdate(),
+                sceneType = it.getlScenetype(),
+                iconUrl = it.getlIconurl()
             )
             resultList.add(l)
         }
@@ -56,6 +73,10 @@
     }
 
     override fun getUserLedgerSummary(userId: String, sceneType: Int, time: String): List<LedgerSubTypeVo> {
+        val c = Calendar.getInstance().apply { this.time = DateUtil.StringToDate(time) }
+        val year = c.get(Calendar.YEAR)
+        val month = c.get(Calendar.MONTH) + 1
+
         val ledgerSubTypes = ledgerSubTypeMapper.selectByExample(Example(LedgerSubType::class.java).apply {
             if (sceneType != SceneType.NoType.value) {
                 createCriteria().andEqualTo("lScenetype", sceneType)
@@ -73,17 +94,28 @@
                 needUpdate = it.getlNeedupdate(),
                 sceneType = it.getlScenetype(),
                 iconUrl = it.getlIconurl(),
-                realTime = it.getlRealTime()
+                realTime = it.getlRealTime(),
+                description = it.getlDescription(),
+                notRelated = it.getlNotRelatedSwitch() ?: true,
+                multigroup = it.getlMultiGroup() ?: false
             )
             for (r in records) {
                 if (l.ledgerSubTypeId == r.lsSubtypeid) {
+                    // FIXME: 2023/5/6 瑙勫垯鍙樺姩锛屼絾涓轰簡涓嶅奖鍝嶄箣鍓嶇殑璁板綍锛屾椂闂翠负2023骞�4鏈堝強涔嬪墠鐨勪笉閫傜敤鏂拌鍒�
+                    if (year >= 2023 && month > 4) {
+                        if (r.lrExtension2 == "notInvolved" && r.lrYear <= year && r.lrMonth < month.toByte()) {
+                            continue
+                        }
+                    }
                     l.ledgerFinished = true
                     l.upLoad = true
 //                    l.checkStatus = r.lrVerifyrst?.toIntOrNull() ?: LedgerCheckStatus.UnCheck.value
+                    l.onTime = r.lrIssubmitontime
                     l.verified
                     l.verifierName = r.lrVerifierrealname
                     l.verified = r.lrIsverify
-                    l.verifyRst = l.verifyRst
+                    l.verifyRst = r.lrVerifyrst
+                    l.involved = r.lrExtension2 != "notInvolved"
                     break
                 }
             }
@@ -93,9 +125,10 @@
         return resultList
     }
 
-    override fun getLedgerDetail(userId: String, ledgerSubTypeId: Int?, sceneType: Int,
-                                 startTime: String, endTime: String,
-                                 page: Int?, perPage: Int, response: HttpServletResponse
+    override fun getLedgerDetail(
+        userId: String, ledgerSubTypeId: Int?, sceneType: Int,
+        startTime: String, endTime: String,
+        page: Int?, perPage: Int, response: HttpServletResponse,
     ): ArrayList<LedgerVo> {
         val result = ArrayList<LedgerVo>()
 
@@ -118,32 +151,32 @@
 
         val records = ledgerRecordMapper.selectByExample(Example(LedgerRecord::class.java).apply {
             createCriteria().andEqualTo("lrSubmitid", userId)
-                    .andEqualTo("lrYear", year)
-                    .andEqualTo("lrMonth", month.toByte())
-                    .apply {
-                        ledgerSubTypeId?.let { andEqualTo("lsSubtypeid", it) }
-                    }
+                .andEqualTo("lrYear", year)
+                .andEqualTo("lrMonth", month.toByte())
+                .apply {
+                    ledgerSubTypeId?.let { andEqualTo("lsSubtypeid", it) }
+                }
             if (sceneType == SceneType.Restaurant.value) {
                 and(createCriteria().andIsNull("lrExtension1")
-                        .orEqualTo("lrExtension1", sceneType.toString()))
-            }else if (sceneType != SceneType.NoType.value) {
+                    .orEqualTo("lrExtension1", sceneType.toString()))
+            } else if (sceneType != SceneType.NoType.value) {
                 and(createCriteria().andEqualTo("lrExtension1", sceneType.toString()))
             }
         })
 
         records.forEach {
             val media = ledgerMediaFileMapper.selectByExample(
-                    Example(LedgerMediaFile::class.java).apply {
-                        createCriteria().andEqualTo("lrGuid", it.lrGuid)
-                                .andEqualTo("mfIsdelete", false)
-                                .andEqualTo("mfFiletype", it.lrEasubmitkind)
-                        orderBy("mfSavetime").desc()
-                    }
+                Example(LedgerMediaFile::class.java).apply {
+                    createCriteria().andEqualTo("lrGuid", it.lrGuid)
+                        .andEqualTo("mfIsdelete", false)
+                        .andEqualTo("mfFiletype", it.lrEasubmitkind)
+                    orderBy("mfSavetime").desc()
+                }
             )
             val type = ledgerSubTypeMapper.selectByExample(
-                    Example(LedgerSubType::class.java).apply {
-                        createCriteria().andEqualTo("lsSubtypeid", it.lsSubtypeid)
-                    }
+                Example(LedgerSubType::class.java).apply {
+                    createCriteria().andEqualTo("lsSubtypeid", it.lsSubtypeid)
+                }
             )
             result.add(LedgerVo().apply {
                 id = it.lrGuid
@@ -160,7 +193,7 @@
                 remark1 = media?.get(0)?.mfDescription1
                 path2 = media?.get(0)?.mfPath2
                 remark2 = media?.get(0)?.mfDescription2
-                this.sceneType = if(it.lrExtension1 == null) SceneType.Restaurant.value else it.lrExtension1.toInt()
+                this.sceneType = if (it.lrExtension1 == null) SceneType.Restaurant.value else it.lrExtension1.toInt()
             })
         }
 
@@ -171,7 +204,12 @@
 
     }
 
-    override fun getLedgerDetail2(userId: String, ledgerSubTypeId: Int?, sceneType: Int, time: String?): List<LedgerVo> {
+    override fun getLedgerDetail2(
+        userId: String,
+        ledgerSubTypeId: Int?,
+        sceneType: Int,
+        time: String?,
+    ): List<LedgerVo> {
         val records = if (time != null) {
             getLedgerRecords(userId, ledgerSubTypeId, sceneType, time)
         } else {
@@ -187,17 +225,17 @@
         val result = ArrayList<LedgerVo>()
         records.forEach {
             val media = ledgerMediaFileMapper.selectByExample(
-                    Example(LedgerMediaFile::class.java).apply {
-                        createCriteria().andEqualTo("lrGuid", it.lrGuid)
-                                .andEqualTo("mfIsdelete", false)
-                                .andEqualTo("mfFiletype", it.lrEasubmitkind)
-                        orderBy("mfSavetime").desc()
-                    }
+                Example(LedgerMediaFile::class.java).apply {
+                    createCriteria().andEqualTo("lrGuid", it.lrGuid)
+                        .andEqualTo("mfIsdelete", false)
+                        .andEqualTo("mfFiletype", it.lrEasubmitkind)
+                    orderBy("mfSavetime").desc()
+                }
             )
             val type = ledgerSubTypeMapper.selectByExample(
-                    Example(LedgerSubType::class.java).apply {
-                        createCriteria().andEqualTo("lsSubtypeid", it.lsSubtypeid)
-                    }
+                Example(LedgerSubType::class.java).apply {
+                    createCriteria().andEqualTo("lsSubtypeid", it.lsSubtypeid)
+                }
             )
             result.add(LedgerVo().apply {
                 id = it.lrGuid
@@ -214,39 +252,113 @@
                 remark1 = media?.get(0)?.mfDescription1
                 path2 = media?.get(0)?.mfPath2
                 remark2 = media?.get(0)?.mfDescription2
-                this.sceneType = if(it.lrExtension1 == null) SceneType.Restaurant.value else it.lrExtension1.toInt()
+                this.sceneType = if (it.lrExtension1 == null) SceneType.Restaurant.value else it.lrExtension1.toInt()
             })
         }
         return result
     }
 
-    override fun uploadLedger(userId: String, ledgerVoList: String, files: Array<MultipartFile>):Boolean {
+    override fun uploadLedger(userId: String, ledgerVo: LedgerVo, files: List<Pair<ByteArray, String>>): Boolean {
+        val user = userInfoRep.getUser(userId)
+
+        ledgerVo.apply {
+            if (fileType == null) fileType = 1
+            user?.extension2?.toInt()?.let { s -> sceneType = s }
+        }
+
+        val historyRecord = ledgerRep.selectRecord(userId, ledgerVo.ledgerSubTypeId, ledgerVo.updateDate)
+
+        var ledgerMedia: LedgerMediaFile? = null
+        if (historyRecord == null) {
+            //鐢熸垚鍙拌处鏇存柊璁板綍
+            val ledgerRecord = ledgerVo.toLedgerRecord(user)
+            ledgerVo.id = ledgerRecord.lrGuid
+            ledgerRep.insertRecord(ledgerRecord)
+            //鐢熸垚涓�鏉″濯掍綋鏂囦欢璁板綍
+            val filePath = ledgerMediaFileRep.saveFile(userId, ledgerVo, files)
+            ledgerMediaFileRep.insert(ledgerVo, filePath)
+        } else {
+            ledgerVo.id = historyRecord.lrGuid
+            ledgerMedia = deleteLedgerFile(historyRecord.lrGuid)
+            // 鍘婚櫎涓嶆秹鍙婃爣蹇楁垨澶嶅埗鏍囧織
+            historyRecord.lrSubmitdate = Date()
+            historyRecord.lrExtension2 = null
+            ledgerRep.updateRecord(historyRecord)
+            //鏇存柊鐨勫濯掍綋鏂囦欢璁板綍鏁版嵁
+            val filePath = ledgerMediaFileRep.saveFile(userId, ledgerVo, files)
+            ledgerMedia?.mfPath1 = filePath
+            ledgerMedia?.mfDescription1 = ledgerVo.remark1
+            ledgerMedia?.mfSavetime = Date()
+            ledgerMediaFileRep.update(ledgerMedia)
+        }
+
+        return true
+    }
+
+    override fun uploadLedger(userId: String, ledgerVoList: String, files: Array<MultipartFile>): Boolean {
 
         val mapper = ObjectMapper()
 
-        val ledgerVos = mapper.readValue<List<LedgerVo>>(ledgerVoList, object :TypeReference<List<LedgerVo>>(){})
+        val ledgerVos = mapper.readValue<List<LedgerVo>>(ledgerVoList, object : TypeReference<List<LedgerVo>>() {})
 
         ledgerVos.forEach {
             it.id = it.id ?: UUIDGenerator.generate16ShortUUID()
             it.fileType = it.fileType ?: 1
 
             val userInfo = userinfoMapper.selectByPrimaryKey(userId)
-            userInfo.extension2?.toInt()?.let {s-> it.sceneType = s }
+            userInfo?.extension2?.toInt()?.let { s -> it.sceneType = s }
 
             val today = Calendar.getInstance().apply { time = Date() }
-                    .get(Calendar.DAY_OF_MONTH)
+                .get(Calendar.DAY_OF_MONTH)
             val cal = Calendar.getInstance().apply { time = it.updateDate ?: Date() }
             val updateYear = cal.get(Calendar.YEAR)
             val updateMonth = cal.get(Calendar.MONTH) + 1
             val updateDay = cal.get(Calendar.DAY_OF_MONTH)
 
+            //妫�鏌ユ暟鎹簱鏄惁宸叉湁璁板綍锛岄�夋嫨鎻掑叆鎴栨洿鏂�
+            val tmp = ledgerRecordMapper.selectByExample(Example(LedgerRecord::class.java).apply {
+                createCriteria().andEqualTo("lsSubtypeid", it.ledgerSubTypeId)
+                    .andEqualTo("lrYear", updateYear)
+                    .andEqualTo("lrMonth", updateMonth)
+                    .andEqualTo("lrSubmitid", userId)
+            })
+            var ledgerMedia: LedgerMediaFile? = null
+            if (tmp.isEmpty()) {
+                //鐢熸垚鍙拌处鏇存柊璁板綍
+                val ledgerRecord = LedgerRecord().apply {
+                    lrGuid = UUIDGenerator.generate16ShortUUID()
+                    lsSubtypeid = it.ledgerSubTypeId
+                    lsSubtypename = it.ledgerName
+                    lrYear = updateYear
+                    lrMonth = updateMonth.toByte()
+                    lrDay = updateDay.toByte()
+                    lrEasubmitkind = it.fileType?.toByte() ?: 1
+                    lrSubmitid = userId
+                    lrSubmitname = userInfo?.acountname ?: ""
+                    lrIssubmitontime = today <= 10
+                    lrSubmitdate = Date()
+                    lrUpdatetype = it.updateType
+                    lrExtension1 = it.sceneType.toString()
+                }
+                it.id = ledgerRecord.lrGuid
+                ledgerRecordMapper.insert(ledgerRecord)
+            } else {
+                val record = tmp[0]
+                it.id = record.lrGuid
+                ledgerMedia = deleteLedgerFile(record.lrGuid)
+                // 鍘婚櫎涓嶆秹鍙婃爣蹇楁垨澶嶅埗鏍囧織
+                record.lrExtension2 = null
+                ledgerRecordMapper.updateByPrimaryKey(record)
+            }
+
             //瀵规瘡寮犲浘鐗囩敓鎴愮浉搴旂殑璺緞骞朵繚瀛�
             var picPath = ""
             val time = DateUtil.DateToString(Date(), DateUtil.DateStyle.YYYY_MM)
-            files.forEach {file->
+            files.forEach { file ->
                 val fileName = file.originalFilename
                 //TODO 姝ゅ鐨勬枃浠惰矾寰勯渶瑕佷慨鏀逛负鍔ㄦ�侀厤缃�
-                val basePath = "D:/02product/05ledger/images/"
+//                val basePath = "D:/02product/05ledger/images/"
+                val basePath = imgPath
                 val path = "$time/$userId/${it.ledgerName}/"
                 picPath += if (picPath.isEmpty()) {
                     "$path$fileName"
@@ -256,59 +368,30 @@
                 try {
                     //璋冪敤鏂囦欢淇濆瓨鏂规硶
                     FileUtil.uploadFile(file.bytes, basePath + path, fileName!!)
-                } catch (e: Exception) {
+                } catch (e: FileNotFoundException) {
                     e.printStackTrace()
                 }
             }
 
             //鐢熸垚涓�鏉″濯掍綋鏂囦欢璁板綍
-            val ledgerMedia = LedgerMediaFile().apply {
-                mfGuid = UUIDGenerator.generate16ShortUUID()
-                lrGuid = it.id
-                mfFiletype = it.fileType
-                mfPath1 = picPath
-                mfDescription1 = it.remark1
-                mfSavetime = Date()
-                mfIsdelete = false
-            }
-
-            //鏌ヨ鏄惁宸叉湁璁板綍锛屽宸叉湁璁板綍灏嗗叾鏍囪涓�"鍒犻櫎"
-            val example = Example(LedgerMediaFile::class.java)
-            val criteria = example.createCriteria()
-            criteria.andEqualTo("lrGuid", it.id)
-                    .andEqualTo("mfIsdelete", false)
-            val result = ledgerMediaFileMapper.selectByExample(example)
-            result.forEach {mediaFile ->
-                mediaFile.mfIsdelete = true
-                ledgerMediaFileMapper.updateByPrimaryKey(mediaFile)
-            }
-
-            //鎻掑叆鏂扮殑澶氬獟浣撴枃浠惰褰曟暟鎹�
-            ledgerMediaFileMapper.insert(ledgerMedia)
-
-            //鐢熸垚鍙拌处鏇存柊璁板綍
-            val ledgerRecord = LedgerRecord().apply {
-                lrGuid = it.id
-                lsSubtypeid = it.ledgerSubTypeId
-                lsSubtypename = it.ledgerName
-                lrYear = updateYear
-                lrMonth = updateMonth.toByte()
-                lrDay = updateDay.toByte()
-                lrEasubmitkind = it.fileType?.toByte() ?: 1
-                lrSubmitid = userId
-                lrSubmitname = userInfo?.acountname ?: ""
-                lrIssubmitontime = today <= 10
-                lrSubmitdate = Date()
-                lrUpdatetype = it.updateType
-                lrExtension1 = it.sceneType.toString()
-            }
-
-            //妫�鏌ユ暟鎹簱鏄惁宸叉湁璁板綍锛岄�夋嫨鎻掑叆鎴栨洿鏂�
-            val tmp = ledgerRecordMapper.selectByPrimaryKey(ledgerRecord.lrGuid)
-            if (tmp == null || tmp.lrGuid == null) {
-                ledgerRecordMapper.insert(ledgerRecord)
+            if (ledgerMedia == null) {
+                ledgerMedia = LedgerMediaFile().apply {
+                    mfGuid = UUIDGenerator.generate16ShortUUID()
+                    lrGuid = it.id
+                    mfFiletype = it.fileType
+                    mfPath1 = picPath
+                    mfDescription1 = it.remark1
+                    mfSavetime = Date()
+                    mfIsdelete = false
+                }
+                //鎻掑叆鏂扮殑澶氬獟浣撴枃浠惰褰曟暟鎹�
+                ledgerMediaFileMapper.insert(ledgerMedia)
             } else {
-                ledgerRecordMapper.updateByPrimaryKey(ledgerRecord)
+                ledgerMedia.mfPath1 = picPath
+                ledgerMedia.mfDescription1 = it.remark1
+                ledgerMedia.mfSavetime = Date()
+                //鏇存柊鐨勫濯掍綋鏂囦欢璁板綍鏁版嵁
+                ledgerMediaFileMapper.updateByPrimaryKey(ledgerMedia)
             }
 
             return true
@@ -317,13 +400,79 @@
         return false
     }
 
+    override fun uploadNoLedger(
+        userId: String,
+        time: String,
+        remark: String?,
+        ledgerIdList: List<Int>,
+    ): BaseResponse<String> {
+        val date = LocalDate.parse(time, DateTimeFormatter.ofPattern("yyyy-MM-dd"))
+        val year = date.year
+        val month = date.monthValue
+        val day = date.dayOfMonth
+        val userInfo = userinfoMapper.selectByPrimaryKey(userId) ?: return BaseResponse(false, "鐢ㄦ埛涓嶅瓨鍦�")
+        ledgerIdList.forEach {
+            //鍘婚噸鍒ゆ柇,褰撹绫诲瀷鍙拌处宸插瓨鍦ㄦ椂锛岄噰鐢ㄨ鐩栨洿鏂版搷浣�
+            val r = ledgerRecordMapper.selectByExample(Example(LedgerRecord::class.java).apply {
+                createCriteria().andEqualTo("lrSubmitid", userId)
+                    .andEqualTo("lsSubtypeid", it)
+                    .andEqualTo("lrYear", year)
+                    .andEqualTo("lrMonth", month)
+            })
+            var record = if (r.size > 0) r[0] else null
+
+            //鐢熸垚鍙拌处鏇存柊璁板綍
+            if (record != null) {
+                record.lrExtension2 = "notInvolved"
+                ledgerRecordMapper.updateByPrimaryKey(record)
+                deleteLedgerFile(record.lrGuid)?.let { m ->
+                    m.mfPath1 = notInvolvedPath
+                    ledgerMediaFileMapper.updateByPrimaryKey(m)
+                }
+            } else {
+                //鑾峰彇鍙拌处绫诲瀷淇℃伅
+                val ledgerType = ledgerSubTypeMapper.selectByPrimaryKey(it) ?: return@forEach
+                record = LedgerRecord().apply {
+                    lrGuid = record?.lrGuid ?: UUIDGenerator.generate16ShortUUID()
+                    lsSubtypeid = ledgerType.lsSubtypeid
+                    lsSubtypename = ledgerType.lsName
+                    lrYear = year
+                    lrMonth = month.toByte()
+                    lrDay = day.toByte()
+                    lrEasubmitkind = 1
+                    lrSubmitid = userId
+                    lrSubmitname = userInfo.acountname ?: ""
+                    lrIssubmitontime = day <= 10
+                    lrSubmitdate = Date()
+                    lrUpdatetype
+                    lrExtension1 = userInfo.extension2
+                    lrExtension2 = "notInvolved"
+                }
+                ledgerRecordMapper.insert(record)
+                //鐢熸垚涓�鏉″濯掍綋鏂囦欢璁板綍
+                val ledgerMedia = LedgerMediaFile().apply {
+                    mfGuid = UUIDGenerator.generate16ShortUUID()
+                    lrGuid = record.lrGuid
+                    mfFiletype = 1
+                    mfPath1 = notInvolvedPath
+                    mfDescription1 = remark
+                    mfSavetime = Date()
+                    mfIsdelete = false
+                }
+                ledgerMediaFileMapper.insert(ledgerMedia)
+            }
+        }
+
+        return BaseResponse(true)
+    }
+
     override fun getLedgerImg(userId: String, ledgerType: Int): List<String> {
         val result = mutableListOf<String>()
 
         PageHelper.startPage<LedgerRecord>(1, 1)
         val record = ledgerRecordMapper.selectByExample(Example(LedgerRecord::class.java).apply {
             createCriteria().andEqualTo("lsSubtypeid", ledgerType)
-                    .andEqualTo("lrSubmitid", userId)
+                .andEqualTo("lrSubmitid", userId)
             orderBy("lrYear").desc().orderBy("lrMonth").desc().orderBy("lrDay").desc()
         }).takeIf { it.isNotEmpty() }?.get(0)
 
@@ -331,7 +480,7 @@
             ledgerMediaFileMapper.selectByExample(Example(LedgerMediaFile::class.java).apply {
                 createCriteria().andEqualTo("lrGuid", it.lrGuid)
             }).forEach {
-                it.mfPath1?.split(";")?.let {list ->
+                it.mfPath1?.split(";")?.let { list ->
                     result.addAll(list)
                 }
             }
@@ -346,14 +495,19 @@
         PageHelper.startPage<LedgerRecord>(1, 1)
         val record = ledgerRecordMapper.selectByExample(Example(LedgerRecord::class.java).apply {
             createCriteria().andIn("lsSubtypeid", ledgerType)
-                    .andEqualTo("lrSubmitid", userId)
+                .andEqualTo("lrSubmitid", userId)
             orderBy("lrYear").desc().orderBy("lrMonth").desc().orderBy("lrDay").desc()
         })
 
         return emptyList()
     }
 
-    override fun getLedgerRecords(userId: String, ledgerSubTypeId: Int?, sceneType: Int, time: String): List<LedgerRecord> {
+    override fun getLedgerRecords(
+        userId: String,
+        ledgerSubTypeId: Int?,
+        sceneType: Int,
+        time: String,
+    ): List<LedgerRecord> {
         val ledgerSubTypes = ledgerSubTypeMapper.selectByExample(Example(LedgerSubType::class.java).apply {
             if (ledgerSubTypeId != null) {
                 createCriteria().andEqualTo("lsSubtypeid", ledgerSubTypeId)
@@ -376,21 +530,29 @@
         map.forEach { (p, v) ->
             // FIXME: 2020/11/10  姝ゅ鏍规嵁鍛ㄦ湡鍜屽綋鍓嶆湀浠借绠楀緱鍒板綋鍓嶆湀浠芥墍鍦ㄥ懆鏈熺殑濮嬫湯鏈堬紝鍙�傜敤浜庡懆鏈熷皬浜庣瓑浜�12涓湀鐨勬儏鍐点�傚悗缁緟淇敼
             val startMon = ceil(month.toDouble() / p).toInt().minus(1).times(p).plus(1)
-            val endMon = startMon + p - 1
+            var endMon = startMon + p - 1
+            if (endMon > month) endMon = month
             val r = ledgerRecordMapper.selectByExample(Example(LedgerRecord::class.java).apply {
                 createCriteria().andEqualTo("lrSubmitid", userId)
-                        .andEqualTo("lrYear", year)
-                        .andGreaterThanOrEqualTo("lrMonth", startMon.toByte())
-                        .andLessThanOrEqualTo("lrMonth", endMon.toByte())
-                and(
-                        createCriteria().apply {
-                            v.forEach {
-                                orEqualTo("lsSubtypeid", it)
-                            }
-                        }
-                )
+                    .andEqualTo("lrYear", year)
+                    .andGreaterThanOrEqualTo("lrMonth", startMon.toByte())
+                    .andLessThanOrEqualTo("lrMonth", endMon.toByte())
+                    .andIn("lsSubtypeid", v)
             })
-            records.addAll(r)
+            val monMap = mutableMapOf<Int, LedgerRecord>()
+            r.forEach {
+                if (monMap.containsKey(it.lsSubtypeid)) {
+                    val record = monMap[it.lsSubtypeid]!!
+                    if (record.lrMonth < it.lrMonth) {
+                        monMap[it.lsSubtypeid] = it
+                    }
+                } else {
+                    monMap[it.lsSubtypeid] = it
+                }
+            }
+            monMap.forEach { (_, u) ->
+                records.add(u)
+            }
         }
 
         return records
@@ -419,7 +581,7 @@
                     .andEqualTo("lsSubtypeid", it.subTypeId)
                     .andEqualTo("lrYear", y)
                     .andEqualTo("lrMonth", m)
-            }).forEach record@ {lr ->
+            }).forEach record@{ lr ->
                 //鑾峰彇璁板綍瀵瑰簲鐨勬枃浠朵俊鎭�
                 val fileList = ledgerMediaFileMapper.selectByExample(Example(LedgerMediaFile::class.java).apply {
                     createCriteria().andEqualTo("lrGuid", lr.lrGuid)
@@ -449,7 +611,11 @@
         return BaseResponse(true)
     }
 
-    override fun checkLedger(verifierId: String, remark: String?, recordList: List<LedgerCheckVo>): BaseResponse<Boolean> {
+    override fun checkLedger(
+        verifierId: String,
+        remark: String?,
+        recordList: List<LedgerCheckVo>,
+    ): BaseResponse<Boolean> {
         val recordIdList = mutableListOf<String?>()
         recordList.forEach { recordIdList.add(it.recordId) }
         val records = ledgerRecordMapper.selectByExample(Example(LedgerRecord::class.java).apply {
@@ -478,4 +644,21 @@
             BaseResponse(true)
         }
     }
+
+    /**
+     * 鍒犻櫎鍙拌处鐨勬枃浠惰褰�
+     * @param lrGuid 鍙拌处璁板綍id
+     */
+    private fun deleteLedgerFile(lrGuid: String): LedgerMediaFile? {
+        return ledgerMediaFileRep.select(lrGuid)?.apply {
+            if (this.mfPath1 != notInvolvedPath) {
+                this.mfPath1.split(";").forEach { p ->
+                    val path = imgPath + p
+                    FileUtil.deleteFile(path)
+                }
+//                this.mfPath1 = notInvolvedPath
+//                ledgerMediaFileMapper.updateByPrimaryKey(this)
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/NotificationServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/NotificationServiceImpl.kt
index b74776f..fde3160 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/NotificationServiceImpl.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/NotificationServiceImpl.kt
@@ -13,6 +13,8 @@
 import cn.flightfeather.supervision.domain.enumeration.SceneType
 import cn.flightfeather.supervision.domain.mapper.*
 import cn.flightfeather.supervision.infrastructure.utils.UUIDGenerator
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import cn.flightfeather.supervision.lightshare.vo.DataHead
 import com.flightfeather.taizhang.model.enumeration.NotificationType
 import com.flightfeather.taizhang.model.enumeration.WorkSubType
 import com.github.pagehelper.PageHelper
@@ -25,15 +27,43 @@
 
 @Service
 class NotificationServiceImpl(
-        val notificationMapper: NotificationMapper,
-        val noticeMapper: NoticeMapper,
-        val noticeReadStateMapper: NoticeReadStateMapper,
-        val userinfoMapper: UserinfoMapper,
-        val meetingParticipantRepository: MeetingParticipantRepository,
-        val templateManager: TemplateManager
+    val notificationMapper: NotificationMapper,
+    val noticeMapper: NoticeMapper,
+    val noticeReadStateMapper: NoticeReadStateMapper,
+    val noticeTemplateMapper: NoticeTemplateMapper,
+    val userinfoMapper: UserinfoMapper,
+    val meetingParticipantRepository: MeetingParticipantRepository,
+    val templateManager: TemplateManager,
 ) : NotificationService {
 
-    override fun getNotificationUnRead(userId: String, page: Int, per_page: Int, response: HttpServletResponse): List<NotificationVo> {
+    override fun getAllNotices(
+        userId: String,
+        noticeConfig: NoticeConfig,
+        page: Int,
+        perPage: Int,
+    ): BaseResponse<List<Notice>> {
+//        val userInfo = userinfoMapper.selectByPrimaryKey(userId)
+        val p = PageHelper.startPage<Notice>(page, perPage)
+        val nList = noticeMapper.selectByExample(Example(Notice::class.java).apply {
+            createCriteria().apply {
+                if (noticeConfig.ecNoticetype != null && noticeConfig.ecNoticetype != 0) {
+                    andEqualTo("ecNoticetype", noticeConfig.ecNoticetype)
+                }
+                if (noticeConfig.ecNoticesubtype != null && noticeConfig.ecNoticesubtype != 0) {
+                    andEqualTo("ecNoticesubtype", noticeConfig.ecNoticesubtype)
+                }
+            }
+            orderBy("ecUpdatedate").desc()
+        })
+        return BaseResponse(true, head = DataHead(p.pageNum, p.pages, p.total), data = nList)
+    }
+
+    override fun getNotificationUnRead(
+        userId: String,
+        page: Int,
+        per_page: Int,
+        response: HttpServletResponse,
+    ): List<NotificationVo> {
         val userInfo = userinfoMapper.selectByPrimaryKey(userId) ?: return emptyList()
         val userTypeId = userInfo.usertypeid
         val district = userInfo.extension1
@@ -42,7 +72,8 @@
 
         when (userTypeId?.toInt()) {
             UserType.Admin.value,
-            UserType.Insider.value -> {
+            UserType.Insider.value,
+            -> {
                 districtCode = null
                 sceneTypeId = null
             }
@@ -57,17 +88,15 @@
         val myPage = PageHelper.startPage<Notice>(page, per_page)
 
         val noticeIdList = mutableListOf<String?>()
-        val resultList = noticeMapper.getUnReadNotification(userId, districtCode, sceneTypeId).also {
-            it.forEach {vo->
-                noticeIdList.add(vo.id)
-            }
+        val resultList = noticeMapper.getUnReadNotification(userId, districtCode, sceneTypeId, userTypeId).onEach { vo ->
+            noticeIdList.add(vo.id)
         }
         if (noticeIdList.isEmpty()) {
             return resultList
         }
         val readStateList = noticeReadStateMapper.selectByExample(Example(NoticeReadState::class.java).apply {
             createCriteria().andEqualTo("nrUserid", userId)
-                    .andIn("ecGuid", noticeIdList)
+                .andIn("ecGuid", noticeIdList)
         })
 
         resultList.forEach {
@@ -96,7 +125,7 @@
                 nrSignstate = it.hasSigned
                 val example = Example(NoticeReadState::class.java)
                 example.createCriteria().andEqualTo("nrUserid", nrUserid)
-                        .andEqualTo("ecGuid", ecGuid)
+                    .andEqualTo("ecGuid", ecGuid)
                 val result = noticeReadStateMapper.selectByExample(example)
                 if (result.isEmpty()) {
                     noticeReadStateMapper.insert(this)
@@ -140,7 +169,8 @@
 
         when (userTypeId?.toInt()) {
             UserType.Admin.value,
-            UserType.Insider.value -> {
+            UserType.Insider.value,
+            -> {
                 districtCode = null
                 sceneTypeId = null
             }
@@ -153,8 +183,8 @@
         }
 
         val noticeIdList = mutableListOf<String?>()
-        val resultList = noticeMapper.getUnReadNotification(userId, districtCode, sceneTypeId).also {
-            it.forEach {vo->
+        val resultList = noticeMapper.getUnReadNotification(userId, districtCode, sceneTypeId, userTypeId).also {
+            it.forEach { vo ->
                 noticeIdList.add(vo.id)
             }
         }
@@ -178,10 +208,16 @@
         return totalCount
     }
 
-    override fun pushMeetingReleaseNotification(meetingVo: MeetingInfo, roomVo: VMRoom?, userId: String, title: String, body: String) {
+    override fun pushMeetingReleaseNotification(
+        meetingVo: MeetingInfo,
+        roomVo: VMRoom?,
+        userId: String,
+        title: String,
+        body: String,
+    ) {
         val accountList = mutableListOf<String>()
         meetingParticipantRepository.getParticipantByType(meetingVo.miGuid
-                ?: "", roomVo?.vmrGuid, ParticipantType.All.value).forEach {
+            ?: "", roomVo?.vmrGuid, ParticipantType.All.value).forEach {
             if (it.mpParticipantid != userId) {
                 accountList.add(it.mpParticipantid)
             }
@@ -201,19 +237,19 @@
         val user = userinfoMapper.selectByPrimaryKey(userId)
 
         val notificationVo = NotificationVo(
-                UUIDGenerator.generate16ShortUUID(),
-                user.guid,
-                user.realname,
-                user.headIconUrl,
-                NotificationType.Work.value.toString(),
-                NotificationType.Work.des,
-                WorkSubType.Meeting.value.toString(),
-                WorkSubType.Meeting.des,
-                meetingVo.miTitle ?: title,
-                body,
-                receiverType = "-1",
-                receiverId = receiverId.toString(),
-                district = "-1"
+            UUIDGenerator.generate16ShortUUID(),
+            user?.guid,
+            user?.realname,
+            user?.headIconUrl,
+            NotificationType.Work.value.toString(),
+            NotificationType.Work.des,
+            WorkSubType.Meeting.value.toString(),
+            WorkSubType.Meeting.des,
+            meetingVo.miTitle ?: title,
+            body,
+            receiverType = "-1",
+            receiverId = receiverId.toString(),
+            district = "-1"
         )
 
         releaseNotice(userId, notificationVo)
@@ -222,7 +258,7 @@
     override fun releaseNotice(userId: String, noticeVo: NotificationVo): Boolean {
         val notice = Notice().apply {
             noticeVo.let {
-                ecGuid = it.id
+                ecGuid = if (it.id == null) UUIDGenerator.generate16ShortUUID() else it.id
                 ecNoticetype = it.typeId?.toInt()
                 ecNoticetypename = it.typeName
                 ecNoticesubtype = it.subTypeId?.toInt()
@@ -244,52 +280,90 @@
                 ecExtension1 = it.district
             }
         }
-        Executors.newSingleThreadExecutor().execute {
-            PushService().run {
-                if (noticeVo.receiverId?.isNotBlank() == true) {
-                    val accountList = noticeVo.receiverId!!.split(";")
-                    pushByAccount(accountList)
-                } else {
-                    val accountList = mutableListOf<String>()
-                    val districts = mutableListOf<String>()
-                    val sceneTypes = mutableListOf<String>()
-                    noticeVo.district?.split(";")?.forEach {
-                        if (it.isNotBlank()) {
-                            districts.add(it)
-                        }
-                    }
-                    noticeVo.receiverType.split(";")?.forEach {
-                        if (it.isNotBlank()) {
-                            sceneTypes.add(it)
-                        }
-                    }
-                    val districtCodeList = mutableListOf<String>()
-                    districts.forEach {
-                        DistrictType.getDes(it)?.let { d-> districtCodeList.add(d)}
-                    }
-                    userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
-                        createCriteria()
-                                .apply {
-                                    if (districts.isNotEmpty()) {
-                                        andIn("extension1", districtCodeList)
-                                    }
-                                    if (noticeVo.receiverType != SceneType.NoType.value.toString()) {
-                                        andIn("extension2", sceneTypes)
-                                    }
-                                }
-                    }).forEach {
-                        accountList.add(it.guid ?: "")
-                    }
-                    pushByAccount(accountList)
-                }
-                push(noticeVo.title?:"鏂伴�氱煡", noticeVo.content?:"鏂伴�氱煡")
-            }
-        }
+//        Executors.newSingleThreadExecutor().execute {
+//            PushService().run {
+//                if (noticeVo.receiverId?.isNotBlank() == true) {
+//                    val accountList = noticeVo.receiverId!!.split(";")
+//                    pushByAccount(accountList)
+//                } else {
+//                    val accountList = mutableListOf<String>()
+//                    val districts = mutableListOf<String>()
+//                    val sceneTypes = mutableListOf<String>()
+//                    noticeVo.district?.split(";")?.forEach {
+//                        if (it.isNotBlank()) {
+//                            districts.add(it)
+//                        }
+//                    }
+//                    noticeVo.receiverType.split(";")?.forEach {
+//                        if (it.isNotBlank()) {
+//                            sceneTypes.add(it)
+//                        }
+//                    }
+//                    val districtCodeList = mutableListOf<String>()
+//                    districts.forEach {
+//                        DistrictType.getDes(it)?.let { d-> districtCodeList.add(d)}
+//                    }
+//                    userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
+//                        createCriteria()
+//                                .apply {
+//                                    if (districts.isNotEmpty()) {
+//                                        andIn("extension1", districtCodeList)
+//                                    }
+//                                    if (noticeVo.receiverType != SceneType.NoType.value.toString()) {
+//                                        andIn("extension2", sceneTypes)
+//                                    }
+//                                }
+//                    }).forEach {
+//                        accountList.add(it.guid ?: "")
+//                    }
+//                    pushByAccount(accountList)
+//                }
+//                push(noticeVo.title?:"鏂伴�氱煡", noticeVo.content?:"鏂伴�氱煡")
+//            }
+//        }
         return noticeMapper.insert(notice) == 1
     }
 
+    override fun releaseNotice2(userId: String, noticeVo: NotificationVo): Notice {
+        val notice = Notice().apply {
+            noticeVo.let {
+                ecGuid = if (it.id == null) UUIDGenerator.generate16ShortUUID() else it.id
+                ecNoticetype = it.typeId?.toInt()
+                ecNoticetypename = NotificationType.getByValue(ecNoticetype)
+                ecNoticesubtype = it.subTypeId?.toInt()
+                ecNoticesubtypename = WorkSubType.getByValue(ecNoticetype, ecNoticesubtype)
+                ecNoticetitle = it.title
+                ecNoticecontent = it.content
+                ecIsinuse = true
+                ecCreatedate = Date()
+                ecCreatorid = it.authorId
+                ecCreator = it.authorName
+                ecUpdatedate = Date()
+                ecModifierid = it.authorId
+                ecModifier = it.authorName
+                ecReceivertype = if (it.receiverType != "-1") it.receiverType + ";" else "-1"
+                ecReceiverid = it.receiverId
+                ecPicurl = it.picUrl
+                ecBodyurl = it.bodyUrl
+                ecNeedsign = it.needSigned
+                ecExtension1 = if (it.district != "-1") it.district + ";" else "-1"
+            }
+        }
+        noticeMapper.insert(notice)
+        return notice
+    }
+
     override fun pushMsgWx(templateId: Int): String {
-        val res = templateManager.sendMsg(templateId, "otZkc5VRlwauEMPqMluQYdVa4zuE", listOf("鍙拌处涓婁紶", "2022骞�10鏈�10鏃�", "3", "璇烽噸鐐瑰叧娉ㄧ幇鍦鸿嚜瀵绘煡閮ㄥ垎"))
+        val res = templateManager.sendMsg(templateId,
+            "otZkc5VRlwauEMPqMluQYdVa4zuE",
+            listOf("鍙拌处涓婁紶", "2022骞�10鏈�10鏃�", "3", "璇烽噸鐐瑰叧娉ㄧ幇鍦鸿嚜瀵绘煡閮ㄥ垎"))
         return if (res) "success" else "fail"
     }
+
+    override fun getTemplate(typeId: Int, subTypeId: Int): BaseResponse<List<NoticeTemplate?>> {
+        val res = noticeTemplateMapper.selectByExample(Example(NoticeTemplate::class.java).apply {
+            createCriteria().andEqualTo("ntNoticeType", typeId).andEqualTo("ntNoticeSubType", subTypeId)
+        })
+        return BaseResponse(true, data = res)
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/OnLineQuestionServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/OnLineQuestionServiceImpl.kt
index 4fea98a..c571173 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/OnLineQuestionServiceImpl.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/OnLineQuestionServiceImpl.kt
@@ -102,175 +102,56 @@
     }
 
     override fun searchLaw(userId: String, keyword: String, type: Byte?, page: Int, perPage: Int): BaseResponse<List<ConsultResultVo>> {
-        val keywordList = if (keyword.isBlank()) {
-            emptyList()
-        } else {
-            nlpController.execute(keyword)
-        }
-        val userInfo = userinfoMapper.selectByPrimaryKey(userId) ?: return BaseResponse(false)
-        val response = BaseResponse<List<ConsultResultVo>>(false, head = DataHead(page, perPage))
-        val result = mutableListOf<ConsultResultVo>()
-
-        //褰撴悳绱笉闄愬埗绫诲瀷鏃讹紝榛樿姣忕绫诲瀷鍙幏鍙栧墠5椤癸紱褰撻檺鍒剁被鍨嬫椂锛屽垯鏍规嵁鍓嶇璇锋眰鍒嗛〉鏁拌繑鍥�
-        val _perPage = if (type == null) 5 else perPage
-        val _page = page
-
-        //娉曞緥娉曡鏂囦欢
-        if (type == null || type == ConsultResultType.TYPE1.value) {
-            val p = PageHelper.startPage<MgtFile>(_page, _perPage)
-            val example = Example(MgtFile::class.java).apply {
-                if (keywordList.isNotEmpty()) {
-                    createCriteria().apply {
-                        keywordList.forEach { k ->
-                            orLike("mfName", "%${k}%")
-                            orLike("mfShortName", "%${k}%")
-                            orLike("mfSummary", "%${k}%")
-                            orLike("mfKeywordLv1", "%${k}%")
-                            orLike("mfKeywordLv2", "%${k}%")
-                            orLike("mfKeywordLv3", "%${k}%")
-                            orLike("mfKeywordLv4", "%${k}%")
-                        }
-                    }
-                    and(createCriteria().orLike("mfExtension1", "%${userInfo.extension2}%")
-                        .orEqualTo("mfExtension1", "")
-                        .orIsNull("mfExtension1"))
-                } else {
-                    // TODO: 2022/9/8 娌℃湁鍏抽敭瀛楁椂锛屾寜鐓х儹闂ㄨ幏鍙栨満鍒惰幏鍙�
-                    createCriteria().orLike("mfExtension1", "%${userInfo.extension2}%")
-                        .orEqualTo("mfExtension1", "")
-                        .orIsNull("mfExtension1")
-                }
-            }
-            mgtFileMapper.selectByExample(example).forEach {
-                result.add(ConsultResultFileVo().apply {
-                    id = it.mfGuid
-                    name = it.mfName
-                    des = it.mfSummary
-                    typeId = ConsultResultType.TYPE1.value
-                    typeName = ConsultResultType.TYPE1.des
-
-                    fileIndustry = IndustryType.getNameByValue(it.mfFileIndustry)
-                    itemType = EnElementType.getNameByValue(it.mfEpItemType)
-                    itemSubType = EnElementSubType.getSubType(it.mfEpItemType, it.mfEpItemSubtype)
-                    fileUrl = it.mfFileUrl
-                    val keyList = it.mfKeywordLv1.split("銆�")
-                    for (i in keyList.indices) {
-                        if (i < 5) {
-                            keywords.add(keyList[i])
-                        } else {
-                            break
-                        }
-                    }
-                    time = it.mfUpdateTime
-                    fileType = ConsultFileType.getNameByValue(it.mfFileType)
-                    referenceNumber = it.mfReferenceNumber
-                    effectiveDate = DateUtil.DateToString(it.mfEffectiveDate, DateUtil.DateStyle.YYYY_MM_DD)
-                    closingDate = DateUtil.DateToString(it.mfClosingDate, DateUtil.DateStyle.YYYY_MM_DD)
-                    effective = Date().time > (it.mfClosingDate?.time ?: 0)
-                })
-            }
-            response.success = true
-            response.head?.run {
-                this.page = p.pageNum
-                this.totalPage = p.pages
-            }
-        }
-        //娉曞緥娉曡鏉$洰
-        if (type == null || type == ConsultResultType.TYPE2.value) {
-            val map = mutableMapOf<String, MgtFile>()
-            val p = PageHelper.startPage<MgtItem>(_page, _perPage)
-            val example = Example(MgtItem::class.java).apply {
-                if (keywordList.isNotEmpty()) {
-                    createCriteria().apply {
-                        keywordList.forEach { k ->
-                            orLike("miChapterKeyword", "%${k}%")
-                            orLike("miKeyword", "%${k}%")
-                        }
-                    }
-                } else {
-                    // TODO: 2022/9/8 娌℃湁鍏抽敭瀛楁椂锛屾寜鐓х儹闂ㄨ幏鍙栨満鍒惰幏鍙栨潯鐩�
-                }
-            }
-            mgtItemMapper.selectByExample(example).forEach {
-
-                if (!map.containsKey(it.mfGuid)) {
-                    map[it.mfGuid] = mgtFileMapper.selectByPrimaryKey(it.mfGuid)
-                }
-                result.add(ConsultResultItemVo().apply {
-                    id = it.miGuid
-                    name = it.miItemName
-                    des = it.miItemContent
-                    typeId = ConsultResultType.TYPE2.value
-                    typeName = ConsultResultType.TYPE2.des
-
+//        val keywordList = if (keyword.isBlank()) {
+//            emptyList()
+//        } else {
+//            nlpController.execute(keyword)
+//        }
+//        val userInfo = userinfoMapper.selectByPrimaryKey(userId) ?: return BaseResponse(false)
+//        val response = BaseResponse<List<ConsultResultVo>>(false, head = DataHead(page, perPage))
+//        val result = mutableListOf<ConsultResultVo>()
+//
+//        //褰撴悳绱笉闄愬埗绫诲瀷鏃讹紝榛樿姣忕绫诲瀷鍙幏鍙栧墠5椤癸紱褰撻檺鍒剁被鍨嬫椂锛屽垯鏍规嵁鍓嶇璇锋眰鍒嗛〉鏁拌繑鍥�
+//        val _perPage = if (type == null) 5 else perPage
+//        val _page = page
+//
+//        //娉曞緥娉曡鏂囦欢
+//        if (type == null || type == ConsultResultType.TYPE1.value) {
+//            val p = PageHelper.startPage<MgtFile>(_page, _perPage)
+//            val example = Example(MgtFile::class.java).apply {
+//                if (keywordList.isNotEmpty()) {
+//                    createCriteria().apply {
+//                        keywordList.forEach { k ->
+//                            orLike("mfName", "%${k}%")
+//                            orLike("mfShortName", "%${k}%")
+//                            orLike("mfSummary", "%${k}%")
+//                            orLike("mfKeywordLv1", "%${k}%")
+//                            orLike("mfKeywordLv2", "%${k}%")
+//                            orLike("mfKeywordLv3", "%${k}%")
+//                            orLike("mfKeywordLv4", "%${k}%")
+//                        }
+//                    }
+//                    and(createCriteria().orLike("mfExtension1", "%${userInfo.extension2}%")
+//                        .orEqualTo("mfExtension1", "")
+//                        .orIsNull("mfExtension1"))
+//                } else {
+//                    // TODO: 2022/9/8 娌℃湁鍏抽敭瀛楁椂锛屾寜鐓х儹闂ㄨ幏鍙栨満鍒惰幏鍙�
+//                    createCriteria().orLike("mfExtension1", "%${userInfo.extension2}%")
+//                        .orEqualTo("mfExtension1", "")
+//                        .orIsNull("mfExtension1")
+//                }
+//            }
+//            mgtFileMapper.selectByExample(example).forEach {
+//                result.add(ConsultResultFileVo().apply {
+//                    id = it.mfGuid
+//                    name = it.mfName
+//                    des = it.mfSummary
+//                    typeId = ConsultResultType.TYPE1.value
+//                    typeName = ConsultResultType.TYPE1.des
+//
 //                    fileIndustry = IndustryType.getNameByValue(it.mfFileIndustry)
 //                    itemType = EnElementType.getNameByValue(it.mfEpItemType)
-//                    fileUrl = it.mfFileUrl
-                    val keyList = it.miKeyword.split("銆�")
-                    for (i in keyList.indices) {
-                        if (i < 5) {
-                            keywords.add(keyList[i])
-                        } else {
-                            break
-                        }
-                    }
-                    time = it.miUpdateTime
-
-                    chapterName = it.miChapterName
-                    fileId = it.mfGuid
-                    fileName = it.mfName
-                    referenceNumber = it.mfReferenceNumber
-                    effectiveDate = DateUtil.DateToString(map[it.mfGuid]?.mfEffectiveDate, DateUtil.DateStyle.YYYY_MM_DD)
-                    closingDate = DateUtil.DateToString(map[it.mfGuid]?.mfClosingDate, DateUtil.DateStyle.YYYY_MM_DD)
-                    effective = Date().time > (map[it.mfGuid]?.mfClosingDate?.time ?: 0)
-                    relatedItems = it.miRelatedItems?.split(";")?.size ?: 0
-                })
-            }
-            response.success = true
-            response.head?.run {
-                this.page = p.pageNum
-                this.totalPage = p.pages
-            }
-        }
-        //鐜繚闂
-        if (type == null || type == ConsultResultType.TYPE4.value) {
-            val p = PageHelper.startPage<CstQuestion>(_page, _perPage)
-            val example = Example(CstQuestion::class.java).apply {
-                if (keywordList.isNotEmpty()) {
-                    createCriteria().orLike("cqScenes", "%${userInfo.extension2}%")
-                        .orEqualTo("cqScenes", "")
-                        .orIsNull("cqScenes")
-                    and(
-                        createCriteria().apply {
-                            keywordList.forEach { k ->
-                                orLike("cqContent", "%${k}%")
-                                orLike("cqKeywords", "%${k}%")
-                            }
-                        }
-                    )
-                } else {
-                    // TODO: 2022/9/8 娌℃湁鍏抽敭瀛楁椂锛屾寜鐓х儹闂ㄨ幏鍙栨満鍒惰幏鍙�
-                    createCriteria().orLike("cqScenes", "%${userInfo.extension2}%")
-                    orderBy("cqTotalnum")
-                }
-            }
-            cstQuestionMapper.selectByExample(example).forEach {
-                val answers = settingAnswerMapper.selectByExample(Example(SettingAnswer::class.java).apply {
-                    createCriteria().andEqualTo("cqGuid", it.cqGuid)
-                })
-
-                result.add(ConsultResultQAVo().apply {
-                    id = it.cqGuid
-                    name = it.cqContent
-                    if (answers.isNotEmpty()) {
-                        des = answers[0].saContent
-                    }
-                    typeId = ConsultResultType.TYPE4.value
-                    typeName = ConsultResultType.TYPE4.des
-
-//                    fileIndustry = IndustryType.getNameByValue(it.mfFileIndustry)
-                    itemType = EnElementType.getNameByValue(it.cqKind)
-                    itemSubType = EnElementSubType.getSubType(it.cqKind, it.cqSubkind)
+//                    itemSubType = EnElementSubType.getSubType(it.mfEpItemType, it.mfEpItemSubtype)
 //                    fileUrl = it.mfFileUrl
 //                    val keyList = it.mfKeywordLv1.split("銆�")
 //                    for (i in keyList.indices) {
@@ -280,77 +161,199 @@
 //                            break
 //                        }
 //                    }
-                    time = it.cqCreateTime
-                    punish = it.cqIsPunish
-                    illegal = it.cqIsIllegal
-                    shotSpot = it.cqIsShotspot
-                    supervise = it.cqIsSupervise
-                })
-            }
-            response.success = true
-            response.head?.run {
-                this.page = p.pageNum
-                this.totalPage = p.pages
-            }
-        }
-        //鎵ф硶妗堜緥
-        if (type == null || type == ConsultResultType.TYPE3.value) {
-            val p = PageHelper.startPage<EnforceCase>(_page, _perPage)
-            val example = Example(EnforceCase::class.java).apply {
-                if (keywordList.isNotEmpty()) {
-                    createCriteria().orLike("ecScenes", "%${userInfo.extension2}%")
-                        .orEqualTo("ecScenes", "")
-                        .orIsNull("ecScenes")
-                    and(
-                        createCriteria().apply {
-                            keywordList.forEach { k ->
-                                orLike("ecTitle", "%${k}%")
-                                orLike("ecKeywords", "%${k}%")
-                            }
-                        }
-                    )
-                } else {
-                    // TODO: 2022/9/8 娌℃湁鍏抽敭瀛楁椂锛屾寜鐓х儹闂ㄨ幏鍙栨満鍒惰幏鍙�
-                    createCriteria().orLike("ecScenes", "%${userInfo.extension2}%")
-                        .orEqualTo("ecScenes", "")
-                        .orIsNull("ecScenes")
-                    orderBy("ecOccurDate").desc()
-                }
-            }
-            enforceCaseMapper.selectByExample(example).forEach {
-                result.add(ConsultResultCaseVo().apply {
-                    id = it.ecGuid
-                    name = it.ecTitle
-                    des = it.ecSummary
-                    typeId = ConsultResultType.TYPE3.value
-                    typeName = ConsultResultType.TYPE3.des
+//                    time = it.mfUpdateTime
+//                    fileType = ConsultFileType.getNameByValue(it.mfFileType)
+//                    referenceNumber = it.mfReferenceNumber
+//                    effectiveDate = DateUtil.DateToString(it.mfEffectiveDate, DateUtil.DateStyle.YYYY_MM_DD)
+//                    closingDate = DateUtil.DateToString(it.mfClosingDate, DateUtil.DateStyle.YYYY_MM_DD)
+//                    effective = Date().time > (it.mfClosingDate?.time ?: 0)
+//                })
+//            }
+//            response.success = true
+//            response.head?.run {
+//                this.page = p.pageNum
+//                this.totalPage = p.pages
+//            }
+//        }
+//        //娉曞緥娉曡鏉$洰
+//        if (type == null || type == ConsultResultType.TYPE2.value) {
+//            val map = mutableMapOf<String, MgtFile>()
+//            val p = PageHelper.startPage<MgtItem>(_page, _perPage)
+//            val example = Example(MgtItem::class.java).apply {
+//                if (keywordList.isNotEmpty()) {
+//                    createCriteria().apply {
+//                        keywordList.forEach { k ->
+//                            orLike("miChapterKeyword", "%${k}%")
+//                            orLike("miKeyword", "%${k}%")
+//                            orLike("miItemContent", "%${k}%")
+//                        }
+//                    }
+//                } else {
+//                    // TODO: 2022/9/8 娌℃湁鍏抽敭瀛楁椂锛屾寜鐓х儹闂ㄨ幏鍙栨満鍒惰幏鍙栨潯鐩�
+//                }
+//            }
+//            mgtItemMapper.selectByExample(example).forEach {
+//
+//                if (!map.containsKey(it.mfGuid)) {
+//                    map[it.mfGuid] = mgtFileMapper.selectByPrimaryKey(it.mfGuid)
+//                }
+//                result.add(ConsultResultItemVo().apply {
+//                    id = it.miGuid
+//                    name = it.miItemName
+//                    des = it.miItemContent
+//                    typeId = ConsultResultType.TYPE2.value
+//                    typeName = ConsultResultType.TYPE2.des
+//
+////                    fileIndustry = IndustryType.getNameByValue(it.mfFileIndustry)
+////                    itemType = EnElementType.getNameByValue(it.mfEpItemType)
+////                    fileUrl = it.mfFileUrl
+//                    val keyList = it.miKeyword.split("銆�")
+//                    for (i in keyList.indices) {
+//                        if (i < 5) {
+//                            keywords.add(keyList[i])
+//                        } else {
+//                            break
+//                        }
+//                    }
+//                    time = it.miUpdateTime
+//
+//                    chapterName = it.miChapterName
+//                    fileId = it.mfGuid
+//                    fileName = it.mfName
+//                    referenceNumber = it.mfReferenceNumber
+//                    effectiveDate = DateUtil.DateToString(map[it.mfGuid]?.mfEffectiveDate, DateUtil.DateStyle.YYYY_MM_DD)
+//                    closingDate = DateUtil.DateToString(map[it.mfGuid]?.mfClosingDate, DateUtil.DateStyle.YYYY_MM_DD)
+//                    effective = Date().time > (map[it.mfGuid]?.mfClosingDate?.time ?: 0)
+//                    relatedItems = it.miRelatedItems?.split(";")?.size ?: 0
+//                })
+//            }
+//            response.success = true
+//            response.head?.run {
+//                this.page = p.pageNum
+//                this.totalPage = p.pages
+//            }
+//        }
+//        //鐜繚闂
+//        if (type == null || type == ConsultResultType.TYPE4.value) {
+//            val p = PageHelper.startPage<CstQuestion>(_page, _perPage)
+//            val example = Example(CstQuestion::class.java).apply {
+//                if (keywordList.isNotEmpty()) {
+//                    createCriteria().orLike("cqScenes", "%${userInfo.extension2}%")
+//                        .orEqualTo("cqScenes", "")
+//                        .orIsNull("cqScenes")
+//                    and(
+//                        createCriteria().apply {
+//                            keywordList.forEach { k ->
+//                                orLike("cqContent", "%${k}%")
+//                                orLike("cqKeywords", "%${k}%")
+//                            }
+//                        }
+//                    )
+//                } else {
+//                    // TODO: 2022/9/8 娌℃湁鍏抽敭瀛楁椂锛屾寜鐓х儹闂ㄨ幏鍙栨満鍒惰幏鍙�
+//                    createCriteria().orLike("cqScenes", "%${userInfo.extension2}%")
+//                    orderBy("cqTotalnum")
+//                }
+//            }
+//            cstQuestionMapper.selectByExample(example).forEach {
+//                val answers = settingAnswerMapper.selectByExample(Example(SettingAnswer::class.java).apply {
+//                    createCriteria().andEqualTo("cqGuid", it.cqGuid)
+//                })
+//
+//                result.add(ConsultResultQAVo().apply {
+//                    id = it.cqGuid
+//                    name = it.cqContent
+//                    if (answers.isNotEmpty()) {
+//                        des = answers[0].saContent
+//                    }
+//                    typeId = ConsultResultType.TYPE4.value
+//                    typeName = ConsultResultType.TYPE4.des
+//
+////                    fileIndustry = IndustryType.getNameByValue(it.mfFileIndustry)
+//                    itemType = EnElementType.getNameByValue(it.cqKind)
+//                    itemSubType = EnElementSubType.getSubType(it.cqKind, it.cqSubkind)
+////                    fileUrl = it.mfFileUrl
+////                    val keyList = it.mfKeywordLv1.split("銆�")
+////                    for (i in keyList.indices) {
+////                        if (i < 5) {
+////                            keywords.add(keyList[i])
+////                        } else {
+////                            break
+////                        }
+////                    }
+//                    time = it.cqCreateTime
+//                    punish = it.cqIsPunish
+//                    illegal = it.cqIsIllegal
+//                    shotSpot = it.cqIsShotspot
+//                    supervise = it.cqIsSupervise
+//                })
+//            }
+//            response.success = true
+//            response.head?.run {
+//                this.page = p.pageNum
+//                this.totalPage = p.pages
+//            }
+//        }
+//        //鎵ф硶妗堜緥
+//        if (type == null || type == ConsultResultType.TYPE3.value) {
+//            val p = PageHelper.startPage<EnforceCase>(_page, _perPage)
+//            val example = Example(EnforceCase::class.java).apply {
+//                if (keywordList.isNotEmpty()) {
+//                    createCriteria().orLike("ecScenes", "%${userInfo.extension2}%")
+//                        .orEqualTo("ecScenes", "")
+//                        .orIsNull("ecScenes")
+//                    and(
+//                        createCriteria().apply {
+//                            keywordList.forEach { k ->
+//                                orLike("ecTitle", "%${k}%")
+//                                orLike("ecKeywords", "%${k}%")
+//                            }
+//                        }
+//                    )
+//                } else {
+//                    // TODO: 2022/9/8 娌℃湁鍏抽敭瀛楁椂锛屾寜鐓х儹闂ㄨ幏鍙栨満鍒惰幏鍙�
+//                    createCriteria().orLike("ecScenes", "%${userInfo.extension2}%")
+//                        .orEqualTo("ecScenes", "")
+//                        .orIsNull("ecScenes")
+//                    orderBy("ecOccurDate").desc()
+//                }
+//            }
+//            enforceCaseMapper.selectByExample(example).forEach {
+//                result.add(ConsultResultCaseVo().apply {
+//                    id = it.ecGuid
+//                    name = it.ecTitle
+//                    des = it.ecSummary
+//                    typeId = ConsultResultType.TYPE3.value
+//                    typeName = ConsultResultType.TYPE3.des
+//
+////                    fileIndustry = IndustryType.getNameByValue(it.mfFileIndustry)
+//                    itemType = EnElementType.getNameByValue(it.ecEpItemType)
+//                    itemSubType = EnElementSubType.getSubType(it.ecEpItemType, it.ecEpItemSubtype)
+//                    imgUrl = it.ecAppendixUrl?.split(";")?.get(0)
+//                    time = it.ecCreateTime
+//
+//                    provinceName = it.ecProvinceName
+//                    cityName = it.ecCityName
+//                    occurDate = DateUtil.DateToString(it.ecOccurDate, DateUtil.DateStyle.YYYY_MM_DD)
+//                    punish = it.ecIsPunish
+//                    detained = it.ecIsDetained
+//                    illegal = it.ecIsIllegal
+//                    shotSpot = it.ecIsShotspot
+//                    supervise = it.ecIsSupervise
+//                    minor = it.ecIsMinor
+//                })
+//            }
+//            response.success = true
+//            response.head?.run {
+//                this.page = p.pageNum
+//                this.totalPage = p.pages
+//            }
+//        }
+//
+//
+//        return response.apply { data = result }
 
-//                    fileIndustry = IndustryType.getNameByValue(it.mfFileIndustry)
-                    itemType = EnElementType.getNameByValue(it.ecEpItemType)
-                    itemSubType = EnElementSubType.getSubType(it.ecEpItemType, it.ecEpItemSubtype)
-                    imgUrl = it.ecAppendixUrl?.split(";")?.get(0)
-                    time = it.ecCreateTime
-
-                    provinceName = it.ecProvinceName
-                    cityName = it.ecCityName
-                    occurDate = DateUtil.DateToString(it.ecOccurDate, DateUtil.DateStyle.YYYY_MM_DD)
-                    punish = it.ecIsPunish
-                    detained = it.ecIsDetained
-                    illegal = it.ecIsIllegal
-                    shotSpot = it.ecIsShotspot
-                    supervise = it.ecIsSupervise
-                    minor = it.ecIsMinor
-                })
-            }
-            response.success = true
-            response.head?.run {
-                this.page = p.pageNum
-                this.totalPage = p.pages
-            }
-        }
-
-
-        return response.apply { data = result }
+        return searchLaw2(userId, keyword, type, page, perPage)
     }
 
     override fun getTopicLaw(userId: String): List<MgtFileVo> {
@@ -474,8 +477,7 @@
 //            }
 //            result.add(vo)
         }
-        val totalCount = cstQuestionMapper.selectCountByExample(example)
-        return BaseResponse(true, head = DataHead(p.pageNum, p.pages, totalCount), data = result)
+        return BaseResponse(true, head = DataHead(p.pageNum, p.pages, p.total), data = result)
     }
 
     override fun getQuestion(userId: String, qId: String): CstQuestionVo {
@@ -570,4 +572,353 @@
         }
         return result
     }
+
+    private fun searchLaw2(userId: String, keyword: String, type: Byte?, page: Int, perPage: Int): BaseResponse<List<ConsultResultVo>> {
+        val keywordList = if (keyword.isBlank()) {
+            emptyList()
+        } else {
+            nlpController.execute(keyword)
+        }
+        val userInfo = userinfoMapper.selectByPrimaryKey(userId) ?: return BaseResponse(false)
+        val response = BaseResponse<List<ConsultResultVo>>(false, head = DataHead(page, perPage))
+        val result = mutableListOf<ConsultResultVo>()
+
+        //褰撴悳绱笉闄愬埗绫诲瀷鏃讹紝榛樿姣忕绫诲瀷鍙幏鍙栧墠5椤癸紱褰撻檺鍒剁被鍨嬫椂锛屽垯鏍规嵁鍓嶇璇锋眰鍒嗛〉鏁拌繑鍥�
+        val _perPage = if (type == null) 5 else perPage
+        val _page = page
+
+        //娉曞緥娉曡鏂囦欢
+        if (type == null || type == ConsultResultType.TYPE1.value) {
+            val p = PageHelper.startPage<MgtFile>(_page, _perPage)
+            val resultMap = mutableMapOf<String, Pair<MgtFile, Int>>()
+            val tempList = mutableListOf<Pair<MgtFile, Int>>()
+            if (keywordList.isNotEmpty()) {
+                keywordList.forEach { k ->
+                    mgtFileMapper.selectByExample(Example(MgtFile::class.java).apply {
+                        createCriteria().orLike("mfName", "%${k}%")
+                            .orLike("mfShortName", "%${k}%")
+                            .orLike("mfSummary", "%${k}%")
+                            .orLike("mfKeywordLv1", "%${k}%")
+                            .orLike("mfKeywordLv2", "%${k}%")
+                            .orLike("mfKeywordLv3", "%${k}%")
+                            .orLike("mfKeywordLv4", "%${k}%")
+                    }).forEach { f ->
+                        if (!resultMap.containsKey(f.mfGuid)) {
+                            resultMap[f.mfGuid] = Pair(f, 0)
+                        }
+                        resultMap[f.mfGuid] = Pair(f, resultMap[f.mfGuid]?.second?.plus(1) ?: 0)
+                    }
+                }
+                resultMap.forEach { (_, u) ->
+                    tempList.add(u)
+                }
+                tempList.sortWith { o1, o2 ->
+                    //鎺掑簭鏉′欢涓�锛氬叧閿瘝鍖归厤娆℃暟
+                    if (o1.second != o2.second) {
+                        return@sortWith o2.second - o1.second
+                    }
+                    //鎺掑簭鏉′欢浜岋細娴忚閲�
+                    if (o1.first.mfRemark != o2.first.mfRemark) {
+                        return@sortWith o2.first.mfRemark.toIntOrNull()?.minus(o1.first.mfRemark.toIntOrNull() ?: 0) ?: 0
+                    }
+                    //鎺掑簭鏉′欢涓夛細鏂囦欢鍙戝竷鏃堕棿
+                    (o2.first.mfReleaseDate.time - o1.first.mfReleaseDate.time).toInt()
+                }
+            } else {
+                mgtFileMapper.selectByExample(Example(MgtFile::class.java).apply {
+                    createCriteria().orLike("mfExtension1", "%${userInfo.extension2}%")
+                        .orEqualTo("mfExtension1", "")
+                        .orIsNull("mfExtension1")
+                }).forEach {
+                    tempList.add(Pair(it, 0))
+                }
+            }
+
+            tempList.forEach {p ->
+                val it = p.first
+                result.add(ConsultResultFileVo().apply {
+                    id = it.mfGuid
+                    name = it.mfName
+                    des = it.mfSummary
+                    typeId = ConsultResultType.TYPE1.value
+                    typeName = ConsultResultType.TYPE1.des
+
+                    fileIndustry = IndustryType.getNameByValue(it.mfFileIndustry)
+                    itemType = EnElementType.getNameByValue(it.mfEpItemType)
+                    itemSubType = EnElementSubType.getSubType(it.mfEpItemType, it.mfEpItemSubtype)
+                    fileUrl = it.mfFileUrl
+                    val keyList = it.mfKeywordLv1.split("銆�")
+                    for (i in keyList.indices) {
+                        if (i < 5) {
+                            keywords.add(keyList[i])
+                        } else {
+                            break
+                        }
+                    }
+                    time = it.mfUpdateTime
+                    fileType = ConsultFileType.getNameByValue(it.mfFileType)
+                    referenceNumber = it.mfReferenceNumber
+                    effectiveDate = DateUtil.DateToString(it.mfEffectiveDate, DateUtil.DateStyle.YYYY_MM_DD)
+                    closingDate = DateUtil.DateToString(it.mfClosingDate, DateUtil.DateStyle.YYYY_MM_DD)
+                    effective = Date().time > (it.mfClosingDate?.time ?: 0)
+                })
+            }
+            response.success = true
+            response.head?.run {
+                this.page = p.pageNum
+                this.totalPage = p.pages
+            }
+        }
+        //娉曞緥娉曡鏉$洰
+        if (type == null || type == ConsultResultType.TYPE2.value) {
+            val map = mutableMapOf<String, MgtFile>()
+            val p = PageHelper.startPage<MgtItem>(_page, _perPage)
+
+            val resultMap = mutableMapOf<String, Pair<MgtItem, Int>>()
+            val tempList = mutableListOf<Pair<MgtItem, Int>>()
+            if (keywordList.isNotEmpty()) {
+                mgtItemMapper.selectByExample(Example(MgtItem::class.java).apply {
+                    createCriteria().apply {
+                        keywordList.forEach { k ->
+                            orLike("miChapterKeyword", "%${k}%")
+                            orLike("miKeyword", "%${k}%")
+                            orLike("miItemContent", "%${k}%")
+                        }
+                    }
+                }).forEach { f ->
+                    if (!resultMap.containsKey(f.miGuid)) {
+                        resultMap[f.miGuid] = Pair(f, 0)
+                    }
+                    resultMap[f.miGuid] = Pair(f, resultMap[f.miGuid]?.second?.plus(1) ?: 0)
+                }
+                resultMap.forEach { (_, u) ->
+                    tempList.add(u)
+                }
+                tempList.sortWith { o1, o2 ->
+                    //鎺掑簭鏉′欢涓�锛氬叧閿瘝鍖归厤娆℃暟
+                    if (o1.second != o2.second) {
+                        return@sortWith o2.second - o1.second
+                    }
+                    //鎺掑簭鏉′欢浜岋細娴忚閲�
+                    return@sortWith o2.first.miRemark.toIntOrNull()?.minus(o1.first.miRemark.toIntOrNull() ?: 0) ?: 0
+                }
+            } else {
+                // TODO: 2022/9/8 娌℃湁鍏抽敭瀛楁椂锛屾寜鐓х儹闂ㄨ幏鍙栨満鍒惰幏鍙栨潯鐩�
+                mgtItemMapper.selectByExample(Example(MgtItem::class.java).apply {
+                    orderBy("miCreateTime").desc()
+                }).forEach {
+                    tempList.add(Pair(it, 0))
+                }
+            }
+
+            tempList.forEach {p ->
+                val it = p.first
+                if (!map.containsKey(it.mfGuid)) {
+                    map[it.mfGuid] = mgtFileMapper.selectByPrimaryKey(it.mfGuid)
+                }
+                result.add(ConsultResultItemVo().apply {
+                    id = it.miGuid
+                    name = it.miItemName
+                    des = it.miItemContent
+                    typeId = ConsultResultType.TYPE2.value
+                    typeName = ConsultResultType.TYPE2.des
+
+//                    fileIndustry = IndustryType.getNameByValue(it.mfFileIndustry)
+//                    itemType = EnElementType.getNameByValue(it.mfEpItemType)
+//                    fileUrl = it.mfFileUrl
+                    val keyList = it.miKeyword.split("銆�")
+                    for (i in keyList.indices) {
+                        if (i < 5) {
+                            keywords.add(keyList[i])
+                        } else {
+                            break
+                        }
+                    }
+                    time = it.miUpdateTime
+
+                    chapterName = it.miChapterName
+                    fileId = it.mfGuid
+                    fileName = it.mfName
+                    referenceNumber = it.mfReferenceNumber
+                    effectiveDate = DateUtil.DateToString(map[it.mfGuid]?.mfEffectiveDate, DateUtil.DateStyle.YYYY_MM_DD)
+                    closingDate = DateUtil.DateToString(map[it.mfGuid]?.mfClosingDate, DateUtil.DateStyle.YYYY_MM_DD)
+                    effective = Date().time > (map[it.mfGuid]?.mfClosingDate?.time ?: 0)
+                    relatedItems = it.miRelatedItems?.split(";")?.size ?: 0
+                })
+            }
+            response.success = true
+            response.head?.run {
+                this.page = p.pageNum
+                this.totalPage = p.pages
+            }
+        }
+        //鐜繚闂
+        if (type == null || type == ConsultResultType.TYPE4.value) {
+            val p = PageHelper.startPage<CstQuestion>(_page, _perPage)
+
+            val resultMap = mutableMapOf<String, Pair<CstQuestion, Int>>()
+            val tempList = mutableListOf<Pair<CstQuestion, Int>>()
+            if (keywordList.isNotEmpty()) {
+                cstQuestionMapper.selectByExample(Example(CstQuestion::class.java).apply {
+                    createCriteria().orLike("cqScenes", "%${userInfo.extension2}%")
+                        .orEqualTo("cqScenes", "")
+                        .orIsNull("cqScenes")
+                    and(
+                        createCriteria().apply {
+                            keywordList.forEach { k ->
+                                orLike("cqContent", "%${k}%")
+                                orLike("cqKeywords", "%${k}%")
+                            }
+                        }
+                    )
+                }).forEach { f ->
+                    if (!resultMap.containsKey(f.cqGuid)) {
+                        resultMap[f.cqGuid] = Pair(f, 0)
+                    }
+                    resultMap[f.cqGuid] = Pair(f, resultMap[f.cqGuid]?.second?.plus(1) ?: 0)
+                }
+                resultMap.forEach { (_, u) ->
+                    tempList.add(u)
+                }
+                tempList.sortWith { o1, o2 ->
+                    //鎺掑簭鏉′欢涓�锛氬叧閿瘝鍖归厤娆℃暟
+                    if (o1.second != o2.second) {
+                        return@sortWith o2.second - o1.second
+                    }
+                    //鎺掑簭鏉′欢浜岋細娴忚閲�
+                    return@sortWith o2.first.cqRemark?.toIntOrNull()?.minus(o1.first.cqRemark.toIntOrNull() ?: 0) ?: 0
+                }
+            } else {
+                // TODO: 2022/9/8 娌℃湁鍏抽敭瀛楁椂锛屾寜鐓х儹闂ㄨ幏鍙栨満鍒惰幏鍙�
+                cstQuestionMapper.selectByExample(Example(CstQuestion::class.java).apply {
+                    createCriteria().orLike("cqScenes", "%${userInfo.extension2}%")
+                    orderBy("cqTotalnum")
+                }).forEach {
+                    tempList.add(Pair(it, 0))
+                }
+            }
+            tempList.forEach {p ->
+                val it = p.first
+                val answers = settingAnswerMapper.selectByExample(Example(SettingAnswer::class.java).apply {
+                    createCriteria().andEqualTo("cqGuid", it.cqGuid)
+                })
+
+                result.add(ConsultResultQAVo().apply {
+                    id = it.cqGuid
+                    name = it.cqContent
+                    if (answers.isNotEmpty()) {
+                        des = answers[0].saContent
+                    }
+                    typeId = ConsultResultType.TYPE4.value
+                    typeName = ConsultResultType.TYPE4.des
+
+//                    fileIndustry = IndustryType.getNameByValue(it.mfFileIndustry)
+                    itemType = EnElementType.getNameByValue(it.cqKind)
+                    itemSubType = EnElementSubType.getSubType(it.cqKind, it.cqSubkind)
+//                    fileUrl = it.mfFileUrl
+//                    val keyList = it.mfKeywordLv1.split("銆�")
+//                    for (i in keyList.indices) {
+//                        if (i < 5) {
+//                            keywords.add(keyList[i])
+//                        } else {
+//                            break
+//                        }
+//                    }
+                    time = it.cqCreateTime
+                    punish = it.cqIsPunish
+                    illegal = it.cqIsIllegal
+                    shotSpot = it.cqIsShotspot
+                    supervise = it.cqIsSupervise
+                })
+            }
+            response.success = true
+            response.head?.run {
+                this.page = p.pageNum
+                this.totalPage = p.pages
+            }
+        }
+        //鎵ф硶妗堜緥
+        if (type == null || type == ConsultResultType.TYPE3.value) {
+            val p = PageHelper.startPage<EnforceCase>(_page, _perPage)
+
+            val resultMap = mutableMapOf<String, Pair<EnforceCase, Int>>()
+            val tempList = mutableListOf<Pair<EnforceCase, Int>>()
+            if (keywordList.isNotEmpty()) {
+                enforceCaseMapper.selectByExample(Example(EnforceCase::class.java).apply {
+
+                    createCriteria().orLike("ecScenes", "%${userInfo.extension2}%")
+                        .orEqualTo("ecScenes", "")
+                        .orIsNull("ecScenes")
+                    and(
+                        createCriteria().apply {
+                            keywordList.forEach { k ->
+                                orLike("ecTitle", "%${k}%")
+                                orLike("ecKeywords", "%${k}%")
+                            }
+                        }
+                    )
+                }).forEach { f ->
+                    if (!resultMap.containsKey(f.ecGuid)) {
+                        resultMap[f.ecGuid] = Pair(f, 0)
+                    }
+                    resultMap[f.ecGuid] = Pair(f, resultMap[f.ecGuid]?.second?.plus(1) ?: 0)
+                }
+                resultMap.forEach { (_, u) ->
+                    tempList.add(u)
+                }
+                tempList.sortWith { o1, o2 ->
+                    //鎺掑簭鏉′欢涓�锛氬叧閿瘝鍖归厤娆℃暟
+                    if (o1.second != o2.second) {
+                        return@sortWith o2.second - o1.second
+                    }
+                    //鎺掑簭鏉′欢浜岋細娴忚閲�
+                    return@sortWith o2.first.ecRemark.toIntOrNull()?.minus(o1.first.ecRemark.toIntOrNull() ?: 0) ?: 0
+                }
+            } else {
+                // TODO: 2022/9/8 娌℃湁鍏抽敭瀛楁椂锛屾寜鐓х儹闂ㄨ幏鍙栨満鍒惰幏鍙�
+                enforceCaseMapper.selectByExample(Example(EnforceCase::class.java).apply {
+                    createCriteria().orLike("ecScenes", "%${userInfo.extension2}%")
+                        .orEqualTo("ecScenes", "")
+                        .orIsNull("ecScenes")
+                    orderBy("ecOccurDate").desc()
+                }).forEach {
+                    tempList.add(Pair(it, 0))
+                }
+            }
+            tempList.forEach {p ->
+                val it = p.first
+                result.add(ConsultResultCaseVo().apply {
+                    id = it.ecGuid
+                    name = it.ecTitle
+                    des = it.ecSummary
+                    typeId = ConsultResultType.TYPE3.value
+                    typeName = ConsultResultType.TYPE3.des
+
+//                    fileIndustry = IndustryType.getNameByValue(it.mfFileIndustry)
+                    itemType = EnElementType.getNameByValue(it.ecEpItemType)
+                    itemSubType = EnElementSubType.getSubType(it.ecEpItemType, it.ecEpItemSubtype)
+                    imgUrl = it.ecAppendixUrl?.split(";")?.get(0)
+                    time = it.ecCreateTime
+
+                    provinceName = it.ecProvinceName
+                    cityName = it.ecCityName
+                    occurDate = DateUtil.DateToString(it.ecOccurDate, DateUtil.DateStyle.YYYY_MM_DD)
+                    punish = it.ecIsPunish
+                    detained = it.ecIsDetained
+                    illegal = it.ecIsIllegal
+                    shotSpot = it.ecIsShotspot
+                    supervise = it.ecIsSupervise
+                    minor = it.ecIsMinor
+                })
+            }
+            response.success = true
+            response.head?.run {
+                this.page = p.pageNum
+                this.totalPage = p.pages
+            }
+        }
+
+
+        return response.apply { data = result }
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/OperationServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/OperationServiceImpl.kt
new file mode 100644
index 0000000..aca0c9d
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/OperationServiceImpl.kt
@@ -0,0 +1,57 @@
+package cn.flightfeather.supervision.lightshare.service.Impl
+
+import cn.flightfeather.supervision.domain.entity.PracticalOperation
+import cn.flightfeather.supervision.domain.entity.PracticalOperationRecord
+import cn.flightfeather.supervision.domain.mapper.PracticalOperationRecordMapper
+import cn.flightfeather.supervision.domain.repository.PracticalOperationRep
+import cn.flightfeather.supervision.domain.repository.UserConfigRep
+import cn.flightfeather.supervision.lightshare.service.OperationService
+import cn.flightfeather.supervision.lightshare.vo.PracticalOperationVo
+import org.springframework.stereotype.Service
+
+@Service
+class OperationServiceImpl(
+    private val userConfigRep: UserConfigRep,
+    private val practicalOperationRep: PracticalOperationRep,
+) : OperationService {
+
+    override fun getOperations(userId: String): List<PracticalOperation?> {
+        val res = mutableListOf<PracticalOperation?>()
+        // 鍏堟煡璇㈡槸鍚︽湁鐗瑰畾灞炰簬璇ョ敤鎴风殑浜嬪姟
+        val r = practicalOperationRep.getOperation(userId)
+        res.addAll(r)
+        // 濡傛灉鐢ㄦ埛娌℃湁鐗瑰畾涓哄叾瀹氬埗鐨勪簨鍔★紝鍒欎娇鐢ㄩ�氱敤鐨勪簨鍔�
+        if (res.isEmpty()) {
+            val configIds = mutableListOf<Int>()
+            userConfigRep.getUserConfig(userId).forEach { it?.let { configIds.add(it.ucId) } }
+            val r1 = practicalOperationRep.getOperation(configIds)
+            res.addAll(r1)
+        }
+        return res
+    }
+
+    override fun executeOperation(
+        userId: String,
+        operationId: Int,
+        stateId: String,
+    ): PracticalOperationRecord? {
+        return practicalOperationRep.executeOperation(userId, operationId, stateId)
+    }
+
+    override fun getOperationRecord(userId: String): List<PracticalOperationVo?> {
+        val result = mutableListOf<PracticalOperationVo>()
+        val operations = getOperations(userId)
+        operations.forEach {
+            it?.let {
+                val vo = PracticalOperationVo()
+                vo.operation = it
+                val records = practicalOperationRep.getRecords(userId, it.poId, perPage = 1)
+                if (records.isNotEmpty()) {
+                    vo.record = records[0]
+                }
+                result.add(vo)
+            }
+        }
+        return result
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ProblemServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ProblemServiceImpl.kt
index 870f031..671130a 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ProblemServiceImpl.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ProblemServiceImpl.kt
@@ -29,4 +29,14 @@
                     .andBetween("prInspectionPeriod", startTime, endTime)
         })
     }
+
+    override fun saveProblem(info: Problem): Int {
+        // TODO: 2023/3/20 not yet implemented
+        return 0
+    }
+
+    override fun updateProblem(info: Problem): Int {
+        // TODO: 2023/3/20 not yet implemented
+        return 0
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/RiskServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/RiskServiceImpl.kt
new file mode 100644
index 0000000..dcc24fc
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/RiskServiceImpl.kt
@@ -0,0 +1,117 @@
+package cn.flightfeather.supervision.lightshare.service.Impl
+
+import cn.flightfeather.supervision.common.risk.DataSource
+import cn.flightfeather.supervision.common.risk.DbMapper
+import cn.flightfeather.supervision.common.risk.RiskAnalysis
+import cn.flightfeather.supervision.domain.entity.Evaluation
+import cn.flightfeather.supervision.domain.entity.RiskEvaluation
+import cn.flightfeather.supervision.domain.mapper.RiskEvaluationMapper
+import cn.flightfeather.supervision.domain.mapper.UserinfoMapper
+import cn.flightfeather.supervision.domain.repository.UserConfigRep
+import cn.flightfeather.supervision.lightshare.service.RiskService
+import cn.flightfeather.supervision.lightshare.vo.*
+import com.github.pagehelper.PageHelper
+import org.springframework.stereotype.Service
+import tk.mybatis.mapper.entity.Example
+import java.util.*
+import javax.servlet.http.HttpServletResponse
+
+@Service
+class RiskServiceImpl(
+    private val userinfoMapper: UserinfoMapper,
+    private val riskEvaluationMapper: RiskEvaluationMapper,
+    private val userConfigRep: UserConfigRep,
+    private val dbMapper: DbMapper,
+) : RiskService {
+
+    override fun getRiskCount(userId: String, condition: UserSearchCondition): BaseResponse<CountVo> {
+        if (condition.sceneTypes.size != 1) return BaseResponse(false, "鍙敮鎸佸崟涓満鏅被鍨嬬殑鏌ヨ")
+
+        val config = userConfigRep.getUserConfigBySubType(userId)
+        val condition2 = UserSearchCondition.fromUserConfig(config, condition)
+
+        // 浣庨闄�
+        var level0 = 0
+        // 涓闄�
+        var level1 = 0
+        // 楂橀闄�
+        var level2 = 0
+        condition2.period = condition2.period
+            ?: riskEvaluationMapper.getLatestPeriod(condition2)
+            ?: return BaseResponse(false, "鏃犺褰�")
+
+        riskEvaluationMapper.getRiskCount(condition2).forEach {
+            when (it.reRiskLevel?.toInt()) {
+                0 -> level0++
+                1 -> level1++
+                2 -> level2++
+            }
+        }
+        val result = CountVo().apply {
+            tag = condition2.period
+            countList.addAll(listOf(level0, level1, level2))
+        }
+
+        return BaseResponse(true, data = result)
+    }
+
+    override fun searchRiskList(
+        userId: String,
+        condition: UserSearchCondition,
+        page: Int,
+        perPage: Int,
+    ): BaseResponse<List<CreditInfoVo>> {
+        if (condition.period == null) return BaseResponse(false, "蹇呴』閫夋嫨鍛ㄦ湡")
+        if (condition.sceneTypes.size > 2) return BaseResponse(false, "鍦烘櫙绫诲瀷鍙敮鎸佷竴绉�")
+        val config = userConfigRep.getUserConfigBySubType(userId)
+        val condition2 = UserSearchCondition.fromUserConfig(config, condition)
+        val p = PageHelper.startPage<Evaluation>(page, perPage)
+        val result = riskEvaluationMapper.searchRiskList(condition2)
+        return BaseResponse(true, head = DataHead(p.pageNum, p.pages, p.total), data = result)
+    }
+
+    override fun getRiskInfo(userId: String, period: String?): BaseResponse<RiskEvaluation> {
+        PageHelper.startPage<RiskEvaluation>(1, 1)
+        val result = riskEvaluationMapper.selectByExample(Example(RiskEvaluation::class.java).apply {
+            createCriteria().andEqualTo("biGuid", userId)
+                .apply {
+                    period?.let {
+                        andLessThanOrEqualTo("reStartTime", it)
+                        andGreaterThanOrEqualTo("reEndTime", it)
+                    }
+                }
+            orderBy("reStartTime").desc()
+        })
+        return if (result.isNotEmpty()) {
+            BaseResponse(true, data = result[0])
+        } else {
+            BaseResponse(false, "鏃犵患鍚堥闄╄褰�")
+        }
+    }
+
+    override fun downloadRiskInfo(
+        district: String,
+        sceneType: String,
+        year: Int,
+        month: Int,
+        response: HttpServletResponse,
+    ) {
+        val dataSource = DataSource(DataSource.Config(district, sceneType, year, month), dbMapper)
+        val riskAnalysis = RiskAnalysis(dataSource, toDatabase = false, toFile = true)
+
+//        val fName = Base64.getEncoder().encodeToString("risk.xlsx".toByteArray())
+        val fName = "risk.xls"
+        response.apply {
+            setHeader("Content-Disposition", "attachment;filename=$fName")
+            setHeader("fileName", fName)
+            addHeader("Access-Control-Expose-Headers", "fileName")
+            contentType = "application/vnd.ms-excel;charset=UTF-8"
+            setHeader("Pragma", "no-cache")
+            setHeader("Cache-Control", "no-cache")
+            setDateHeader("Expires", 0)
+        }
+        riskAnalysis.executeToStream(response.outputStream)
+
+        return
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ScheduleServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ScheduleServiceImpl.kt
new file mode 100644
index 0000000..f69ab1d
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ScheduleServiceImpl.kt
@@ -0,0 +1,95 @@
+package cn.flightfeather.supervision.lightshare.service.Impl
+
+import cn.flightfeather.supervision.domain.entity.ScheduleSignRecord
+import cn.flightfeather.supervision.domain.mapper.BaseInfoMapper
+import cn.flightfeather.supervision.domain.mapper.EnvironmentalScheduleMapper
+import cn.flightfeather.supervision.domain.mapper.ScheduleSignRecordMapper
+import cn.flightfeather.supervision.domain.mapper.UserinfoMapper
+import cn.flightfeather.supervision.lightshare.repository.ScheduleRepository
+import cn.flightfeather.supervision.lightshare.repository.ScheduleSignRecordRepository
+import cn.flightfeather.supervision.domain.repository.UserConfigRep
+import cn.flightfeather.supervision.lightshare.service.ScheduleService
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import cn.flightfeather.supervision.lightshare.vo.ScheduleOption
+import cn.flightfeather.supervision.lightshare.vo.ScheduleVo
+import com.github.pagehelper.PageHelper
+import org.springframework.stereotype.Service
+import tk.mybatis.mapper.entity.Example
+import java.time.LocalDate
+import java.time.ZoneId
+import java.util.*
+
+@Service
+class ScheduleServiceImpl(
+    private val scheduleMapper: EnvironmentalScheduleMapper,
+    private val scheduleSignRecordMapper: ScheduleSignRecordMapper,
+    private val userinfoMapper: UserinfoMapper,
+    private val baseInfoMapper: BaseInfoMapper,
+    private val userConfigRep: UserConfigRep,
+    private val scheduleRepository: ScheduleRepository,
+    private val scheduleSignRecordRepository: ScheduleSignRecordRepository
+) : ScheduleService {
+
+    override fun getSchedules(option: ScheduleOption): BaseResponse<List<ScheduleVo>> {
+        option.userId ?: return BaseResponse(false, "鐢ㄦ埛id涓嶈兘涓虹┖")
+        val userInfo = userinfoMapper.selectByPrimaryKey(option.userId) ?: return BaseResponse(false, "鐢ㄦ埛涓嶅瓨鍦�")
+        val baseInfo = baseInfoMapper.selectByPrimaryKey(option.userId)
+        val config = userConfigRep.getUserConfig(userInfo, baseInfo)
+        val res = mutableListOf<ScheduleVo>()
+        scheduleRepository.getSchedules(userInfo, config, option).forEach{
+            it?.let {
+                res.addAll(ScheduleVo.toScheduleVoList(it, option))
+            }
+        }
+
+        res.forEach {
+            val millisecond = it.time?.time!! + 1000 * 60 * 60 * 24
+            val eTime = Date(millisecond)
+            val r = scheduleSignRecordRepository.getRecord(option.userId, it.id, it.time, eTime)
+            if (r.isNotEmpty()) {
+                it.recordId = r[0]?.srId
+                it.finished = r[0]?.srSignStatus ?: false
+            }
+        }
+
+        return BaseResponse(true, data = res)
+    }
+
+    override fun completeSchedule(userId: String, id: Int): BaseResponse<ScheduleSignRecord> {
+        val now = LocalDate.now().atTime(0,0,0)
+        val sTime = Date.from(now.atZone(ZoneId.systemDefault()).toInstant())
+        val eTime = Date.from(now.plusDays(1).atZone(ZoneId.systemDefault()).toInstant())
+        val records = scheduleSignRecordRepository.getRecord(userId, id, sTime, eTime)
+        return if (records.isNotEmpty()) {
+            records[0]?.srSignStatus = true
+            val r = scheduleSignRecordMapper.updateByPrimaryKeySelective(records[0])
+            BaseResponse(r == 1, data = records[0])
+        } else {
+            PageHelper.startPage<ScheduleSignRecord>(1, 1)
+            val latestOne = scheduleSignRecordMapper.selectByExample(Example(ScheduleSignRecord::class.java).apply {
+                orderBy("srId").desc()
+            })
+            val index = if (latestOne.isEmpty()) {
+                1
+            } else {
+                (latestOne[0]?.srId ?: 0) + 1
+            }
+            val record = ScheduleSignRecord().apply {
+                srId = index
+                srScheduleId = id
+                srUserId = userId
+                srSignStatus = true
+                srSignTime = Date()
+            }
+            val r = scheduleSignRecordMapper.insert(record)
+            BaseResponse(r == 1, data = record)
+        }
+    }
+
+    override fun revokeSchedule(userId: String, recordId: Int): BaseResponse<Boolean> {
+        val record = scheduleSignRecordMapper.selectByPrimaryKey(recordId) ?: return BaseResponse(false, "璇ユ棩绋嬩笉瀛樺湪")
+        record.srSignStatus = false
+        val r = scheduleSignRecordMapper.updateByPrimaryKeySelective(record)
+        return BaseResponse(r == 1)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/SelfPatrolServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/SelfPatrolServiceImpl.kt
new file mode 100644
index 0000000..4e10000
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/SelfPatrolServiceImpl.kt
@@ -0,0 +1,461 @@
+package cn.flightfeather.supervision.lightshare.service.Impl
+
+import cn.flightfeather.supervision.domain.entity.*
+import cn.flightfeather.supervision.domain.enumeration.SceneType
+import cn.flightfeather.supervision.domain.enumeration.SelfPatrolTaskStatus
+import cn.flightfeather.supervision.domain.mapper.*
+import cn.flightfeather.supervision.infrastructure.utils.DateUtil
+import cn.flightfeather.supervision.infrastructure.utils.FileUtil
+import cn.flightfeather.supervision.infrastructure.utils.UUIDGenerator
+import cn.flightfeather.supervision.lightshare.service.SelfPatrolService
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import cn.flightfeather.supervision.lightshare.vo.LedgerSubTypeVo
+import cn.flightfeather.supervision.lightshare.vo.LedgerVo
+import cn.flightfeather.supervision.lightshare.vo.SelfPatrolTaskVo
+import com.fasterxml.jackson.core.type.TypeReference
+import com.fasterxml.jackson.databind.ObjectMapper
+import org.springframework.beans.factory.annotation.Value
+import org.springframework.stereotype.Service
+import org.springframework.web.multipart.MultipartFile
+import tk.mybatis.mapper.entity.Example
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.format.DateTimeFormatter
+import java.util.*
+
+@Service
+class SelfPatrolServiceImpl(
+    private val selfPatrolTaskMapper: SelfPatrolTaskMapper,
+    private val selfPatrolRecordMapper: SelfPatrolRecordMapper,
+    private val selfPatrolMediaFileMapper: SelfPatrolMediaFileMapper,
+    private val userinfoMapper: UserinfoMapper,
+    private val ledgerSubTypeMapper: LedgerSubTypeMapper,
+) : SelfPatrolService {
+
+    @Value("\${imgPath}")
+    lateinit var imgPath: String
+
+    private val notInvolvedPath = "ledgerIcons/ledger_not_involved.jpg"
+
+    override fun getPatrolType(sceneType: Int): BaseResponse<List<LedgerSubTypeVo>> {
+        val ledgerSubTypes = ledgerSubTypeMapper.selectByExample(Example(LedgerSubType::class.java).apply {
+            if (sceneType != SceneType.NoType.value) {
+                createCriteria().andEqualTo("lScenetype", sceneType)
+                    .andEqualTo("lTypeid", -1)
+            }
+        })
+        val resultList = ArrayList<LedgerSubTypeVo>()
+        ledgerSubTypes.forEach {
+            val l = LedgerSubTypeVo(
+                it.lsSubtypeid,
+                it.lsName,
+                it.getlTypeid(),
+                it.getlTypename(),
+                needUpdate = it.getlNeedupdate(),
+                sceneType = it.getlScenetype(),
+                iconUrl = it.getlIconurl()
+            )
+            resultList.add(l)
+        }
+        return BaseResponse(true, data = resultList)
+    }
+
+    override fun publishTask(tasks: List<SelfPatrolTask>): BaseResponse<Boolean> {
+        var r = 0
+        val now = LocalDateTime.now()
+        val date = Date()
+        tasks.forEach {
+            it.spGuid = UUIDGenerator.generate16ShortUUID()
+            it.spTaskYear = now.year
+            it.spTaskMonth = now.monthValue
+            it.spCreateTime = date
+            it.spTaskStatus = SelfPatrolTaskStatus.Published.value
+            r += selfPatrolTaskMapper.insert(it)
+        }
+
+        return BaseResponse(r == tasks.size)
+    }
+
+    override fun getPublishedTask(userId: String, date: String?): BaseResponse<List<SelfPatrolTaskVo>> {
+//        val res = selfPatrolTaskMapper.selectByExample(Example(SelfPatrolTask::class.java).apply {
+//            createCriteria().andEqualTo("spFromUserId", userId).apply {
+//                date?.let {
+//                    val time = LocalDate.parse(it)
+//                    andEqualTo("spTaskYear", time.year).andEqualTo("spTaskMonth", time.monthValue)
+//                }
+//            }
+//        })
+        val ledgerTypes = ledgerSubTypeMapper.selectAll()
+        val time = LocalDate.parse(date)
+        val res = selfPatrolTaskMapper.getPublishedTask(userId, time?.year, time?.monthValue)
+        res.forEach {
+            it.sceneType = SceneType.getByValue(it.sceneTypeId).des
+            it.total = it.ledgerTypeId?.split(";")?.size ?: 0
+            it.ledgerTypeId?.split(";")?.forEach {l ->
+                if (it.ledgerTypeName.isNotBlank()) it.ledgerTypeName += ';'
+                it.ledgerTypeName += ledgerTypes.find { t -> t.lsSubtypeid.toString() == l }?.lsName
+            }
+        }
+
+        return BaseResponse(true, data = res)
+    }
+
+    override fun getToTask(userId: String, date: String?): BaseResponse<List<SelfPatrolTask?>> {
+        val res = selfPatrolTaskMapper.selectByExample(Example(SelfPatrolTask::class.java).apply {
+            createCriteria().andEqualTo("spToUserId", userId).apply {
+                date?.let {
+                    val time = LocalDate.parse(it)
+                    andEqualTo("spTaskYear", time.year).andEqualTo("spTaskMonth", time.monthValue)
+                }
+            }
+            orderBy("spCreateTime").desc()
+        })
+
+        return BaseResponse(true, data = res)
+    }
+
+    override fun getTaskRecord(taskId: String): BaseResponse<List<LedgerSubTypeVo>> {
+        val task = selfPatrolTaskMapper.selectByPrimaryKey(taskId) ?: return BaseResponse(false, "璇ュ簲鎬ヨ嚜宸℃煡浠诲姟涓嶅瓨鍦�")
+        val sceneTypeId = task.spSceneTypeId
+        val typeId = task.spLedgerTypeId
+        val ledgerSubTypes = ledgerSubTypeMapper.selectByExample(Example(LedgerSubType::class.java).apply {
+            createCriteria().andEqualTo("lTypeid", -1)
+                .apply {
+                    if (sceneTypeId != SceneType.NoType.value) {
+                        andEqualTo("lScenetype", sceneTypeId)
+                    }
+                    andIn("lsSubtypeid", typeId.split(";"))
+                }
+            orderBy("lTypeid")
+        })
+        val records = selfPatrolRecordMapper.selectByExample(Example(SelfPatrolRecord::class.java).apply {
+            createCriteria().andEqualTo("spGuid", taskId)
+        })
+
+        val resultList = mutableListOf<LedgerSubTypeVo>()
+        ledgerSubTypes.forEach {
+            val l = LedgerSubTypeVo(
+                it.lsSubtypeid,
+                it.lsName,
+                it.getlTypeid(),
+                it.getlTypename(),
+                needUpdate = it.getlNeedupdate(),
+                sceneType = it.getlScenetype(),
+                iconUrl = it.getlIconurl(),
+                realTime = it.getlRealTime(),
+                description = it.getlDescription(),
+                notRelated = it.getlNotRelatedSwitch() ?: true,
+                multigroup = it.getlMultiGroup() ?: false
+            )
+            for (r in records) {
+                if (l.ledgerSubTypeId == r?.lsSubtypeid) {
+                    l.ledgerFinished = true
+                    l.upLoad = true
+//                    l.checkStatus = r.lrVerifyrst?.toIntOrNull() ?: LedgerCheckStatus.UnCheck.value
+                    l.onTime = r?.srIssubmitontime ?: false
+                    l.verified
+                    l.verifierName = r?.srVerifierrealname
+                    l.verified = r?.srIsverify
+                    l.verifyRst = r?.srVerifyrst
+                    break
+                }
+            }
+            resultList.add(l)
+        }
+
+        return BaseResponse(true, data = resultList)
+    }
+
+    override fun uploadSelfPatrol(
+        userId: String,
+        taskId: String?,
+        list: String,
+        files: Array<MultipartFile>,
+    ): BaseResponse<Boolean> {
+        val mapper = ObjectMapper()
+        val ledgerVos = mapper.readValue(list, object : TypeReference<List<LedgerVo>>() {})
+        ledgerVos.forEach {
+            it.id = it.id ?: UUIDGenerator.generate16ShortUUID()
+            it.fileType = it.fileType ?: 1
+
+            val userInfo = userinfoMapper.selectByPrimaryKey(userId)
+            userInfo?.extension2?.toInt()?.let { s -> it.sceneType = s }
+
+            val today = Calendar.getInstance().apply { time = Date() }
+                .get(Calendar.DAY_OF_MONTH)
+            val cal = Calendar.getInstance().apply { time = it.updateDate ?: Date() }
+            val updateYear = cal.get(Calendar.YEAR)
+            val updateMonth = cal.get(Calendar.MONTH) + 1
+            val updateDay = cal.get(Calendar.DAY_OF_MONTH)
+
+            //妫�鏌ユ暟鎹簱鏄惁宸叉湁璁板綍锛岄�夋嫨鎻掑叆鎴栨洿鏂�
+            val tmp = selfPatrolRecordMapper.selectByExample(Example(SelfPatrolRecord::class.java).apply {
+                createCriteria().andEqualTo("lsSubtypeid", it.ledgerSubTypeId)
+                    .andEqualTo("srYear", updateYear)
+                    .andEqualTo("srMonth", updateMonth)
+                    .andEqualTo("srSubmitid", userId)
+                    .andEqualTo("spGuid", taskId)
+            })
+            var ledgerMedia: SelfPatrolMediaFile? = null
+            if (tmp.isEmpty()) {
+                checkSelfPatrolFinished(taskId, 1)
+                //鐢熸垚鍙拌处鏇存柊璁板綍
+                val ledgerRecord = SelfPatrolRecord().apply {
+                    srGuid = it.id
+                    spGuid = taskId
+                    lsSubtypeid = it.ledgerSubTypeId
+                    lsSubtypename = it.ledgerName
+                    srYear = updateYear
+                    srMonth = updateMonth.toByte()
+                    srDay = updateDay.toByte()
+                    srEasubmitkind = it.fileType?.toByte() ?: 1
+                    srSubmitid = userId
+                    srSubmitname = userInfo?.acountname ?: ""
+                    srIssubmitontime = today <= 10
+                    srSubmitdate = Date()
+                    srUpdatetype = it.updateType
+                    srExtension1 = it.sceneType.toString()
+                }
+                it.id = ledgerRecord.srGuid
+                selfPatrolRecordMapper.insert(ledgerRecord)
+            } else {
+                val record = tmp[0]
+                it.id = record?.srGuid
+                ledgerMedia = deleteLedgerFile(it.id)
+                record?.srExtension2 = null
+                selfPatrolRecordMapper.updateByPrimaryKey(record)
+            }
+
+            //瀵规瘡寮犲浘鐗囩敓鎴愮浉搴旂殑璺緞骞朵繚瀛�
+            var picPath = ""
+            val time = DateUtil.DateToString(Date(), DateUtil.DateStyle.YYYY_MM)
+            files.forEach { file ->
+                val fileName = file.originalFilename
+                val basePath = imgPath
+                val path = "$time/$userId/${it.ledgerName}/"
+                picPath += if (picPath.isEmpty()) {
+                    "$path$fileName"
+                } else {
+                    ";$path$fileName"
+                }
+                try {
+                    //璋冪敤鏂囦欢淇濆瓨鏂规硶
+                    FileUtil.uploadFile(file.bytes, basePath + path, fileName!!)
+                } catch (e: Exception) {
+                    e.printStackTrace()
+                }
+            }
+
+            //鐢熸垚涓�鏉″濯掍綋鏂囦欢璁板綍
+            if (ledgerMedia == null) {
+                ledgerMedia = SelfPatrolMediaFile().apply {
+                    mfGuid = UUIDGenerator.generate16ShortUUID()
+                    lrGuid = it.id
+                    mfFiletype = it.fileType
+                    mfPath1 = picPath
+                    mfDescription1 = it.remark1
+                    mfSavetime = Date()
+                    mfIsdelete = false
+                }
+                //鎻掑叆鏂扮殑澶氬獟浣撴枃浠惰褰曟暟鎹�
+                selfPatrolMediaFileMapper.insert(ledgerMedia)
+            } else {
+                ledgerMedia.mfPath1 = picPath
+                ledgerMedia.mfDescription1 = it.remark1
+                ledgerMedia.mfSavetime = Date()
+                selfPatrolMediaFileMapper.updateByPrimaryKey(ledgerMedia)
+            }
+
+            return BaseResponse(true)
+        }
+
+        return BaseResponse(false)
+    }
+
+    override fun uploadNoSelfPatrol(
+        userId: String,
+        taskId: String?,
+        time: String,
+        remark: String?,
+        idList: List<Int>,
+    ): BaseResponse<String> {
+        val date = LocalDate.parse(time, DateTimeFormatter.ofPattern("yyyy-MM-dd"))
+        val year = date.year
+        val month = date.monthValue
+        val day = date.dayOfMonth
+        val userInfo = userinfoMapper.selectByPrimaryKey(userId) ?: return BaseResponse(false, "鐢ㄦ埛涓嶅瓨鍦�")
+        idList.forEach {
+            //鍘婚噸鍒ゆ柇
+            val r = selfPatrolRecordMapper.selectByExample(Example(SelfPatrolRecord::class.java).apply {
+                createCriteria().andEqualTo("srSubmitid", userId)
+                    .andEqualTo("lsSubtypeid", it)
+                    .andEqualTo("srYear", year)
+                    .andEqualTo("srMonth", month)
+            })
+            if (r.size > 0) {
+                return@forEach
+            }
+
+            //鑾峰彇鍙拌处绫诲瀷淇℃伅
+            val ledgerType = ledgerSubTypeMapper.selectByPrimaryKey(it) ?: return@forEach
+
+            //鐢熸垚鍙拌处鏇存柊璁板綍
+            val ledgerRecord = SelfPatrolRecord().apply {
+                srGuid = UUIDGenerator.generate16ShortUUID()
+                spGuid = taskId
+                lsSubtypeid = ledgerType.lsSubtypeid
+                lsSubtypename = ledgerType.lsName
+                srYear = year
+                srMonth = month.toByte()
+                srDay = day.toByte()
+                srEasubmitkind = 1
+                srSubmitid = userId
+                srSubmitname = userInfo.acountname ?: ""
+                srIssubmitontime = day <= 10
+                srSubmitdate = Date()
+                srUpdatetype
+                srExtension1 = userInfo.extension2
+                srExtension2 = "notInvolved"
+            }
+            checkSelfPatrolFinished(taskId, 1)
+            selfPatrolRecordMapper.insert(ledgerRecord)
+
+            //鐢熸垚涓�鏉″濯掍綋鏂囦欢璁板綍
+            val ledgerMedia = SelfPatrolMediaFile().apply {
+                mfGuid = UUIDGenerator.generate16ShortUUID()
+                lrGuid = ledgerRecord.srGuid
+                mfFiletype = 1
+                mfPath1 = "ledgerIcons/self_patrol_not_involved.jpg"
+                mfDescription1 = remark
+                mfSavetime = Date()
+                mfIsdelete = false
+            }
+            selfPatrolMediaFileMapper.insert(ledgerMedia)
+        }
+        return BaseResponse(true)
+    }
+
+    override fun getDetail(userId: String, subTypeId: Int, taskId: String): BaseResponse<LedgerVo?> {
+        val records = selfPatrolRecordMapper.selectByExample(Example(SelfPatrolRecord::class.java).apply {
+            createCriteria().andEqualTo("srSubmitid", userId)
+                .andEqualTo("lsSubtypeid", subTypeId)
+                .andEqualTo("spGuid", taskId)
+            orderBy("srSubmitdate").desc()
+        })
+        val result = mutableListOf<LedgerVo>()
+        records.forEach {
+            if (it == null) return@forEach
+
+            val media = selfPatrolMediaFileMapper.selectByExample(
+                Example(SelfPatrolMediaFile::class.java).apply {
+                    createCriteria().andEqualTo("lrGuid", it.srGuid)
+                        .andEqualTo("mfIsdelete", false)
+                        .andEqualTo("mfFiletype", it.srEasubmitkind)
+                    orderBy("mfSavetime").desc()
+                }
+            )
+            val type = ledgerSubTypeMapper.selectByExample(
+                Example(LedgerSubType::class.java).apply {
+                    createCriteria().andEqualTo("lsSubtypeid", it.lsSubtypeid)
+                }
+            )
+            result.add(LedgerVo().apply {
+                id = it.srGuid
+                this.ledgerSubTypeId = it.lsSubtypeid
+                ledgerName = it.lsSubtypename
+                ledgerTypeId = type?.get(0)?.getlTypeid()
+                ledgerType = type?.get(0)?.getlTypename()
+                ledgerFinished = true
+                isUpLoad = true
+                updateDate = it.srSubmitdate
+                updateType = it.srUpdatetype
+                fileType = it.srEasubmitkind.toInt()
+                path1 = media?.get(0)?.mfPath1
+                remark1 = media?.get(0)?.mfDescription1
+                path2 = media?.get(0)?.mfPath2
+                remark2 = media?.get(0)?.mfDescription2
+                this.sceneType = if(it.srExtension1 == null) SceneType.Restaurant.value else it.srExtension1.toInt()
+            })
+        }
+        return if (result.isEmpty()) BaseResponse(false, "璁板綍涓嶅瓨鍦�") else BaseResponse(true, data = result[0])
+    }
+
+    override fun getDetailList(taskId: String): BaseResponse<List<LedgerVo>> {
+        // 鑷贰鏌ヤ换鍔�
+        val task = selfPatrolTaskMapper.selectByPrimaryKey(taskId) ?: return BaseResponse(false, "鑷贰鏌ヤ换鍔′笉瀛樺湪")
+        // 鑷鏌ヤ换鍔″寘鍚殑鍙拌处绫诲瀷
+        val ledgerTypes = ledgerSubTypeMapper.selectByExample(Example(LedgerSubType::class.java).apply {
+            createCriteria().andIn("lsSubtypeid", task.spLedgerTypeId.split(";"))
+        })
+        // 鐢ㄦ埛涓婁紶鐨勮嚜宸℃煡璁板綍
+        val records = selfPatrolRecordMapper.selectByExample(Example(SelfPatrolRecord::class.java).apply {
+            createCriteria().andEqualTo("spGuid", taskId)
+            orderBy("srSubmitdate").desc()
+        })
+        val result = mutableListOf<LedgerVo>()
+        ledgerTypes.forEach {type->
+            val it = records.find { record ->
+                record?.lsSubtypeid == type.lsSubtypeid
+            }
+
+            val media = if (it != null) {
+                selfPatrolMediaFileMapper.selectByExample(
+                    Example(SelfPatrolMediaFile::class.java).apply {
+                        createCriteria().andEqualTo("lrGuid", it?.srGuid)
+                            .andEqualTo("mfIsdelete", false)
+                            .andEqualTo("mfFiletype", it?.srEasubmitkind)
+                        orderBy("mfSavetime").desc()
+                    }
+                )
+            } else null
+
+            result.add(LedgerVo().apply {
+                id = it?.srGuid
+                this.ledgerSubTypeId = type.lsSubtypeid
+                ledgerName = type.lsName
+                ledgerTypeId = type.getlTypeid()
+                ledgerType = type.getlTypename()
+                ledgerFinished = it != null
+                isUpLoad = it != null
+                updateDate = it?.srSubmitdate
+                updateType = it?.srUpdatetype
+                fileType = it?.srEasubmitkind?.toInt()
+                path1 = media?.get(0)?.mfPath1
+                remark1 = media?.get(0)?.mfDescription1
+                path2 = media?.get(0)?.mfPath2
+                remark2 = media?.get(0)?.mfDescription2
+                this.sceneType = task.spSceneTypeId
+            })
+        }
+        return BaseResponse(true, data = result)
+    }
+
+    override fun checkSelfPatrolFinished(taskId: String?, justFinishedNum: Int) {
+        val task = selfPatrolTaskMapper.selectByPrimaryKey(taskId) ?: return
+        val ledgerNum = task.spLedgerTypeId.split(";").size
+        val recordNum = selfPatrolRecordMapper.selectCountByExample(Example(SelfPatrolRecord::class.java).apply {
+            createCriteria().andEqualTo("spGuid", taskId)
+        })
+        if (recordNum + justFinishedNum >= ledgerNum) {
+            task.spTaskStatus = SelfPatrolTaskStatus.Finished.value
+            selfPatrolTaskMapper.updateByPrimaryKey(task)
+        }
+    }
+
+    /**
+     * 鍒犻櫎鍙拌处鐨勬枃浠惰褰�
+     * @param guid 鍙拌处璁板綍id
+     */
+    private fun deleteLedgerFile(guid: String?): SelfPatrolMediaFile? {
+        return selfPatrolMediaFileMapper.selectOne(SelfPatrolMediaFile().apply { lrGuid = guid })?.apply {
+            if (this.mfPath1 != notInvolvedPath) {
+                this.mfPath1.split(";").forEach { p ->
+                    val path = imgPath + p
+                    FileUtil.deleteFile(path)
+                }
+//                this.mfPath1 = notInvolvedPath
+//                ledgerMediaFileMapper.updateByPrimaryKey(this)
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/UserSpecialInfoServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/UserSpecialInfoServiceImpl.kt
new file mode 100644
index 0000000..b0c5c84
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/UserSpecialInfoServiceImpl.kt
@@ -0,0 +1,71 @@
+package cn.flightfeather.supervision.lightshare.service.Impl
+
+import cn.flightfeather.supervision.domain.entity.RestaurantBaseInfo
+import cn.flightfeather.supervision.domain.entity.VehicleBaseInfo
+import cn.flightfeather.supervision.domain.mapper.BaseInfoMapper
+import cn.flightfeather.supervision.domain.mapper.RestaurantBaseInfoMapper
+import cn.flightfeather.supervision.domain.mapper.VehicleBaseInfoMapper
+import cn.flightfeather.supervision.infrastructure.utils.UUIDGenerator
+import cn.flightfeather.supervision.lightshare.service.UserSpecialInfoService
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import org.springframework.stereotype.Service
+
+@Service
+class UserSpecialInfoServiceImpl(
+    private val baseInfoMapper: BaseInfoMapper,
+    private val restaurantBaseInfoMapper: RestaurantBaseInfoMapper,
+    private val vehicleBaseInfoMapper: VehicleBaseInfoMapper
+) : UserSpecialInfoService {
+
+    override fun findOneRestaurant(id: String): BaseResponse<RestaurantBaseInfo> {
+        val res = restaurantBaseInfoMapper.selectByPrimaryKey(id) ?: return BaseResponse(false, "鐢ㄦ埛id涓嶅瓨鍦�")
+        return BaseResponse(true, data = res)
+    }
+
+    override fun saveRestaurant(info: RestaurantBaseInfo): BaseResponse<Int> {
+        if (info.rbGuid == null) return BaseResponse(false, "蹇呴』鎸囧畾涓婚敭涓虹敤鎴穒d")
+        baseInfoMapper.selectByPrimaryKey(info.rbGuid) ?: return BaseResponse(false, "鍒涘缓椁愰ギ淇℃伅涔嬪墠璇峰厛鍒涘缓鐢ㄦ埛鍩烘湰淇℃伅")
+        restaurantBaseInfoMapper.selectByPrimaryKey(info.rbGuid)?.run { return BaseResponse(false, "椁愰ギ淇℃伅宸插瓨鍦紝鏃犳硶閲嶅鏂板缓") }
+        val res = restaurantBaseInfoMapper.insert(info)
+        return if (res == 1) {
+            BaseResponse(true, data = res)
+        } else {
+            BaseResponse(false, "鎻掑叆鏁版嵁搴撳け璐�", data = res)
+        }
+    }
+
+    override fun updateRestaurant(info: RestaurantBaseInfo): BaseResponse<Int> {
+        val res = restaurantBaseInfoMapper.updateByPrimaryKeySelective(info)
+        return if (res == 1) {
+            BaseResponse(true, data = res)
+        } else {
+            BaseResponse(false, "鏇存柊鏁版嵁搴撳け璐�", data = res)
+        }
+    }
+
+    override fun findOneVehicleRepair(id: String): BaseResponse<VehicleBaseInfo> {
+        val res = vehicleBaseInfoMapper.selectByPrimaryKey(id) ?: return BaseResponse(false, "鐢ㄦ埛id涓嶅瓨鍦�")
+        return BaseResponse(true, data = res)
+    }
+
+    override fun saveVehicleRepair(info: VehicleBaseInfo): BaseResponse<Int> {
+        if (info.vbGuid == null) return BaseResponse(false, "蹇呴』鎸囧畾涓婚敭涓虹敤鎴穒d")
+        baseInfoMapper.selectByPrimaryKey(info.vbGuid) ?: return BaseResponse(false, "鍒涘缓姹戒慨淇℃伅涔嬪墠璇峰厛鍒涘缓鐢ㄦ埛鍩烘湰淇℃伅")
+        vehicleBaseInfoMapper.selectByPrimaryKey(info.vbGuid)?.run { return BaseResponse(false, "姹戒慨淇℃伅宸插瓨鍦紝鏃犳硶閲嶅鏂板缓") }
+        val res = vehicleBaseInfoMapper.insert(info)
+        return if (res == 1) {
+            BaseResponse(true, data = res)
+        } else {
+            BaseResponse(false, "鎻掑叆鏁版嵁搴撳け璐�", data = res)
+        }
+    }
+
+    override fun updateVehicleRepair(info: VehicleBaseInfo): BaseResponse<Int> {
+        val res = vehicleBaseInfoMapper.updateByPrimaryKeySelective(info)
+        return if (res == 1) {
+            BaseResponse(true, data = res)
+        } else {
+            BaseResponse(false, "鏇存柊鏁版嵁搴撳け璐�", data = res)
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/UserinfoServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/UserinfoServiceImpl.kt
index c371dc0..5548748 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/UserinfoServiceImpl.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/UserinfoServiceImpl.kt
@@ -1,17 +1,20 @@
 package cn.flightfeather.supervision.lightshare.service.Impl
 
-import cn.flightfeather.supervision.domain.entity.BaseInfo
-import cn.flightfeather.supervision.domain.entity.Company
-import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.domain.entity.*
 import cn.flightfeather.supervision.domain.enumeration.SceneType
+import cn.flightfeather.supervision.domain.enumeration.UserType
 import cn.flightfeather.supervision.domain.mapper.*
+import cn.flightfeather.supervision.domain.repository.UserInfoRep
 import cn.flightfeather.supervision.infrastructure.utils.FileUtil
 import cn.flightfeather.supervision.infrastructure.utils.UUIDGenerator
+import cn.flightfeather.supervision.domain.repository.UserConfigRep
 import cn.flightfeather.supervision.lightshare.service.UserinfoService
 import cn.flightfeather.supervision.lightshare.vo.*
 import com.github.pagehelper.PageHelper
+import org.apache.poi.hssf.usermodel.HSSFWorkbook
 import org.springframework.beans.BeanUtils
 import org.springframework.stereotype.Service
+import org.springframework.transaction.annotation.Transactional
 import org.springframework.web.multipart.MultipartFile
 import tk.mybatis.mapper.entity.Example
 import java.math.BigDecimal
@@ -25,9 +28,12 @@
     val companyMapper: CompanyMapper,
     val restaurantBaseInfoMapper: RestaurantBaseInfoMapper,
     val vehicleBaseInfoMapper: VehicleBaseInfoMapper,
+    val industrialBaseInfoMapper: IndustrialBaseInfoMapper,
     val userMapMapper: UserMapMapper,
     val personalInfoMapper: PersonalInfoMapper,
-    val userInfoWxMapper: UserInfoWxMapper
+    val userInfoWxMapper: UserInfoWxMapper,
+    val userInfoRep: UserInfoRep,
+    val userConfigRep: UserConfigRep,
 ) : UserinfoService {
 
     //鏍规嵁userinfo鏉′欢鏌ヨ
@@ -37,7 +43,7 @@
         criteria.andEqualTo("acountname", userinfo.acountname)
         val result = userinfoMapper.selectByExample(example)
         return if (result.isNotEmpty()) {
-            result[0]
+            result?.get(0) ?: Userinfo()
         } else {
             Userinfo()
         }
@@ -45,17 +51,79 @@
 
     override fun findOne(id: String): Userinfo {
         val userInfo = userinfoMapper.selectByPrimaryKey(id)
+//        userInfo?.password = null
         userMapMapper.selectByPrimaryKey(id)?.let {
             userInfo?.extension3 = it.svUserId
         }
         return userInfo ?: Userinfo()
     }
 
-    override fun findAll(): MutableList<Userinfo> = userinfoMapper.selectAll()
+    override fun findAll(): MutableList<Userinfo?> = userinfoMapper.selectAll()
 
-    override fun save(userinfo: Userinfo): Int = userinfoMapper.insert(userinfo)
+    override fun save(userinfo: Userinfo): BaseResponse<Int> {
+        userinfoMapper.selectByPrimaryKey(userinfo.guid)?.run { return BaseResponse(false, "鐢ㄦ埛宸插瓨鍦�", data = 0) }
+        userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
+            createCriteria().andEqualTo("acountname", userinfo.acountname)
+        }).run { if (isNotEmpty()) return BaseResponse(false, "鐢ㄦ埛鐧诲綍璐︽埛鍚嶇О宸插瓨鍦�", data = 0) }
+        userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
+            createCriteria().andEqualTo("realname", userinfo.realname)
+        }).run { if (isNotEmpty()) return BaseResponse(false, "鐢ㄦ埛鏄电О宸插瓨鍦�", data = 0) }
 
-    override fun update(userinfo: Userinfo): Int = userinfoMapper.updateByPrimaryKeySelective(userinfo)
+        userinfo.apply {
+            guid = UUIDGenerator.generate16ShortUUID()
+            headIconUrl = ""
+            password = "123456"
+            if (isenable == null) isenable = true
+            uiCreateTime = Date()
+        }
+        val res = userinfoMapper.insert(userinfo)
+        return if (res == 1) {
+            BaseResponse(true, data = res)
+        } else {
+            BaseResponse(false, "鎻掑叆鏁版嵁搴撳け璐�", data = res)
+        }
+    }
+
+    @Transactional
+    override fun save2(info: UserBaseInfo): BaseResponse<Int> {
+        info.userInfo ?: return BaseResponse(false, "鐢ㄦ埛淇℃伅缂哄け锛屾棤娉曟柊寤虹敤鎴�")
+        info.baseInfo ?: return BaseResponse(false, "鐢ㄦ埛淇℃伅缂哄け锛屾棤娉曟柊寤虹敤鎴�")
+        val repeatRes = userInfoRep.checkIsRepeat(info.userInfo)
+        if (repeatRes.first) return BaseResponse(false, repeatRes.second)
+
+        info.userInfo.apply {
+            guid = UUIDGenerator.generate16ShortUUID()
+            headIconUrl = ""
+            password = "123456"
+            if (isenable == null) isenable = true
+            uiCreateTime = Date()
+        }
+        info.baseInfo.apply {
+            biGuid = info.userInfo.guid
+            biName = info.userInfo.realname
+            biCreateTime = info.userInfo.uiCreateTime
+            biExtension1 = info.userInfo.acountname
+        }
+        userinfoMapper.insert(info.userInfo)
+        baseInfoMapper.insert(info.baseInfo)
+        return BaseResponse(true)
+    }
+
+    override fun resetPassword(userId: String): BaseResponse<Boolean> {
+        val info = userinfoMapper.selectByPrimaryKey(userId) ?: return BaseResponse(false, "鐢ㄦ埛涓嶅瓨鍦�")
+        info.password = "123456"
+        val r = userinfoMapper.updateByPrimaryKeySelective(info)
+        return BaseResponse(r == 1)
+    }
+
+    override fun update(userinfo: Userinfo): BaseResponse<Int> {
+        val res = userinfoMapper.updateByPrimaryKeySelective(userinfo)
+        return if (res == 1) {
+            BaseResponse(true, data = res)
+        } else {
+            BaseResponse(false, "鎻掑叆鏁版嵁搴撳け璐�", data = res)
+        }
+    }
 
     override fun delete(id: String): Int = userinfoMapper.deleteByPrimaryKey(id)
 
@@ -64,11 +132,15 @@
         val example = Example(Userinfo::class.java)
         val criteria = example.createCriteria()
         criteria.andEqualTo("acountname", loginRequestVo.userName)
-                .andEqualTo("password",loginRequestVo.password)
+            .andEqualTo("password", loginRequestVo.password)
         val result = userinfoMapper.selectByExample(example)
         return AccessToken().apply {
             if (result.isNotEmpty()) {
-                userId = result[0].guid
+                val u = result?.get(0)
+                u?.uiLoginTime = Date()
+                userinfoMapper.updateByPrimaryKeySelective(u)
+                userInfoRep.loginLog(u?.guid)
+                userId = u?.guid
                 val sUser = userMapMapper.selectByPrimaryKey(userId)
                 sUserId = sUser?.svUserId
                 success = true
@@ -159,24 +231,24 @@
             createCriteria().andEqualTo("extension1", userInfo.extension1)
                 .andGreaterThanOrEqualTo("usertypeid", userInfo.usertypeid)
         })
-        .forEach {
-            val groupName = if (it.extension1.isNullOrEmpty()){
-                "鏈垎缁�"
-            } else {
-                "${it.extension1!!}-${it.usertype}-${SceneType.getNameByValue(it.extension2?.toInt() ?: -1)}"
+            .forEach {
+                val groupName = if (it?.extension1.isNullOrEmpty()) {
+                    "鏈垎缁�"
+                } else {
+                    "${it?.extension1!!}-${it.usertype}-${SceneType.getByValue(it.extension2?.toInt() ?: -1).des}"
+                }
+                val friend = if (it?.guid != userId) {
+                    FriendVo(groupName)
+                } else {
+                    FriendVo("鎴�")
+                }
+                BeanUtils.copyProperties(it, friend)
+                if (it?.guid == userId) {
+                    resultList.add(0, friend)
+                } else {
+                    resultList.add(friend)
+                }
             }
-            val friend = if (it.guid != userId) {
-                FriendVo(groupName)
-            } else {
-                FriendVo("鎴�")
-            }
-            BeanUtils.copyProperties(it, friend)
-            if (it.guid == userId) {
-                resultList.add(0, friend)
-            } else {
-                resultList.add(friend)
-            }
-        }
         return resultList
     }
 
@@ -222,16 +294,20 @@
         }
     }
 
-    override fun searchUser(userId: String, condition: UserSearchCondition, page: Int, perPage: Int, response: HttpServletResponse): List<Userinfo> {
+    override fun searchUser(
+        userId: String, condition: UserSearchCondition, page: Int, perPage: Int,
+        response:
+        HttpServletResponse,
+    ): List<Userinfo?> {
         val user = userinfoMapper.selectByPrimaryKey(userId)
-        val districtName = condition.districtName ?: user.extension1
+        val districtName = condition.districtName ?: user?.extension1
 
         val p = PageHelper.startPage<Userinfo>(page, perPage)
         val result = userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
-            if (condition.searchText.isNotBlank()) {
+            if (condition.searchText?.isNotBlank() == true) {
                 and(createCriteria()
-                        .orLike("acountname", "%${condition.searchText}%")
-                        .orLike("realname", "%${condition.searchText}%")
+                    .orLike("acountname", "%${condition.searchText}%")
+                    .orLike("realname", "%${condition.searchText}%")
                 )
             }
             if (condition.sceneTypes.isNotEmpty()) {
@@ -242,35 +318,44 @@
                 })
             }
             and(createCriteria().andEqualTo("extension1", districtName)
-                    .andEqualTo("isenable", true))
+                .andEqualTo("isenable", true).apply {
+                    condition.userTypeId?.let { andEqualTo("usertypeid", it) }
+                })
             //todo 2020.8.19 琛楅晣鐨勬潯浠舵煡璇㈤渶瑕佹墿鍏匓aseInfo鏁版嵁琛ㄥ瓧娈靛悗鍐嶅疄鐜�
         })
 
         response.setIntHeader("totalPage", p.pages)
         response.setIntHeader("currentPage", p.pageNum)
+        response.setIntHeader("totalCount", p.total.toInt())
 
         return result
     }
 
     override fun getBaseInfo(userId: String, wxUserId: String?): UserBaseInfo {
         val userInfo = userinfoMapper.selectByPrimaryKey(userId) ?: return UserBaseInfo(userId)
+        userInfo.password = null
         val baseInfo = baseInfoMapper.selectByPrimaryKey(userId)
         val wxUser = if (wxUserId != null) userInfoWxMapper.selectByPrimaryKey(wxUserId) else null
 
         val mapper = when (userInfo.extension2) {
             SceneType.Restaurant.value.toString() -> restaurantBaseInfoMapper
             SceneType.VehicleRepair.value.toString() -> vehicleBaseInfoMapper
+            SceneType.Industrial.value.toString() -> industrialBaseInfoMapper
             else -> null
         }
 
         val specialInfo = mapper?.selectByPrimaryKey(baseInfo?.biGuid)
-        val companyInfo = companyMapper.selectByPrimaryKey(if (baseInfo?.ciGuid != null) baseInfo.ciGuid else wxUser?.ciGuid)
-        val personalInfo = personalInfoMapper.selectByPrimaryKey(wxUser?.piGuid)
+        val companyInfo =
+            companyMapper.selectByPrimaryKey(if (baseInfo?.ciGuid != null) baseInfo.ciGuid else wxUser?.ciGuid)
+        val personalInfo = personalInfoMapper.selectByExample(Example(PersonalInfo::class.java).apply {
+            createCriteria().andEqualTo("piSceneId", userId).andEqualTo("piWxId", wxUser?.uiOpenId)
+        }).takeIf { it.isNotEmpty() }?.get(0)
 
-        return UserBaseInfo(userId, userInfo.realname, baseInfo, companyInfo, specialInfo, personalInfo)
+        return UserBaseInfo(userId, userInfo.realname, userInfo, baseInfo, companyInfo, specialInfo, personalInfo)
     }
 
-    override fun search(district: String?, sceneType: Int?, userType: Int?, page: Int, perPage: Int): BaseResponse<List<Userinfo>> {
+    override fun search(district: String?, sceneType: Int?, userType: Int?, page: Int, perPage: Int):
+            BaseResponse<List<Userinfo?>> {
         val result = userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
             createCriteria().apply {
                 district?.let { andEqualTo("extension1", it) }
@@ -281,4 +366,29 @@
 
         return BaseResponse(true, data = result)
     }
+
+    override fun getSceneCount(userId: String, condition: UserSearchCondition): BaseResponse<Triple<Int, Int, Int>> {
+//        val user = userinfoMapper.selectByPrimaryKey(userId)
+//        val baseInfo = baseInfoMapper.selectByPrimaryKey(userId)
+//        condition.districtName = condition.districtName ?: user?.extension1
+
+        val config = userConfigRep.getUserConfigBySubType(userId)
+        val c = UserSearchCondition.fromUserConfig(config, condition).apply {
+            userTypeId = UserType.Enterprise.value.toByte()
+//            sceneTypes = condition.sceneTypes
+        }
+
+        val result = userinfoMapper.searchUser(c)
+        val total = result.size
+        val enabled = result.filter { u ->
+            return@filter u.isenable == true
+        }.size
+        val disabled = total - enabled
+
+        return BaseResponse(true, data = Triple(total, enabled, disabled))
+    }
+
+    override fun createUsers(workbook: HSSFWorkbook) {
+        TODO("Not yet implemented")
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/WxUserServiceImpl.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/WxUserServiceImpl.kt
index c6475a9..74e4ddf 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/WxUserServiceImpl.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/WxUserServiceImpl.kt
@@ -8,11 +8,13 @@
 import cn.flightfeather.supervision.domain.entity.UserInfoWx
 import cn.flightfeather.supervision.domain.entity.Userinfo
 import cn.flightfeather.supervision.domain.mapper.*
+import cn.flightfeather.supervision.domain.repository.UserInfoRep
 import cn.flightfeather.supervision.lightshare.service.WxUserService
 import cn.flightfeather.supervision.lightshare.vo.AccessToken
 import cn.flightfeather.supervision.lightshare.vo.AccessTokenPW
 import cn.flightfeather.supervision.lightshare.vo.AccessTokenWX
 import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import cn.flightfeather.supervision.bgtask.sysnotice.SysNoticeManager
 import com.alibaba.fastjson.JSON
 import com.alibaba.fastjson.JSONArray
 import com.alibaba.fastjson.JSONObject
@@ -28,7 +30,9 @@
         val userMapMapper: UserMapMapper,
         val baseInfoMapper: BaseInfoMapper,
         private val msgSubscribeWxMapper: MsgSubscribeWxMapper,
-        private val logMsgSubscribeWxMapper: LogMsgSubscribeWxMapper
+        private val logMsgSubscribeWxMapper: LogMsgSubscribeWxMapper,
+        private val sysNoticeManager: SysNoticeManager,
+        private val userInfoRep: UserInfoRep
 ): WxUserService {
 
     private val LOGGER = LoggerFactory.getLogger(WxUserServiceImpl::class.java)
@@ -73,6 +77,7 @@
                 }
             } else {
                 if (user.uiGuid != null) {
+                    userInfoRep.loginLog(user.uiGuid)
                     val userinfo = userinfoMapper.selectByPrimaryKey(user.uiGuid)
                     BaseResponse(true, "寰俊鐢ㄦ埛鐧诲綍鎴愬姛", data = userinfo)
                 } else {
@@ -96,7 +101,7 @@
             val result = AccessToken()
             //1.1 寰俊id涓虹┖锛岀洿鎺ョ櫥褰�; 寰俊id涓嶄负绌猴紝缁戝畾鑷宠处鍙�
             if (!accessTokenPW.code.isNullOrBlank()) {
-                val baseInfo = baseInfoMapper.selectByPrimaryKey(user[0].guid)
+                val baseInfo = baseInfoMapper.selectByPrimaryKey(user[0]?.guid)
                 WXHttpService.code2Session(accessTokenPW.code!!)?.let {
                     val openid = it.first
                     val unionid = it.second
@@ -104,7 +109,7 @@
                     result.openId = openid
                     return@let if (userWx == null || userWx.uiOpenId == null) {
                         val newUserWx = UserInfoWx().apply {
-                            uiGuid = user[0].guid
+                            uiGuid = user[0]?.guid
                             ciGuid = baseInfo?.ciGuid
                             uiOpenId = openid
                             uiNickName = accessTokenPW.nickName
@@ -116,8 +121,8 @@
                             uiUnionid = unionid
                         }
                         userInfoWxMapper.insert(newUserWx)
-                    } else if (userWx.uiGuid != user[0].guid) {
-                        userWx.uiGuid = user[0].guid
+                    } else if (userWx.uiGuid != user[0]?.guid) {
+                        userWx.uiGuid = user[0]?.guid
                         userWx.ciGuid = baseInfo?.ciGuid
                         userInfoWxMapper.updateByPrimaryKey(userWx)
                     } else {
@@ -125,8 +130,12 @@
                     }
                 }
             }
+            val u = user[0]
+            u?.uiLoginTime = Date()
+            userinfoMapper.updateByPrimaryKeySelective(u)
+            userInfoRep.loginLog(u?.guid)
             return result.apply {
-                userId = user[0].guid
+                userId = user[0]?.guid
                 val sUser = userMapMapper.selectByPrimaryKey(userId)
                 sUserId = sUser?.svUserId
                 success = true
@@ -142,6 +151,9 @@
                     AccessToken()
                 } else {
                     val user = userinfoMapper.selectByPrimaryKey(userWx.uiGuid)
+                    user?.uiLoginTime = Date()
+                    userinfoMapper.updateByPrimaryKeySelective(user)
+                    userInfoRep.loginLog(user?.guid)
                     AccessToken().apply {
                         if (user?.guid == null) {
                             success = false
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/LedgerService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/LedgerService.kt
index 2625971..438257e 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/LedgerService.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/LedgerService.kt
@@ -4,6 +4,7 @@
 import cn.flightfeather.supervision.lightshare.vo.*
 import org.springframework.http.client.MultipartBodyBuilder
 import org.springframework.web.multipart.MultipartFile
+import java.io.File
 import java.util.*
 import javax.servlet.http.HttpServletResponse
 import kotlin.collections.ArrayList
@@ -18,8 +19,21 @@
 
     fun getLedgerDetail2(userId: String, ledgerSubTypeId: Int? = null, sceneType: Int, time: String?): List<LedgerVo>
 
+    /**
+     * 涓婁紶鍙拌处
+     */
+    fun uploadLedger(userId: String, ledgerVo: LedgerVo, files: List<Pair<ByteArray, String>>): Boolean
+
+    /**
+     * 涓婁紶鍙拌处
+     */
     fun uploadLedger(userId: String, ledgerVoList: String, files: Array<MultipartFile>): Boolean
 
+    /**
+     * 涓婁紶涓嶆秹鍙婂彴璐�
+     */
+    fun uploadNoLedger(userId: String, time: String, remark: String?, ledgerIdList: List<Int>): BaseResponse<String>
+
     fun getLedgerImg(userId: String, ledgerType: Int): List<String>
 
     fun getLedgerImgs(userId: String, ledgerType: List<Int>): List<LedgerVo>
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/NotificationService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/NotificationService.kt
index bd6839c..871af70 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/NotificationService.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/NotificationService.kt
@@ -1,17 +1,15 @@
 package cn.flightfeather.supervision.lightshare.service
 
 import cn.flightfeather.supervision.common.wx.MessageWxVo
-import cn.flightfeather.supervision.domain.entity.MeetingInfo
-import cn.flightfeather.supervision.domain.entity.VMRoom
-import cn.flightfeather.supervision.lightshare.vo.LedgerSubTypeVo
-import cn.flightfeather.supervision.lightshare.vo.LedgerVo
-import cn.flightfeather.supervision.lightshare.vo.NoticeReadStateVo
-import cn.flightfeather.supervision.lightshare.vo.NotificationVo
+import cn.flightfeather.supervision.domain.entity.*
+import cn.flightfeather.supervision.lightshare.vo.*
 import java.util.*
 import javax.servlet.http.HttpServletResponse
 import kotlin.collections.ArrayList
 
 interface NotificationService {
+
+    fun getAllNotices(userId: String, noticeConfig: NoticeConfig, page: Int, perPage: Int): BaseResponse<List<Notice>>
 
     fun getNotificationUnRead(userId: String, page: Int, per_page: Int, response: HttpServletResponse): List<NotificationVo>
 
@@ -28,5 +26,9 @@
 
     fun releaseNotice(userId: String, noticeVo: NotificationVo): Boolean
 
+    fun releaseNotice2(userId: String, noticeVo: NotificationVo): Notice
+
     fun pushMsgWx(templateId: Int): String
+
+    fun getTemplate(typeId: Int, subTypeId: Int):BaseResponse<List<NoticeTemplate?>>
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/OperationService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/OperationService.kt
new file mode 100644
index 0000000..de47ed1
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/OperationService.kt
@@ -0,0 +1,25 @@
+package cn.flightfeather.supervision.lightshare.service
+
+import cn.flightfeather.supervision.domain.entity.PracticalOperation
+import cn.flightfeather.supervision.domain.entity.PracticalOperationRecord
+import cn.flightfeather.supervision.domain.entity.ScheduleSignRecord
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import cn.flightfeather.supervision.lightshare.vo.PracticalOperationVo
+import cn.flightfeather.supervision.lightshare.vo.ScheduleOption
+import cn.flightfeather.supervision.lightshare.vo.ScheduleVo
+
+interface OperationService {
+
+    /**
+     * 鑾峰彇鐢ㄦ埛鐨勫疄鎿嶄簨鍔�
+     */
+    fun getOperations(userId: String): List<PracticalOperation?>
+
+    /**
+     * 鐢ㄦ埛瀹屾垚鏌愰」浜嬪姟
+     */
+    fun executeOperation(userId: String, operationId: Int, stateId: String): PracticalOperationRecord?
+
+    fun getOperationRecord(userId: String): List<PracticalOperationVo?>
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ProblemService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ProblemService.kt
index b70f5c2..6da13cd 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ProblemService.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ProblemService.kt
@@ -5,4 +5,8 @@
 interface ProblemService {
 
     fun getProblemsByPeriod(userId: String, year: Int, month: Int): List<Problem>
+
+    fun saveProblem(info: Problem): Int
+
+    fun updateProblem(info: Problem): Int
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/RiskService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/RiskService.kt
new file mode 100644
index 0000000..38973b6
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/RiskService.kt
@@ -0,0 +1,20 @@
+package cn.flightfeather.supervision.lightshare.service
+
+import cn.flightfeather.supervision.domain.entity.RiskEvaluation
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import cn.flightfeather.supervision.lightshare.vo.CountVo
+import cn.flightfeather.supervision.lightshare.vo.CreditInfoVo
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+import javax.servlet.http.HttpServletResponse
+
+interface RiskService {
+
+    fun getRiskCount(userId: String, condition: UserSearchCondition): BaseResponse<CountVo>
+
+    fun searchRiskList(userId: String, condition: UserSearchCondition, page: Int, perPage: Int):
+            BaseResponse<List<CreditInfoVo>>
+
+    fun getRiskInfo(userId: String, period: String?): BaseResponse<RiskEvaluation>
+
+    fun downloadRiskInfo(district: String, sceneType: String, year: Int, month: Int, response: HttpServletResponse)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ScheduleService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ScheduleService.kt
new file mode 100644
index 0000000..40718e2
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ScheduleService.kt
@@ -0,0 +1,15 @@
+package cn.flightfeather.supervision.lightshare.service
+
+import cn.flightfeather.supervision.domain.entity.ScheduleSignRecord
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import cn.flightfeather.supervision.lightshare.vo.ScheduleOption
+import cn.flightfeather.supervision.lightshare.vo.ScheduleVo
+
+interface ScheduleService {
+
+    fun getSchedules(option: ScheduleOption): BaseResponse<List<ScheduleVo>>
+
+    fun completeSchedule(userId: String, id: Int): BaseResponse<ScheduleSignRecord>
+
+    fun revokeSchedule(userId: String, recordId: Int): BaseResponse<Boolean>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/SelfPatrolService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/SelfPatrolService.kt
new file mode 100644
index 0000000..fab8e14
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/SelfPatrolService.kt
@@ -0,0 +1,59 @@
+package cn.flightfeather.supervision.lightshare.service
+
+import cn.flightfeather.supervision.domain.entity.SelfPatrolTask
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import cn.flightfeather.supervision.lightshare.vo.LedgerSubTypeVo
+import cn.flightfeather.supervision.lightshare.vo.LedgerVo
+import cn.flightfeather.supervision.lightshare.vo.SelfPatrolTaskVo
+import org.springframework.web.multipart.MultipartFile
+
+interface SelfPatrolService {
+
+    fun getPatrolType(sceneType: Int): BaseResponse<List<LedgerSubTypeVo>>
+
+    /**
+     * 鍙戝竷搴旀�ヨ嚜宸℃煡浠诲姟
+     */
+    fun publishTask(tasks: List<SelfPatrolTask>): BaseResponse<Boolean>
+
+    /**
+     * 鑾峰彇璇ョ敤鎴峰彂甯冪殑鑷鏌ヤ换鍔�
+     */
+    fun getPublishedTask(userId: String, date: String?): BaseResponse<List<SelfPatrolTaskVo>>
+
+    /**
+     * 鑾峰彇鍙戝竷缁欒鐢ㄦ埛鐨勮嚜宸℃煡浠诲姟
+     */
+    fun getToTask(userId: String, date: String?): BaseResponse<List<SelfPatrolTask?>>
+
+    /**
+     * 鑾峰彇鑷贰鏌ヤ换鍔$殑涓婁紶璁板綍
+     */
+    fun getTaskRecord(taskId: String): BaseResponse<List<LedgerSubTypeVo>>
+
+    /**
+     * 涓婁紶鑷贰鏌ュ浘鐗囩瓑鐩稿叧鍐呭
+     */
+    fun uploadSelfPatrol(
+        userId: String,
+        taskId: String?,
+        list: String,
+        files: Array<MultipartFile>,
+    ): BaseResponse<Boolean>
+
+    /**
+     * 涓婁紶鑷贰鏌ヤ笉娑夊強
+     */
+    fun uploadNoSelfPatrol(userId: String, taskId: String?, time: String, remark: String?, idList: List<Int>): BaseResponse<String>
+
+    fun getDetail(userId: String, subTypeId: Int, taskId: String): BaseResponse<LedgerVo?>
+
+    fun getDetailList(taskId: String): BaseResponse<List<LedgerVo>>
+
+    /**
+     * 鍒ゆ柇搴旀�ヨ嚜宸℃煡浠诲姟鏄惁瀹屾垚骞舵洿鏂扮姸鎬�
+     * @param taskId 浠诲姟id
+     * @param justFinishedNum 鍐呭瓨涓垰瀹屾垚鐨勪换鍔℃暟锛堣�冭檻鍒氭墽琛屼换鍔¤褰曠殑鎻掑叆璇彞杩樻湭鐪熸鍏ュ簱鐨勬儏鍐碉級
+     */
+    fun checkSelfPatrolFinished(taskId: String?, justFinishedNum: Int)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/UserSpecialInfoService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/UserSpecialInfoService.kt
new file mode 100644
index 0000000..0d079df
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/UserSpecialInfoService.kt
@@ -0,0 +1,22 @@
+package cn.flightfeather.supervision.lightshare.service
+
+import cn.flightfeather.supervision.domain.entity.RestaurantBaseInfo
+import cn.flightfeather.supervision.domain.entity.VehicleBaseInfo
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+
+interface UserSpecialInfoService {
+
+    // 椁愰ギ
+    fun findOneRestaurant(id: String): BaseResponse<RestaurantBaseInfo>
+
+    fun saveRestaurant(info: RestaurantBaseInfo): BaseResponse<Int>
+
+    fun updateRestaurant(info: RestaurantBaseInfo): BaseResponse<Int>
+
+    // 姹戒慨
+    fun findOneVehicleRepair(id: String): BaseResponse<VehicleBaseInfo>
+
+    fun saveVehicleRepair(info: VehicleBaseInfo): BaseResponse<Int>
+
+    fun updateVehicleRepair(info: VehicleBaseInfo): BaseResponse<Int>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/UserinfoService.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/UserinfoService.kt
index 7e23222..9405863 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/UserinfoService.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/service/UserinfoService.kt
@@ -2,24 +2,28 @@
 
 import cn.flightfeather.supervision.domain.entity.Userinfo
 import cn.flightfeather.supervision.lightshare.vo.*
+import org.apache.poi.hssf.usermodel.HSSFWorkbook
 import org.springframework.web.multipart.MultipartFile
 import javax.servlet.http.HttpServletResponse
 
 interface UserinfoService {
     fun findOne(id: String): Userinfo
 
-    fun findAll(): MutableList<Userinfo>
+    fun findAll(): MutableList<Userinfo?>
 
-    fun save(userinfo: Userinfo): Int
+    fun save(userinfo: Userinfo): BaseResponse<Int>
 
-    fun update(userinfo: Userinfo): Int
+    fun save2(info: UserBaseInfo): BaseResponse<Int>
+
+    fun resetPassword(userId: String):BaseResponse<Boolean>
+
+    fun update(userinfo: Userinfo): BaseResponse<Int>
 
     fun delete(id: String): Int
 
     fun findOneByName(userinfo: Userinfo): Userinfo
 
     fun login(loginRequestVo: LoginRequestVo): AccessToken
-
 
     fun register(loginRequestVo: LoginRequestVo): AccessToken
 
@@ -31,10 +35,19 @@
 
     fun changePassword(userId: String, oldPassword: String, newPassword: String): BaseResponse<String>
 
-    fun searchUser(userId: String,condition: UserSearchCondition, page: Int, perPage: Int, response: HttpServletResponse): List<Userinfo>
+    fun searchUser(
+        userId: String, condition: UserSearchCondition, page: Int, perPage: Int,
+        response:
+        HttpServletResponse,
+    ): List<Userinfo?>
 
     fun getBaseInfo(userId: String, wxUserId: String?): UserBaseInfo
 
-    fun search(district: String?, sceneType: Int?, userType: Int?, page: Int, perPage: Int): BaseResponse<List<Userinfo>>
+    fun search(district: String?, sceneType: Int?, userType: Int?, page: Int, perPage: Int):
+            BaseResponse<List<Userinfo?>>
+
+    fun getSceneCount(userId: String, condition: UserSearchCondition): BaseResponse<Triple<Int, Int, Int>>
+
+    fun createUsers(workbook: HSSFWorkbook)
 
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AuthSceneIndVo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AuthSceneIndVo.kt
new file mode 100644
index 0000000..79a9951
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AuthSceneIndVo.kt
@@ -0,0 +1,65 @@
+package cn.flightfeather.supervision.lightshare.vo
+
+import cn.flightfeather.supervision.domain.entity.IndustrialBaseInfo
+import cn.flightfeather.supervision.domain.entity.RestaurantBaseInfo
+import org.springframework.beans.BeanUtils
+import java.util.*
+import kotlin.math.round
+
+class AuthSceneIndVo : AuthSceneVo() {
+
+    val ibProductionTechnique: String? = null
+
+    /**
+     * 搴熸皵澶勭悊宸ヨ壓鍚嶇О
+     */
+    var ibWasteGasTechnique: String? = null
+
+    /**
+     * 搴熸皵澶勭悊鏈夋棤鐩戞帶鎺柦
+     */
+    var ibWasteGasMeasure: String? = null
+
+    /**
+     * 鏄惁閲囩敤鏇存崲寮忓惛闄勫鐞嗗伐鑹�
+     */
+    var ibHasAbsorbTechnique: Boolean? = false
+
+    /**
+     * 鍚搁檮鍓傚~鍏呴噺鏄惁绗﹀悎璁捐鏂囦欢
+     */
+    var ibAdsorbentCorrect: Boolean? = false
+
+    /**
+     * 鍚搁檮鍓傛洿鎹㈠懆鏈熸槸鍚︾鍚堣璁℃枃浠�
+     */
+    var ibPeriodCorrect: Boolean? = false
+
+    /**
+     * 鏄惁鏈夎喘涔板惛闄勫墏鍜屽簾鍚搁檮鍓傚鐞嗙殑鐩稿叧鍚堝悓銆佺エ鎹�
+     */
+    var ibHasContract: Boolean? = false
+
+    /**
+     * 鐩稿叧鍚堝悓銆佺エ鎹槸鍚︿繚瀛�3骞�
+     */
+    var ibKeepContract: Boolean? = false
+
+    /**
+     * 鐢熸垚鏂扮殑宸ヤ笟淇℃伅瀵硅薄
+     */
+    fun toNewIndInfo(userId: String) = IndustrialBaseInfo().apply {
+        this.ibGuid = userId
+        this.ibCreateTime = Date()
+        updateIndInfo(this)
+    }
+
+    /**
+     * 鏇存柊鑷抽楗俊鎭�
+     */
+    fun updateIndInfo(restInfo: IndustrialBaseInfo) {
+        restInfo.apply {
+            BeanUtils.copyProperties(this@AuthSceneIndVo, this)
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AuthSceneRestVo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AuthSceneRestVo.kt
index 2687db7..d365008 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AuthSceneRestVo.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AuthSceneRestVo.kt
@@ -7,6 +7,7 @@
 import cn.flightfeather.supervision.infrastructure.utils.UUIDGenerator
 import org.springframework.beans.BeanUtils
 import java.util.*
+import kotlin.math.round
 
 /**
  * 椁愰ギ搴楄璇佷俊鎭�
@@ -58,7 +59,8 @@
 //            rbOutfallLocation = rbOutfallLocation
 //            rbOutfallNum = rbOutfallNum
             BeanUtils.copyProperties(this@AuthSceneRestVo, this)
-            rbCookingOilCapacity = this@AuthSceneRestVo.rbCookingOilCapacity?.div(12).toString()
+            val o = this@AuthSceneRestVo.rbCookingOilCapacity?.toDouble()?.div(12)
+            rbCookingOilCapacity = round(o?.times(100) ?: .0).div(100).toString()
         }
     }
 
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AuthSceneVo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AuthSceneVo.kt
index f42a973..4bf75b3 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AuthSceneVo.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AuthSceneVo.kt
@@ -27,12 +27,12 @@
     /**
      * 鐢熸垚鏂扮殑鍦烘櫙鍩虹淇℃伅瀵硅薄
      */
-    fun toNewBaseInfo(newUser: Userinfo, cInfo:Company?) = BaseInfo().apply {
-        biGuid = newUser.guid
+    fun toNewBaseInfo(newUser: Userinfo?, cInfo:Company?) = BaseInfo().apply {
+        biGuid = newUser?.guid
         ciGuid = cInfo?.ciGuid
         ciName = cInfo?.ciName
         biCreateTime = Date()
-        biExtension1 = newUser.acountname
+        biExtension1 = newUser?.acountname
         updateBaseInfo(this)
     }
 
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/BaseInfoVo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/BaseInfoVo.kt
new file mode 100644
index 0000000..2b8aecb
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/BaseInfoVo.kt
@@ -0,0 +1,9 @@
+package cn.flightfeather.supervision.lightshare.vo
+
+import cn.flightfeather.supervision.domain.entity.BaseInfo
+import cn.flightfeather.supervision.domain.entity.Userinfo
+
+class BaseInfoVo : BaseInfo() {
+    var userInfo: Userinfo? = null
+    var sceneTypeName: String? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/BaseResponse.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/BaseResponse.kt
index b2e496a..1901eef 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/BaseResponse.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/BaseResponse.kt
@@ -10,28 +10,28 @@
  */
 @ApiModel("璇锋眰杩斿洖鍩烘湰缁撴瀯")
 data class BaseResponse<T>(
-        @ApiModelProperty("璇锋眰鏄惁鎴愬姛")
-        var success: Boolean,
-        @ApiModelProperty("璇锋眰杩斿洖娑堟伅")
-        var message: String = "璇锋眰鎴愬姛",
-        @ApiModelProperty("璇锋眰杩斿洖澶翠俊鎭�")
-        val head: DataHead? = null,
-        @ApiModelProperty("璇锋眰杩斿洖鏁版嵁")
-        var data: T? = null
+    @ApiModelProperty("璇锋眰鏄惁鎴愬姛")
+    var success: Boolean,
+    @ApiModelProperty("璇锋眰杩斿洖娑堟伅")
+    var message: String = "璇锋眰鎴愬姛",
+    @ApiModelProperty("璇锋眰杩斿洖澶翠俊鎭�")
+    val head: DataHead? = null,
+    @ApiModelProperty("璇锋眰杩斿洖鏁版嵁")
+    var data: T? = null,
 ) {
-        init {
-                if (message.isBlank()) {
-                        message = if (success) {
-                                "璇锋眰鎴愬姛"
-                        } else {
-                                "璇锋眰澶辫触"
-                        }
-                }
+    init {
+        if (message.isBlank()) {
+            message = if (success) {
+                "璇锋眰鎴愬姛"
+            } else {
+                "璇锋眰澶辫触"
+            }
         }
+    }
 }
 
 data class DataHead(
-        var page: Int = 1,
-        var totalPage: Int = 1,
-        var totalCount: Int = 0
+    var page: Int = 1,
+    var totalPage: Int = 1,
+    var totalCount: Long = 0,
 )
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/CountVo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/CountVo.kt
new file mode 100644
index 0000000..9aaa64c
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/CountVo.kt
@@ -0,0 +1,12 @@
+package cn.flightfeather.supervision.lightshare.vo
+
+/**
+ * 鏁伴噺缁熻
+ */
+class CountVo {
+    // 缁熻鏁版嵁鏍囪瘑锛堝悕绉般�佹椂闂寸瓑绛夛級
+    var tag: String? = null
+
+    // 缁熻缁撴灉
+    var countList = mutableListOf<Int>()
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/CreditInfoVo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/CreditInfoVo.kt
index 98c44ca..09dbb62 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/CreditInfoVo.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/CreditInfoVo.kt
@@ -1,6 +1,7 @@
 package cn.flightfeather.supervision.lightshare.vo
 
 import cn.flightfeather.supervision.domain.enumeration.SceneType
+import org.apache.xpath.operations.Bool
 
 /**
  * @author riku
@@ -43,5 +44,11 @@
 
         /**************姹戒慨鐩稿叧灞炴��******************/
         //瀹℃壒鏂囧彿
-        var approvalNum: String? = null
+        var approvalNum: String? = null,
+        /**************姹戒慨鐩稿叧灞炴��******************/
+
+        //杩愯惀鐘舵��
+        var status: Boolean = true,
+        //椋庨櫓绛夌骇
+        var riskLevel: String? = null,
 )
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/DataCatageryCountVo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/DataCatageryCountVo.kt
new file mode 100644
index 0000000..210222c
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/DataCatageryCountVo.kt
@@ -0,0 +1,16 @@
+package cn.flightfeather.supervision.lightshare.vo
+
+/**
+ * 鏁版嵁鍒嗙被鏁伴噺缁熻
+ * @date 2024/6/3
+ * @author feiyu02
+ */
+class DataCategoryCountVo {
+    // 鍚嶇О
+    var name: String? = null
+    // 绫诲埆鍚嶇О
+    var category: String? = null
+    // 鏁伴噺
+    var count: Int? = null
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/DataVo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/DataVo.kt
index b41962b..8cb053f 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/DataVo.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/DataVo.kt
@@ -16,5 +16,9 @@
         @ApiModelProperty(value = "鏁版嵁鍊�", notes = "鍗曚綅锛歮g/m鲁")
         var value: Double = 0.0,
         @ApiModelProperty(value = "绔欑偣缂栧彿")
-        var mnCode: String? = null
+        var mnCode: String? = null,
+        @ApiModelProperty(value = "绔欑偣鍚嶇О")
+        var siteName: String? = null,
+        @ApiModelProperty(value = "绔欑偣渚涘簲鍟�")
+        var supplier: String? = null,
 )
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/GradeDetailVo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/GradeDetailVo.kt
index ce2f18c..538c812 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/GradeDetailVo.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/GradeDetailVo.kt
@@ -25,4 +25,7 @@
 
     //澶卞垎椤圭洰
     var loseScore: MutableMap<String?, MutableMap<String?, MutableList<Triple<String, String, String>>>> = mutableMapOf()
+
+    //寰楀垎椤圭洰
+    var scoring: MutableMap<String?, MutableMap<String?, MutableList<Triple<String, String, String>>>> = mutableMapOf()
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnConstructionInfo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnConstructionInfo.kt
new file mode 100644
index 0000000..1f06eeb
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnConstructionInfo.kt
@@ -0,0 +1,98 @@
+package cn.flightfeather.supervision.lightshare.vo
+
+/**
+ * 闈欏畨
+ * 宸ュ湴鐐逛綅鍩虹淇℃伅
+ */
+class JinAnConstructionInfo {
+    //瀹夎鍦板潃
+    var address : String? = null
+    //寮�宸ユ椂闂�
+    var beginDate : String? = null
+    //寤虹瓚闈㈢Н
+    var buildArea : String? = null
+    //娓呮礂鎺柦
+    var cleanMeasure : String? = null
+    //绔欑偣缂栫爜
+    var code : String? = null
+    //鏂藉伐鍗曚綅
+    var constructionUnit : String? = null
+    //鐐逛綅鎺у埗绾�
+    var controlLevel : String? = null
+    //閲囬泦鏃堕棿
+    var dataTime : String? = null
+    //寮�鍙戝晢
+    var developers : String? = null
+    //鎵ц鏃堕棿
+    var doTime : String? = null
+    //杩愮淮鍟�
+    var dutyCompany : String? = null
+    //杩愮淮鍟唅d
+    var dutyCompanyId : String? = null
+    //缁撴潫鏃堕棿
+    var endDate : String? = null
+    //褰撳墠鏂藉伐闃舵
+    var engineeringStage : String? = null
+    //褰撳墠鏂藉伐闃舵缂栫爜
+    var engineeringStageCode : String? = null
+    //璁惧缂栫爜
+    var equipmentCode : String? = null
+    //鍗犲湴闈㈢Н
+    var floorArea : String? = null
+    //鎵�灞炲尯鍘夸唬鐮�
+    var groupId : String? = null
+    //鎵�灞炲尯鍘�
+    var groupName : String? = null
+    //鏄惁鏈夌洃娴�
+    var hasMonitor : String? = null
+    //宸ョ▼缂栧彿
+    var id : String? = null
+    //鏄惁鍦ㄧ嚎
+    var isOnline : String? = null
+    //璁惧鏄惁寮傚父
+    var isTrouble : String? = null
+    //鍒犻櫎鏍囧織浣�
+    var jhptDelete : String? = null
+    //鏇存柊鏃堕棿
+    var jhptUpdateTime : String? = null
+    //kindex
+    var kindex : String? = null
+    //绾害
+    var latitude : String? = null
+    //鑱旂郴浜�
+    var linkman : String? = null
+    //缁忓害
+    var longitude : String? = null
+    //璁惧缂栫爜
+    var mnCode : String? = null
+    //绔欑偣鍚嶇О
+    var name : String? = null
+    //鍣0鍔熻兘鍖�
+    var noiseRegion : String? = null
+    //鑱旂郴浜虹數璇�
+    var phone : String? = null
+    //鎵�灞炵渷浠�
+    var province : String? = null
+    //璐熻矗浜�
+    var responsible : String? = null
+    //鍐呬腑澶栫幆缂栫爜
+    var ringId : String? = null
+    //鍐呬腑澶栫幆
+    var ringName : String? = null
+    //闃舵寮�濮嬫棩鏈�
+    var stageBeginDate : String? = null
+    //鍋滄鏃堕棿
+    var stopTime : String? = null
+    //tsp娴撳害
+    var tsp : String? = null
+    //绫诲瀷缂栫爜
+    var typeId : String? = null
+    //绫诲瀷鍚嶇О
+    var typename : String? = null
+    //缁熻绫诲瀷缂栫爜
+    var unionTypeId : String? = null
+    //鍥村楂樺害
+    var wallHeight : String? = null
+    //涓氬姟鏃堕棿
+    var ywsjDate : String? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnHourDustData.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnHourDustData.kt
new file mode 100644
index 0000000..816c046
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnHourDustData.kt
@@ -0,0 +1,43 @@
+package cn.flightfeather.supervision.lightshare.vo
+
+import com.google.gson.annotations.SerializedName
+import java.util.*
+
+/**
+ * 闈欏畨
+ * 鎵皹灏忔椂鐩戞祴鏁版嵁
+ */
+class JinAnHourDustData {
+    //鎵皹鍊�
+    var dustvalue : Double? = null
+    //FLAG
+    var flag : String? = null
+    //绛夌骇
+    var grade : String? = null
+    //鎵�灞炲尯鍘�
+    var groupname : String? = null
+    //涓婚敭
+    var id : String? = null
+    //鍏ュ簱鏃堕棿
+//    @SerializedName("inserttime")
+    var createTime : Date? = null
+    //寮�濮嬫椂闂�
+//    @SerializedName("lst")
+    var stTime : Date? = null
+    //缁撴潫鏃堕棿
+//    @SerializedName("lst_END")
+    var etTime : Date? = null
+    //鐩戞祴璁惧缂栫爜
+    var mncode : String? = null
+    //宸ョ▼鍚嶇О
+    var name : String? = null
+    //鍣0鍊�
+    var noisevalue : Double? = null
+    //宸ョ▼ID
+    var projectid : String? = null
+    //宸ョ▼绫诲埆ID
+    var projecttypeid : String? = null
+    //璐ㄩ噺
+    var quality : String? = null
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnLampDeviceData.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnLampDeviceData.kt
new file mode 100644
index 0000000..f34cf43
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnLampDeviceData.kt
@@ -0,0 +1,33 @@
+package cn.flightfeather.supervision.lightshare.vo
+
+import java.math.BigDecimal
+
+/**
+ * 闈欏畨
+ * 椁愰ギ娌圭儫鐩戞祴鏁版嵁
+ */
+class JinAnLampDeviceData {
+    //閫氶亾鍙�
+    var channelNum : String? = null
+    //娓呮磥搴�
+    var cleanLiness : String? = null
+    //璁惧缂栧彿
+    var deviceCode : String? = null
+    //璁惧鍚嶇О
+    var deviceName : String? = null
+    //璁惧鐘舵��
+    var deviceState : String? = null
+    //浼佷笟缂栧彿
+    var enterId : String? = null
+    //椋庢墖鐘舵��
+    var fanState : String? = null
+    //娌圭儫娴撳害
+    var lampblackValue : BigDecimal? = null
+    //鐩戞祴鏃堕棿
+    var monitorTime : String? = null
+    //鐢熶骇鏃堕棿
+    var productionDate : String? = null
+    //鍑�鍖栧櫒鐘舵��
+    var purifierState : String? = null
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnLampEnterBaseInfo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnLampEnterBaseInfo.kt
new file mode 100644
index 0000000..e1b8d15
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/JinAnLampEnterBaseInfo.kt
@@ -0,0 +1,42 @@
+package cn.flightfeather.supervision.lightshare.vo
+
+import java.math.BigDecimal
+
+/**
+ * 闈欏畨
+ * 椁愰ギ娌圭儫浼佷笟淇℃伅
+ */
+class JinAnLampEnterBaseInfo {
+    //浼佷笟鍦板潃
+    var address : String? = null
+    //钀ヤ笟鏃堕棿
+    var businessDate : String? = null
+    //鏁版嵁婧�
+    var datasource : String? = null
+    //浼佷笟缂栫爜
+    var enterId : String? = null
+    //浼佷笟鍚嶇О
+    var enterName : String? = null
+    //闆嗚仛鍖虹紪鐮�
+    var jjqCode : String? = null
+    //闆嗚仛鍖哄悕绉�
+    var jjqName : String? = null
+    //绾害
+    var latitude : BigDecimal? = null
+    //鑱旂郴浜�
+    var linkMan : String? = null
+    //鑱旂郴鐢佃瘽
+    var linkPhone : String? = null
+    //缁忓害
+    var longitude : BigDecimal? = null
+    //琛屾斂鍖哄悕绉�
+    var regionName : String? = null
+    //娉ㄥ唽鏃堕棿
+    var registDate : String? = null
+    //鐘舵��
+    var state : String? = null
+    //鎵�灞炶閬�
+    var street : String? = null
+
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/LedgerSubTypeVo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/LedgerSubTypeVo.kt
index a34da29..24a1620 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/LedgerSubTypeVo.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/LedgerSubTypeVo.kt
@@ -26,12 +26,20 @@
         var needUpdate: Boolean = true,
         //鍙拌处瀹℃牳鐘舵�侊紙0锛氭湭瀹℃牳锛�1锛氶�氳繃锛�2锛氭湭閫氳繃锛�
 //        var checkStatus: Int = LedgerCheckStatus.UnCheck.value,
+        //涓婁紶鏄惁鍑嗘椂
+        var onTime: Boolean = false,
 
         var sceneType: Int = SceneType.Restaurant.value,
         //鍙拌处鍥炬爣
         var iconUrl: String? = null,
-        //鍙拌处鏄惁鏈夊疄鏃舵�ц姹�
+        //鍙拌处鏄惁鏈夊疄鏃舵�ц姹傦紝娌℃湁瀹炴椂鎬ц姹傜殑鍙拌处鎵嶅彲浠ュ鍒�
         var realTime: Boolean = false,
+        //鍙拌处璇存槑
+        var description: String? = null,
+        //鍙拌处鏄惁寮�鍚笉娑夊強閫夐」锛堥粯璁ゅ紑鍚級
+        var notRelated: Boolean = true,
+        //鍙拌处鏄惁寮�鍚缁勪笂浼犻�夐」锛堥粯璁や笉寮�鍚級
+        var multigroup: Boolean = false,
         //瀹℃牳浜篿d
         var verifierId: String? = null,
         //瀹℃牳浜哄悕绉�
@@ -39,5 +47,7 @@
         //瀹℃牳缁撴灉銆俷ull锛氭湭瀹℃牳锛沠alse锛氬鏍镐笉閫氳繃锛泃rue锛氬鏍搁�氳繃
         var verified: Boolean? = null,
         //瀹℃牳澶囨敞
-        var verifyRst: String? = null
+        var verifyRst: String? = null,
+        //鏄惁娑夊強锛堟嫢鏈夛級璇ョ被鍙拌处
+        var involved: Boolean = true,
 )
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/LedgerVo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/LedgerVo.kt
index 62620ae..f91b6d7 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/LedgerVo.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/LedgerVo.kt
@@ -1,7 +1,13 @@
 package cn.flightfeather.supervision.lightshare.vo
 
+import cn.flightfeather.supervision.domain.entity.LedgerRecord
+import cn.flightfeather.supervision.domain.entity.LedgerSubType
+import cn.flightfeather.supervision.domain.entity.Userinfo
 import cn.flightfeather.supervision.domain.enumeration.SceneType
+import cn.flightfeather.supervision.infrastructure.utils.UUIDGenerator
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties
+import java.time.LocalDateTime
+import java.time.ZoneId
 import java.util.*
 
 /**
@@ -11,34 +17,62 @@
  */
 @JsonIgnoreProperties(ignoreUnknown = true)
 data class LedgerVo constructor(
-        //鍙拌处璁板綍id
-        var id: String? = null,
-        //鍙拌处瀛愮被鍨婭D
-        var ledgerSubTypeId: Int? = null,
-        //鍙拌处鍚嶇О
-        var ledgerName: String? = null,
-        //鍙拌处绫诲瀷ID
-        var ledgerTypeId: Int? = null,
-        //鍙拌处绫诲瀷
-        var ledgerType: String? = null,
-        //鍙拌处鏄惁鏈湴濉啓瀹屾垚
-        var ledgerFinished: Boolean = false,
-        //鍙拌处鏄惁涓婁紶
-        var isUpLoad: Boolean = false,
-        //鍙拌处鏇存柊鏃ユ湡
-        var updateDate: Date? = null,
-        //鍙拌处鏇存柊绫诲瀷锛�0閮ㄥ垎鏇存柊锛堥儴鍒嗙己澶便�侀仐澶憋級銆�1宸叉洿鏂般��2鏃犳洿鏂扮瓑锛�
-        var updateType: Byte? = null,
-        //鍙拌处澶氬獟浣撴枃浠剁被鍨�
-        var fileType: Int? = null,
-        //鍙拌处鍩虹澶氬獟浣撴枃浠惰矾寰�
-        var path1: String? = null,
-        //鍙拌处鍩虹澶氬獟浣撴枃浠跺娉�
-        var remark1: String? = null,
-        //鍙拌处琛ュ厖澶氬獟浣撴枃浠惰矾寰�
-        var path2: String? = null,
-        //鍙拌处琛ュ厖澶氬獟浣撴枃浠跺娉�
-        var remark2: String? = null,
-        //鍙拌处鎵�灞炵殑鍦烘櫙绫诲瀷
-        var sceneType: Int = SceneType.NoType.value
-)
\ No newline at end of file
+    //鍙拌处璁板綍id
+    var id: String? = null,
+    //鍙拌处瀛愮被鍨婭D
+    var ledgerSubTypeId: Int? = null,
+    //鍙拌处鍚嶇О
+    var ledgerName: String? = null,
+    //鍙拌处绫诲瀷ID
+    var ledgerTypeId: Int? = null,
+    //鍙拌处绫诲瀷
+    var ledgerType: String? = null,
+    //鍙拌处鏄惁鏈湴濉啓瀹屾垚
+    var ledgerFinished: Boolean = false,
+    //鍙拌处鏄惁涓婁紶
+    var isUpLoad: Boolean = false,
+    //鍙拌处鏇存柊鏃ユ湡
+    var updateDate: Date? = null,
+    //鍙拌处鏇存柊绫诲瀷锛�0閮ㄥ垎鏇存柊锛堥儴鍒嗙己澶便�侀仐澶憋級銆�1宸叉洿鏂般��2鏃犳洿鏂扮瓑锛�
+    var updateType: Byte? = null,
+    //鍙拌处澶氬獟浣撴枃浠剁被鍨�
+    var fileType: Int? = null,
+    //鍙拌处鍩虹澶氬獟浣撴枃浠惰矾寰�
+    var path1: String? = null,
+    //鍙拌处鍩虹澶氬獟浣撴枃浠跺娉�
+    var remark1: String? = null,
+    //鍙拌处琛ュ厖澶氬獟浣撴枃浠惰矾寰�
+    var path2: String? = null,
+    //鍙拌处琛ュ厖澶氬獟浣撴枃浠跺娉�
+    var remark2: String? = null,
+    //鍙拌处鎵�灞炵殑鍦烘櫙绫诲瀷
+    var sceneType: Int = SceneType.NoType.value,
+) {
+    companion object {
+        fun fromLedgerSubtype(ledger: LedgerSubType?) = LedgerVo().apply {
+            ledgerSubTypeId = ledger?.lsSubtypeid
+            ledgerName = ledger?.lsName
+            ledgerTypeId = ledger?.getlTypeid()
+            ledgerType = ledger?.getlTypename()
+            updateDate = Date()
+            fileType = 1
+        }
+    }
+
+    fun toLedgerRecord(userInfo: Userinfo?) = LedgerRecord().apply {
+        val updateTime = LocalDateTime.ofInstant(updateDate?.toInstant(), ZoneId.systemDefault())
+        lrGuid = UUIDGenerator.generate16ShortUUID()
+        lsSubtypeid = ledgerSubTypeId
+        lsSubtypename = ledgerName
+        lrYear = updateTime.year
+        lrMonth = updateTime.monthValue.toByte()
+        lrDay = updateTime.dayOfMonth.toByte()
+        lrEasubmitkind = fileType?.toByte() ?: 1
+        lrSubmitid = userInfo?.guid
+        lrSubmitname = userInfo?.acountname
+        lrIssubmitontime = updateTime.dayOfMonth <= 10
+        lrSubmitdate = Date()
+        lrUpdatetype = updateType
+        lrExtension1 = sceneType.toString()
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/NotificationVo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/NotificationVo.kt
index 10518b8..88dab77 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/NotificationVo.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/NotificationVo.kt
@@ -42,10 +42,10 @@
         var hasSigned: Boolean? = false,
         //鏄惁闇�瑕佺鏀�
         var needSigned: Boolean? = false,
-        //鎺ユ敹鐢ㄦ埛绫诲瀷锛� -1 浠h〃鎵�鏈変汉
+        //鎺ユ敹鐢ㄦ埛绫诲瀷锛� 0 浠h〃鎵�鏈変汉, -1 浠h〃鏈缃�
         var receiverType: String = SceneType.NoType.value.toString(),
         //鎺ユ敹鐢ㄦ埛id锛� 浠� ; 鍒嗛殧
         var receiverId: String? = null,
-        //鍖哄幙
+        //鍖哄幙锛� 0 浠h〃鎵�鏈変汉, -1 浠h〃鏈缃�
         var district: String? = null
 )
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/PracticalOperationVo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/PracticalOperationVo.kt
new file mode 100644
index 0000000..29540eb
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/PracticalOperationVo.kt
@@ -0,0 +1,9 @@
+package cn.flightfeather.supervision.lightshare.vo
+
+import cn.flightfeather.supervision.domain.entity.PracticalOperation
+import cn.flightfeather.supervision.domain.entity.PracticalOperationRecord
+
+class PracticalOperationVo {
+    var operation: PracticalOperation? = null
+    var record: PracticalOperationRecord? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/QCondition.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/QCondition.kt
index 353c322..fa0b2bd 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/QCondition.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/QCondition.kt
@@ -8,5 +8,5 @@
         var showLevel: Byte? = null,
         var factorType: Byte? = null,
         var worKind: Byte? = null,
-        var resourceKind: Byte? = null
+        var resourceKind: Byte? = null,
 )
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/ScheduleOption.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/ScheduleOption.kt
new file mode 100644
index 0000000..ff3abfa
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/ScheduleOption.kt
@@ -0,0 +1,23 @@
+package cn.flightfeather.supervision.lightshare.vo
+
+import io.swagger.annotations.ApiModel
+import io.swagger.annotations.ApiModelProperty
+import org.springframework.format.annotation.DateTimeFormat
+import java.util.*
+
+@ApiModel("鐜繚鏃ョ▼鏌ヨ鍙傛暟")
+class ScheduleOption {
+    @ApiModelProperty(value = "鐢ㄦ埛id")
+    var userId: String? = null
+
+    @ApiModelProperty(value = "寮�濮嬫椂闂�")
+    @DateTimeFormat
+    var startTime: Date = Date()
+
+    @ApiModelProperty(value = "缁撴潫鏃堕棿")
+    @DateTimeFormat
+    var endTime: Date = Date()
+
+    @ApiModelProperty(value = "鏃ョ▼绫诲瀷")
+    var type: Int? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/ScheduleVo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/ScheduleVo.kt
new file mode 100644
index 0000000..b147a6c
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/ScheduleVo.kt
@@ -0,0 +1,147 @@
+package cn.flightfeather.supervision.lightshare.vo
+
+import cn.flightfeather.supervision.domain.entity.EnvironmentalSchedule
+import java.time.Duration
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.ZoneId
+import java.time.format.DateTimeFormatter
+import java.util.*
+import kotlin.math.abs
+
+class ScheduleVo {
+
+    inner class Step{
+        var title: String? = null
+        var content: String? = null
+    }
+
+    // 鏃ョ▼缂栧彿
+    var id: Int? = null
+
+    // 鏃ョ▼鍚嶇О
+    var title: String? = null
+
+    // 鏃ョ▼鎻忚堪
+    var content: String? = null
+
+    // 鏃ョ▼姝ラ瑙h
+    var steps: MutableList<Step> = mutableListOf()
+
+    // 鏃ョ▼绫诲瀷锛�0锛氱幆淇濇棩绋嬶紱1锛氱幆淇濅簨鍔�
+    var type: Byte? = null
+
+    // 鏃ョ▼鐢熸晥鏃堕棿
+    var time: Date? = null
+        set(value) {
+            if (value != null) {
+                val now = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0)
+                val date = LocalDateTime.ofInstant(value.toInstant(), ZoneId.systemDefault()).withHour(0).withMinute(0).withSecond(0)
+                this.diffDays = Duration.between(now, date).toDays().toInt()
+            }
+            field = value
+        }
+
+    // 鏃ョ▼鏄惁闇�瑕佺鏀�
+    var needSign: Boolean = false
+
+    // 鏃ョ▼鍜屾湇鍔″櫒鏃堕棿鐩稿樊澶╂暟
+    var diffDays: Int = 0
+
+    // 鏃ョ▼鏄惁鏈夊凡缁忕鏀跺畬鎴�
+    var finished: Boolean = false
+
+    // 绛炬敹璁板綍id
+    var recordId: Int? = null
+
+    companion object {
+
+        fun toScheduleVo(schedule: EnvironmentalSchedule) = ScheduleVo().apply {
+            id = schedule.scId
+            title = schedule.scTitle
+            content = schedule.scContent
+            type = schedule.scType
+            needSign = schedule.scNeedSign ?: false
+
+            if (schedule.scStepName != null && schedule.scStepDetail != null) {
+                val stepNames = schedule.scStepName.split(";")
+                val stepDetail = schedule.scStepDetail.split(";")
+                val count = if (stepNames.size > stepDetail.size) stepDetail.size else stepNames.size
+                for (i in 0 until count) {
+                    steps.add(Step().apply {
+                        title = stepNames[i]
+                        content = stepDetail[i]
+                    })
+                }
+            }
+        }
+
+        fun toScheduleVoList(schedule: EnvironmentalSchedule, option: ScheduleOption): List<ScheduleVo> {
+            val sT = LocalDateTime.ofInstant(option.startTime.toInstant(), ZoneId.systemDefault()).toLocalDate()
+            val eT = LocalDateTime.ofInstant(option.endTime.toInstant(), ZoneId.systemDefault()).toLocalDate()
+            val dateList = mutableListOf<Date>()
+            when (schedule.scPeriodType.toInt()) {
+                // 姣忔棩
+                0 -> {
+                    do {
+                        dateList.add(Date.from(sT.atTime(0, 0, 0).atZone(ZoneId.systemDefault()).toInstant()))
+                        sT.plusDays(1)
+                    } while (sT.isAfter(eT))
+                }
+                // 姣忓懆
+                1 -> {
+                    val weekList = schedule.scEveryWeek.split(";")
+                    do {
+                        if (weekList.contains(sT.dayOfWeek.value.toString())) {
+                            dateList.add(Date.from(sT.atTime(0, 0, 0).atZone(ZoneId.systemDefault()).toInstant()))
+                        }
+                        sT.plusDays(1)
+                    } while (sT.isAfter(eT))
+                }
+                // 姣忔湀
+                2 -> {
+                    val dayList = schedule.scEveryMonth.split(";")
+//                    do {
+//                        if (dayList.contains(sT.dayOfMonth.toString())) {
+//                            dateList.add(Date.from(sT.atTime(0, 0, 0).atZone(ZoneId.systemDefault()).toInstant()))
+//                        }
+//                        sT.plusDays(1)
+//                    } while (sT.isAfter(eT))
+                    var diffDays: Int? = null
+                    var mostRecentSchedule: Date? = null
+                    dayList.forEach {
+                        val diff = abs(it.toInt() - sT.dayOfMonth)
+                        if (diffDays == null || diff < diffDays!!) {
+                            mostRecentSchedule = Date.from(sT.withDayOfMonth(it.toInt()).atTime(0, 0, 0).atZone(ZoneId
+                                .systemDefault())
+                                .toInstant())
+                            diffDays = diff
+                        }
+                    }
+                    mostRecentSchedule?.let { dateList.add(it) }
+                }
+                // 姣忓勾
+                3 -> {
+                    val dayList = schedule.scEveryYear.split(";")
+                    do {
+                        val timeFormat = sT.format(DateTimeFormatter.ofPattern("MM-dd"))
+                        if (dayList.contains(timeFormat)) {
+                            dateList.add(Date.from(sT.atTime(0, 0, 0).atZone(ZoneId.systemDefault()).toInstant()))
+                        }
+                        sT.plusDays(1)
+                    } while (sT.isAfter(eT))
+                }
+                // 鍥哄畾鏃ユ湡
+                4 -> {
+                    val time = LocalDateTime.ofInstant(schedule.scEffectiveTime.toInstant(), ZoneId.systemDefault()).toLocalDate()
+                    if (
+                        (sT.isBefore(time) || sT.isEqual(time)) && (eT.isAfter(time) || eT.isEqual(time))
+                    ) {
+                        dateList.add(schedule.scEffectiveTime)
+                    }
+                }
+            }
+            return dateList.map { toScheduleVo(schedule).apply { time = it } }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/SelfPatrolTaskVo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/SelfPatrolTaskVo.kt
new file mode 100644
index 0000000..c793da8
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/SelfPatrolTaskVo.kt
@@ -0,0 +1,24 @@
+package cn.flightfeather.supervision.lightshare.vo
+
+import cn.flightfeather.supervision.domain.enumeration.SelfPatrolTaskStatus
+import java.util.*
+
+class SelfPatrolTaskVo {
+
+    var guid: String? = null
+    var toUserId: String? = null
+    var toUserName: String? = null
+    var fromUserId: String? = null
+    var fromUserName: String? = null
+    var sceneTypeId: Int? = null
+    var sceneType: String? = null
+    var ledgerTypeId: String? = null
+    var ledgerTypeName: String = ""
+    var tag: String? = null
+    var publishUnit: String? = null
+    var createTime: Date? = null
+    var deadline: Date? = null
+    var taskStatus: Int = SelfPatrolTaskStatus.UnPublish.value
+    var finished:Int = 0
+    var total: Int = 0
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/UserBaseInfo.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/UserBaseInfo.kt
index f795b96..bab35ae 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/UserBaseInfo.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/UserBaseInfo.kt
@@ -1,9 +1,6 @@
 package cn.flightfeather.supervision.lightshare.vo
 
-import cn.flightfeather.supervision.domain.entity.BaseInfo
-import cn.flightfeather.supervision.domain.entity.BaseSpecialInfo
-import cn.flightfeather.supervision.domain.entity.Company
-import cn.flightfeather.supervision.domain.entity.PersonalInfo
+import cn.flightfeather.supervision.domain.entity.*
 import com.fasterxml.jackson.annotation.JsonInclude
 
 /**
@@ -12,10 +9,11 @@
  */
 @JsonInclude(JsonInclude.Include.NON_NULL)
 data class UserBaseInfo(
-        val userId: String,
-        val name: String? = null,
-        val baseInfo: BaseInfo? = null,
-        val company: Company? = null,
-        val specialInfo: BaseSpecialInfo? = null,
-        val personalInfo: PersonalInfo? = null
+    val userId: String? = null,
+    val name: String? = null,
+    val userInfo: Userinfo? = null,
+    val baseInfo: BaseInfo? = null,
+    val company: Company? = null,
+    val specialInfo: BaseSpecialInfo? = null,
+    val personalInfo: PersonalInfo? = null,
 )
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/UserSearchCondition.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/UserSearchCondition.kt
index c4b263a..179a04e 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/UserSearchCondition.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/UserSearchCondition.kt
@@ -1,25 +1,106 @@
 package cn.flightfeather.supervision.lightshare.vo
 
+import cn.flightfeather.supervision.domain.entity.UserConfig
+
 /**
  * 鐢ㄦ埛鏌ヨ鏉′欢
  */
-data class UserSearchCondition(
-        /**
-         * 鍦烘櫙绫诲瀷
-         * @see [cn.flightfeather.supervision.domain.enumeration.SceneType.value]
-         */
-        val sceneTypes: List<String> = emptyList(),
+class UserSearchCondition {
+    companion object {
 
-        /**
-         * 琛楅晣琛屾斂浠g爜
-         */
-        val townCodes: List<String> = emptyList(),
+        fun fromUserConfig(config: UserConfig?, condition: UserSearchCondition? = null): UserSearchCondition {
+            return condition?.apply {
+                config?.ucProvinceCode?.let { provinceCode = it }
+                config?.ucProvinceName?.let { provinceName = it }
+                config?.ucCityCode?.let { cityCode = it }
+                config?.ucCityName?.let { cityName = it }
+                config?.ucDistrictCode?.let { districtCode = it }
+                config?.ucDistrictName?.let { districtName = it }
+                config?.ucTownCode?.let { townCode = it }
+                config?.ucTownName?.let { townName = it }
+                config?.ucAreaCode?.let { areaCode = it }
+                config?.ucArea?.let { area = it }
+                config?.ucManagementCompanyId?.let { mcId = it }
+                config?.ucManagementCompany?.let { mcName = it }
+                //                userTypeId = config?.ucUserTypeId?.toByte()
+                //                userSubTypeId = config?.ucUserSubtypeId?.toByte()
+            }
+                ?: UserSearchCondition().apply {
+                    config?.ucProvinceCode?.let { provinceCode = it }
+                    config?.ucProvinceName?.let { provinceName = it }
+                    config?.ucCityCode?.let { cityCode = it }
+                    config?.ucCityName?.let { cityName = it }
+                    config?.ucDistrictCode?.let { districtCode = it }
+                    config?.ucDistrictName?.let { districtName = it }
+                    config?.ucTownCode?.let { townCode = it }
+                    config?.ucTownName?.let { townName = it }
+                    config?.ucAreaCode?.let { areaCode = it }
+                    config?.ucArea?.let { area = it }
+                    config?.ucManagementCompanyId?.let { mcId = it }
+                    config?.ucManagementCompany?.let { mcName = it }
+                    //                userTypeId = config?.ucUserTypeId?.toByte()
+                    //                userSubTypeId = config?.ucUserSubtypeId?.toByte()
+                }
+        }
+    }
 
-        val districtName: String? = null,
+    var provinceCode: String? = null
 
-        /**
-         * 鏌ヨ瀛楁锛屽搴斾紒涓氬悕绉�
-         */
-        val searchText: String = ""
+    var provinceName: String? = null
 
-)
\ No newline at end of file
+    var cityCode: String? = null
+
+    var cityName: String? = null
+
+    var districtCode: String? = null
+
+    var districtName: String? = null
+
+    //琛楅晣琛屾斂浠g爜
+    var townCode: String? = null
+
+    var townName: String? = null
+
+    //闆嗕腑鍖虹紪鍙�
+    var areaCode: String? = null
+
+    //闆嗕腑鍖哄悕绉�
+    var area: String? = null
+
+    //鎵�灞炵墿涓歩d
+    var mcId: String? = null
+
+    //鎵�灞炵墿涓氬悕绉�
+    var mcName: String? = null
+
+    //鐢ㄦ埛绫诲瀷id
+    var userTypeId: Byte? = null
+
+    //鐢ㄦ埛瀛愮被鍨媔d
+    var userSubTypeId: Byte? = null
+
+    //鏄惁鍙敤
+    var online: Boolean? = null
+
+    /**
+     * 鍦烘櫙绫诲瀷
+     * @see [cn.flightfeather.supervision.domain.enumeration.SceneType.value]
+     */
+    var sceneTypes: List<String> = emptyList()
+
+
+    // 鏌ヨ瀛楁锛屽搴斾紒涓氬悕绉�
+    var searchText: String? = null
+
+    // 鎸夌収璇勫垎鎺掑簭锛岄粯璁ら檷搴�
+    var sorts: String = "desc"
+
+    // 鍛ㄦ湡, yyyy/M-M 鎴� yyyy-MM-dd
+    var period: String? = null
+
+    // 鐜俊鐮佺瓑绾э紝0锛氱豢鐮侊紱1锛氶粍鐮侊紱2锛氱孩鐮侊紱null锛氬叏閮�
+    var codeType: Int? = null
+
+    // 椋庨櫓绛夌骇锛�0锛氫綆椋庨櫓锛�1锛氫腑椋庨櫓锛�2锛氶珮椋庨櫓锛沶ull锛氬叏閮�
+    var riskType: Int? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/AuthController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/AuthController.kt
index 6f00f35..31d785c 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/AuthController.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/AuthController.kt
@@ -36,10 +36,16 @@
         @ApiParam("涓汉淇℃伅") @RequestBody personalInfo: PersonalInfo
     ) = authService.authPersonal(wxUserId, personalInfo)
 
-    @ApiOperation(value = "鑾峰彇鐢ㄦ埛璁よ瘉鐘舵��")
+    @ApiOperation(value = "鑾峰彇鐢ㄦ埛鐩稿叧璁よ瘉鐘舵��")
     @GetMapping("/status")
     fun authStatus(
         @ApiParam("鐢ㄦ埛寰俊id") @RequestParam(value = "wxUserId", required = false) wxUserId: String?,
         @ApiParam("鐢ㄦ埛鍦烘櫙id") @RequestParam(value = "userId", required = false) userId: String?,
     ) = authService.authStatus(wxUserId, userId)
+
+    @ApiOperation(value = "鑾峰彇浼佷笟鐩稿叧璁よ瘉鐘舵��")
+    @GetMapping("/status/scene")
+    fun sceneAuthStatus(
+        @ApiParam("鐢ㄦ埛鍦烘櫙id") @RequestParam(value = "userId", required = false) userId: String?,
+    ) = authService.sceneAuthStatus(userId)
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/BaseInfoController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/BaseInfoController.kt
new file mode 100644
index 0000000..c23e55f
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/BaseInfoController.kt
@@ -0,0 +1,41 @@
+package cn.flightfeather.supervision.lightshare.web
+
+import cn.flightfeather.supervision.domain.entity.BaseInfo
+import cn.flightfeather.supervision.lightshare.service.BaseInfoService
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+import io.swagger.annotations.Api
+import io.swagger.annotations.ApiOperation
+import io.swagger.annotations.ApiParam
+import org.springframework.web.bind.annotation.*
+
+@Api(tags = ["鐢ㄦ埛鍩烘湰淇℃伅鐩稿叧API鎺ュ彛"])
+@RestController
+@RequestMapping("/baseInfo")
+class BaseInfoController(val baseInfoService: BaseInfoService) {
+
+    @ApiOperation(value = "鏍规嵁鐢ㄦ埛id鑾峰彇鐢ㄦ埛鍩烘湰淇℃伅")
+    @GetMapping("/{id}")
+    fun getById(
+        @ApiParam("鐢ㄦ埛id") @PathVariable id: String
+    ) = baseInfoService.findOne(id)
+
+    @ApiOperation(value = "鍒涘缓鐢ㄦ埛鍩烘湰淇℃伅")
+    @PutMapping("")
+    fun save(
+        @ApiParam("鐢ㄦ埛鍩烘湰淇℃伅") @RequestBody baseInfo: BaseInfo,
+    ) = baseInfoService.save(baseInfo)
+
+    @ApiOperation(value = "鏇存柊鐢ㄦ埛淇℃伅")
+    @PostMapping("")
+    fun update(
+        @ApiParam("鐢ㄦ埛鍩烘湰淇℃伅") @RequestBody baseInfo: BaseInfo
+    ) = baseInfoService.update(baseInfo)
+
+    @ApiOperation(value = "鎼滅储鐢ㄦ埛淇℃伅")
+    @PostMapping("/search")
+    fun search(
+        @ApiParam("鏌ヨ鏉′欢") @RequestBody condition: UserSearchCondition,
+        @ApiParam("椤电爜") @RequestParam(value = "page") page: Int,
+        @ApiParam("鍗曢〉鏁版嵁閲�") @RequestParam(value = "per_page") perPage: Int,
+    ) = baseInfoService.searchUser(condition, page, perPage)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/BaseResPack.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/BaseResPack.kt
new file mode 100644
index 0000000..3cc30f6
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/BaseResPack.kt
@@ -0,0 +1,26 @@
+package cn.flightfeather.supervision.lightshare.web
+
+import cn.flightfeather.supervision.common.exception.ResponseErrorException
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import cn.flightfeather.supervision.lightshare.vo.DataHead
+
+/**
+ * 鍖呰鎺ュ彛杩斿洖缁撴灉
+ */
+fun resPack(service: () -> Any?): BaseResponse<Any> {
+    return try {
+        val res = service()
+        if (res is Pair<*, *>) {
+            val head = res.first
+            if (head is DataHead) {
+                BaseResponse(true, head = head, data = res.second)
+            } else {
+                BaseResponse(true, data = res)
+            }
+        } else {
+            BaseResponse(true, data = res)
+        }
+    } catch (e: ResponseErrorException) {
+        BaseResponse(false, message = e.message ?: "")
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/CommitmentController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/CommitmentController.kt
index 7862833..2e89d21 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/CommitmentController.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/CommitmentController.kt
@@ -31,6 +31,12 @@
         response: HttpServletResponse
     ) = commitmentService.getLetterOfCommitment(userId, page, perPage, response)
 
+    @ApiOperation(value = "鑾峰彇鐢ㄦ埛鎵胯涔︽ā鏉�")
+    @GetMapping("/letter/template")
+    fun getTemplateOfCommitment(
+        @ApiParam(value = "鐢ㄦ埛id") @RequestParam("userId") userId: String,
+    ) = commitmentService.getTemplateOfCommitment(userId)
+
     @ApiOperation(value = "涓婁紶鎵胯涔�")
     @PostMapping("/letter/upload")
     fun uploadLetterOfCommitment(
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/CompanyController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/CompanyController.kt
new file mode 100644
index 0000000..3b5443b
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/CompanyController.kt
@@ -0,0 +1,35 @@
+package cn.flightfeather.supervision.lightshare.web
+
+import cn.flightfeather.supervision.domain.entity.BaseInfo
+import cn.flightfeather.supervision.domain.entity.Company
+import cn.flightfeather.supervision.lightshare.service.CompanyService
+import io.swagger.annotations.Api
+import io.swagger.annotations.ApiOperation
+import io.swagger.annotations.ApiParam
+import org.springframework.web.bind.annotation.*
+
+@Api(tags = ["鐢ㄦ埛浼佷笟淇℃伅鐩稿叧API鎺ュ彛"])
+@RestController
+@RequestMapping("/company")
+class CompanyController(val companyService: CompanyService) {
+
+    @ApiOperation(value = "鏍规嵁鐢ㄦ埛id鑾峰彇鐢ㄦ埛浼佷笟淇℃伅")
+    @GetMapping("/{id}")
+    fun getById(
+        @ApiParam("鐢ㄦ埛id") @PathVariable id: String
+    ) = companyService.findOne(id)
+
+    @ApiOperation(value = "鍒涘缓浼佷笟鍩烘湰淇℃伅")
+    @PutMapping("/{userId}")
+    fun save(
+        @ApiParam(value = "鐢ㄦ埛id") @PathVariable("userId") userId: String,
+        @ApiParam("浼佷笟淇℃伅") @RequestBody info: Company,
+    ) = companyService.save(userId, info)
+
+    @ApiOperation(value = "鏇存柊鐢ㄦ埛淇℃伅")
+    @PostMapping("/{userId}")
+    fun update(
+        @ApiParam(value = "鐢ㄦ埛id") @PathVariable("userId") userId: String,
+        @ApiParam("浼佷笟淇℃伅") @RequestBody info: Company,
+    ) = companyService.update(userId, info)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/ConfigController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/ConfigController.kt
new file mode 100644
index 0000000..44bd7d3
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/ConfigController.kt
@@ -0,0 +1,33 @@
+package cn.flightfeather.supervision.lightshare.web
+
+import cn.flightfeather.supervision.lightshare.service.ConfigService
+import cn.flightfeather.supervision.lightshare.service.CreditService
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+import io.swagger.annotations.Api
+import io.swagger.annotations.ApiOperation
+import io.swagger.annotations.ApiParam
+import org.springframework.web.bind.annotation.*
+
+@Api(tags = ["鍔ㄦ�侀厤缃瓵PI鎺ュ彛"])
+@RestController
+@RequestMapping("/config")
+class ConfigController(private val configService: ConfigService){
+
+    @ApiOperation(value = "鑾峰彇鐢ㄦ埛绫诲瀷鍙敤鐨勫満鏅寖鍥�")
+    @GetMapping("/scene/range")
+    fun getSceneRange(
+        @ApiParam("鐢ㄦ埛id") @RequestParam("userId") userId: String,
+    ) = resPack { configService.getSceneRange(userId) }
+
+    @ApiOperation(value = "鑾峰彇鎵胯涔︽ā鏉�")
+    @PostMapping("/commitment/template")
+    fun getCommitmentTemplate(
+        @ApiParam("鏌ヨ鏉′欢") @RequestBody condition: UserSearchCondition,
+    ) = resPack { configService.getCommitmentTemplate(condition) }
+
+    @ApiOperation(value = "鑾峰彇鐢ㄦ埛绫诲瀷鍙敤鐨勫満鏅寖鍥�")
+    @GetMapping("/user/config")
+    fun getUserConfig(
+        @ApiParam("鐢ㄦ埛id") @RequestParam("userId") userId: String,
+    ) = resPack { configService.getUserConfig(userId) }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/CreditController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/CreditController.kt
new file mode 100644
index 0000000..67c953b
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/CreditController.kt
@@ -0,0 +1,32 @@
+package cn.flightfeather.supervision.lightshare.web
+
+import cn.flightfeather.supervision.lightshare.service.CreditService
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+import io.swagger.annotations.Api
+import io.swagger.annotations.ApiOperation
+import io.swagger.annotations.ApiParam
+import org.springframework.web.bind.annotation.*
+import springfox.documentation.annotations.ApiIgnore
+import javax.servlet.http.HttpServletResponse
+
+@Api(tags = ["淇$敤璇勪及API鎺ュ彛"])
+@RestController
+@RequestMapping("/credit")
+class CreditController(private val creditService: CreditService){
+
+    @ApiOperation(value = "鑾峰彇鐜俊鐮佺粨鏋�")
+    @PostMapping("/ecCode")
+    fun searchGradeList(
+        @ApiParam("鐢ㄦ埛id") @RequestParam("userId") userId: String,
+        @ApiParam("鏌ヨ鏉′欢") @RequestBody condition: UserSearchCondition,
+        @ApiParam("椤电爜") @RequestParam(value = "page") page: Int,
+        @ApiParam("鍗曢〉鏁版嵁閲�") @RequestParam(value = "per_page") perPage: Int,
+    ) = creditService.searchEcCodeList(userId, condition, page, perPage)
+
+    @ApiOperation(value = "涓嬭浇鐜俊鐮佸浘鐗�")
+    @GetMapping("/ecCode/download")
+    fun downloadEcCodeImg(
+        @ApiParam("鐢ㄦ埛id") @RequestParam("userId") userId: String,
+        @ApiIgnore response: HttpServletResponse,
+    ) = creditService.downloadEcCodeImg(userId, response)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/DeviceController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/DeviceController.kt
index 5f77ef5..4940711 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/DeviceController.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/DeviceController.kt
@@ -1,5 +1,6 @@
 package cn.flightfeather.supervision.lightshare.web
 
+import cn.flightfeather.supervision.domain.entity.VocPurifyDevice
 import cn.flightfeather.supervision.lightshare.service.DeviceService
 import cn.flightfeather.supervision.lightshare.vo.DateVo
 import io.swagger.annotations.Api
@@ -58,4 +59,39 @@
         @ApiParam(value = "椤垫暟") @RequestParam("page") page: Int,
         @ApiParam(value = "姣忛〉鏁版嵁閲�") @RequestParam("per_page") perPage: Int
     ) = deviceService.getRealTimeData(page, perPage)
+
+    @ApiOperation(value = "鑾峰彇闈欏畨宸ュ湴鎵皹灏忔椂鏁版嵁")
+    @GetMapping("/dust/jingan/value")
+    fun getJingAnDustHourValue(
+        @ApiParam(value = "鐢ㄦ埛id") @RequestParam("userId") userId: String,
+        @ApiParam(value = "寮�濮嬫椂闂�", example = "yyyy-MM-dd HH:mm") @RequestParam("startTime") startTime: String?,
+        @ApiParam(value = "缁撴潫鏃堕棿", example = "yyyy-MM-dd HH:mm") @RequestParam("endTime") endTime: String?,
+    ) = deviceService.getJingAnDustHourValue(userId, startTime, endTime)
+
+    @ApiOperation(value = "鑾峰彇闈欏畨椁愰ギ鏁版嵁")
+    @GetMapping("/fume/jingan/value")
+    fun getJingAnFumeValue(
+        @ApiParam(value = "鐢ㄦ埛id") @RequestParam("userId") userId: String,
+        @ApiParam(value = "寮�濮嬫椂闂�", example = "yyyy-MM-dd HH:mm") @RequestParam("startTime") startTime: String?,
+        @ApiParam(value = "缁撴潫鏃堕棿", example = "yyyy-MM-dd HH:mm") @RequestParam("endTime") endTime: String?,
+    ) = deviceService.getJingAnFumeValue(userId, startTime, endTime)
+
+    @ApiOperation(value = "鑾峰彇璁惧淇℃伅")
+    @GetMapping("/monitor/deviceInfo")
+    fun getDeviceInfo(
+        @ApiParam(value = "鐢ㄦ埛id") @RequestParam("userId") userId: String,
+    ) = deviceService.getDeviceInfo(userId)
+
+    @ApiOperation(value = "涓婁紶voc澶勭悊璁惧淇℃伅")
+    @PostMapping("/voc/upload")
+    fun saveVOCPurifyDevice(
+        @ApiParam(value = "鐢ㄦ埛id") @RequestParam("userId") userId: String,
+        @ApiParam(value = "鏃堕棿") @RequestBody infoList: List<VocPurifyDevice>,
+    ) = deviceService.saveVOCPurifyDevice(userId, infoList)
+
+    @ApiOperation(value = "鑾峰彇VOC鍑�鍖栬澶囦俊鎭�")
+    @GetMapping("/voc/purify/info")
+    fun getVOCPurifyDevice(
+        @ApiParam(value = "鐢ㄦ埛id") @RequestParam("userId") userId: String
+    ) = deviceService.getVOCPurifyDevice(userId)
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/EnforceCaseController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/EnforceCaseController.kt
new file mode 100644
index 0000000..bf33a2c
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/EnforceCaseController.kt
@@ -0,0 +1,28 @@
+package cn.flightfeather.supervision.lightshare.web
+
+import cn.flightfeather.supervision.domain.entity.EnforceCase
+import cn.flightfeather.supervision.lightshare.service.EnforceCaseService
+import io.swagger.annotations.Api
+import io.swagger.annotations.ApiOperation
+import io.swagger.annotations.ApiParam
+import org.springframework.web.bind.annotation.*
+
+@Api(tags = ["鐜繚鐫e療妗堜緥API鎺ュ彛"])
+@RestController
+@RequestMapping("/enforceCase")
+class EnforceCaseController(private val enforceCaseService: EnforceCaseService) {
+
+    @ApiOperation(value = "鏂板妗堜緥")
+    @PutMapping("/add")
+    fun add(
+        @ApiParam(value = "鐢ㄦ埛id") @RequestParam userId: String,
+        @ApiParam(value = "鍜ㄨ闂") @RequestBody case: EnforceCase,
+    ) = enforceCaseService.addCase(userId, case)
+
+    @ApiOperation(value = "鏇存柊妗堜緥")
+    @PostMapping("/update")
+    fun update(
+        @ApiParam(value = "鐢ㄦ埛id") @RequestParam userId: String,
+        @ApiParam(value = "鍜ㄨ闂") @RequestBody case: EnforceCase,
+    ) = enforceCaseService.updateCase(userId, case)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/EvaluationController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/EvaluationController.kt
index 2dbd910..0324cb9 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/EvaluationController.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/EvaluationController.kt
@@ -3,6 +3,7 @@
 import cn.flightfeather.supervision.domain.entity.Evaluation
 import cn.flightfeather.supervision.lightshare.service.EvaluationService
 import cn.flightfeather.supervision.lightshare.vo.AssessmentSearchCondition
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
 import io.swagger.annotations.Api
 import io.swagger.annotations.ApiOperation
 import io.swagger.annotations.ApiParam
@@ -20,7 +21,7 @@
     @ApiOperation(value = "涓婁紶涓�鏉¤瘎浼版�诲垎璁板綍")
     @PutMapping
     fun add(
-        @ApiParam(value = "璇勪及鏁版嵁") @RequestBody evaluation: Evaluation
+        @ApiParam(value = "璇勪及鏁版嵁") @RequestBody evaluation: Evaluation,
     ) = evaluationService.save(evaluation)
 
     @ApiOperation(value = "鏇存柊涓�鏉¤瘎浼版�诲垎璁板綍")
@@ -44,7 +45,7 @@
         @ApiParam(value = "缁撴潫鏃堕棿") @RequestParam("endTime") endTime: String,
         @ApiParam(value = "鍦烘櫙绫诲瀷id") @RequestParam("sceneTypeId", required = false) sceneTypeId: Int?,
         @ApiParam(value = "瀛愪换鍔d") @RequestParam("erGuid", required = false) erGuid: String?,
-        @ApiParam(value = "璇勪及淇℃伅涓婚敭id") @RequestParam("eId", required = false) eId: String?
+        @ApiParam(value = "璇勪及淇℃伅涓婚敭id") @RequestParam("eId", required = false) eId: String?,
     ) = evaluationService.getTotalPoints(userId, evaluatorType, startTime, endTime, sceneTypeId, erGuid, eId)
 
     @ApiOperation(value = "鑾峰彇鐢ㄦ埛璇勪及鎬诲垎")
@@ -53,15 +54,24 @@
         @ApiParam(value = "鐢ㄦ埛id") @PathVariable("userId") userId: String,
         @ApiParam(value = "椤电爜") @RequestParam(value = "page") page: Int,
         @ApiParam(value = "鍗曢〉鏁版嵁閲�") @RequestParam(value = "per_page") perPage: Int,
-        @ApiParam(value = "鍓嶇骞冲彴") @RequestParam("platform", required = false) platform:String?,
-        response: HttpServletResponse
-    ) = evaluationService.getHistoryPoint(userId, page, perPage, platform, response)
+        @ApiParam(value = "鍓嶇骞冲彴") @RequestParam("platform", required = false) platform: String?,
+        @ApiParam(value = "璇勫垎鍛ㄦ湡") @RequestParam("period", required = false) period: String?,
+        response: HttpServletResponse,
+    ) = evaluationService.getHistoryPoint(userId, page, perPage, platform, period, response)
 
     @ApiOperation(value = "鑾峰彇淇$敤璇勪及缁撴灉")
     @GetMapping("/creditInfo")
     fun getCreditInfo(
-        @ApiParam(value = "鐢ㄦ埛id") @RequestParam("userId") userId: String
-    ) = evaluationService.getCreditInfo(userId)
+        @ApiParam(value = "鐢ㄦ埛id") @RequestParam("userId") userId: String,
+        @ApiParam(value = "鍛ㄦ湡") @RequestParam(value = "period", required = false) period: String?,
+    ) = evaluationService.getCreditInfo(userId, period)
+
+    @ApiOperation(value = "鑾峰彇淇$敤璇勪及缁撴灉")
+    @PostMapping("/credit/count")
+    fun getCreditCount(
+        @ApiParam(value = "鐢ㄦ埛id") @RequestParam("userId") userId: String,
+        @ApiParam("鏌ヨ鏉′欢") @RequestBody condition: UserSearchCondition,
+    ) = evaluationService.getCreditCount(userId, condition)
 
     @ApiOperation(value = "鑾峰彇鏌愪釜鐢ㄦ埛鐨勪俊鐢ㄨ瘎浼扮粨鏋�")
     @PostMapping("/search/{userId}")
@@ -70,14 +80,14 @@
         @ApiParam(value = "鏌ヨ鏉′欢") @RequestBody condition: AssessmentSearchCondition,
         @ApiParam(value = "椤电爜") @RequestParam(value = "page") page: Int,
         @ApiParam(value = "鍗曢〉鏁版嵁閲�") @RequestParam(value = "per_page") perPage: Int,
-        response: HttpServletResponse
+        response: HttpServletResponse,
     ) = evaluationService.getAssessments(userId, condition, page, perPage, response)
 
     fun autoScore(
-            @RequestParam(value = "year") year: Int,
-            @RequestParam(value = "month") month: Int,
-            @RequestParam("sceneType") sceneType: Int,
-            response: HttpServletResponse
+        @RequestParam(value = "year") year: Int,
+        @RequestParam(value = "month") month: Int,
+        @RequestParam("sceneType") sceneType: Int,
+        response: HttpServletResponse,
     ) = evaluationService.autoScore(year, month, sceneType, response)
 
 
@@ -93,7 +103,16 @@
     @ApiOperation(value = "鑾峰彇娴嬭瘎璇︽儏")
     @GetMapping("/detail")
     fun getDetail(
-            @ApiParam(value = "鐢ㄦ埛id") @RequestParam("userId") userId: String,
-            @ApiParam(value = "璇勫垎鍛ㄦ湡") @RequestParam("period") period: String,
+        @ApiParam(value = "鐢ㄦ埛id") @RequestParam("userId") userId: String,
+        @ApiParam(value = "璇勫垎鍛ㄦ湡") @RequestParam("period") period: String,
     ) = evaluationService.getDetail(userId, period)
+
+    @ApiOperation(value = "鑾峰彇鐢ㄦ埛璇勫垎淇℃伅锛岃嚜璇勬垨鐜舰鐮佽瘎浼�")
+    @PostMapping("/gradeList")
+    fun searchGradeList(
+        @ApiParam("鐢ㄦ埛id") @RequestParam("userId") userId: String,
+        @ApiParam("鏌ヨ鏉′欢") @RequestBody condition: UserSearchCondition,
+        @ApiParam("椤电爜") @RequestParam(value = "page") page: Int,
+        @ApiParam("鍗曢〉鏁版嵁閲�") @RequestParam(value = "per_page") perPage: Int,
+    ) = evaluationService.searchGradeList(userId, condition, page, perPage)
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/LedgerController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/LedgerController.kt
index 172a37d..66405a0 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/LedgerController.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/LedgerController.kt
@@ -63,6 +63,15 @@
         @ApiParam("鍙拌处鍥剧墖") @RequestPart("images") files:Array<MultipartFile>
     ) = ledgerService.uploadLedger(userId, ledgerVoList, files)
 
+    @ApiOperation("涓婁紶涓嶆秹鍙婂彴璐�")
+    @PostMapping("/upload/noLedger")
+    fun uploadNoLedger(
+        @RequestParam("userId") userId: String,
+        @RequestParam("time") time: String,
+        @RequestParam(required = false) remark: String?,
+        @RequestBody ledgerIdList: List<Int>
+    ) = ledgerService.uploadNoLedger(userId, time, remark, ledgerIdList)
+
     @ApiOperation(value = "鑾峰彇鏌愪釜鍙拌处鏄剧ず鍥炬爣url")
     @GetMapping("/{userId}/img")
     fun getLedgerImg(
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/NotificationController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/NotificationController.kt
index f7f9453..e5538ae 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/NotificationController.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/NotificationController.kt
@@ -1,5 +1,6 @@
 package cn.flightfeather.supervision.lightshare.web
 
+import cn.flightfeather.supervision.domain.entity.NoticeConfig
 import cn.flightfeather.supervision.lightshare.service.NotificationService
 import cn.flightfeather.supervision.lightshare.vo.NoticeReadStateVo
 import cn.flightfeather.supervision.lightshare.vo.NotificationVo
@@ -13,6 +14,15 @@
 @RestController
 @RequestMapping("/notifications")
 class NotificationController(val notificationService: NotificationService) {
+
+    @ApiOperation(value = "鎸夋煡璇㈡潯浠惰幏鍙栭�氱煡")
+    @PostMapping("/history")
+    fun getAllNotices(
+        @ApiParam("鐢ㄦ埛id") @RequestParam(value = "userId") userId: String,
+        @ApiParam("閫氱煡鏌ヨ鏉′欢") @RequestBody noticeConfig: NoticeConfig,
+        @ApiParam("椤电爜") @RequestParam(value = "page") page: Int,
+        @ApiParam("鍗曢〉鏁版嵁閲�") @RequestParam(value = "per_page") perPage: Int,
+    ) = notificationService.getAllNotices(userId, noticeConfig, page, perPage)
 
     @ApiOperation(value = "鑾峰彇鐢ㄦ埛鏈閫氱煡")
     @GetMapping
@@ -49,9 +59,23 @@
         @ApiParam("閫氱煡") @RequestBody notice: NotificationVo
     ) = notificationService.releaseNotice(userId, notice)
 
+    @ApiOperation(value = "鍙戝竷閫氱煡")
+    @PostMapping("/{userId}/release2")
+    fun releaseNotice2(
+        @ApiParam("鐢ㄦ埛id") @PathVariable("userId") userId: String,
+        @ApiParam("閫氱煡") @RequestBody notice: NotificationVo
+    ) = notificationService.releaseNotice2(userId, notice)
+
     @ApiOperation(value = "鎺ㄩ�佷竴鏉″井淇¤闃呮秷鎭�")
     @GetMapping("/wx/message/subscribe/send")
     fun pushMsgWx(
         @ApiParam("妯℃澘id") @RequestParam("templateId") templateId: Int
     ) = notificationService.pushMsgWx(templateId)
+
+    @ApiOperation(value = "鑾峰彇閫氱煡妯℃澘")
+    @GetMapping("/template")
+    fun getTemplate(
+        @ApiParam("閫氱煡绫诲瀷") @RequestParam("typeId") typeId: Int,
+        @ApiParam("閫氱煡瀛愮被鍨�") @RequestParam("subTypeId") subTypeId: Int,
+    ) = notificationService.getTemplate(typeId, subTypeId)
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/OpenApiWordController.java b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/OpenApiWordController.java
index 5c19761..819d2db 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/OpenApiWordController.java
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/OpenApiWordController.java
@@ -9,6 +9,7 @@
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RequestPart;
 import org.springframework.web.multipart.MultipartFile;
 import org.thymeleaf.context.Context;
@@ -52,6 +53,18 @@
         writeContentToResponse(model, response);
     }
 
+    @ApiOperation(value = "灏� swagger json鏂囦欢杞崲鎴� word鏂囨。骞朵笅杞�", notes = "")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "璇锋眰鎴愬姛銆�")})
+    @RequestMapping(value = "/OpenApiFileToWord2", method = {RequestMethod.POST})
+    public void getWord2(
+            Model model,
+            @ApiParam("swagger json url") @RequestParam("url") String url,
+            HttpServletResponse response
+    ) throws Exception {
+        generateModelData(model, url);
+        writeContentToResponse(model, response);
+    }
+
     private void generateModelData(Model model, MultipartFile jsonFile) throws IOException {
         Map<String, Object> result = openApiWordService.tableList(jsonFile);
         fileName = jsonFile.getOriginalFilename();
@@ -67,11 +80,11 @@
         model.addAllAttributes(result);
     }
 
-    private void generateModelData(Model model, String url, Integer download) {
+    private void generateModelData(Model model, String url) {
         url = StringUtils.defaultIfBlank(url, swaggerUrl);
         Map<String, Object> result = openApiWordService.tableList(url);
         model.addAttribute("url", url);
-        model.addAttribute("download", download);
+        model.addAttribute("download", 0);
         model.addAllAttributes(result);
     }
 
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/OperationController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/OperationController.kt
new file mode 100644
index 0000000..316ec4f
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/OperationController.kt
@@ -0,0 +1,31 @@
+package cn.flightfeather.supervision.lightshare.web
+
+import cn.flightfeather.supervision.lightshare.service.OperationService
+import io.swagger.annotations.Api
+import io.swagger.annotations.ApiOperation
+import io.swagger.annotations.ApiParam
+import org.springframework.web.bind.annotation.*
+
+@Api(tags = ["瀹炴搷浜嬪姟API鎺ュ彛"])
+@RestController
+@RequestMapping("/operation")
+class OperationController(private val operationService: OperationService){
+
+    @ApiOperation(value = "鑾峰彇鐢ㄦ埛鐨勫疄鎿嶄簨鍔�")
+    @GetMapping("/get")
+    fun getOperations(@ApiParam("鐢ㄦ埛id") @RequestParam userId: String) =
+        resPack { operationService.getOperations(userId) }
+
+    @ApiOperation(value = "鑾峰彇鐢ㄦ埛鐨勫疄鎿嶄簨鍔′互鍙婃渶鏂版墽琛岃褰�")
+    @GetMapping("/get/record")
+    fun getOperationRecord(@ApiParam("鐢ㄦ埛id") @RequestParam userId: String) =
+        resPack { operationService.getOperationRecord(userId) }
+
+    @ApiOperation(value = "鐢ㄦ埛瀹屾垚鏌愰」浜嬪姟")
+    @PostMapping("/execute")
+    fun executeOperation(
+        @ApiParam("鐢ㄦ埛id") @RequestParam userId: String,
+        @ApiParam("瀹炴搷浜嬪姟id") @RequestParam operationId: Int,
+        @ApiParam("瀹炴搷浜嬪姟鐘舵�乮d") @RequestParam stateId: String,
+    ) = resPack { operationService.executeOperation(userId, operationId, stateId) }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/RiskController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/RiskController.kt
new file mode 100644
index 0000000..3b4f058
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/RiskController.kt
@@ -0,0 +1,50 @@
+package cn.flightfeather.supervision.lightshare.web
+
+import cn.flightfeather.supervision.lightshare.service.CreditService
+import cn.flightfeather.supervision.lightshare.service.RiskService
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+import io.swagger.annotations.Api
+import io.swagger.annotations.ApiOperation
+import io.swagger.annotations.ApiParam
+import org.springframework.web.bind.annotation.*
+import springfox.documentation.annotations.ApiIgnore
+import javax.servlet.http.HttpServletResponse
+
+@Api(tags = ["缁煎悎椋庨櫓API鎺ュ彛"])
+@RestController
+@RequestMapping("/risk")
+class RiskController(private val riskService: RiskService){
+
+    @ApiOperation(value = "鑾峰彇浼佷笟椋庨櫓")
+    @PostMapping("/search")
+    fun searchRiskList(
+        @ApiParam("鐢ㄦ埛id") @RequestParam("userId") userId: String,
+        @ApiParam("鏌ヨ鏉′欢") @RequestBody condition: UserSearchCondition,
+        @ApiParam("椤电爜") @RequestParam(value = "page") page: Int,
+        @ApiParam("鍗曢〉鏁版嵁閲�") @RequestParam(value = "per_page") perPage: Int,
+    ) = riskService.searchRiskList(userId, condition, page, perPage)
+
+    @ApiOperation(value = "鑾峰彇浼佷笟椋庨櫓鏁伴噺缁熻")
+    @PostMapping("/count")
+    fun getRiskCount(
+        @ApiParam(value = "鐢ㄦ埛id") @RequestParam("userId") userId: String,
+        @ApiParam("鏌ヨ鏉′欢") @RequestBody condition: UserSearchCondition,
+    ) = riskService.getRiskCount(userId, condition)
+
+    @ApiOperation(value = "鑾峰彇鐢ㄦ埛鍚堣椋庨櫓璇︽儏")
+    @GetMapping("/detail")
+    fun getRiskInfo(
+        @ApiParam(value = "鐢ㄦ埛id") @RequestParam("userId") userId: String,
+        @ApiParam(value = "鍛ㄦ湡") @RequestParam(value = "period", required = false) period: String?
+    ) = riskService.getRiskInfo(userId, period)
+
+    @ApiOperation(value = "涓嬭浇鐢ㄦ埛鍚堣椋庨櫓璇︽儏")
+    @GetMapping("/detail/download")
+    fun downloadRiskInfo(
+        @ApiParam(value = "鍖哄幙") @RequestParam district: String,
+        @ApiParam(value = "鍦烘櫙绫诲瀷") @RequestParam sceneType: String,
+        @ApiParam(value = "骞�") @RequestParam year: Int,
+        @ApiParam(value = "鏈�") @RequestParam month: Int,
+        @ApiIgnore response: HttpServletResponse,
+    ) = riskService.downloadRiskInfo(district, sceneType, year, month, response)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/ScheduleController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/ScheduleController.kt
new file mode 100644
index 0000000..de47d74
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/ScheduleController.kt
@@ -0,0 +1,34 @@
+package cn.flightfeather.supervision.lightshare.web
+
+import cn.flightfeather.supervision.lightshare.service.ScheduleService
+import cn.flightfeather.supervision.lightshare.vo.ScheduleOption
+import io.swagger.annotations.Api
+import io.swagger.annotations.ApiOperation
+import io.swagger.annotations.ApiParam
+import org.springframework.web.bind.annotation.*
+
+@Api(tags = ["鐜繚鏃ョ▼API鎺ュ彛"])
+@RestController
+@RequestMapping("/schedule")
+class ScheduleController(private val scheduleService: ScheduleService){
+
+    @ApiOperation(value = "鑾峰彇鏌愮绫诲瀷鐨勬棩绋�")
+    @PostMapping("/get")
+    fun getSchedules(
+        @ApiParam("鏃ョ▼鏌ヨ鍙傛暟") @RequestBody option: ScheduleOption,
+    ) = scheduleService.getSchedules(option)
+
+    @ApiOperation(value = "鐢ㄦ埛瀹屾垚鏌愰」鏃ョ▼")
+    @PostMapping("/complete")
+    fun completeSchedule(
+        @ApiParam("鐢ㄦ埛id") @RequestParam userId: String,
+        @ApiParam("鏃ョ▼id") @RequestParam id: Int,
+    ) = scheduleService.completeSchedule(userId, id)
+
+    @ApiOperation(value = "鐢ㄦ埛鎾ら攢鏌愰」鏃ョ▼鐨勫畬鎴愮姸鎬�")
+    @PostMapping("/revoke")
+    fun revokeSchedule(
+        @ApiParam("鐢ㄦ埛id") @RequestParam userId: String,
+        @ApiParam("瀹屾垚璁板綍id") @RequestParam recordId: Int,
+    ) = scheduleService.revokeSchedule(userId, recordId)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/SelfPatrolController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/SelfPatrolController.kt
new file mode 100644
index 0000000..55fda86
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/SelfPatrolController.kt
@@ -0,0 +1,86 @@
+package cn.flightfeather.supervision.lightshare.web
+
+import cn.flightfeather.supervision.domain.entity.Company
+import cn.flightfeather.supervision.domain.entity.PersonalInfo
+import cn.flightfeather.supervision.domain.entity.SelfPatrolTask
+import cn.flightfeather.supervision.lightshare.service.AuthService
+import cn.flightfeather.supervision.lightshare.service.SelfPatrolService
+import cn.flightfeather.supervision.lightshare.vo.AuthSceneVo
+import io.swagger.annotations.Api
+import io.swagger.annotations.ApiOperation
+import io.swagger.annotations.ApiParam
+import org.springframework.format.annotation.DateTimeFormat
+import org.springframework.web.bind.annotation.*
+import org.springframework.web.multipart.MultipartFile
+import java.util.*
+
+@Api(tags = ["搴旀�ヨ嚜宸℃煡鐩稿叧API鎺ュ彛"])
+@RestController
+@RequestMapping("/selfPatrol")
+class SelfPatrolController(val selfPatrolService: SelfPatrolService) {
+
+    @ApiOperation(value = "鑾峰彇鑷贰鏌ョ被鍨�")
+    @GetMapping("/type")
+    fun getPatrolType(
+        @ApiParam("鍦烘櫙绫诲瀷id") @RequestParam(value = "sceneType") sceneType: Int
+    ) = selfPatrolService.getPatrolType(sceneType)
+
+    @ApiOperation(value = "鍙戝竷搴旀�ヨ嚜宸℃煡浠诲姟")
+    @PostMapping("/publish")
+    fun publishTask(
+        @ApiParam("鑷贰鏌ヤ换鍔�") @RequestBody tasks: List<SelfPatrolTask>,
+    ) = selfPatrolService.publishTask(tasks)
+
+    @ApiOperation(value = "鑾峰彇璇ョ敤鎴峰彂甯冪殑鑷鏌ヤ换鍔�")
+    @GetMapping("/task/published")
+    fun getPublishedTask(
+        @ApiParam("鍙戝竷浜篿d") @RequestParam("userId") userId: String,
+        @ApiParam("鍙戝竷鏃堕棿") @RequestParam(value = "date", required = false) date: String?,
+    ) = selfPatrolService.getPublishedTask(userId, date)
+
+    @ApiOperation(value = "鑾峰彇鍙戝竷缁欒鐢ㄦ埛鐨勮嚜宸℃煡浠诲姟")
+    @GetMapping("/task/uploaded")
+    fun getToTask(
+        @ApiParam("鎺ユ敹浜篿d") @RequestParam("userId") userId: String,
+        @ApiParam("鍙戝竷鏃堕棿") @RequestParam(value = "date", required = false) date: String?,
+    ) = selfPatrolService.getToTask(userId, date)
+
+    @ApiOperation(value = "鑾峰彇鑷贰鏌ヤ换鍔$殑涓婁紶璁板綍")
+    @GetMapping("/task/record")
+    fun getTaskRecord(
+        @ApiParam("浠诲姟id") @RequestParam("taskId") taskId: String,
+    ) = selfPatrolService.getTaskRecord(taskId)
+
+    @ApiOperation(value = "涓婁紶鑷贰鏌ヤ俊鎭�")
+    @PostMapping("/task/record/upload")
+    fun uploadSelfPatrol(
+        @ApiParam("鐢ㄦ埛id") @RequestParam userId: String,
+        @ApiParam("搴旀�ヨ嚜宸℃煡浠诲姟id") @RequestParam(required = false) taskId: String?,
+        @ApiParam("鑷贰鏌ヤ俊鎭痡son") @RequestParam("params") list: String,
+        @ApiParam("鑷贰鏌ュ浘鐗�") @RequestPart("images") files: Array<MultipartFile>,
+    ) = selfPatrolService.uploadSelfPatrol(userId, taskId, list, files)
+
+    @ApiOperation("涓婁紶涓嶆秹鍙婅嚜宸℃煡")
+    @PostMapping("/task/record/upload/noInvolved")
+    fun uploadNoSelfPatrol(
+        @RequestParam("userId") userId: String,
+        @ApiParam("搴旀�ヨ嚜宸℃煡浠诲姟id") @RequestParam(required = false) taskId: String?,
+        @RequestParam("time") time: String,
+        @RequestParam(required = false) remark: String?,
+        @RequestBody idList: List<Int>,
+    ) = selfPatrolService.uploadNoSelfPatrol(userId, taskId, time, remark, idList)
+
+    @ApiOperation(value = "鑾峰彇鐢ㄦ埛鏌愮被鑷贰鏌ヨ鎯�")
+    @GetMapping("/record/detail")
+    fun getDetail(
+        @ApiParam("鐢ㄦ埛id") @RequestParam userId: String,
+        @ApiParam(value = "鑷贰鏌ュ瓙绫诲瀷id") @RequestParam subTypeId: Int,
+        @ApiParam(value = "鑷鏌ヤ换鍔d") @RequestParam taskId: String,
+    ) = selfPatrolService.getDetail(userId, subTypeId, taskId)
+
+    @ApiOperation(value = "鑾峰彇鏌愯嚜宸℃煡浠诲姟鐨勮鎯�")
+    @GetMapping("/record/details")
+    fun getDetailList(
+        @ApiParam(value = "鑷鏌ヤ换鍔d") @RequestParam taskId: String,
+    ) = selfPatrolService.getDetailList(taskId)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/UserSpecialInfoController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/UserSpecialInfoController.kt
new file mode 100644
index 0000000..4d9b57f
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/UserSpecialInfoController.kt
@@ -0,0 +1,54 @@
+package cn.flightfeather.supervision.lightshare.web
+
+import cn.flightfeather.supervision.domain.entity.BaseInfo
+import cn.flightfeather.supervision.domain.entity.RestaurantBaseInfo
+import cn.flightfeather.supervision.domain.entity.VehicleBaseInfo
+import cn.flightfeather.supervision.lightshare.service.UserSpecialInfoService
+import io.swagger.annotations.Api
+import io.swagger.annotations.ApiOperation
+import io.swagger.annotations.ApiParam
+import org.springframework.web.bind.annotation.*
+
+@Api(tags = ["鐢ㄦ埛琛屼笟鐗规畩淇℃伅鐩稿叧API鎺ュ彛"])
+@RestController
+@RequestMapping("/specialInfo")
+class UserSpecialInfoController(val specialInfoService: UserSpecialInfoService) {
+
+    /**椁愰ギ*********************************************************************/
+    @ApiOperation(value = "鏍规嵁鐢ㄦ埛id鑾峰彇鐢ㄦ埛椁愰ギ淇℃伅")
+    @GetMapping("/rest/{id}")
+    fun getRestaurantById(
+        @ApiParam("鐢ㄦ埛id") @PathVariable id: String
+    ) = specialInfoService.findOneRestaurant(id)
+
+    @ApiOperation(value = "鍒涘缓椁愰ギ琛屼笟淇℃伅")
+    @PutMapping("/rest")
+    fun saveRestaurant(
+        @ApiParam("椁愰ギ琛屼笟淇℃伅") @RequestBody baseInfo: RestaurantBaseInfo,
+    ) = specialInfoService.saveRestaurant(baseInfo)
+
+    @ApiOperation(value = "鏇存柊椁愰ギ琛屼笟淇℃伅")
+    @PostMapping("/rest")
+    fun updateRestaurant(
+        @ApiParam("椁愰ギ琛屼笟淇℃伅") @RequestBody baseInfo: RestaurantBaseInfo
+    ) = specialInfoService.updateRestaurant(baseInfo)
+
+    /**姹戒慨*********************************************************************/
+    @ApiOperation(value = "鏍规嵁鐢ㄦ埛id鑾峰彇鐢ㄦ埛姹戒慨淇℃伅")
+    @GetMapping("/vehicle/{id}")
+    fun getVehicleRepairById(
+        @ApiParam("鐢ㄦ埛id") @PathVariable id: String
+    ) = specialInfoService.findOneVehicleRepair(id)
+
+    @ApiOperation(value = "鍒涘缓姹戒慨琛屼笟淇℃伅")
+    @PutMapping("/vehicle")
+    fun saveVehicleRepair(
+        @ApiParam("姹戒慨琛屼笟淇℃伅") @RequestBody baseInfo: VehicleBaseInfo,
+    ) = specialInfoService.saveVehicleRepair(baseInfo)
+
+    @ApiOperation(value = "鏇存柊姹戒慨琛屼笟淇℃伅")
+    @PostMapping("/vehicle")
+    fun updateVehicleRepair(
+        @ApiParam("姹戒慨琛屼笟淇℃伅") @RequestBody baseInfo: VehicleBaseInfo
+    ) = specialInfoService.updateVehicleRepair(baseInfo)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/UserinfoController.kt b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/UserinfoController.kt
index d69f90d..e29bba6 100644
--- a/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/UserinfoController.kt
+++ b/src/main/kotlin/cn/flightfeather/supervision/lightshare/web/UserinfoController.kt
@@ -3,6 +3,7 @@
 import cn.flightfeather.supervision.domain.entity.Userinfo
 import cn.flightfeather.supervision.lightshare.service.UserinfoService
 import cn.flightfeather.supervision.lightshare.vo.LoginRequestVo
+import cn.flightfeather.supervision.lightshare.vo.UserBaseInfo
 import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
 import io.swagger.annotations.Api
 import io.swagger.annotations.ApiOperation
@@ -29,6 +30,18 @@
     fun add(
         @ApiParam("鐢ㄦ埛淇℃伅") @RequestBody userinfo: Userinfo
     ) = userinfoService.save(userinfo)
+
+    @ApiOperation(value = "涓婁紶鐢ㄦ埛淇℃伅(鏇磋缁�)")
+    @PutMapping("/create")
+    fun add2(
+        @ApiParam("鐢ㄦ埛淇℃伅") @RequestBody info: UserBaseInfo
+    ) = userinfoService.save2(info)
+
+    @ApiOperation(value = "閲嶇疆鐢ㄦ埛瀵嗙爜")
+    @PostMapping("/resetPw")
+    fun resetPassword(
+        @ApiParam("鐢ㄦ埛id") @RequestParam userId: String
+    ) = userinfoService.resetPassword(userId)
 
     @ApiOperation(value = "鏇存柊鐢ㄦ埛淇℃伅")
     @PostMapping("")
@@ -104,4 +117,11 @@
         @ApiParam("椤电爜") @RequestParam(value = "page") page: Int,
         @ApiParam("鍗曢〉鏁版嵁閲�") @RequestParam(value = "per_page") perPage: Int,
     ) = userinfoService.search(district, sceneType, userType, page, perPage)
+
+    @ApiOperation(value = "鑾峰彇鏌愪釜鍖哄幙鏌愪釜鍦烘櫙鐨勮繍钀ュ満鏅粺璁�")
+    @PostMapping("/count")
+    fun getSceneCount(
+            @ApiParam("鐢ㄦ埛id") @RequestParam("userId") userId: String,
+            @ApiParam("鏌ヨ鏉′欢") @RequestBody condition: UserSearchCondition,
+    ) = userinfoService.getSceneCount(userId, condition)
 }
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/scheduler/ScheduleService.kt b/src/main/kotlin/cn/flightfeather/supervision/scheduler/ScheduleService.kt
new file mode 100644
index 0000000..9c199ba
--- /dev/null
+++ b/src/main/kotlin/cn/flightfeather/supervision/scheduler/ScheduleService.kt
@@ -0,0 +1,57 @@
+package cn.flightfeather.supervision.scheduler
+
+import cn.flightfeather.supervision.bgtask.TaskJinAnHourlyDustData
+import cn.flightfeather.supervision.bgtask.maintenance.MTJinAnHourlyDustData
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.springframework.beans.factory.annotation.Value
+import org.springframework.scheduling.annotation.Async
+import org.springframework.scheduling.annotation.Scheduled
+import org.springframework.stereotype.Component
+import java.time.LocalDateTime
+
+/**
+ * 瀹氭椂浠诲姟璋冨害
+ * 涓�涓猚ron琛ㄨ揪寮忔湁鑷冲皯6涓紙涔熷彲鑳�7涓級鏈夌┖鏍煎垎闅旂殑鏃堕棿鍏冪礌銆傛寜椤哄簭渚濇涓猴細
+ * 绉掞紙0~59锛�
+ * 鍒嗛挓锛�0~59锛�
+ * 灏忔椂锛�0~23锛�
+ * 澶╋紙0~31锛�
+ * 鏈堬紙0~11锛�
+ * 鏄熸湡锛�1~7 1=SUN 鎴� SUN锛孧ON锛孴UE锛學ED锛孴HU锛孎RI锛孲AT锛�
+ * 骞翠唤锛�1970锛�2099锛�
+ */
+@Component
+class ScheduleService(
+    @Value("\${mode}") var mode: String,
+    private val taskJinAnHourlyDustData: TaskJinAnHourlyDustData,
+    private val mTaskJinAnHourlyDustData: MTJinAnHourlyDustData,
+) {
+    val logger: Logger = LoggerFactory.getLogger(ScheduleService::class.java)
+
+    @Async
+    @Scheduled(cron = "0 0 * * * *")
+    fun eachHour() {
+        if (mode != "proapp") return
+        logger.info("=====>>>>>姣忓皬鏃朵换鍔℃墽琛� {}", System.currentTimeMillis())
+        taskJinAnHourlyDustData.doTask(LocalDateTime.now())
+        logger.info("=====>>>>>姣忓皬鏃朵换鍔$粨鏉� {}", System.currentTimeMillis())
+    }
+
+//    @Async
+//    @Scheduled(cron = "0 0 0 * * *")
+    fun eachDay() {
+        logger.info("=====>>>>>姣忔棩浠诲姟鎵ц {}", System.currentTimeMillis())
+
+        logger.info("=====>>>>>姣忔棩浠诲姟缁撴潫 {}", System.currentTimeMillis())
+    }
+
+    @Async
+    @Scheduled(cron = "0 0 0 * * SUN")
+    fun eachSunday() {
+        if (mode != "proapp") return
+        logger.info("=====>>>>>姣忓懆鏃ラ浂鐐逛换鍔℃墽琛� {}", System.currentTimeMillis())
+        mTaskJinAnHourlyDustData.handle()
+        logger.info("=====>>>>>姣忓懆鏃ラ浂鐐逛换鍔$粨鏉� {}", System.currentTimeMillis())
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/timingtask/FetchVOC.kt b/src/main/kotlin/cn/flightfeather/supervision/timingtask/FetchVOC.kt
deleted file mode 100644
index 5e4c86b..0000000
--- a/src/main/kotlin/cn/flightfeather/supervision/timingtask/FetchVOC.kt
+++ /dev/null
@@ -1,113 +0,0 @@
-package cn.flightfeather.supervision.timingtask
-
-import cn.flightfeather.supervision.common.net.VOCHttpService
-import cn.flightfeather.supervision.domain.entity.DeviceInfo
-import cn.flightfeather.supervision.domain.entity.VOCHourValue
-import cn.flightfeather.supervision.domain.enumeration.DistrictType
-import cn.flightfeather.supervision.domain.enumeration.SceneType
-import cn.flightfeather.supervision.domain.mapper.DeviceInfoMapper
-import cn.flightfeather.supervision.domain.mapper.VOCHourValueMapper
-import cn.flightfeather.supervision.infrastructure.utils.DateUtil
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.stereotype.Component
-import tk.mybatis.mapper.entity.Example
-import java.time.LocalDateTime
-import java.util.*
-import javax.annotation.PostConstruct
-
-/**
- * 鑾峰彇voc鐩戞祴鏁版嵁
- */
-@Component
-class FetchVOC : BaseTimingTask() {
-    companion object {
-        private lateinit var instance: FetchVOC
-    }
-
-    @Autowired
-    lateinit var deviceInfoMapper: DeviceInfoMapper
-
-    @Autowired
-    lateinit var vocHourValueMapper: VOCHourValueMapper
-
-    @PostConstruct
-    fun init() {
-        instance = this
-    }
-
-    override val period: Long
-        get() = 15L
-
-    override fun doTask(localtime:LocalDateTime) {
-        getVOCData()
-    }
-
-    private fun getVOCData() {
-        val deviceCodeList = mutableListOf<String>()
-        deviceInfoMapper.selectByExample(Example(DeviceInfo::class.java).apply {
-            createCriteria().andEqualTo("diProvinceCode", "31")
-                .andEqualTo("diCityCode", "3100")
-                .andEqualTo("diDistrictCode", DistrictType.XuHui.code)
-                .andEqualTo("diSceneTypeId", SceneType.VehicleRepair.value)
-                .andEqualTo("diDeviceTypeId", 1)
-        }).forEach {
-            it?.let {
-                deviceCodeList.add(it.diCode)
-            }
-        }
-
-        val cal = Calendar.getInstance(Locale.CHINA).apply {
-            set(Calendar.MINUTE, 0)
-            set(Calendar.SECOND, 0)
-        }
-        val endTime = DateUtil.DateToString(cal.time, "yyyy-MM-dd HH:mm:ss") ?: ""
-        cal.add(Calendar.HOUR_OF_DAY, -1)
-        val startTime = DateUtil.DateToString(cal.time, "yyyy-MM-dd HH:mm:ss") ?: ""
-
-        deviceCodeList.forEach {
-            val deviceInfo = VOCHttpService.DeviceInfo(listOf(it), startTime, endTime)
-//            threadPoo?.execute {
-                VOCHttpService.getVOCData(deviceInfo)?.run {
-                    try {
-                        if (this["code"].asInt == 200) {
-                            val data = this["data"].asJsonObject
-                            data["rtdMinuteHourDayBeans"].asJsonArray.forEach {e ->
-                                e.asJsonObject.let { o->
-                                    val hourValue = VOCHourValue()
-
-                                    hourValue.vocStatCode = o["deviceCode"].asString
-
-                                    val collectTime = o["collectTime"].asString
-                                    hourValue.vocDataTime = DateUtil.StringToDate(collectTime)
-
-                                    o["minuteHourDayValueBeans"].asJsonArray.forEach {e1 ->
-                                        e1.asJsonObject.let {o1 ->
-                                            when (o1["factorCode"].asString) {
-                                                "e70201" -> hourValue.vocFanElectricity1 = o1["factorAvg"].asDouble
-                                                "e70202" -> hourValue.vocFanElectricity2 = o1["factorAvg"].asDouble
-                                                "e70203" -> hourValue.vocFanElectricity3 = o1["factorAvg"].asDouble
-                                                "e70204" -> hourValue.vocFanElectricity4 = o1["factorAvg"].asDouble
-                                                "e70205" -> hourValue.vocFanElectricity5 = o1["factorAvg"].asDouble
-                                                "e70206" -> hourValue.vocFanElectricity6 = o1["factorAvg"].asDouble
-                                                "g29001" -> hourValue.vocValue = o1["factorAvg"].asDouble
-                                            }
-                                        }
-                                    }
-                                    val r = vocHourValueMapper.selectByExample(Example(VOCHourValue::class.java).apply {
-                                        createCriteria().andEqualTo("vocDataTime", hourValue.vocDataTime)
-                                                .andEqualTo("vocStatCode", it)
-                                    })
-                                    if (r.isEmpty()) {
-                                        vocHourValueMapper.insertSelective(hourValue)
-                                    }
-                                }
-                            }
-                        }
-                    } catch (e: Throwable) {
-                        e.printStackTrace()
-                    }
-                }
-//            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/timingtask/PushFume.kt b/src/main/kotlin/cn/flightfeather/supervision/timingtask/PushFume.kt
deleted file mode 100644
index b2e4007..0000000
--- a/src/main/kotlin/cn/flightfeather/supervision/timingtask/PushFume.kt
+++ /dev/null
@@ -1,163 +0,0 @@
-package cn.flightfeather.supervision.timingtask
-
-import cn.flightfeather.supervision.common.net.FumeHttpService
-import cn.flightfeather.supervision.domain.entity.DeviceInfo
-import cn.flightfeather.supervision.domain.entity.FumeMinuteValue
-import cn.flightfeather.supervision.domain.enumeration.DistrictType
-import cn.flightfeather.supervision.domain.enumeration.SceneType
-import cn.flightfeather.supervision.domain.mapper.DeviceInfoMapper
-import cn.flightfeather.supervision.domain.mapper.FumeMinuteValueMapper
-import cn.flightfeather.supervision.infrastructure.utils.DateUtil
-import com.github.pagehelper.PageHelper
-import org.slf4j.LoggerFactory
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.stereotype.Component
-import tk.mybatis.mapper.entity.Example
-import java.time.LocalDateTime
-import java.time.LocalTime
-import java.time.ZoneId
-import java.time.ZoneOffset
-import java.time.format.DateTimeFormatter
-import java.util.*
-import javax.annotation.PostConstruct
-import kotlin.math.round
-
-/**
- * 涓婁紶娌圭儫鐩戞祴鏁版嵁
- */
-@Component
-class PushFume : BaseTimingTask() {
-
-    companion object {
-//        private lateinit var instance: PushFume
-        val LOGGER = LoggerFactory.getLogger(PushFume::class.java)
-    }
-
-    @Autowired
-    lateinit var deviceInfoMapper: DeviceInfoMapper
-
-    @Autowired
-    lateinit var fumeMinuteValueMapper: FumeMinuteValueMapper
-
-//    @PostConstruct
-//    fun init() {
-//        instance = this
-//    }
-
-    private val deviceCodeList = mutableListOf<String>()
-
-    override val period: Long
-        get() = 1L
-
-    override fun doTask(localtime: LocalDateTime) {
-        LOGGER.info("===========寮�濮嬫墽琛屾补鐑熸暟鎹笂浼犱换鍔�===============")
-        // 鍒锋柊鐩戞祴鐐圭紪鍙�
-        refreshDeviceCode()
-
-        //姣�10鍒嗛挓璁$畻涓�娆″钩鍧囧�煎苟涓婁紶
-        // FIXME: 2021/4/8 鍧囧�肩殑璁$畻閫昏緫涔嬪悗搴旇鏀惧埌鍏朵粬妯″潡
-        val min = localtime.minute
-        if (min != 0 && min != 10 && min != 20 && min != 30 && min != 40 && min != 50) return
-
-        //璁$畻鍙栧�兼椂闂�
-        val endTime = Date.from(localtime.minusMinutes(1).withSecond(59).atZone(ZoneId.systemDefault()).toInstant())
-        val startTime = Date.from(localtime.minusMinutes(10).withSecond(0).atZone(ZoneId.systemDefault()).toInstant())
-
-        //鐢熸垚涓婁紶鏁版嵁缁撴瀯浣�
-        val postData = FumeHttpService.PostData()
-        val allData = mutableListOf<FumeMinuteValue>()
-        deviceCodeList.forEach {
-            //鑾峰彇鍓�10鍒嗛挓鐨勬暟鎹�
-            val dataList = fumeMinuteValueMapper.selectByExample(Example(FumeMinuteValue::class.java).apply {
-                createCriteria().andEqualTo("mvStatCode", it)
-                        .andBetween("mvCreateTime", startTime, endTime)
-                and(createCriteria().orIsNull("mvUpload")
-                        .orEqualTo("mvUpload", false))
-            })
-
-            //璁$畻鍧囧��
-            var count = 0
-            var total = 0.0
-            dataList.forEach {
-                total += it.mvFumeConcentration2
-                if (it.mvFumeConcentration2 != 0.0) {
-                    count++
-                }
-            }
-            if (count == 0) {
-                dataUpdate(dataList)
-                return@forEach
-            }
-            val average = round(total / count * 100) / 100
-
-            //鍧囧�肩瓑浜�0锛屼笉涓婃姤锛岀洿鎺ユ洿鏂颁笂浼犵姸鎬�
-            if (average == 0.0) {
-                dataUpdate(dataList)
-                return@forEach
-            }
-
-            //鐢熸垚涓婁紶鏁版嵁缁撴瀯浣�
-            dataList.last().let {
-                postData.data.add(FumeHttpService.FumeData(
-                        "hengzhiyuan_${it.mvStatCode}",
-                    DateUtil.DateToString(startTime, DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS),
-                        0.0, average,
-                        if (it.mvFanStatus) 3 else 2,
-                        it.mvFanElectricity, 0,
-                        if (it.mvPurifierStatus) 3 else 2,
-                        it.mvPurifierElectricity, 0,
-                        0, 0.0
-                ))
-            }
-
-            allData.addAll(dataList)
-        }
-
-        //涓婁紶鏁版嵁骞舵洿鏂版暟鎹姸鎬�
-        LOGGER.info("===========鏁版嵁閲囨牱鏃堕棿锛�$localtime")
-        postData.data.forEach {
-            LOGGER.info("${it.equipmentShowId}   **   ${it.dataTime}")
-        }
-        LOGGER.info("=================================")
-        FumeHttpService.uploadData(postData)?.run {
-            LOGGER.info(this.toString())
-            if (this["code"].asInt == 0 && this["data"].asInt > 0) {
-                dataUpdate(allData)
-            }
-            LOGGER.info("===========娌圭儫鏁版嵁涓婁紶浠诲姟缁撴潫============")
-        }
-    }
-
-    /**
-     * 鍒锋柊鐩戞祴鐐圭紪鍙�
-     */
-    @Synchronized
-    private fun refreshDeviceCode() {
-        val now = LocalDateTime.now()
-        if (deviceCodeList.isEmpty() || (now.hour == 0 && now.minute <= period)) {
-            deviceCodeList.clear()
-            deviceInfoMapper.selectByExample(Example(DeviceInfo::class.java).apply {
-                createCriteria().andEqualTo("diProvinceCode", "31")
-                        .andEqualTo("diCityCode", "3100")
-                        .andEqualTo("diDistrictCode", DistrictType.XuHui.code)
-                        .andEqualTo("diSceneTypeId", SceneType.Restaurant.value)
-                        .andEqualTo("diDeviceTypeId", 1)
-                        .andEqualTo("diSupplier", "hengzhiyuan")
-            }).forEach {
-                it?.let {
-                    deviceCodeList.add(it.diCode)
-                }
-            }
-        }
-    }
-
-    /**
-     * 鏇存柊鏁版嵁鐘舵��
-     */
-    private fun dataUpdate(dataList: List<FumeMinuteValue>) {
-        dataList.forEach {
-            it.mvUpload = true
-            fumeMinuteValueMapper.updateByPrimaryKey(it)
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskFetchVOC.kt b/src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskFetchVOC.kt
deleted file mode 100644
index 788b89e..0000000
--- a/src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskFetchVOC.kt
+++ /dev/null
@@ -1,113 +0,0 @@
-package cn.flightfeather.supervision.timingtask
-
-import cn.flightfeather.supervision.common.net.VOCHttpService
-import cn.flightfeather.supervision.domain.entity.DeviceInfo
-import cn.flightfeather.supervision.domain.entity.VOCHourValue
-import cn.flightfeather.supervision.domain.enumeration.DistrictType
-import cn.flightfeather.supervision.domain.enumeration.SceneType
-import cn.flightfeather.supervision.domain.mapper.DeviceInfoMapper
-import cn.flightfeather.supervision.domain.mapper.VOCHourValueMapper
-import cn.flightfeather.supervision.infrastructure.utils.DateUtil
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.stereotype.Component
-import tk.mybatis.mapper.entity.Example
-import java.time.LocalDateTime
-import java.util.*
-import javax.annotation.PostConstruct
-
-/**
- * 鑾峰彇voc鐩戞祴鏁版嵁
- */
-@Component
-class TaskFetchVOC : BaseTimingTask() {
-    companion object {
-        private lateinit var instance: TaskFetchVOC
-    }
-
-    @Autowired
-    lateinit var deviceInfoMapper: DeviceInfoMapper
-
-    @Autowired
-    lateinit var vocHourValueMapper: VOCHourValueMapper
-
-    @PostConstruct
-    fun init() {
-        instance = this
-    }
-
-    override val period: Long
-        get() = 15L
-
-    override fun doTask(localtime:LocalDateTime) {
-        getVOCData()
-    }
-
-    private fun getVOCData() {
-        val deviceCodeList = mutableListOf<String>()
-        deviceInfoMapper.selectByExample(Example(DeviceInfo::class.java).apply {
-            createCriteria().andEqualTo("diProvinceCode", "31")
-                .andEqualTo("diCityCode", "3100")
-                .andEqualTo("diDistrictCode", DistrictType.XuHui.code)
-                .andEqualTo("diSceneTypeId", SceneType.VehicleRepair.value)
-                .andEqualTo("diDeviceTypeId", 1)
-        }).forEach {
-            it?.let {
-                deviceCodeList.add(it.diCode)
-            }
-        }
-
-        val cal = Calendar.getInstance(Locale.CHINA).apply {
-            set(Calendar.MINUTE, 0)
-            set(Calendar.SECOND, 0)
-        }
-        val endTime = DateUtil.DateToString(cal.time, "yyyy-MM-dd HH:mm:ss") ?: ""
-        cal.add(Calendar.HOUR_OF_DAY, -1)
-        val startTime = DateUtil.DateToString(cal.time, "yyyy-MM-dd HH:mm:ss") ?: ""
-
-        deviceCodeList.forEach {
-            val deviceInfo = VOCHttpService.DeviceInfo(listOf(it), startTime, endTime)
-//            threadPoo?.execute {
-                VOCHttpService.getVOCData(deviceInfo)?.run {
-                    try {
-                        if (this["code"].asInt == 200) {
-                            val data = this["data"].asJsonObject
-                            data["rtdMinuteHourDayBeans"].asJsonArray.forEach {e ->
-                                e.asJsonObject.let { o->
-                                    val hourValue = VOCHourValue()
-
-                                    hourValue.vocStatCode = o["deviceCode"].asString
-
-                                    val collectTime = o["collectTime"].asString
-                                    hourValue.vocDataTime = DateUtil.StringToDate(collectTime)
-
-                                    o["minuteHourDayValueBeans"].asJsonArray.forEach {e1 ->
-                                        e1.asJsonObject.let {o1 ->
-                                            when (o1["factorCode"].asString) {
-                                                "e70201" -> hourValue.vocFanElectricity1 = o1["factorAvg"].asDouble
-                                                "e70202" -> hourValue.vocFanElectricity2 = o1["factorAvg"].asDouble
-                                                "e70203" -> hourValue.vocFanElectricity3 = o1["factorAvg"].asDouble
-                                                "e70204" -> hourValue.vocFanElectricity4 = o1["factorAvg"].asDouble
-                                                "e70205" -> hourValue.vocFanElectricity5 = o1["factorAvg"].asDouble
-                                                "e70206" -> hourValue.vocFanElectricity6 = o1["factorAvg"].asDouble
-                                                "g29001" -> hourValue.vocValue = o1["factorAvg"].asDouble
-                                            }
-                                        }
-                                    }
-                                    val r = vocHourValueMapper.selectByExample(Example(VOCHourValue::class.java).apply {
-                                        createCriteria().andEqualTo("vocDataTime", hourValue.vocDataTime)
-                                                .andEqualTo("vocStatCode", it)
-                                    })
-                                    if (r.isEmpty()) {
-                                        vocHourValueMapper.insertSelective(hourValue)
-                                    }
-                                }
-                            }
-                        }
-                    } catch (e: Throwable) {
-                        e.printStackTrace()
-                    }
-                }
-//            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskPushFume.kt b/src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskPushFume.kt
deleted file mode 100644
index 26ded0e..0000000
--- a/src/main/kotlin/cn/flightfeather/supervision/timingtask/TaskPushFume.kt
+++ /dev/null
@@ -1,158 +0,0 @@
-package cn.flightfeather.supervision.timingtask
-
-import cn.flightfeather.supervision.common.net.FumeHttpService
-import cn.flightfeather.supervision.domain.entity.DeviceInfo
-import cn.flightfeather.supervision.domain.entity.FumeMinuteValue
-import cn.flightfeather.supervision.domain.enumeration.DistrictType
-import cn.flightfeather.supervision.domain.enumeration.SceneType
-import cn.flightfeather.supervision.domain.mapper.DeviceInfoMapper
-import cn.flightfeather.supervision.domain.mapper.FumeMinuteValueMapper
-import cn.flightfeather.supervision.infrastructure.utils.DateUtil
-import org.slf4j.LoggerFactory
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.stereotype.Component
-import tk.mybatis.mapper.entity.Example
-import java.time.LocalDateTime
-import java.time.ZoneId
-import java.util.*
-import kotlin.math.round
-
-/**
- * 涓婁紶娌圭儫鐩戞祴鏁版嵁
- */
-@Component
-class TaskPushFume : BaseTimingTask() {
-
-    companion object {
-//        private lateinit var instance: PushFume
-        val LOGGER = LoggerFactory.getLogger(TaskPushFume::class.java)
-    }
-
-    @Autowired
-    lateinit var deviceInfoMapper: DeviceInfoMapper
-
-    @Autowired
-    lateinit var fumeMinuteValueMapper: FumeMinuteValueMapper
-
-//    @PostConstruct
-//    fun init() {
-//        instance = this
-//    }
-
-    private val deviceCodeList = mutableListOf<String>()
-
-    override val period: Long
-        get() = 1L
-
-    override fun doTask(localtime: LocalDateTime) {
-        //姣�10鍒嗛挓璁$畻涓�娆″钩鍧囧�煎苟涓婁紶
-        // FIXME: 2021/4/8 鍧囧�肩殑璁$畻閫昏緫涔嬪悗搴旇鏀惧埌鍏朵粬妯″潡
-        val min = localtime.minute
-        if (min != 0 && min != 10 && min != 20 && min != 30 && min != 40 && min != 50) return
-
-        LOGGER.info("===========寮�濮嬫墽琛屾补鐑熸暟鎹笂浼犱换鍔�===============")
-        // 鍒锋柊鐩戞祴鐐圭紪鍙�
-        refreshDeviceCode()
-
-        //璁$畻鍙栧�兼椂闂�
-        val endTime = Date.from(localtime.minusMinutes(1).withSecond(59).atZone(ZoneId.systemDefault()).toInstant())
-        val startTime = Date.from(localtime.minusMinutes(10).withSecond(0).atZone(ZoneId.systemDefault()).toInstant())
-
-        //鐢熸垚涓婁紶鏁版嵁缁撴瀯浣�
-        val postData = FumeHttpService.PostData()
-        val allData = mutableListOf<FumeMinuteValue>()
-        deviceCodeList.forEach {
-            //鑾峰彇鍓�10鍒嗛挓鐨勬暟鎹�
-            val dataList = fumeMinuteValueMapper.selectByExample(Example(FumeMinuteValue::class.java).apply {
-                createCriteria().andEqualTo("mvStatCode", it)
-                        .andBetween("mvCreateTime", startTime, endTime)
-                and(createCriteria().orIsNull("mvUpload")
-                        .orEqualTo("mvUpload", false))
-            })
-
-            //璁$畻鍧囧��
-            var count = 0
-            var total = 0.0
-            dataList.forEach {
-                total += it.mvFumeConcentration2
-                if (it.mvFumeConcentration2 != 0.0) {
-                    count++
-                }
-            }
-            if (count == 0) {
-                dataUpdate(dataList)
-                return@forEach
-            }
-            val average = round(total / count * 100) / 100
-
-            //鍧囧�肩瓑浜�0锛屼笉涓婃姤锛岀洿鎺ユ洿鏂颁笂浼犵姸鎬�
-            if (average == 0.0) {
-                dataUpdate(dataList)
-                return@forEach
-            }
-
-            //鐢熸垚涓婁紶鏁版嵁缁撴瀯浣�
-            dataList.last().let {
-                postData.data.add(FumeHttpService.FumeData(
-                        "hengzhiyuan_${it.mvStatCode}",
-                    DateUtil.DateToString(startTime, DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS),
-                        0.0, average,
-                        if (it.mvFanStatus) 3 else 2,
-                        it.mvFanElectricity, 0,
-                        if (it.mvPurifierStatus) 3 else 2,
-                        it.mvPurifierElectricity, 0,
-                        0, 0.0
-                ))
-            }
-
-            allData.addAll(dataList)
-        }
-
-        //涓婁紶鏁版嵁骞舵洿鏂版暟鎹姸鎬�
-        LOGGER.info("===========鏁版嵁閲囨牱鏃堕棿锛�$localtime")
-        postData.data.forEach {
-            LOGGER.info("${it.equipmentShowId}   **   ${it.dataTime}")
-        }
-        LOGGER.info("=================================")
-        FumeHttpService.uploadData(postData)?.run {
-            LOGGER.info(this.toString())
-            if (this["code"].asInt == 0 && this["data"].asInt > 0) {
-                dataUpdate(allData)
-            }
-            LOGGER.info("===========娌圭儫鏁版嵁涓婁紶浠诲姟缁撴潫============")
-        }
-    }
-
-    /**
-     * 鍒锋柊鐩戞祴鐐圭紪鍙�
-     */
-    @Synchronized
-    private fun refreshDeviceCode() {
-        val now = LocalDateTime.now()
-        if (deviceCodeList.isEmpty() || (now.hour == 0 && now.minute <= period)) {
-            deviceCodeList.clear()
-            deviceInfoMapper.selectByExample(Example(DeviceInfo::class.java).apply {
-                createCriteria().andEqualTo("diProvinceCode", "31")
-                        .andEqualTo("diCityCode", "3100")
-                        .andEqualTo("diDistrictCode", DistrictType.XuHui.code)
-                        .andEqualTo("diSceneTypeId", SceneType.Restaurant.value)
-                        .andEqualTo("diDeviceTypeId", 1)
-                        .andEqualTo("diSupplier", "hengzhiyuan")
-            }).forEach {
-                it?.let {
-                    deviceCodeList.add(it.diCode)
-                }
-            }
-        }
-    }
-
-    /**
-     * 鏇存柊鏁版嵁鐘舵��
-     */
-    private fun dataUpdate(dataList: List<FumeMinuteValue>) {
-        dataList.forEach {
-            it.mvUpload = true
-            fumeMinuteValueMapper.updateByPrimaryKey(it)
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index 15211b4..d3fb755 100644
--- a/src/main/resources/application-dev.yml
+++ b/src/main/resources/application-dev.yml
@@ -1,4 +1,14 @@
-name: dev
+spring:
+  datasource:
+    # 灞�鍩熺綉娴嬭瘯
+    #    url: jdbc:mysql://192.168.0.200:3306/ledger?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
+    #    username: root
+    #    password: cn.FLIGHTFEATHER
+
+    # 鏈湴娴嬭瘯
+    url: jdbc:mysql://localhost:3306/ledger?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
+    username: root
+    password: 123456
 
 springfox:
   documentation:
@@ -6,5 +16,7 @@
       v2:
         enabled: true
 
-imgPath: images/
-filePath: D:/02product/05ledger/files/
\ No newline at end of file
+imgPath: C:\work\ideaProject\ledgerserver\target\
+filePath: D:/02product/05ledger/files/
+
+mode: dev
\ No newline at end of file
diff --git a/src/main/resources/application-pro.yml b/src/main/resources/application-pro.yml
index 9859cc9..d145b46 100644
--- a/src/main/resources/application-pro.yml
+++ b/src/main/resources/application-pro.yml
@@ -1,12 +1,13 @@
-name: pro
-
-springfox:
-  documentation:
-    swagger:
-      v2:
-        enabled: false
+spring:
+  datasource:
+    # 鍙戝竷鏈嶅姟鍣�
+    url: jdbc:mysql://localhost:3306/ledger?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&allowMultiQueries=true&useSSL=false
+    username: ledger
+    password: ledger_fxxchackxr
 
 imgPath: D:/02product/05ledger/images/
 filePath: D:/02product/05ledger/files/
 #imgPath: C:/02product/05ledger/images/
-#filePath: C:/02product/05ledger/files/
\ No newline at end of file
+#filePath: C:/02product/05ledger/files/
+
+mode: pro
\ No newline at end of file
diff --git a/src/main/resources/application-proapp.yml b/src/main/resources/application-proapp.yml
new file mode 100644
index 0000000..1ecffa8
--- /dev/null
+++ b/src/main/resources/application-proapp.yml
@@ -0,0 +1,13 @@
+spring:
+  datasource:
+    # 鍙戝竷鏈嶅姟鍣�
+    url: jdbc:mysql://localhost:3306/ledger?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&allowMultiQueries=true&useSSL=false
+    username: ledger
+    password: ledger_fxxchackxr
+
+imgPath: D:/02product/05ledger/images/
+filePath: D:/02product/05ledger/files/
+
+#閽堝寰俊灏忕▼搴忓拰瀹夊崜app涓ょ鍓嶇锛岀洰鍓嶆湁閮ㄥ垎鍖哄埆锛宼rue锛氳〃绀篴pp锛宖alse锛氳〃绀哄皬绋嬪簭
+systemIsApp: true
+mode: proapp
\ No newline at end of file
diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml
new file mode 100644
index 0000000..f666cf3
--- /dev/null
+++ b/src/main/resources/application-test.yml
@@ -0,0 +1,22 @@
+spring:
+  datasource:
+  # 114鏈嶅姟鍣�
+  #    url: jdbc:mysql://localhost:3306/ledger?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
+  #    username: feiyu_admin
+  #    password: shfyhb2021
+
+  #   寮�鍙戣繙绋嬫湇鍔″櫒
+    url: jdbc:mysql://47.100.191.150:3306/ledger?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&allowMultiQueries=true&useSSL=false
+    username: remoteU1
+    password: eSoF8DnzfGTlhAjE
+
+springfox:
+  documentation:
+    swagger:
+      v2:
+        enabled: true
+
+imgPath: images/
+filePath: D:/02product/05ledger/files/
+
+mode: test
\ No newline at end of file
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index ee08b70..4f0622c 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -2,24 +2,6 @@
   datasource:
     type: com.alibaba.druid.pool.DruidDataSource
     driver-class-name: com.mysql.jdbc.Driver
-    #-Test-
-#    url: jdbc:mysql://192.168.0.200:3306/ledger?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
-#    username: root
-#    password: cn.FLIGHTFEATHER
-
-#    url: jdbc:mysql://localhost:3306/ledger?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
-#    username: root
-#    password: 123456
-    #-TestEnd-
-
-    url: jdbc:mysql://localhost:3306/ledger?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&allowMultiQueries=true&useSSL=false
-    username: ledger
-    password: ledger_fxxchackxr
-
-    #   寮�鍙戣繙绋嬫湇鍔″櫒
-#    url: jdbc:mysql://47.100.191.150:3306/ledger?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&allowMultiQueries=true&useSSL=false
-#    username: remoteU1
-#    password: eSoF8DnzfGTlhAjE
 
     initialSize: 5
     minIdle: 5
@@ -51,8 +33,9 @@
   jackson:
     time-zone: GMT+8
 
+#鏍规嵁鐜閫夋嫨閰嶇疆
   profiles:
-    active: pro
+    active: @profileActive@
 
   jmx:
     default-domain: ledger
@@ -73,11 +56,17 @@
 logging:
     config: classpath:log4j2.xml
 
-#springfox:
-#  documentation:
-#    swagger:
-#      v2:
-#        enabled: true
+springfox:
+  documentation:
+    swagger:
+      v2:
+        enabled: false
+
 # Swagger json url address
 # etc. https://petstore.swagger.io/
-swagger.url: http://localhost:8080/v3/swagger.json
\ No newline at end of file
+swagger.url: http://localhost:8080/v3/api-docs
+# api璁块棶缃戝潃
+# api url : http://localhost:8080/swagger-ui/index.html
+
+#閽堝寰俊灏忕▼搴忓拰瀹夊崜app涓ょ鍓嶇锛岀洰鍓嶆湁閮ㄥ垎鍖哄埆锛宼rue锛氳〃绀篴pp锛宖alse锛氳〃绀哄皬绋嬪簭
+systemIsApp: false
\ No newline at end of file
diff --git a/src/main/resources/font/STSONG.TTF b/src/main/resources/font/STSONG.TTF
new file mode 100644
index 0000000..3870605
--- /dev/null
+++ b/src/main/resources/font/STSONG.TTF
Binary files differ
diff --git "a/src/main/resources/font/\346\226\271\346\255\243\345\205\260\344\272\255\350\266\205\347\273\206\351\273\221\347\256\200\344\275\223.ttf" "b/src/main/resources/font/\346\226\271\346\255\243\345\205\260\344\272\255\350\266\205\347\273\206\351\273\221\347\256\200\344\275\223.ttf"
new file mode 100644
index 0000000..8e72232
--- /dev/null
+++ "b/src/main/resources/font/\346\226\271\346\255\243\345\205\260\344\272\255\350\266\205\347\273\206\351\273\221\347\256\200\344\275\223.ttf"
Binary files differ
diff --git a/src/main/resources/generator/generatorConfig.xml b/src/main/resources/generator/generatorConfig.xml
index de7b1eb..964ddbe 100644
--- a/src/main/resources/generator/generatorConfig.xml
+++ b/src/main/resources/generator/generatorConfig.xml
@@ -64,8 +64,8 @@
         <!--<table tableName="tc_t_vmroom" domainObjectName="VMRoom" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>-->
         <!--<table tableName="ea_companyinfo" domainObjectName="Company" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>-->
         <!--<table tableName="tc_t_m_materials_sign_state" domainObjectName="MaterialSignState" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>-->
-        <table tableName="ec_t_lawsregulations" domainObjectName="LawsRegulations" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
-        <!--<table tableName="ea_t_baseinfo" domainObjectName="BaseInfo" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>-->
+<!--        <table tableName="ec_t_lawsregulations" domainObjectName="LawsRegulations" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>-->
+<!--        <table tableName="ea_t_baseinfo" domainObjectName="BaseInfo" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>-->
         <!--<table tableName="ea_t_evaluation" domainObjectName="Evaluation2" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>-->
         <!--<table tableName="ea_t_fumepurifydevice" domainObjectName="FumePurifyDevice" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>-->
 <!--        <table tableName="sm_t_monitordevice" domainObjectName="MonitorDevice" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>-->
@@ -102,6 +102,86 @@
 <!--        <table tableName="sys_log_msg_subscribe_wx" domainObjectName="LogMsgSubscribeWx" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false"-->
 <!--               enableSelectByExample="false"-->
 <!--               selectByExampleQueryId="false"/>-->
-<!--        <table tableName="sm_t_userinfo" domainObjectName="Userinfo" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
+<!--        <table tableName="sm_t_userinfo" domainObjectName="Userinfo" enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
+<!--        <table tableName="ja_t_dust_site_info" domainObjectName="DustSiteInfo" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ja_t_hour_dust_data" domainObjectName="HourDustData" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ja_t_lamp_device_data" domainObjectName="LampDeviceData" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ja_t_lamp_enter_base_info" domainObjectName="LampEnterBaseInfo" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ea_t_risk_evaluation" domainObjectName="RiskEvaluation" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="sm_t_user_config" domainObjectName="UserConfig" enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ea_t_commitment_template" domainObjectName="CommitmentTemplate" enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ea_t_schedule" domainObjectName="EnvironmentalSchedule" enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ea_t_schedule_sign_record" domainObjectName="ScheduleSignRecord" enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ea_t_self_patrol_task" domainObjectName="SelfPatrolTask" enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ea_t_self_patrol_record" domainObjectName="SelfPatrolRecord" enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ea_t_self_patrol_media_file" domainObjectName="SelfPatrolMediaFile"-->
+<!--               enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ec_t_notice_template" domainObjectName="NoticeTemplate" enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ea_t_industrial_base_info" domainObjectName="IndustrialBaseInfo"-->
+<!--               enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ea_t_voc_purify_device" domainObjectName="VocPurifyDevice"-->
+<!--               enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="sm_t_user_login_log" domainObjectName="UserLoginLog"-->
+<!--               enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ea_t_scene_type" domainObjectName="SceneType"-->
+<!--               enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ja_t_dust_site_map" domainObjectName="DustSiteMap"-->
+<!--               enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ea_t_practical_operation" domainObjectName="PracticalOperation"-->
+<!--               enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+<!--        <table tableName="ea_t_practical_operation_record" domainObjectName="PracticalOperationRecord"-->
+<!--               enableCountByExample="false"-->
+<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
+<!--               enableSelectByExample="false" selectByExampleQueryId="false" />-->
+        <table tableName="sm_t_province" domainObjectName="Province"
+               enableCountByExample="false"
+               enableUpdateByExample="false" enableDeleteByExample="false"
+               enableSelectByExample="false" selectByExampleQueryId="false" />
+        <table tableName="sm_t_city" domainObjectName="City"
+               enableCountByExample="false"
+               enableUpdateByExample="false" enableDeleteByExample="false"
+               enableSelectByExample="false" selectByExampleQueryId="false" />
+        <table tableName="sm_t_district" domainObjectName="District"
+               enableCountByExample="false"
+               enableUpdateByExample="false" enableDeleteByExample="false"
+               enableSelectByExample="false" selectByExampleQueryId="false" />
+        <table tableName="sm_t_town" domainObjectName="Town"
+               enableCountByExample="false"
+               enableUpdateByExample="false" enableDeleteByExample="false"
+               enableSelectByExample="false" selectByExampleQueryId="false" />
     </context>
 </generatorConfiguration>
\ No newline at end of file
diff --git a/src/main/resources/mapper/BaseInfoMapper.xml b/src/main/resources/mapper/BaseInfoMapper.xml
index 88f9e98..fe596f5 100644
--- a/src/main/resources/mapper/BaseInfoMapper.xml
+++ b/src/main/resources/mapper/BaseInfoMapper.xml
@@ -1,42 +1,117 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
-<mapper namespace="cn.flightfeather.supervision.domain.mapper.BaseInfoMapper" >
-  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.BaseInfo" >
-    <!--
-      WARNING - @mbg.generated
-    -->
-    <id column="BI_GUID" property="biGuid" jdbcType="VARCHAR" />
-    <result column="BI_Name" property="biName" jdbcType="VARCHAR" />
-    <result column="BI_Nick_Name" property="biNickName" jdbcType="VARCHAR" />
-    <result column="CI_GUID" property="ciGuid" jdbcType="VARCHAR" />
-    <result column="CI_Name" property="ciName" jdbcType="VARCHAR" />
-    <result column="BI_Province_Code" property="biProvinceCode" jdbcType="VARCHAR" />
-    <result column="BI_Province_Name" property="biProvinceName" jdbcType="VARCHAR" />
-    <result column="BI_City_Code" property="biCityCode" jdbcType="VARCHAR" />
-    <result column="BI_City_Name" property="biCityName" jdbcType="VARCHAR" />
-    <result column="BI_District_Code" property="biDistrictCode" jdbcType="VARCHAR" />
-    <result column="BI_District_Name" property="biDistrictName" jdbcType="VARCHAR" />
-    <result column="BI_Town_Code" property="biTownCode" jdbcType="VARCHAR" />
-    <result column="BI_Town_Name" property="biTownName" jdbcType="VARCHAR" />
-    <result column="BI_Management_Company_Id" property="biManagementCompanyId" jdbcType="VARCHAR" />
-    <result column="BI_Management_Company" property="biManagementCompany" jdbcType="VARCHAR" />
-    <result column="BI_Contact" property="biContact" jdbcType="VARCHAR" />
-    <result column="BI_Telephone" property="biTelephone" jdbcType="VARCHAR" />
-    <result column="BI_Address" property="biAddress" jdbcType="VARCHAR" />
-    <result column="BI_Create_Time" property="biCreateTime" jdbcType="TIMESTAMP" />
-    <result column="BI_Update_Time" property="biUpdateTime" jdbcType="TIMESTAMP" />
-    <result column="BI_Extension1" property="biExtension1" jdbcType="VARCHAR" />
-    <result column="BI_Extension2" property="biExtension2" jdbcType="VARCHAR" />
-    <result column="BI_Extension3" property="biExtension3" jdbcType="VARCHAR" />
-    <result column="BI_Remark" property="biRemark" jdbcType="VARCHAR" />
-  </resultMap>
-  <sql id="Base_Column_List" >
-    <!--
-      WARNING - @mbg.generated
-    -->
-    BI_GUID, BI_Name, BI_Nick_Name, CI_GUID, CI_Name, BI_Province_Code, BI_Province_Name, 
-    BI_City_Code, BI_City_Name, BI_District_Code, BI_District_Name, BI_Town_Code, BI_Town_Name, 
-    BI_Management_Company_Id, BI_Management_Company, BI_Contact, BI_Telephone, BI_Address, 
-    BI_Create_Time, BI_Update_Time, BI_Extension1, BI_Extension2, BI_Extension3, BI_Remark
-  </sql>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.BaseInfoMapper">
+    <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.BaseInfo">
+        <!--
+          WARNING - @mbg.generated
+        -->
+        <id column="BI_GUID" jdbcType="VARCHAR" property="biGuid"/>
+        <result column="BI_Name" jdbcType="VARCHAR" property="biName"/>
+        <result column="BI_Nick_Name" jdbcType="VARCHAR" property="biNickName"/>
+        <result column="CI_GUID" jdbcType="VARCHAR" property="ciGuid"/>
+        <result column="CI_Name" jdbcType="VARCHAR" property="ciName"/>
+        <result column="BI_Province_Code" jdbcType="VARCHAR" property="biProvinceCode"/>
+        <result column="BI_Province_Name" jdbcType="VARCHAR" property="biProvinceName"/>
+        <result column="BI_City_Code" jdbcType="VARCHAR" property="biCityCode"/>
+        <result column="BI_City_Name" jdbcType="VARCHAR" property="biCityName"/>
+        <result column="BI_District_Code" jdbcType="VARCHAR" property="biDistrictCode"/>
+        <result column="BI_District_Name" jdbcType="VARCHAR" property="biDistrictName"/>
+        <result column="BI_Town_Code" jdbcType="VARCHAR" property="biTownCode"/>
+        <result column="BI_Town_Name" jdbcType="VARCHAR" property="biTownName"/>
+        <result column="BI_Area_Code" jdbcType="VARCHAR" property="biAreaCode"/>
+        <result column="BI_Area" jdbcType="VARCHAR" property="biArea"/>
+        <result column="BI_Management_Company_Id" jdbcType="VARCHAR" property="biManagementCompanyId"/>
+        <result column="BI_Management_Company" jdbcType="VARCHAR" property="biManagementCompany"/>
+        <result column="BI_Contact" jdbcType="VARCHAR" property="biContact"/>
+        <result column="BI_Telephone" jdbcType="VARCHAR" property="biTelephone"/>
+        <result column="BI_Address" jdbcType="VARCHAR" property="biAddress"/>
+        <result column="BI_Create_Time" jdbcType="TIMESTAMP" property="biCreateTime"/>
+        <result column="BI_Update_Time" jdbcType="TIMESTAMP" property="biUpdateTime"/>
+        <result column="BI_Extension1" jdbcType="VARCHAR" property="biExtension1"/>
+        <result column="BI_Extension2" jdbcType="VARCHAR" property="biExtension2"/>
+        <result column="BI_Extension3" jdbcType="VARCHAR" property="biExtension3"/>
+        <result column="BI_Remark" jdbcType="VARCHAR" property="biRemark"/>
+    </resultMap>
+    <sql id="Base_Column_List">
+        <!--
+          WARNING - @mbg.generated
+        -->
+        BI_GUID, BI_Name, BI_Nick_Name, CI_GUID, CI_Name, BI_Province_Code, BI_Province_Name,
+        BI_City_Code, BI_City_Name, BI_District_Code, BI_District_Name, BI_Town_Code, BI_Town_Name,
+        BI_Area_Code, BI_Area, BI_Management_Company_Id, BI_Management_Company, BI_Contact,
+        BI_Telephone, BI_Address, BI_Create_Time, BI_Update_Time, BI_Extension1, BI_Extension2,
+        BI_Extension3, BI_Remark
+    </sql>
+
+    <resultMap id="UserMap" type="cn.flightfeather.supervision.lightshare.vo.BaseInfoVo" extends="BaseResultMap">
+        <result column="SC_Name" jdbcType="VARCHAR" property="sceneTypeName"/>
+        <association property="userInfo" resultMap="cn.flightfeather.supervision.domain.mapper.UserinfoMapper.BaseResultMap" />
+    </resultMap>
+
+    <select id="searchUser" resultMap="UserMap">
+        SELECT
+        c.SC_Name,
+        a.*,
+        b.*
+        FROM
+        sm_t_userinfo AS a
+        LEFT JOIN ea_t_baseinfo AS b ON a.UI_GUID = b.BI_GUID
+        LEFT JOIN ea_t_scene_type AS c ON a.UI_Extension2 = c.SC_Id
+        <where>
+            <if test="provinceCode != null">
+                AND b.BI_Province_Code = #{provinceCode}
+            </if>
+            <if test="provinceName != null">
+                AND b.BI_Province_Name = #{provinceName}
+            </if>
+            <if test="cityCode != null">
+                AND b.BI_City_Code = #{cityCode}
+            </if>
+            <if test="cityName != null">
+                AND b.BI_City_Name = #{cityName}
+            </if>
+            <if test="districtCode != null">
+                AND b.BI_District_Code = #{districtCode}
+            </if>
+            <if test="districtName != null">
+                AND (b.BI_District_Name = #{districtName} OR a.UI_Extension1 = #{districtName})
+            </if>
+            <if test="townCode != null">
+                AND b.BI_Town_Code = #{townCode}
+            </if>
+            <if test="townName != null">
+                AND b.BI_Town_Name = #{townName}
+            </if>
+            <if test="areaCode != null">
+                AND b.BI_Area_Code = #{areaCode}
+            </if>
+            <if test="area != null">
+                AND b.BI_Area = #{area}
+            </if>
+            <if test="mcId != null">
+                AND b.BI_Management_Company_Id = #{mcId}
+            </if>
+            <if test="mcName != null">
+                AND b.BI_Management_Company = #{mcName}
+            </if>
+            <if test="userTypeId != null">
+                AND a.UI_UserTypeID = #{userTypeId}
+            </if>
+            <if test="userSubTypeId != null">
+                AND a.UI_User_SubType_Id = #{userSubTypeId}
+            </if>
+            <if test="online != null">
+                AND a.UI_IsEnable = #{online}
+            </if>
+            <if test="sceneTypes.size() != 0">
+                AND a.UI_Extension2 in
+                <foreach collection="sceneTypes" item="type" open="(" separator="," close=")">
+                    #{type, jdbcType=VARCHAR}
+                </foreach>
+            </if>
+            <if test="searchText != null and searchText != ''">
+                AND a.UI_RealName LIKE CONCAT('%', #{searchText}, '%')
+            </if>
+        </where>
+    </select>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/CityMapper.xml b/src/main/resources/mapper/CityMapper.xml
new file mode 100644
index 0000000..554a689
--- /dev/null
+++ b/src/main/resources/mapper/CityMapper.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.CityMapper">
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.City">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="C_CityID" jdbcType="INTEGER" property="cCityid" />
+    <result column="P_PronvinceID" jdbcType="INTEGER" property="pPronvinceid" />
+    <result column="C_CityCode" jdbcType="VARCHAR" property="cCitycode" />
+    <result column="C_CityName" jdbcType="VARCHAR" property="cCityname" />
+    <result column="C_Station" jdbcType="VARCHAR" property="cStation" />
+  </resultMap>
+  <sql id="Base_Column_List">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    C_CityID, P_PronvinceID, C_CityCode, C_CityName, C_Station
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/CommitmentTemplateMapper.xml b/src/main/resources/mapper/CommitmentTemplateMapper.xml
new file mode 100644
index 0000000..fbdc09e
--- /dev/null
+++ b/src/main/resources/mapper/CommitmentTemplateMapper.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.CommitmentTemplateMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.CommitmentTemplate" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="CT_GUID" property="ctGuid" jdbcType="VARCHAR" />
+    <result column="CT_Scene_Type_Id" property="ctSceneTypeId" jdbcType="INTEGER" />
+    <result column="CT_Province_Code" property="ctProvinceCode" jdbcType="VARCHAR" />
+    <result column="CT_Province_Name" property="ctProvinceName" jdbcType="VARCHAR" />
+    <result column="CT_City_Code" property="ctCityCode" jdbcType="VARCHAR" />
+    <result column="CT_City_Name" property="ctCityName" jdbcType="VARCHAR" />
+    <result column="CT_District_Code" property="ctDistrictCode" jdbcType="VARCHAR" />
+    <result column="CT_District_Name" property="ctDistrictName" jdbcType="VARCHAR" />
+    <result column="CT_Town_Code" property="ctTownCode" jdbcType="VARCHAR" />
+    <result column="CT_Town_Name" property="ctTownName" jdbcType="VARCHAR" />
+    <result column="CT_Create_Time" property="ctCreateTime" jdbcType="TIMESTAMP" />
+    <result column="CT_Update_Time" property="ctUpdateTime" jdbcType="TIMESTAMP" />
+    <result column="CT_Extension1" property="ctExtension1" jdbcType="VARCHAR" />
+    <result column="CT_Extension2" property="ctExtension2" jdbcType="VARCHAR" />
+    <result column="CT_Extension3" property="ctExtension3" jdbcType="VARCHAR" />
+    <result column="CT_Remark" property="ctRemark" jdbcType="VARCHAR" />
+  </resultMap>
+  <resultMap id="ResultMapWithBLOBs" type="cn.flightfeather.supervision.domain.entity.CommitmentTemplate" extends="BaseResultMap" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <result column="CT_Content" property="ctContent" jdbcType="LONGVARCHAR" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    CT_GUID, CT_Scene_Type_Id, CT_Province_Code, CT_Province_Name, CT_City_Code, CT_City_Name, 
+    CT_District_Code, CT_District_Name, CT_Town_Code, CT_Town_Name, CT_Create_Time, CT_Update_Time, 
+    CT_Extension1, CT_Extension2, CT_Extension3, CT_Remark
+  </sql>
+  <sql id="Blob_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    CT_Content
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/DeviceInfoMapper.xml b/src/main/resources/mapper/DeviceInfoMapper.xml
index 241534f..296fda7 100644
--- a/src/main/resources/mapper/DeviceInfoMapper.xml
+++ b/src/main/resources/mapper/DeviceInfoMapper.xml
@@ -20,6 +20,7 @@
     <result column="DI_Town_Code" jdbcType="VARCHAR" property="diTownCode" />
     <result column="DI_Town_Name" jdbcType="VARCHAR" property="diTownName" />
     <result column="DI_Supplier" jdbcType="VARCHAR" property="diSupplier" />
+    <result column="DI_Online" jdbcType="BIT" property="diOnline" />
   </resultMap>
   <sql id="Base_Column_List">
     <!--
@@ -27,6 +28,6 @@
     -->
     DI_GUID, DI_Code, DI_Device_Type_Id, DI_Device_Type, DI_Scene_Type_Id, DI_Scene_Type, 
     DI_Province_Code, DI_Province_Name, DI_City_Code, DI_City_Name, DI_District_Code, 
-    DI_District_Name, DI_Town_Code, DI_Town_Name, DI_Supplier
+    DI_District_Name, DI_Town_Code, DI_Town_Name, DI_Supplier, DI_Online
   </sql>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/DistrictMapper.xml b/src/main/resources/mapper/DistrictMapper.xml
new file mode 100644
index 0000000..6addbbc
--- /dev/null
+++ b/src/main/resources/mapper/DistrictMapper.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.DistrictMapper">
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.District">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="D_DistrictID" jdbcType="INTEGER" property="dDistrictid" />
+    <result column="P_ProvinceID" jdbcType="INTEGER" property="pProvinceid" />
+    <result column="C_CityID" jdbcType="INTEGER" property="cCityid" />
+    <result column="D_DistrictCode" jdbcType="VARCHAR" property="dDistrictcode" />
+    <result column="D_DistrictName" jdbcType="VARCHAR" property="dDistrictname" />
+    <result column="D_Station" jdbcType="VARCHAR" property="dStation" />
+  </resultMap>
+  <sql id="Base_Column_List">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    D_DistrictID, P_ProvinceID, C_CityID, D_DistrictCode, D_DistrictName, D_Station
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/DustSiteInfoMapper.xml b/src/main/resources/mapper/DustSiteInfoMapper.xml
new file mode 100644
index 0000000..18f454c
--- /dev/null
+++ b/src/main/resources/mapper/DustSiteInfoMapper.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.DustSiteInfoMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.DustSiteInfo" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="id" property="id" jdbcType="VARCHAR" />
+    <result column="address" property="address" jdbcType="VARCHAR" />
+    <result column="begin_date" property="beginDate" jdbcType="TIMESTAMP" />
+    <result column="build_area" property="buildArea" jdbcType="VARCHAR" />
+    <result column="data_time" property="dataTime" jdbcType="TIMESTAMP" />
+    <result column="clean_measure" property="cleanMeasure" jdbcType="VARCHAR" />
+    <result column="code" property="code" jdbcType="VARCHAR" />
+    <result column="construction_unit" property="constructionUnit" jdbcType="VARCHAR" />
+    <result column="control_level" property="controlLevel" jdbcType="VARCHAR" />
+    <result column="developers" property="developers" jdbcType="VARCHAR" />
+    <result column="do_time" property="doTime" jdbcType="TIMESTAMP" />
+    <result column="duty_company" property="dutyCompany" jdbcType="VARCHAR" />
+    <result column="duty_company_id" property="dutyCompanyId" jdbcType="VARCHAR" />
+    <result column="end_date" property="endDate" jdbcType="TIMESTAMP" />
+    <result column="engineering_stage" property="engineeringStage" jdbcType="VARCHAR" />
+    <result column="engineering_stage_code" property="engineeringStageCode" jdbcType="VARCHAR" />
+    <result column="equipment_code" property="equipmentCode" jdbcType="VARCHAR" />
+    <result column="floor_area" property="floorArea" jdbcType="VARCHAR" />
+    <result column="group_id" property="groupId" jdbcType="VARCHAR" />
+    <result column="group_name" property="groupName" jdbcType="VARCHAR" />
+    <result column="has_monitor" property="hasMonitor" jdbcType="VARCHAR" />
+    <result column="is_online" property="isOnline" jdbcType="VARCHAR" />
+    <result column="is_trouble" property="isTrouble" jdbcType="VARCHAR" />
+    <result column="jhpt_delete" property="jhptDelete" jdbcType="VARCHAR" />
+    <result column="jhpt_update_time" property="jhptUpdateTime" jdbcType="VARCHAR" />
+    <result column="kindex" property="kindex" jdbcType="VARCHAR" />
+    <result column="latitude" property="latitude" jdbcType="VARCHAR" />
+    <result column="linkman" property="linkman" jdbcType="VARCHAR" />
+    <result column="longitude" property="longitude" jdbcType="VARCHAR" />
+    <result column="mn_code" property="mnCode" jdbcType="VARCHAR" />
+    <result column="name" property="name" jdbcType="VARCHAR" />
+    <result column="noise_region" property="noiseRegion" jdbcType="VARCHAR" />
+    <result column="phone" property="phone" jdbcType="VARCHAR" />
+    <result column="province" property="province" jdbcType="VARCHAR" />
+    <result column="responsible" property="responsible" jdbcType="VARCHAR" />
+    <result column="ring_id" property="ringId" jdbcType="VARCHAR" />
+    <result column="stage_begin_date" property="stageBeginDate" jdbcType="TIMESTAMP" />
+    <result column="stop_time" property="stopTime" jdbcType="TIMESTAMP" />
+    <result column="tsp" property="tsp" jdbcType="DOUBLE" />
+    <result column="type_id" property="typeId" jdbcType="VARCHAR" />
+    <result column="typename" property="typename" jdbcType="VARCHAR" />
+    <result column="union_type_id" property="unionTypeId" jdbcType="VARCHAR" />
+    <result column="wall_height" property="wallHeight" jdbcType="VARCHAR" />
+    <result column="ywsj_date" property="ywsjDate" jdbcType="TIMESTAMP" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    id, address, begin_date, build_area, data_time, clean_measure, code, construction_unit, 
+    control_level, developers, do_time, duty_company, duty_company_id, end_date, engineering_stage, 
+    engineering_stage_code, equipment_code, floor_area, group_id, group_name, has_monitor, 
+    is_online, is_trouble, jhpt_delete, jhpt_update_time, kindex, latitude, linkman, 
+    longitude, mn_code, name, noise_region, phone, province, responsible, ring_id, stage_begin_date, 
+    stop_time, tsp, type_id, typename, union_type_id, wall_height, ywsj_date
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/DustSiteMapMapper.xml b/src/main/resources/mapper/DustSiteMapMapper.xml
new file mode 100644
index 0000000..dff69d0
--- /dev/null
+++ b/src/main/resources/mapper/DustSiteMapMapper.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.DustSiteMapMapper">
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.DustSiteMap">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="Id" jdbcType="INTEGER" property="id" />
+    <result column="TZ_User_Id" jdbcType="VARCHAR" property="tzUserId" />
+    <result column="TZ_User_Name" jdbcType="VARCHAR" property="tzUserName" />
+    <result column="JA_MN_Code" jdbcType="VARCHAR" property="jaMnCode" />
+    <result column="JA_Scene_Name" jdbcType="VARCHAR" property="jaSceneName" />
+    <result column="SV_User_Id" jdbcType="VARCHAR" property="svUserId" />
+    <result column="SV_User_name" jdbcType="VARCHAR" property="svUserName" />
+    <result column="Create_Time" jdbcType="TIMESTAMP" property="createTime" />
+  </resultMap>
+  <sql id="Base_Column_List">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    Id, TZ_User_Id, TZ_User_Name, JA_MN_Code, JA_Scene_Name, SV_User_Id, SV_User_name, 
+    Create_Time
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/EnvironmentalScheduleMapper.xml b/src/main/resources/mapper/EnvironmentalScheduleMapper.xml
new file mode 100644
index 0000000..84adbd6
--- /dev/null
+++ b/src/main/resources/mapper/EnvironmentalScheduleMapper.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.EnvironmentalScheduleMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.EnvironmentalSchedule" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="SC_ID" property="scId" jdbcType="INTEGER" />
+    <result column="SC_Title" property="scTitle" jdbcType="VARCHAR" />
+    <result column="SC_Step_Name" property="scStepName" jdbcType="VARCHAR" />
+    <result column="SC_Type" property="scType" jdbcType="TINYINT" />
+    <result column="SC_Type_Name" property="scTypeName" jdbcType="VARCHAR" />
+    <result column="SC_Period_Type" property="scPeriodType" jdbcType="TINYINT" />
+    <result column="SC_Period_Type_Name" property="scPeriodTypeName" jdbcType="VARCHAR" />
+    <result column="SC_Every_Week" property="scEveryWeek" jdbcType="VARCHAR" />
+    <result column="SC_Every_Month" property="scEveryMonth" jdbcType="VARCHAR" />
+    <result column="SC_Every_Year" property="scEveryYear" jdbcType="VARCHAR" />
+    <result column="SC_Effective_Time" property="scEffectiveTime" jdbcType="TIMESTAMP" />
+    <result column="SC_User_ID" property="scUserId" jdbcType="VARCHAR" />
+    <result column="SC_User_Config_Id" property="scUserConfigId" jdbcType="INTEGER" />
+    <result column="SC_Scene_Type" property="scSceneType" jdbcType="INTEGER" />
+    <result column="SC_Need_Sign" property="scNeedSign" jdbcType="BIT" />
+  </resultMap>
+  <resultMap id="ResultMapWithBLOBs" type="cn.flightfeather.supervision.domain.entity.EnvironmentalSchedule" extends="BaseResultMap" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <result column="SC_Content" property="scContent" jdbcType="LONGVARCHAR" />
+    <result column="SC_Step_Detail" property="scStepDetail" jdbcType="LONGVARCHAR" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    SC_ID, SC_Title, SC_Step_Name, SC_Type, SC_Type_Name, SC_Period_Type, SC_Period_Type_Name, 
+    SC_Every_Week, SC_Every_Month, SC_Every_Year, SC_Effective_Time, SC_User_ID, SC_User_Config_Id, 
+    SC_Scene_Type, SC_Need_Sign
+  </sql>
+  <sql id="Blob_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    SC_Content, SC_Step_Detail
+  </sql>
+
+  <select id="getSchedules" resultMap="ResultMapWithBLOBs">
+    SELECT
+    *
+    FROM
+    ea_t_schedule
+    WHERE
+    (SC_User_ID = '${param1}'
+    OR (
+    SC_User_Config_Id in
+    <foreach collection="param2" index="index" item="item" open="(" separator="," close=")">
+      #{item}
+    </foreach>
+    AND (
+    SC_Scene_Type = '${param3}'
+    OR SC_Scene_Type IS NULL
+    )
+    )
+    OR (
+    SC_User_ID IS NULL
+    AND SC_User_Config_Id IS NULL
+    AND SC_Scene_Type IS NULL
+    ))
+    <if test="param4 != null">
+      AND SC_Type = ${param4}
+    </if>
+  </select>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/EvaluationMapper.xml b/src/main/resources/mapper/EvaluationMapper.xml
index 391e492..7c8be3b 100644
--- a/src/main/resources/mapper/EvaluationMapper.xml
+++ b/src/main/resources/mapper/EvaluationMapper.xml
@@ -52,7 +52,10 @@
     E_ResultScoreBef, E_PromissedNum, E_ChangedNum, ResultStandardAft, E_ResultScoreAft, 
     E_CreateDate, E_UpdateDate, E_Extension1, E_Extension2, E_Extension3, E_Remark
   </sql>
-  
+
+  <resultMap id="CreditInfoVo" type="cn.flightfeather.supervision.lightshare.vo.CreditInfoVo">
+
+  </resultMap>
   <select id="getAssessments" resultType="map">
     select
       b.UI_GUID as userId,
@@ -76,4 +79,73 @@
       </if>
     order by a.E_UpdateDate desc
   </select>
+
+  <select id="searchGradeList" resultMap="CreditInfoVo">
+    SELECT
+      b.UI_GUID AS userId,
+      b.UI_RealName AS name,
+      b.UI_Extension2 AS sceneType,
+      d.CI_Name AS departmentName,
+      d.BI_Management_Company AS managementCompany,
+      a.E_CreateDate AS updateTime,
+      a.E_ResultScoreBef AS score,
+      b.UI_Extension1 AS district,
+      d.BI_Town_Name AS town,
+      b.UI_IsEnable AS status
+    FROM
+      sm_t_userinfo AS b
+      LEFT JOIN ea_t_baseinfo AS d ON b.UI_GUID = d.BI_GUID
+      LEFT JOIN (
+        SELECT <include refid="Base_Column_List" /> FROM ea_t_evaluation AS t_e
+        LEFT JOIN sm_t_evaluationrule AS t_r ON t_e.ST_GUID = t_r.ER_GUID
+        WHERE t_e.E_ScenseName = '${period}' AND t_r.ER_RuleType = 0
+      ) AS a ON a.I_GUID = b.UI_GUID
+    <where>
+      b.UI_IsEnable = 1
+      AND (b.UI_WorkNo != 'test' OR b.UI_WorkNo IS NULL)
+      <if test="provinceCode != null">
+        AND d.BI_Province_Code = #{provinceCode}
+      </if>
+      <if test="provinceName != null">
+        AND d.BI_Province_Name = #{provinceName}
+      </if>
+      <if test="cityCode != null">
+        AND d.BI_City_Code = #{cityCode}
+      </if>
+      <if test="cityName != null">
+        AND d.BI_City_Name = #{cityName}
+      </if>
+      <if test="districtCode != null">
+        AND d.BI_District_Code = #{districtCode}
+      </if>
+      <if test="districtName != null">
+        AND d.BI_District_Name = #{districtName}
+      </if>
+      <if test="townCode != null">
+        AND d.BI_Town_Code = #{townCode}
+      </if>
+      <if test="townName != null">
+        AND d.BI_Town_Name = #{townName}
+      </if>
+      <if test="areaCode != null">
+        AND d.BI_Area_Code = #{areaCode}
+      </if>
+      <if test="area != null">
+        AND d.BI_Area = #{area}
+      </if>
+      <if test="mcId != null">
+        AND d.BI_Management_Company_Id = #{mcId}
+      </if>
+      <if test="mcName != null">
+        AND d.BI_Management_Company = #{mcName}
+      </if>
+      <if test="sceneTypes.size() != 0">
+        AND b.UI_Extension2 in
+        <foreach collection="sceneTypes" item="type" open="(" separator="," close=")">
+          #{type, jdbcType=VARCHAR}
+        </foreach>
+      </if>
+    </where>
+    ORDER BY CONVERT (a.E_ResultScoreBef, signed) ${sorts}
+  </select>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/FumeMinuteValueMapper.xml b/src/main/resources/mapper/FumeMinuteValueMapper.xml
index ffb7d1b..443ddff 100644
--- a/src/main/resources/mapper/FumeMinuteValueMapper.xml
+++ b/src/main/resources/mapper/FumeMinuteValueMapper.xml
@@ -45,7 +45,7 @@
           AND MV_Data_Time IS NOT NULL
         ORDER BY
           MV_Data_Time DESC
-        LIMIT 100000
+        LIMIT 1000
       ) t
     GROUP BY
       MV_Stat_Code
diff --git a/src/main/resources/mapper/HourDustDataMapper.xml b/src/main/resources/mapper/HourDustDataMapper.xml
new file mode 100644
index 0000000..7bce7fc
--- /dev/null
+++ b/src/main/resources/mapper/HourDustDataMapper.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.HourDustDataMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.HourDustData" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="id" property="id" jdbcType="VARCHAR" />
+    <result column="dustvalue" property="dustvalue" jdbcType="DOUBLE" />
+    <result column="flag" property="flag" jdbcType="VARCHAR" />
+    <result column="grade" property="grade" jdbcType="VARCHAR" />
+    <result column="groupname" property="groupname" jdbcType="VARCHAR" />
+    <result column="inserttime" property="inserttime" jdbcType="TIMESTAMP" />
+    <result column="lst" property="lst" jdbcType="TIMESTAMP" />
+    <result column="lst_end" property="lstEnd" jdbcType="TIMESTAMP" />
+    <result column="mncode" property="mncode" jdbcType="VARCHAR" />
+    <result column="name" property="name" jdbcType="VARCHAR" />
+    <result column="noisevalue" property="noisevalue" jdbcType="VARCHAR" />
+    <result column="projectid" property="projectid" jdbcType="VARCHAR" />
+    <result column="projecttypeid" property="projecttypeid" jdbcType="VARCHAR" />
+    <result column="quality" property="quality" jdbcType="VARCHAR" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    id, dustvalue, flag, grade, groupname, inserttime, lst, lst_end, mncode, name, noisevalue, 
+    projectid, projecttypeid, quality
+  </sql>
+
+  <resultMap id="DataCategoryCountVo" type="cn.flightfeather.supervision.lightshare.vo.DataCategoryCountVo" />
+
+  <select id="findDataCountEachDay" resultMap="DataCategoryCountVo">
+    SELECT
+    `name`,
+    DATE(lst) as category,
+    COUNT(*) as count
+    FROM ja_t_hour_dust_data
+    WHERE
+    lst BETWEEN #{startTime} AND #{endTime}
+    GROUP BY mncode, DATE(lst)
+  </select>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/IndustrialBaseInfoMapper.xml b/src/main/resources/mapper/IndustrialBaseInfoMapper.xml
new file mode 100644
index 0000000..bafe40a
--- /dev/null
+++ b/src/main/resources/mapper/IndustrialBaseInfoMapper.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.IndustrialBaseInfoMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.IndustrialBaseInfo" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="IB_GUID" property="ibGuid" jdbcType="VARCHAR" />
+    <result column="IB_Production_Technique" property="ibProductionTechnique" jdbcType="VARCHAR" />
+    <result column="IB_Waste_Gas_Technique" property="ibWasteGasTechnique" jdbcType="VARCHAR" />
+    <result column="IB_Waste_Gas_Measure" property="ibWasteGasMeasure" jdbcType="VARCHAR" />
+    <result column="IB_Has_Absorb_Technique" property="ibHasAbsorbTechnique" jdbcType="BIT" />
+    <result column="IB_Adsorbent_Correct" property="ibAdsorbentCorrect" jdbcType="BIT" />
+    <result column="IB_Period_Correct" property="ibPeriodCorrect" jdbcType="BIT" />
+    <result column="IB_Has_Contract" property="ibHasContract" jdbcType="BIT" />
+    <result column="IB_Keep_Contract" property="ibKeepContract" jdbcType="BIT" />
+    <result column="IB_Create_Time" property="ibCreateTime" jdbcType="TIMESTAMP" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    IB_GUID, IB_Production_Technique, IB_Waste_Gas_Technique, IB_Waste_Gas_Measure, IB_Has_Absorb_Technique, 
+    IB_Adsorbent_Correct, IB_Period_Correct, IB_Has_Contract, IB_Keep_Contract, IB_Create_Time
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/LampDeviceDataMapper.xml b/src/main/resources/mapper/LampDeviceDataMapper.xml
new file mode 100644
index 0000000..b8aac7b
--- /dev/null
+++ b/src/main/resources/mapper/LampDeviceDataMapper.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.LampDeviceDataMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.LampDeviceData" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="id" property="id" jdbcType="INTEGER" />
+    <result column="channel_num" property="channelNum" jdbcType="VARCHAR" />
+    <result column="clean_liness" property="cleanLiness" jdbcType="VARCHAR" />
+    <result column="device_code" property="deviceCode" jdbcType="VARCHAR" />
+    <result column="device_name" property="deviceName" jdbcType="VARCHAR" />
+    <result column="device_state" property="deviceState" jdbcType="VARCHAR" />
+    <result column="enter_id" property="enterId" jdbcType="VARCHAR" />
+    <result column="fan_state" property="fanState" jdbcType="VARCHAR" />
+    <result column="lampblack_value" property="lampblackValue" jdbcType="DOUBLE" />
+    <result column="monitor_time" property="monitorTime" jdbcType="TIMESTAMP" />
+    <result column="production_date" property="productionDate" jdbcType="TIMESTAMP" />
+    <result column="purifier_state" property="purifierState" jdbcType="VARCHAR" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    id, channel_num, clean_liness, device_code, device_name, device_state, enter_id, 
+    fan_state, lampblack_value, monitor_time, production_date, purifier_state
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/LampEnterBaseInfoMapper.xml b/src/main/resources/mapper/LampEnterBaseInfoMapper.xml
new file mode 100644
index 0000000..7efc248
--- /dev/null
+++ b/src/main/resources/mapper/LampEnterBaseInfoMapper.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.LampEnterBaseInfoMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.LampEnterBaseInfo" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="enter_id" property="enterId" jdbcType="VARCHAR" />
+    <result column="enter_name" property="enterName" jdbcType="VARCHAR" />
+    <result column="address" property="address" jdbcType="VARCHAR" />
+    <result column="business_date" property="businessDate" jdbcType="VARCHAR" />
+    <result column="datasource" property="datasource" jdbcType="VARCHAR" />
+    <result column="jjq_code" property="jjqCode" jdbcType="VARCHAR" />
+    <result column="jjq_name" property="jjqName" jdbcType="VARCHAR" />
+    <result column="latitude" property="latitude" jdbcType="DOUBLE" />
+    <result column="link_man" property="linkMan" jdbcType="VARCHAR" />
+    <result column="link_phone" property="linkPhone" jdbcType="VARCHAR" />
+    <result column="longitude" property="longitude" jdbcType="DOUBLE" />
+    <result column="region_name" property="regionName" jdbcType="VARCHAR" />
+    <result column="regist_date" property="registDate" jdbcType="TIMESTAMP" />
+    <result column="state" property="state" jdbcType="VARCHAR" />
+    <result column="street" property="street" jdbcType="VARCHAR" />
+    <result column="outfall_type" property="outfallType" jdbcType="VARCHAR" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    enter_id, enter_name, address, business_date, datasource, jjq_code, jjq_name, latitude, 
+    link_man, link_phone, longitude, region_name, regist_date, state, street
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/LedgerRecordMapper.xml b/src/main/resources/mapper/LedgerRecordMapper.xml
index a63755e..1862b26 100644
--- a/src/main/resources/mapper/LedgerRecordMapper.xml
+++ b/src/main/resources/mapper/LedgerRecordMapper.xml
@@ -80,7 +80,9 @@
     ) as t_ledger
     LEFT JOIN sm_t_userinfo AS b ON t_ledger.LR_SubmitID = b.UI_GUID
     LEFT JOIN ea_t_ledgersubtype AS c ON t_ledger.LS_SubTypeId = c.LS_SubTypeId
-    WHERE b.UI_IsEnable = TRUE AND c.L_Auto_Copy = TRUE) as r
-    WHERE i = 1
+    WHERE b.UI_IsEnable = TRUE AND c.L_Auto_Copy = TRUE
+    and (t_ledger.LR_Extension2 is null or t_ledger.LR_Extension2 != 'notInvolved')
+    ) as r
+    WHERE r.i = 1
   </select>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/LedgerSubTypeMapper.xml b/src/main/resources/mapper/LedgerSubTypeMapper.xml
index 4e28a3f..165e11a 100644
--- a/src/main/resources/mapper/LedgerSubTypeMapper.xml
+++ b/src/main/resources/mapper/LedgerSubTypeMapper.xml
@@ -14,12 +14,16 @@
     <result column="L_NeedUpdate" jdbcType="BIT" property="lNeedupdate" />
     <result column="L_Period" jdbcType="INTEGER" property="lPeriod" />
     <result column="L_Real_Time" jdbcType="BIT" property="lRealTime" />
+    <result column="L_Auto_Copy" jdbcType="BIT" property="lAutoCopy" />
+    <result column="L_Description" jdbcType="VARCHAR" property="lDescription" />
+    <result column="L_Not_Related_Switch" jdbcType="BIT" property="lNotRelatedSwitch" />
+    <result column="L_Multi_Group" jdbcType="BIT" property="lMultiGroup" />
   </resultMap>
   <sql id="Base_Column_List">
     <!--
       WARNING - @mbg.generated
     -->
     LS_SubTypeId, LS_Name, L_TypeId, L_TypeName, L_IconUrl, L_SceneType, L_NeedUpdate, 
-    L_Period, L_Real_Time
+    L_Period, L_Real_Time, L_Auto_Copy, L_Description, L_Not_Related_Switch, L_Multi_Group
   </sql>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/NoticeMapper.xml b/src/main/resources/mapper/NoticeMapper.xml
index 8960825..c5481ca 100644
--- a/src/main/resources/mapper/NoticeMapper.xml
+++ b/src/main/resources/mapper/NoticeMapper.xml
@@ -92,6 +92,9 @@
             <if test="param2 != null">
                 and (a.EC_Extension1 like '%0;%' or a.EC_Extension1 like CONCAT('%',#{param2},';%'))
             </if>
+            <if test="param4 != null">
+              and (a.EC_Extension2 is null or a.EC_Extension2 like CONCAT('%',#{param4},';%'))
+            </if>
           )
     )
     and a.EC_IsInUse = true
diff --git a/src/main/resources/mapper/NoticeTemplateMapper.xml b/src/main/resources/mapper/NoticeTemplateMapper.xml
new file mode 100644
index 0000000..67a080d
--- /dev/null
+++ b/src/main/resources/mapper/NoticeTemplateMapper.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.NoticeTemplateMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.NoticeTemplate" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="NT_ID" property="ntId" jdbcType="INTEGER" />
+    <result column="NT_Notice_Type" property="ntNoticeType" jdbcType="INTEGER" />
+    <result column="NT_Notice_Type_Name" property="ntNoticeTypeName" jdbcType="VARCHAR" />
+    <result column="NT_Notice_Sub_Type" property="ntNoticeSubType" jdbcType="INTEGER" />
+    <result column="NT_Notice_Sub_Type_Name" property="ntNoticeSubTypeName" jdbcType="VARCHAR" />
+    <result column="NT_Notice_Title" property="ntNoticeTitle" jdbcType="VARCHAR" />
+  </resultMap>
+  <resultMap id="ResultMapWithBLOBs" type="cn.flightfeather.supervision.domain.entity.NoticeTemplate" extends="BaseResultMap" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <result column="NT_Notice_Template" property="ntNoticeTemplate" jdbcType="LONGVARCHAR" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    NT_ID, NT_Notice_Type, NT_Notice_Type_Name, NT_Notice_Sub_Type, NT_Notice_Sub_Type_Name, 
+    NT_Notice_Title
+  </sql>
+  <sql id="Blob_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    NT_Notice_Template
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/OverallEvaluationMapper.xml b/src/main/resources/mapper/OverallEvaluationMapper.xml
index 71cd250..9c5c4e6 100644
--- a/src/main/resources/mapper/OverallEvaluationMapper.xml
+++ b/src/main/resources/mapper/OverallEvaluationMapper.xml
@@ -1,25 +1,215 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
-<mapper namespace="cn.flightfeather.supervision.domain.mapper.OverallEvaluationMapper" >
-  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.OverallEvaluation" >
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.OverallEvaluationMapper">
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.OverallEvaluation">
     <!--
       WARNING - @mbg.generated
     -->
-    <id column="OE_GUID" property="oeGuid" jdbcType="INTEGER" />
-    <result column="BI_GUID" property="ciGuid" jdbcType="VARCHAR" />
-    <result column="OE_Score" property="oeScore" jdbcType="INTEGER" />
-    <result column="OE_Publish_Time" property="oePublishTime" jdbcType="DATE" />
-    <result column="OE_Update_Time" property="oeUpdateTime" jdbcType="DATE" />
-    <result column="OE_Scene_Type_Id" property="oeSceneTypeId" jdbcType="TINYINT" />
-    <result column="OE_Scene_Type" property="oeSceneType" jdbcType="VARCHAR" />
-    <result column="OE_Period" property="oePeriod" jdbcType="VARCHAR" />
-    <result column="OE_Code_Level" property="oeCodeLevel" jdbcType="TINYINT" />
+    <id column="OE_GUID" jdbcType="INTEGER" property="oeGuid" />
+    <result column="BI_GUID" jdbcType="VARCHAR" property="biGuid" />
+    <result column="OE_Score" jdbcType="INTEGER" property="oeScore" />
+    <result column="OE_Publish_Time" jdbcType="TIMESTAMP" property="oePublishTime" />
+    <result column="OE_Update_Time" jdbcType="TIMESTAMP" property="oeUpdateTime" />
+    <result column="OE_Scene_Type_Id" jdbcType="TINYINT" property="oeSceneTypeId" />
+    <result column="OE_Scene_Type" jdbcType="VARCHAR" property="oeSceneType" />
+    <result column="OE_Period" jdbcType="VARCHAR" property="oePeriod" />
+    <result column="OE_Code_Level" jdbcType="TINYINT" property="oeCodeLevel" />
+    <result column="OE_Start_Time" jdbcType="DATE" property="oeStartTime" />
+    <result column="OE_End_Time" jdbcType="DATE" property="oeEndTime" />
   </resultMap>
-  <sql id="Base_Column_List" >
+  <sql id="Base_Column_List">
     <!--
       WARNING - @mbg.generated
     -->
-    OE_GUID, BI_GUID, OE_Score, OE_Publish_Time, OE_Update_Time, OE_Scene_Type_Id, OE_Scene_Type,
-    OE_Period, OE_Code_Level
+    OE_GUID, BI_GUID, OE_Score, OE_Publish_Time, OE_Update_Time, OE_Scene_Type_Id, OE_Scene_Type, 
+    OE_Period, OE_Code_Level, OE_Start_Time, OE_End_Time
   </sql>
+
+  <resultMap id="CreditInfoVo" type="cn.flightfeather.supervision.lightshare.vo.CreditInfoVo">
+
+  </resultMap>
+
+  <select id="getLatestPeriod" resultType="String">
+    SELECT @var_period:= (
+    SELECT
+    a.OE_Start_Time
+    FROM
+    ea_t_overall_evaluation AS a
+    LEFT JOIN ea_t_baseinfo AS b ON a.BI_GUID = b.BI_GUID
+    <where>
+      <if test="provinceCode != null">
+        AND b.BI_Province_Code = #{provinceCode}
+      </if>
+      <if test="provinceName != null">
+        AND b.BI_Province_Name = #{provinceName}
+      </if>
+      <if test="cityCode != null">
+        AND b.BI_City_Code = #{cityCode}
+      </if>
+      <if test="cityName != null">
+        AND b.BI_City_Name = #{cityName}
+      </if>
+      <if test="districtCode != null">
+        AND b.BI_District_Code = #{districtCode}
+      </if>
+      <if test="districtName != null">
+        AND b.BI_District_Name = #{districtName}
+      </if>
+      <if test="townCode != null">
+        AND b.BI_Town_Code = #{townCode}
+      </if>
+      <if test="townName != null">
+        AND b.BI_Town_Name = #{townName}
+      </if>
+      <if test="areaCode != null">
+        AND b.BI_Area_Code = #{areaCode}
+      </if>
+      <if test="area != null">
+        AND b.BI_Area = #{area}
+      </if>
+      <if test="mcId != null">
+        AND b.BI_Management_Company_Id = #{mcId}
+      </if>
+      <if test="mcName != null">
+        AND b.BI_Management_Company = #{mcName}
+      </if>
+      <if test="sceneTypes.size() != 0">
+        AND a.OE_Scene_Type_Id in
+        <foreach collection="sceneTypes" item="type" open="(" separator="," close=")">
+          #{type, jdbcType=VARCHAR}
+        </foreach>
+      </if>
+    </where>
+    ORDER BY
+    a.OE_Publish_Time DESC
+    LIMIT 1
+    );
+  </select>
+  <select id="getCreditCount" resultMap="BaseResultMap">
+    SELECT
+    a.*
+    FROM
+    ea_t_overall_evaluation AS a
+    LEFT JOIN ea_t_baseinfo AS b ON a.BI_GUID = b.BI_GUID
+    <where>
+      <if test="provinceCode != null">
+        AND b.BI_Province_Code = #{provinceCode}
+      </if>
+      <if test="provinceName != null">
+        AND b.BI_Province_Name = #{provinceName}
+      </if>
+      <if test="cityCode != null">
+        AND b.BI_City_Code = #{cityCode}
+      </if>
+      <if test="cityName != null">
+        AND b.BI_City_Name = #{cityName}
+      </if>
+      <if test="districtCode != null">
+        AND b.BI_District_Code = #{districtCode}
+      </if>
+      <if test="districtName != null">
+        AND b.BI_District_Name = #{districtName}
+      </if>
+      <if test="townCode != null">
+        AND b.BI_Town_Code = #{townCode}
+      </if>
+      <if test="townName != null">
+        AND b.BI_Town_Name = #{townName}
+      </if>
+      <if test="areaCode != null">
+        AND b.BI_Area_Code = #{areaCode}
+      </if>
+      <if test="area != null">
+        AND b.BI_Area = #{area}
+      </if>
+      <if test="mcId != null">
+        AND b.BI_Management_Company_Id = #{mcId}
+      </if>
+      <if test="mcName != null">
+        AND b.BI_Management_Company = #{mcName}
+      </if>
+      <if test="sceneTypes.size() != 0">
+        AND a.OE_Scene_Type_Id in
+        <foreach collection="sceneTypes" item="type" open="(" separator="," close=")">
+          #{type}
+        </foreach>
+      </if>
+      <if test="period != null">
+        AND a.OE_Start_Time &lt;= '${period}'
+        AND a.OE_End_Time >= '${period}'
+      </if>
+    </where>
+  </select>
+  <select id="searchEcCodeList" resultMap="CreditInfoVo">
+    SELECT
+      b.BI_GUID AS userId,
+      b.BI_Name AS name,
+      c.UI_Extension2 AS sceneType,
+      b.CI_Name AS departmentName,
+      b.BI_Management_Company AS managementCompany,
+      a.OE_Publish_Time AS publishTime,
+      a.OE_Update_Time AS updateTime,
+      a.OE_Code_Level AS codeLevel,
+      b.BI_District_Name AS district,
+      b.BI_Town_Name AS town,
+      c.UI_IsEnable AS status
+    FROM
+      ea_t_overall_evaluation AS a
+      LEFT JOIN ea_t_baseinfo AS b ON a.BI_GUID = b.BI_GUID
+      LEFT JOIN sm_t_userinfo AS c ON a.BI_GUID = c.UI_GUID
+    <where>
+      <if test="provinceCode != null">
+        AND b.BI_Province_Code = #{provinceCode}
+      </if>
+      <if test="provinceName != null">
+        AND b.BI_Province_Name = #{provinceName}
+      </if>
+      <if test="cityCode != null">
+        AND b.BI_City_Code = #{cityCode}
+      </if>
+      <if test="cityName != null">
+        AND b.BI_City_Name = #{cityName}
+      </if>
+      <if test="districtCode != null">
+        AND b.BI_District_Code = #{districtCode}
+      </if>
+      <if test="districtName != null">
+        AND b.BI_District_Name = #{districtName}
+      </if>
+      <if test="townCode != null">
+        AND b.BI_Town_Code = #{townCode}
+      </if>
+      <if test="townName != null">
+        AND b.BI_Town_Name = #{townName}
+      </if>
+      <if test="areaCode != null">
+        AND b.BI_Area_Code = #{areaCode}
+      </if>
+      <if test="area != null">
+        AND b.BI_Area = #{area}
+      </if>
+      <if test="mcId != null">
+        AND b.BI_Management_Company_Id = #{mcId}
+      </if>
+      <if test="mcName != null">
+        AND b.BI_Management_Company = #{mcName}
+      </if>
+      <if test="sceneTypes.size() != 0">
+        AND a.OE_Scene_Type_Id in
+        <foreach collection="sceneTypes" item="type" open="(" separator="," close=")">
+          #{type, jdbcType=VARCHAR}
+        </foreach>
+      </if>
+      <if test="codeType != null">
+        AND a.OE_Code_Level = ${codeType}
+      </if>
+      <if test="searchText != null">
+        AND b.BI_Name LIKE '%${searchText}%'
+      </if>
+      <if test="period != null">
+        AND a.OE_Start_Time &lt;= '${period}'
+        AND a.OE_End_Time >= '${period}'
+      </if>
+    </where>
+  </select>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/PersonalInfoMapper.xml b/src/main/resources/mapper/PersonalInfoMapper.xml
index a920f0d..3974691 100644
--- a/src/main/resources/mapper/PersonalInfoMapper.xml
+++ b/src/main/resources/mapper/PersonalInfoMapper.xml
@@ -1,27 +1,29 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
-<mapper namespace="cn.flightfeather.supervision.domain.mapper.PersonalInfoMapper" >
-  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.PersonalInfo" >
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.PersonalInfoMapper">
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.PersonalInfo">
     <!--
       WARNING - @mbg.generated
     -->
-    <id column="PI_GUID" property="piGuid" jdbcType="VARCHAR" />
-    <result column="PI_Name" property="piName" jdbcType="VARCHAR" />
-    <result column="PI_ID_Type_Num" property="piIdTypeNum" jdbcType="TINYINT" />
-    <result column="PI_ID_Type" property="piIdType" jdbcType="VARCHAR" />
-    <result column="PI_ID" property="piId" jdbcType="VARCHAR" />
-    <result column="PI_Position_Num" property="piPositionNum" jdbcType="TINYINT" />
-    <result column="PI_Position" property="piPosition" jdbcType="VARCHAR" />
-    <result column="PI_Extension1" property="piExtension1" jdbcType="VARCHAR" />
-    <result column="PI_Extension2" property="piExtension2" jdbcType="VARCHAR" />
-    <result column="PI_Extension3" property="piExtension3" jdbcType="VARCHAR" />
-    <result column="PI_Remark" property="piRemark" jdbcType="VARCHAR" />
+    <id column="PI_GUID" jdbcType="VARCHAR" property="piGuid" />
+    <result column="PI_Name" jdbcType="VARCHAR" property="piName" />
+    <result column="PI_ID_Type_Num" jdbcType="TINYINT" property="piIdTypeNum" />
+    <result column="PI_ID_Type" jdbcType="VARCHAR" property="piIdType" />
+    <result column="PI_ID" jdbcType="VARCHAR" property="piId" />
+    <result column="PI_Position_Num" jdbcType="TINYINT" property="piPositionNum" />
+    <result column="PI_Position" jdbcType="VARCHAR" property="piPosition" />
+    <result column="PI_Wx_Id" jdbcType="VARCHAR" property="piWxId" />
+    <result column="PI_Scene_Id" jdbcType="VARCHAR" property="piSceneId" />
+    <result column="PI_Extension1" jdbcType="VARCHAR" property="piExtension1" />
+    <result column="PI_Extension2" jdbcType="VARCHAR" property="piExtension2" />
+    <result column="PI_Extension3" jdbcType="VARCHAR" property="piExtension3" />
+    <result column="PI_Remark" jdbcType="VARCHAR" property="piRemark" />
   </resultMap>
-  <sql id="Base_Column_List" >
+  <sql id="Base_Column_List">
     <!--
       WARNING - @mbg.generated
     -->
     PI_GUID, PI_Name, PI_ID_Type_Num, PI_ID_Type, PI_ID, PI_Position_Num, PI_Position, 
-    PI_Extension1, PI_Extension2, PI_Extension3, PI_Remark
+    PI_Wx_Id, PI_Scene_Id, PI_Extension1, PI_Extension2, PI_Extension3, PI_Remark
   </sql>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/PracticalOperationMapper.xml b/src/main/resources/mapper/PracticalOperationMapper.xml
new file mode 100644
index 0000000..309f096
--- /dev/null
+++ b/src/main/resources/mapper/PracticalOperationMapper.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.PracticalOperationMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.PracticalOperation" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="PO_ID" property="poId" jdbcType="INTEGER" />
+    <result column="PO_Module_Name" property="poModuleName" jdbcType="VARCHAR" />
+    <result column="PO_Type_Id" property="poTypeId" jdbcType="INTEGER" />
+    <result column="PO_Type_Name" property="poTypeName" jdbcType="VARCHAR" />
+    <result column="PO_Sub_Type_Id" property="poSubTypeId" jdbcType="INTEGER" />
+    <result column="PO_Sub_Type_Name" property="poSubTypeName" jdbcType="VARCHAR" />
+    <result column="PO_Title" property="poTitle" jdbcType="VARCHAR" />
+    <result column="PO_Content" property="poContent" jdbcType="VARCHAR" />
+    <result column="PO_Device_Code" property="poDeviceCode" jdbcType="VARCHAR" />
+    <result column="PO_State_Range_Id" property="poStateRangeId" jdbcType="VARCHAR" />
+    <result column="PO_State_Range" property="poStateRange" jdbcType="VARCHAR" />
+    <result column="PO_State_Remind_Range" property="poStateRemindRange" jdbcType="VARCHAR" />
+    <result column="PO_State_Rule" property="poStateRule" jdbcType="INTEGER" />
+    <result column="PO_Ledger_Type_Id" property="poLedgerTypeId" jdbcType="INTEGER" />
+    <result column="PO_Ledger_Type_Name" property="poLedgerTypeName" jdbcType="VARCHAR" />
+    <result column="PO_User_Config_Id" property="poUserConfigId" jdbcType="INTEGER" />
+    <result column="PO_User_Id" property="poUserId" jdbcType="VARCHAR" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    PO_ID, PO_Module_Name, PO_Type_Id, PO_Type_Name, PO_Sub_Type_Id, PO_Sub_Type_Name, 
+    PO_Title, PO_Content, PO_Device_Code, PO_State_Range_Id, PO_State_Range, PO_State_Remind_Range, 
+    PO_State_Rule, PO_Ledger_Type_Id, PO_Ledger_Type_Name, PO_User_Config_Id, PO_User_Id
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/PracticalOperationRecordMapper.xml b/src/main/resources/mapper/PracticalOperationRecordMapper.xml
new file mode 100644
index 0000000..04df33d
--- /dev/null
+++ b/src/main/resources/mapper/PracticalOperationRecordMapper.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.PracticalOperationRecordMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.PracticalOperationRecord" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="PR_Id" property="prId" jdbcType="INTEGER" />
+    <result column="PO_Id" property="poId" jdbcType="INTEGER" />
+    <result column="PO_Title" property="poTitle" jdbcType="VARCHAR" />
+    <result column="PR_User_Id" property="prUserId" jdbcType="VARCHAR" />
+    <result column="PR_User_Name" property="prUserName" jdbcType="VARCHAR" />
+    <result column="PR_User_Scene_Type" property="prUserSceneType" jdbcType="INTEGER" />
+    <result column="PR_Time" property="prTime" jdbcType="TIMESTAMP" />
+    <result column="PR_State_Id" property="prStateId" jdbcType="VARCHAR" />
+    <result column="PR_State_Name" property="prStateName" jdbcType="VARCHAR" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    PR_Id, PO_Id, PO_Title, PR_User_Id, PR_User_Name, PR_User_Scene_Type, PR_Time, PR_State_Id, 
+    PR_State_Name
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/ProvinceMapper.xml b/src/main/resources/mapper/ProvinceMapper.xml
new file mode 100644
index 0000000..45089e9
--- /dev/null
+++ b/src/main/resources/mapper/ProvinceMapper.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.ProvinceMapper">
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.Province">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="P_ProvinceID" jdbcType="INTEGER" property="pProvinceid" />
+    <result column="P_ProvinceCode" jdbcType="VARCHAR" property="pProvincecode" />
+    <result column="P_ProvinceName" jdbcType="VARCHAR" property="pProvincename" />
+  </resultMap>
+  <sql id="Base_Column_List">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    P_ProvinceID, P_ProvinceCode, P_ProvinceName
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/RiskEvaluationMapper.xml b/src/main/resources/mapper/RiskEvaluationMapper.xml
new file mode 100644
index 0000000..2682a90
--- /dev/null
+++ b/src/main/resources/mapper/RiskEvaluationMapper.xml
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.RiskEvaluationMapper">
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.RiskEvaluation">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="RE_ID" jdbcType="INTEGER" property="reId" />
+    <result column="BI_GUID" jdbcType="VARCHAR" property="biGuid" />
+    <result column="RE_Risk_Level" jdbcType="INTEGER" property="reRiskLevel" />
+    <result column="RE_Publish_Time" jdbcType="TIMESTAMP" property="rePublishTime" />
+    <result column="RE_Scene_Type_Id" jdbcType="INTEGER" property="reSceneTypeId" />
+    <result column="RE_Scene_Type" jdbcType="VARCHAR" property="reSceneType" />
+    <result column="RE_Period" jdbcType="VARCHAR" property="rePeriod" />
+    <result column="RE_Start_Time" jdbcType="DATE" property="reStartTime" />
+    <result column="RE_End_Time" jdbcType="DATE" property="reEndTime" />
+  </resultMap>
+  <resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="cn.flightfeather.supervision.domain.entity.RiskEvaluation">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <result column="RE_Summary" jdbcType="LONGVARCHAR" property="reSummary" />
+  </resultMap>
+  <sql id="Base_Column_List">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    RE_ID, BI_GUID, RE_Risk_Level, RE_Publish_Time, RE_Scene_Type_Id, RE_Scene_Type, 
+    RE_Period, RE_Start_Time, RE_End_Time
+  </sql>
+  <sql id="Blob_Column_List">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    RE_Summary
+  </sql>
+
+  <resultMap id="CreditInfoVo" type="cn.flightfeather.supervision.lightshare.vo.CreditInfoVo">
+
+  </resultMap>
+
+  <select id="getLatestPeriod" resultType="String">
+    SELECT @var_period:= (
+    SELECT
+    a.RE_Start_Time
+    FROM
+    ea_t_risk_evaluation AS a
+    LEFT JOIN ea_t_baseinfo AS b ON a.BI_GUID = b.BI_GUID
+    <where>
+      <if test="provinceCode != null">
+        AND b.BI_Province_Code = #{provinceCode}
+      </if>
+      <if test="provinceName != null">
+        AND b.BI_Province_Name = #{provinceName}
+      </if>
+      <if test="cityCode != null">
+        AND b.BI_City_Code = #{cityCode}
+      </if>
+      <if test="cityName != null">
+        AND b.BI_City_Name = #{cityName}
+      </if>
+      <if test="districtCode != null">
+        AND b.BI_District_Code = #{districtCode}
+      </if>
+      <if test="districtName != null">
+        AND b.BI_District_Name = #{districtName}
+      </if>
+      <if test="townCode != null">
+        AND b.BI_Town_Code = #{townCode}
+      </if>
+      <if test="townName != null">
+        AND b.BI_Town_Name = #{townName}
+      </if>
+      <if test="areaCode != null">
+        AND b.BI_Area_Code = #{areaCode}
+      </if>
+      <if test="area != null">
+        AND b.BI_Area = #{area}
+      </if>
+      <if test="mcId != null">
+        AND b.BI_Management_Company_Id = #{mcId}
+      </if>
+      <if test="mcName != null">
+        AND b.BI_Management_Company = #{mcName}
+      </if>
+      <if test="sceneTypes.size() != 0">
+        AND a.RE_Scene_Type_Id in
+        <foreach collection="sceneTypes" item="type" open="(" separator="," close=")">
+          #{type, jdbcType=VARCHAR}
+        </foreach>
+      </if>
+    </where>
+    ORDER BY
+    a.RE_Publish_Time DESC
+    LIMIT 1
+    )
+  </select>
+  <select id="getRiskCount" resultMap="BaseResultMap">
+    SELECT
+    a.*
+    FROM
+    ea_t_risk_evaluation AS a
+    LEFT JOIN ea_t_baseinfo AS b ON a.BI_GUID = b.BI_GUID
+    <where>
+      <if test="provinceCode != null">
+        AND b.BI_Province_Code = #{provinceCode}
+      </if>
+      <if test="provinceName != null">
+        AND b.BI_Province_Name = #{provinceName}
+      </if>
+      <if test="cityCode != null">
+        AND b.BI_City_Code = #{cityCode}
+      </if>
+      <if test="cityName != null">
+        AND b.BI_City_Name = #{cityName}
+      </if>
+      <if test="districtCode != null">
+        AND b.BI_District_Code = #{districtCode}
+      </if>
+      <if test="districtName != null">
+        AND b.BI_District_Name = #{districtName}
+      </if>
+      <if test="townCode != null">
+        AND b.BI_Town_Code = #{townCode}
+      </if>
+      <if test="townName != null">
+        AND b.BI_Town_Name = #{townName}
+      </if>
+      <if test="areaCode != null">
+        AND b.BI_Area_Code = #{areaCode}
+      </if>
+      <if test="area != null">
+        AND b.BI_Area = #{area}
+      </if>
+      <if test="mcId != null">
+        AND b.BI_Management_Company_Id = #{mcId}
+      </if>
+      <if test="mcName != null">
+        AND b.BI_Management_Company = #{mcName}
+      </if>
+      <if test="sceneTypes.size() != 0">
+        AND a.RE_Scene_Type_Id in
+        <foreach collection="sceneTypes" item="type" open="(" separator="," close=")">
+          #{type}
+        </foreach>
+      </if>
+      <if test="period != null">
+        AND a.RE_Start_Time &lt;= '${period}'
+        AND a.RE_End_Time >= '${period}'
+      </if>
+    </where>
+  </select>
+  <select id="searchRiskList" resultMap="CreditInfoVo">
+    SELECT
+    b.BI_GUID AS userId,
+    b.BI_Name AS name,
+    a.RE_Scene_Type_Id AS sceneType,
+    b.CI_Name AS departmentName,
+    b.BI_Management_Company AS managementCompany,
+    a.RE_Publish_Time AS publishTime,
+    a.RE_Publish_Time AS updateTime,
+    a.RE_Risk_Level AS riskLevel,
+    b.BI_District_Name AS district,
+    b.BI_Town_Name AS town,
+    c.UI_IsEnable AS status
+    FROM
+    ea_t_risk_evaluation AS a
+    LEFT JOIN ea_t_baseinfo AS b ON a.BI_GUID = b.BI_GUID
+    LEFT JOIN sm_t_userinfo AS c ON a.BI_GUID = c.UI_GUID
+    <where>
+      <if test="provinceCode != null">
+        AND b.BI_Province_Code = #{provinceCode}
+      </if>
+      <if test="provinceName != null">
+        AND b.BI_Province_Name = #{provinceName}
+      </if>
+      <if test="cityCode != null">
+        AND b.BI_City_Code = #{cityCode}
+      </if>
+      <if test="cityName != null">
+        AND b.BI_City_Name = #{cityName}
+      </if>
+      <if test="districtCode != null">
+        AND b.BI_District_Code = #{districtCode}
+      </if>
+      <if test="districtName != null">
+        AND b.BI_District_Name = #{districtName}
+      </if>
+      <if test="townCode != null">
+        AND b.BI_Town_Code = #{townCode}
+      </if>
+      <if test="townName != null">
+        AND b.BI_Town_Name = #{townName}
+      </if>
+      <if test="areaCode != null">
+        AND b.BI_Area_Code = #{areaCode}
+      </if>
+      <if test="area != null">
+        AND b.BI_Area = #{area}
+      </if>
+      <if test="mcId != null">
+        AND b.BI_Management_Company_Id = #{mcId}
+      </if>
+      <if test="mcName != null">
+        AND b.BI_Management_Company = #{mcName}
+      </if>
+      <if test="sceneTypes.size() != 0">
+        AND a.RE_Scene_Type_Id in
+        <foreach collection="sceneTypes" item="type" open="(" separator="," close=")">
+          #{type, jdbcType=VARCHAR}
+        </foreach>
+      </if>
+      <if test="riskType != null">
+        AND a.RE_Risk_Level = ${riskType}
+      </if>
+      <if test="searchText != null">
+        AND b.BI_Name LIKE '%${searchText}%'
+      </if>
+      <if test="period != null">
+        AND a.RE_Start_Time &lt;= '${period}'
+        AND a.RE_End_Time >= '${period}'
+      </if>
+    </where>
+  </select>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/SceneTypeMapper.xml b/src/main/resources/mapper/SceneTypeMapper.xml
new file mode 100644
index 0000000..c84fe31
--- /dev/null
+++ b/src/main/resources/mapper/SceneTypeMapper.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.SceneTypeMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.SceneType" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="SC_Id" property="scId" jdbcType="INTEGER" />
+    <result column="SC_Name" property="scName" jdbcType="VARCHAR" />
+    <result column="SC_Tag" property="scTag" jdbcType="VARCHAR" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    SC_Id, SC_Name, SC_Tag
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/ScheduleSignRecordMapper.xml b/src/main/resources/mapper/ScheduleSignRecordMapper.xml
new file mode 100644
index 0000000..7f1d702
--- /dev/null
+++ b/src/main/resources/mapper/ScheduleSignRecordMapper.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.ScheduleSignRecordMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.ScheduleSignRecord" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="SR_ID" property="srId" jdbcType="INTEGER" />
+    <result column="SR_Schedule_Id" property="srScheduleId" jdbcType="INTEGER" />
+    <result column="SR_User_ID" property="srUserId" jdbcType="VARCHAR" />
+    <result column="SR_Sign_Status" property="srSignStatus" jdbcType="BIT" />
+    <result column="SR_Sign_Time" property="srSignTime" jdbcType="TIMESTAMP" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    SR_ID, SR_Schedule_Id, SR_User_ID, SR_Sign_Status, SR_Sign_Time
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/SelfPatrolMediaFileMapper.xml b/src/main/resources/mapper/SelfPatrolMediaFileMapper.xml
new file mode 100644
index 0000000..77b1e85
--- /dev/null
+++ b/src/main/resources/mapper/SelfPatrolMediaFileMapper.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.SelfPatrolMediaFileMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.SelfPatrolMediaFile" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="MF_GUID" property="mfGuid" jdbcType="VARCHAR" />
+    <result column="LR_GUID" property="lrGuid" jdbcType="VARCHAR" />
+    <result column="CI_GUID" property="ciGuid" jdbcType="VARCHAR" />
+    <result column="MF_FileType" property="mfFiletype" jdbcType="INTEGER" />
+    <result column="MF_SaveTime" property="mfSavetime" jdbcType="TIMESTAMP" />
+    <result column="MF_IsDelete" property="mfIsdelete" jdbcType="BIT" />
+    <result column="MF_Extension1" property="mfExtension1" jdbcType="VARCHAR" />
+    <result column="MF_Extension2" property="mfExtension2" jdbcType="VARCHAR" />
+    <result column="MF_Extension3" property="mfExtension3" jdbcType="VARCHAR" />
+    <result column="MF_Remark" property="mfRemark" jdbcType="VARCHAR" />
+  </resultMap>
+  <resultMap id="ResultMapWithBLOBs" type="cn.flightfeather.supervision.domain.entity.SelfPatrolMediaFile" extends="BaseResultMap" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <result column="MF_Path1" property="mfPath1" jdbcType="LONGVARCHAR" />
+    <result column="MF_Description1" property="mfDescription1" jdbcType="LONGVARCHAR" />
+    <result column="MF_Path2" property="mfPath2" jdbcType="LONGVARCHAR" />
+    <result column="MF_Description2" property="mfDescription2" jdbcType="LONGVARCHAR" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    MF_GUID, LR_GUID, CI_GUID, MF_FileType, MF_SaveTime, MF_IsDelete, MF_Extension1, 
+    MF_Extension2, MF_Extension3, MF_Remark
+  </sql>
+  <sql id="Blob_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    MF_Path1, MF_Description1, MF_Path2, MF_Description2
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/SelfPatrolRecordMapper.xml b/src/main/resources/mapper/SelfPatrolRecordMapper.xml
new file mode 100644
index 0000000..7b0c295
--- /dev/null
+++ b/src/main/resources/mapper/SelfPatrolRecordMapper.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.SelfPatrolRecordMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.SelfPatrolRecord" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="SR_GUID" property="srGuid" jdbcType="VARCHAR" />
+    <result column="SP_GUID" property="spGuid" jdbcType="VARCHAR" />
+    <result column="LS_SubTypeId" property="lsSubtypeid" jdbcType="INTEGER" />
+    <result column="LS_SubTypeName" property="lsSubtypename" jdbcType="VARCHAR" />
+    <result column="SR_Year" property="srYear" jdbcType="INTEGER" />
+    <result column="SR_Month" property="srMonth" jdbcType="TINYINT" />
+    <result column="SR_Day" property="srDay" jdbcType="TINYINT" />
+    <result column="CI_GUID" property="ciGuid" jdbcType="VARCHAR" />
+    <result column="CI_Name" property="ciName" jdbcType="VARCHAR" />
+    <result column="SR_EASubmitKind" property="srEasubmitkind" jdbcType="TINYINT" />
+    <result column="SR_VerifierID" property="srVerifierid" jdbcType="VARCHAR" />
+    <result column="SR_VerifierRealName" property="srVerifierrealname" jdbcType="VARCHAR" />
+    <result column="SR_VerifyDate" property="srVerifydate" jdbcType="TIMESTAMP" />
+    <result column="SR_IsVerify" property="srIsverify" jdbcType="BIT" />
+    <result column="SR_VerifyRst" property="srVerifyrst" jdbcType="VARCHAR" />
+    <result column="SR_AIVerifyTime" property="srAiverifytime" jdbcType="INTEGER" />
+    <result column="SR_AIIsVerify" property="srAiisverify" jdbcType="BIT" />
+    <result column="SR_AIVerifyRst" property="srAiverifyrst" jdbcType="VARCHAR" />
+    <result column="SR_IsAI" property="srIsai" jdbcType="BIT" />
+    <result column="SR_SubmitID" property="srSubmitid" jdbcType="VARCHAR" />
+    <result column="SR_SubmitName" property="srSubmitname" jdbcType="VARCHAR" />
+    <result column="SR_IsSubmitOnTime" property="srIssubmitontime" jdbcType="BIT" />
+    <result column="SR_SubmitDate" property="srSubmitdate" jdbcType="TIMESTAMP" />
+    <result column="SR_UpdateType" property="srUpdatetype" jdbcType="TINYINT" />
+    <result column="SR_Extension1" property="srExtension1" jdbcType="VARCHAR" />
+    <result column="SR_Extension2" property="srExtension2" jdbcType="VARCHAR" />
+    <result column="SR_Extension3" property="srExtension3" jdbcType="VARCHAR" />
+    <result column="SR_Remark" property="srRemark" jdbcType="VARCHAR" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    SR_GUID, SP_GUID, LS_SubTypeId, LS_SubTypeName, SR_Year, SR_Month, SR_Day, CI_GUID, 
+    CI_Name, SR_EASubmitKind, SR_VerifierID, SR_VerifierRealName, SR_VerifyDate, SR_IsVerify, 
+    SR_VerifyRst, SR_AIVerifyTime, SR_AIIsVerify, SR_AIVerifyRst, SR_IsAI, SR_SubmitID, 
+    SR_SubmitName, SR_IsSubmitOnTime, SR_SubmitDate, SR_UpdateType, SR_Extension1, SR_Extension2, 
+    SR_Extension3, SR_Remark
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/SelfPatrolTaskMapper.xml b/src/main/resources/mapper/SelfPatrolTaskMapper.xml
new file mode 100644
index 0000000..3b02870
--- /dev/null
+++ b/src/main/resources/mapper/SelfPatrolTaskMapper.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.SelfPatrolTaskMapper">
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.SelfPatrolTask">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="SP_GUID" jdbcType="VARCHAR" property="spGuid" />
+    <result column="SP_To_User_Id" jdbcType="VARCHAR" property="spToUserId" />
+    <result column="SP_From_User_Id" jdbcType="VARCHAR" property="spFromUserId" />
+    <result column="SP_Scene_Type_Id" jdbcType="INTEGER" property="spSceneTypeId" />
+    <result column="SP_Ledger_Type_Id" jdbcType="VARCHAR" property="spLedgerTypeId" />
+    <result column="SP_Tag" jdbcType="VARCHAR" property="spTag" />
+    <result column="SP_Publish_Unit" jdbcType="VARCHAR" property="spPublishUnit" />
+    <result column="SP_Task_Year" jdbcType="INTEGER" property="spTaskYear" />
+    <result column="SP_Task_Month" jdbcType="INTEGER" property="spTaskMonth" />
+    <result column="SP_Create_Time" jdbcType="TIMESTAMP" property="spCreateTime" />
+    <result column="SP_Deadline" jdbcType="TIMESTAMP" property="spDeadline" />
+    <result column="SP_Task_Status" jdbcType="INTEGER" property="spTaskStatus" />
+  </resultMap>
+  <sql id="Base_Column_List">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    SP_GUID, SP_To_User_Id, SP_From_User_Id, SP_Scene_Type_Id, SP_Ledger_Type_Id, SP_Tag, 
+    SP_Publish_Unit, SP_Task_Year, SP_Task_Month, SP_Create_Time, SP_Deadline, SP_Task_Status
+  </sql>
+
+  <resultMap id="SelfPatrolTaskVo" type="cn.flightfeather.supervision.lightshare.vo.SelfPatrolTaskVo" />
+  <select id="getPublishedTask" resultMap="SelfPatrolTaskVo">
+    SELECT
+    a.SP_GUID AS guid,
+    a.SP_To_User_Id AS toUserId,
+    b.UI_RealName AS toUserName,
+    a.SP_From_User_Id AS fromUserId,
+    c.UI_RealName AS fromUserName,
+    a.SP_Scene_Type_Id AS sceneTypeId,
+    a.SP_Ledger_Type_Id AS ledgerTypeId,
+    a.SP_Tag AS tag,
+    a.SP_Publish_Unit AS publishUnit,
+    a.SP_Create_Time AS createTime,
+    a.SP_Deadline AS deadline,
+    a.SP_Task_Status AS taskStatus,
+    SUM(IF(d.SP_GUID IS NOT NULL, 1, 0)) AS finished
+    FROM
+    ea_t_self_patrol_task AS a
+    LEFT JOIN sm_t_userinfo AS b ON a.SP_To_User_Id = b.UI_GUID
+    LEFT JOIN sm_t_userinfo AS c ON a.SP_From_User_Id = c.UI_GUID
+    LEFT JOIN ea_t_self_patrol_record AS d ON a.SP_GUID = d.SP_GUID
+    WHERE a.SP_From_User_Id = #{userId}
+    <if test="year != null">
+      AND a.SP_Task_Year = #{year}
+    </if>
+    <if test="month != null">
+      AND a.SP_Task_Month = #{month}
+    </if>
+    GROUP BY
+    a.SP_GUID
+    ORDER BY createTime DESC
+  </select>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/TownMapper.xml b/src/main/resources/mapper/TownMapper.xml
new file mode 100644
index 0000000..474690d
--- /dev/null
+++ b/src/main/resources/mapper/TownMapper.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.TownMapper">
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.Town">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="T_TownID" jdbcType="INTEGER" property="tTownid" />
+    <result column="D_DistrictID" jdbcType="INTEGER" property="dDistrictid" />
+    <result column="C_CityID" jdbcType="INTEGER" property="cCityid" />
+    <result column="P_ProvinceID" jdbcType="INTEGER" property="pProvinceid" />
+    <result column="T_TownCode" jdbcType="VARCHAR" property="tTowncode" />
+    <result column="T_TownName" jdbcType="VARCHAR" property="tTownname" />
+    <result column="T_Station" jdbcType="VARCHAR" property="tStation" />
+  </resultMap>
+  <sql id="Base_Column_List">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    T_TownID, D_DistrictID, C_CityID, P_ProvinceID, T_TownCode, T_TownName, T_Station
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/UserConfigMapper.xml b/src/main/resources/mapper/UserConfigMapper.xml
new file mode 100644
index 0000000..6713e76
--- /dev/null
+++ b/src/main/resources/mapper/UserConfigMapper.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.UserConfigMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.UserConfig" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="UC_Id" property="ucId" jdbcType="INTEGER" />
+    <result column="UC_User_Type_Id" property="ucUserTypeId" jdbcType="INTEGER" />
+    <result column="UC_User_Type" property="ucUserType" jdbcType="VARCHAR" />
+    <result column="UC_User_SubType_Id" property="ucUserSubtypeId" jdbcType="INTEGER" />
+    <result column="UC_User_SubType" property="ucUserSubtype" jdbcType="VARCHAR" />
+    <result column="UC_Province_Code" property="ucProvinceCode" jdbcType="VARCHAR" />
+    <result column="UC_Province_Name" property="ucProvinceName" jdbcType="VARCHAR" />
+    <result column="UC_City_Code" property="ucCityCode" jdbcType="VARCHAR" />
+    <result column="UC_City_Name" property="ucCityName" jdbcType="VARCHAR" />
+    <result column="UC_District_Code" property="ucDistrictCode" jdbcType="VARCHAR" />
+    <result column="UC_District_Name" property="ucDistrictName" jdbcType="VARCHAR" />
+    <result column="UC_Town_Code" property="ucTownCode" jdbcType="VARCHAR" />
+    <result column="UC_Town_Name" property="ucTownName" jdbcType="VARCHAR" />
+    <result column="UC_Area_Code" property="ucAreaCode" jdbcType="VARCHAR" />
+    <result column="UC_Area" property="ucArea" jdbcType="VARCHAR" />
+    <result column="UC_Management_Company_Id" property="ucManagementCompanyId" jdbcType="VARCHAR" />
+    <result column="UC_Management_Company" property="ucManagementCompany" jdbcType="VARCHAR" />
+    <result column="UC_Scene_Range" property="ucSceneRange" jdbcType="VARCHAR" />
+    <result column="UC_Extension1" property="ucExtension1" jdbcType="VARCHAR" />
+    <result column="UC_Extension2" property="ucExtension2" jdbcType="VARCHAR" />
+    <result column="UC_Extension3" property="ucExtension3" jdbcType="VARCHAR" />
+    <result column="UC_Remark" property="ucRemark" jdbcType="VARCHAR" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    UC_Id, UC_User_Type_Id, UC_User_Type, UC_User_SubType_Id, UC_User_SubType, UC_Province_Code, 
+    UC_Province_Name, UC_City_Code, UC_City_Name, UC_District_Code, UC_District_Name, 
+    UC_Town_Code, UC_Town_Name, UC_Area_Code, UC_Area, UC_Management_Company_Id, UC_Management_Company, 
+    UC_Scene_Range, UC_Extension1, UC_Extension2, UC_Extension3, UC_Remark
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/UserLoginLogMapper.xml b/src/main/resources/mapper/UserLoginLogMapper.xml
new file mode 100644
index 0000000..b95966d
--- /dev/null
+++ b/src/main/resources/mapper/UserLoginLogMapper.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.UserLoginLogMapper" >
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.UserLoginLog" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="UL_Id" property="ulId" jdbcType="INTEGER" />
+    <result column="UL_User_GUID" property="ulUserGuid" jdbcType="VARCHAR" />
+    <result column="UL_Login_Time" property="ulLoginTime" jdbcType="TIMESTAMP" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    <!--
+      WARNING - @mbg.generated
+    -->
+    UL_Id, UL_User_GUID, UL_Login_Time
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/UserMapMapper.xml b/src/main/resources/mapper/UserMapMapper.xml
index 1d467f5..67f7b42 100644
--- a/src/main/resources/mapper/UserMapMapper.xml
+++ b/src/main/resources/mapper/UserMapMapper.xml
@@ -1,19 +1,20 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
-<mapper namespace="cn.flightfeather.supervision.domain.mapper.UserMapMapper" >
-  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.UserMap" >
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.UserMapMapper">
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.UserMap">
     <!--
       WARNING - @mbg.generated
     -->
-    <id column="TZ_User_Id" property="tzUserId" jdbcType="VARCHAR" />
-    <result column="TZ_User_Name" property="tzUserName" jdbcType="VARCHAR" />
-    <result column="SV_User_Id" property="svUserId" jdbcType="VARCHAR" />
-    <result column="SV_User_Name" property="svUserName" jdbcType="VARCHAR" />
+    <id column="TZ_User_Id" jdbcType="VARCHAR" property="tzUserId" />
+    <result column="TZ_User_Name" jdbcType="VARCHAR" property="tzUserName" />
+    <result column="SV_User_Id" jdbcType="VARCHAR" property="svUserId" />
+    <result column="SV_User_Name" jdbcType="VARCHAR" property="svUserName" />
+    <result column="UM_Create_Time" jdbcType="TIMESTAMP" property="umCreateTime" />
   </resultMap>
-  <sql id="Base_Column_List" >
+  <sql id="Base_Column_List">
     <!--
       WARNING - @mbg.generated
     -->
-    TZ_User_Id, TZ_User_Name, SV_User_Id, SV_User_Name
+    TZ_User_Id, TZ_User_Name, SV_User_Id, SV_User_Name, UM_Create_Time
   </sql>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/UserinfoMapper.xml b/src/main/resources/mapper/UserinfoMapper.xml
new file mode 100644
index 0000000..7fdffc3
--- /dev/null
+++ b/src/main/resources/mapper/UserinfoMapper.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.UserinfoMapper">
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.Userinfo">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="UI_GUID" jdbcType="VARCHAR" property="guid" />
+    <result column="UI_HeadIconUrl" jdbcType="VARCHAR" property="headIconUrl" />
+    <result column="UI_AcountName" jdbcType="VARCHAR" property="acountname" />
+    <result column="UI_RealName" jdbcType="VARCHAR" property="realname" />
+    <result column="UI_Password" jdbcType="VARCHAR" property="password" />
+    <result column="UI_UserTypeID" jdbcType="TINYINT" property="usertypeid" />
+    <result column="UI_UserType" jdbcType="VARCHAR" property="usertype" />
+    <result column="UI_User_SubType_Id" jdbcType="INTEGER" property="userSubTypeId" />
+    <result column="UI_User_SubType" jdbcType="VARCHAR" property="userSubType" />
+    <result column="D_GUID" jdbcType="VARCHAR" property="dGuid" />
+    <result column="UI_DepartmentName" jdbcType="VARCHAR" property="departmentname" />
+    <result column="UI_IsEnable" jdbcType="BIT" property="isenable" />
+    <result column="UI_WorkNo" jdbcType="VARCHAR" property="workno" />
+    <result column="UI_Telephone" jdbcType="VARCHAR" property="telephone" />
+    <result column="UI_WechatID" jdbcType="VARCHAR" property="wechatid" />
+    <result column="UI_Create_Time" jdbcType="TIMESTAMP" property="uiCreateTime" />
+    <result column="UI_Login_Time" jdbcType="TIMESTAMP" property="uiLoginTime" />
+    <result column="UI_Extension1" jdbcType="VARCHAR" property="extension1" />
+    <result column="UI_Extension2" jdbcType="VARCHAR" property="extension2" />
+    <result column="UI_Extension3" jdbcType="VARCHAR" property="extension3" />
+    <result column="UI_Remark" jdbcType="VARCHAR" property="remark" />
+  </resultMap>
+  <sql id="Base_Column_List">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    UI_GUID, UI_HeadIconUrl, UI_AcountName, UI_RealName, UI_Password, UI_UserTypeID, 
+    UI_UserType, UI_User_SubType_Id, UC_User_SubType, D_GUID, UI_DepartmentName, UI_IsEnable, 
+    UI_WorkNo, UI_Telephone, UI_WechatID, UI_Create_Time, UI_Login_Time, UI_Extension1, 
+    UI_Extension2, UI_Extension3, UI_Remark
+  </sql>
+
+  <select id="searchUser" resultMap="BaseResultMap">
+    SELECT
+    a.*
+    FROM
+    sm_t_userinfo AS a
+    LEFT JOIN ea_t_baseinfo AS b ON a.UI_GUID = b.BI_GUID
+    WHERE
+    (a.UI_WorkNo IS NULL OR a.UI_WorkNo != 'test')
+    AND (a.UI_WorkNo != 'test' || a.UI_WorkNo IS NULL)
+    <if test="provinceCode != null">
+      AND b.BI_Province_Code = #{provinceCode}
+    </if>
+    <if test="provinceName != null">
+      AND b.BI_Province_Name = #{provinceName}
+    </if>
+    <if test="cityCode != null">
+      AND b.BI_City_Code = #{cityCode}
+    </if>
+    <if test="cityName != null">
+      AND b.BI_City_Name = #{cityName}
+    </if>
+    <if test="districtCode != null">
+      AND b.BI_District_Code = #{districtCode}
+    </if>
+    <if test="districtName != null">
+      AND (b.BI_District_Name = #{districtName} OR a.UI_Extension1 = #{districtName})
+    </if>
+    <if test="townCode != null">
+      AND b.BI_Town_Code = #{townCode}
+    </if>
+    <if test="townName != null">
+      AND b.BI_Town_Name = #{townName}
+    </if>
+    <if test="areaCode != null">
+      AND b.BI_Area_Code = #{areaCode}
+    </if>
+    <if test="area != null">
+      AND b.BI_Area = #{area}
+    </if>
+    <if test="mcId != null">
+      AND b.BI_Management_Company_Id = #{mcId}
+    </if>
+    <if test="mcName != null">
+      AND b.BI_Management_Company = #{mcName}
+    </if>
+    <if test="userTypeId != null">
+      AND a.UI_UserTypeID = #{userTypeId}
+    </if>
+    <if test="userSubTypeId != null">
+      AND a.UI_User_SubType_Id = #{userSubTypeId}
+    </if>
+    <if test="sceneTypes.size() != 0">
+      AND a.UI_Extension2 in
+      <foreach collection="sceneTypes" item="type" open="(" separator="," close=")">
+        #{type, jdbcType=VARCHAR}
+      </foreach>
+    </if>
+    <if test="searchText != null and searchText != ''">
+      AND a.UI_RealName LIKE CONCAT('%', #{searchText}, '%')
+    </if>
+  </select>
+
+  <select id="getUnAuthedUsers" resultMap="BaseResultMap">
+    SELECT
+    a.*
+    FROM
+    sm_t_userinfo AS a
+    LEFT JOIN ea_t_personal_info AS b ON a.UI_GUID = b.PI_Scene_Id
+    LEFT JOIN ea_t_baseinfo AS c ON a.UI_GUID = c.BI_GUID
+    WHERE
+    a.UI_IsEnable = TRUE
+    AND a.UI_UserTypeID = 3
+    AND (
+    a.UI_WorkNo IS NULL
+    OR a.UI_WorkNo != 'test'
+    )
+    AND a.UI_Login_Time IS NOT NULL
+    AND (
+    (
+    c.BI_Extension3 != 'authenticated'
+    OR c.BI_Extension3 IS NULL
+    )
+    OR b.PI_Extension3 IS NULL
+    )
+  </select>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/VOCHourValueMapper.xml b/src/main/resources/mapper/VOCHourValueMapper.xml
index 84f2296..7cb92dc 100644
--- a/src/main/resources/mapper/VOCHourValueMapper.xml
+++ b/src/main/resources/mapper/VOCHourValueMapper.xml
@@ -1,28 +1,31 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
-<mapper namespace="cn.flightfeather.supervision.domain.mapper.VOCHourValueMapper" >
-  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.VOCHourValue" >
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.VOCHourValueMapper">
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.VOCHourValue">
     <!--
       WARNING - @mbg.generated
     -->
-    <id column="VOC_ID" property="vocId" jdbcType="INTEGER" />
-    <result column="VOC_Stat_Code" property="vocStatCode" jdbcType="VARCHAR" />
-    <result column="VOC_Create_Time" property="vocCreateTime" jdbcType="TIMESTAMP" />
-    <result column="VOC_Data_Time" property="vocDataTime" jdbcType="TIMESTAMP" />
-    <result column="VOC_Value" property="vocValue" jdbcType="DOUBLE" />
-    <result column="VOC_Fan_Electricity_1" property="vocFanElectricity1" jdbcType="DOUBLE" />
-    <result column="VOC_Fan_Electricity_2" property="vocFanElectricity2" jdbcType="DOUBLE" />
-    <result column="VOC_Fan_Electricity_3" property="vocFanElectricity3" jdbcType="DOUBLE" />
-    <result column="VOC_Fan_Electricity_4" property="vocFanElectricity4" jdbcType="DOUBLE" />
-    <result column="VOC_Fan_Electricity_5" property="vocFanElectricity5" jdbcType="DOUBLE" />
-    <result column="VOC_Fan_Electricity_6" property="vocFanElectricity6" jdbcType="DOUBLE" />
+    <id column="VOC_ID" jdbcType="INTEGER" property="vocId" />
+    <result column="VOC_Stat_Code" jdbcType="VARCHAR" property="vocStatCode" />
+    <result column="VOC_Create_Time" jdbcType="TIMESTAMP" property="vocCreateTime" />
+    <result column="VOC_Data_Time" jdbcType="TIMESTAMP" property="vocDataTime" />
+    <result column="VOC_Value" jdbcType="DOUBLE" property="vocValue" />
+    <result column="VOC_Unit" jdbcType="VARCHAR" property="vocUnit" />
+    <result column="VOC_Temperature" jdbcType="DOUBLE" property="vocTemperature" />
+    <result column="VOC_RH" jdbcType="DOUBLE" property="vocRh" />
+    <result column="VOC_Fan_Electricity_1" jdbcType="DOUBLE" property="vocFanElectricity1" />
+    <result column="VOC_Fan_Electricity_2" jdbcType="DOUBLE" property="vocFanElectricity2" />
+    <result column="VOC_Fan_Electricity_3" jdbcType="DOUBLE" property="vocFanElectricity3" />
+    <result column="VOC_Fan_Electricity_4" jdbcType="DOUBLE" property="vocFanElectricity4" />
+    <result column="VOC_Fan_Electricity_5" jdbcType="DOUBLE" property="vocFanElectricity5" />
+    <result column="VOC_Fan_Electricity_6" jdbcType="DOUBLE" property="vocFanElectricity6" />
   </resultMap>
-  <sql id="Base_Column_List" >
+  <sql id="Base_Column_List">
     <!--
       WARNING - @mbg.generated
     -->
-    VOC_ID, VOC_Stat_Code, VOC_Create_Time, VOC_Data_Time, VOC_Value, VOC_Fan_Electricity_1, 
-    VOC_Fan_Electricity_2, VOC_Fan_Electricity_3, VOC_Fan_Electricity_4, VOC_Fan_Electricity_5, 
-    VOC_Fan_Electricity_6
+    VOC_ID, VOC_Stat_Code, VOC_Create_Time, VOC_Data_Time, VOC_Value, VOC_Unit, VOC_Temperature, 
+    VOC_RH, VOC_Fan_Electricity_1, VOC_Fan_Electricity_2, VOC_Fan_Electricity_3, VOC_Fan_Electricity_4, 
+    VOC_Fan_Electricity_5, VOC_Fan_Electricity_6
   </sql>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/VocPurifyDeviceMapper.xml b/src/main/resources/mapper/VocPurifyDeviceMapper.xml
new file mode 100644
index 0000000..7d098de
--- /dev/null
+++ b/src/main/resources/mapper/VocPurifyDeviceMapper.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.flightfeather.supervision.domain.mapper.VocPurifyDeviceMapper">
+  <resultMap id="BaseResultMap" type="cn.flightfeather.supervision.domain.entity.VocPurifyDevice">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="VP_Id" jdbcType="INTEGER" property="vpId" />
+    <result column="IB_GUID" jdbcType="VARCHAR" property="ibGuid" />
+    <result column="VP_Air_Volume" jdbcType="INTEGER" property="vpAirVolume" />
+    <result column="VP_Absorbent_Name" jdbcType="VARCHAR" property="vpAbsorbentName" />
+    <result column="VP_Absorbent_Amount" jdbcType="INTEGER" property="vpAbsorbentAmount" />
+    <result column="VP_Period_Unit" jdbcType="VARCHAR" property="vpPeriodUnit" />
+    <result column="VP_Period_Count" jdbcType="INTEGER" property="vpPeriodCount" />
+    <result column="VP_Period_Weight" jdbcType="DOUBLE" property="vpPeriodWeight" />
+    <result column="VP_Create_Time" jdbcType="TIMESTAMP" property="vpCreateTime" />
+    <result column="VP_Change_Time" jdbcType="TIMESTAMP" property="vpChangeTime" />
+  </resultMap>
+  <sql id="Base_Column_List">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    VP_Id, IB_GUID, VP_Air_Volume, VP_Absorbent_Name, VP_Absorbent_Amount, VP_Period_Unit, 
+    VP_Period_Count, VP_Period_Weight, VP_Create_Time, VP_Change_Time
+  </sql>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/templates/commitment-industrial.ftl b/src/main/resources/templates/commitment-industrial.ftl
new file mode 100644
index 0000000..f12f8b3
--- /dev/null
+++ b/src/main/resources/templates/commitment-industrial.ftl
@@ -0,0 +1,183 @@
+锘�<html>
+
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <meta http-equiv="Content-Style-Type" content="text/css" />
+    <meta name="generator" content="Aspose.Words for .NET 15.1.0.0" />
+    <title></title>
+</head>
+
+<body>
+    <div>
+        <p style="margin:0pt; orphans:0; text-align:center; widows:0">
+            <span style="font-family:瀹嬩綋; font-size:18pt; font-weight:bold">${City}${District}</span>
+            <span style="font-family:瀹嬩綋; font-size:18pt; font-weight:bold">宸ヤ笟浼佷笟鐜瀹堟硶鎵胯涔�</span>
+        </p>
+        <div style="text-align:center">
+            <table cellspacing="0" cellpadding="0" style="border-collapse:collapse; margin:0 auto; width:501.7pt">
+                <tr style="height:24.6pt">
+                    <td colspan="2"
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-left-color:#000000; border-left-style:solid; border-left-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.03pt; padding-right:5.03pt; vertical-align:middle; width:106.85pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鍗曚綅鍚嶇О</span></p>
+                    </td>
+                    <td colspan="3"
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:middle; width:372.5pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">${Department}</span></p>
+                    </td>
+                </tr>
+                <tr style="height:25.75pt">
+                    <td colspan="2"
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-left-color:#000000; border-left-style:solid; border-left-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.03pt; padding-right:5.03pt; vertical-align:middle; width:106.85pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">缁熶竴绀句細淇$敤浠g爜</span></p>
+                    </td>
+                    <td
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:middle; width:133.55pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">${SocialCode}</span></p>
+                    </td>
+                    <td
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:middle; width:97.8pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鐜瘎瀹℃壒鏂囧彿</span></p>
+                    </td>
+                    <td
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:middle; width:119.55pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">${Number}</span></p>
+                    </td>
+                </tr>
+                <tr style="height:24.95pt">
+                    <td colspan="2"
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-left-color:#000000; border-left-style:solid; border-left-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.03pt; padding-right:5.03pt; vertical-align:middle; width:106.85pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">娉曚汉</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">浠h〃</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">濮撳悕</span></p>
+                    </td>
+                    <td
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:middle; width:133.55pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">${JuridicalPerson}</span></p>
+                    </td>
+                    <td
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:middle; width:97.8pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">娉曚汉</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">浠h〃</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">韬唤璇佸彿</span></p>
+                    </td>
+                    <td
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:middle; width:119.55pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">${IdNo}</span></p>
+                    </td>
+                </tr>
+                <tr style="height:507.1pt">
+                    <td
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-left-color:#000000; border-left-style:solid; border-left-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.03pt; padding-right:5.03pt; vertical-align:middle; width:31.5pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:14pt">鎵�</span></p>
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:14pt">璇�</span></p>
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:14pt">浜�</span></p>
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:14pt">椤�</span></p>
+                    </td>
+                    <td colspan="4"
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:top; width:447.85pt">
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">涓鸿返琛岀豢鑹插彂灞曠悊蹇碉紝鍔姏钀ラ�犺瘹瀹炲畧淇$殑绀句細鐜锛岃惤瀹炲伐涓氫紒涓氱幆淇濊矗浠伙紝闄嶄綆鍥犵幆澧冪瓑鍥犵礌閫犳垚鐨勫伐涓氫紒涓氬畨鍏ㄩ殣鎮e拰灞呮皯绾犵悍锛岀‘淇濆伐涓氫紒涓氬仴搴锋湁搴忓彂灞曪紝鏈崟浣嶏紙鎴栨湰浜猴級鑷効浣滃嚭濡備笅鎵胯锛�</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span
+                                style="font-family:瀹嬩綋; font-size:12pt">涓�銆佷弗鏍奸伒瀹堝浗瀹躲�佸競銆佸尯鏈夊叧鐜淇濇姢娉曞緥銆佹硶瑙勩�佽绔犮�佹爣鍑嗗拰鏀跨瓥瑙勫畾锛屽潥鎸佸畧娉曠敓浜х粡钀ワ紝绉瀬灞ヨ鐜淇濇姢绀句細璐d换銆�</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">浜屻��</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">寤虹珛鍋ュ叏绠$悊鍒跺害锛屽姞寮烘棩甯哥鐞嗭紝寤虹珛鍗遍櫓搴熺墿鍙拌处鍜岀鐞嗚鍒掋�佹薄鏌撻槻娌昏鏂借繍琛岀鐞嗗彴璐︼紝钀藉疄鐜鐩戞祴绛夊悇椤硅姹傦紝钀藉疄鍚勭被鐜椋庨櫓闃茶寖鎺柦</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">銆�</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">涓夈��</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">宸ヤ笟搴熸按鍏ㄩ儴鏀堕泦锛屼弗鏍兼寜鐜瘎鏂囦欢杩涜澶勭疆銆�</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">鍥涖�佹秹鍙奦OCs绛夊簾姘旀帓鏀剧殑锛岄』瀹夎搴熸皵鍑�鍖栬缃紝鎺掓斁鐨勫悇绫诲ぇ姘旀薄鏌撶墿搴旇揪鍒扮幆璇勬枃浠惰瀹氱殑鎺掓斁闄愬�艰姹傘�傚簾姘斿噣鍖栬缃畾鏈熺淮鎶わ紝骞跺畾鏈熸洿鎹㈢浉搴旇�楁潗锛堟椿鎬х偔绛夛級锛屽強鏃惰褰曠浉鍏冲彴璐︼紝纭繚鍏舵甯镐娇鐢紝闃叉瀵瑰懆杈瑰眳姘戦�犳垚鐢熸椿鐜姹℃煋銆�</span>
+                               
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">浼佷笟涓秹鍚玍OCs鍘熻緟鏂欎粨搴撱�佷骇鐢烿OCs宸ヨ壓鐜妭鎴栫敓浜х嚎銆佸嵄搴熶粨搴撶瓑鍖哄煙浜х敓鐨勫簾姘斿潎搴旂嫭绔嬫敹闆嗭紝骞剁粡娲绘�х偔鍚搁檮绛夋柟寮忓鐞嗗悗锛岄�氳繃鎺掓皵绛掗珮绌烘帓鏀俱�傛帓姘旂瓛楂樺害涓嶄綆浜�15绫筹紝鍏蜂綋楂樺害鎸夌幆澧冨奖鍝嶈瘎浠疯姹傜‘瀹氥��</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span
+                                style="font-family:瀹嬩綋; font-size:12pt">浜斻�佷笌鍏锋湁銆婂嵄闄╁簾鐗╃粡钀ヨ鍙瘉銆嬭祫璐ㄥ崟浣嶇璁㈠嵄搴熷缃悎鍚岋紝骞剁‘淇濆悎鍚岀殑鏈夋晥鎬с�傛寜鏃剁紪鍒跺嵄闄╁簾鐗╃鐞嗭紙杞Щ锛夎鍒掑苟鍙婃椂鍚戠幆淇濅富绠¢儴闂ㄥ妗堬紝</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">骞朵弗鏍艰惤瀹炲嵄闄╁簾鐗╄浆绉昏仈鍗曞埗搴︺�傚叾浠栦竴鑸浐浣撳簾鐗╂寜鐓ф湰甯傛湁鍏宠瀹氬Ε鍠勫缃��</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">搴熸椿鎬х偔銆佸簾婊よ姱绛変富瑕佸嵄搴熷簲绗﹀悎銆婂嵄闄╁簾鐗╄串瀛樻薄鏌撴帶鍒舵爣鍑嗐�嬶紙GB18597-2001锛夌殑鏈夊叧瑕佹眰锛岃串瀛樻恫鎬佹垨鍗婃恫鎬佸嵄搴熺殑搴旇缃硠闇叉恫浣撴敹闆嗚缃紝鍗遍櫓搴熺墿涓嶅緱娣峰叆闈炲嵄闄╁簾鐗╀腑璐瓨锛涙敹闆嗐�佽串瀛樸�佽繍杈撱�佸埄鐢ㄣ�佸缃嵄闄╁簾鐗╃殑璁炬柦銆佸満鎵�锛屽繀椤昏缃嵄闄╁簾鐗╄绀烘爣蹇楀拰璇嗗埆鏍囧織锛屾寜鐓у嵄闄╁簾鐗╃壒鎬у垎绫昏繘琛屾敹闆嗐�佽串瀛橈紝涓嶅悓绫诲簾鐗╅棿鏈夋槑鏄剧殑闂撮殧锛屽嵄闄╁簾鐗╂爣绛惧拰鐩稿叧鏍囧織绛夊簲绗﹀悎銆婂嵄闄╁簾鐗╄瘑鍒爣蹇楄缃妧鏈鑼冦�嬶紙HJ 1276-2022锛夌浉鍏宠姹傘��</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">鍏��</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鍚屾剰鏈壙璇哄悜绀句細鍏紑锛屽苟鑷鎺ュ彈鏀垮簻銆佽涓氱粍缁囥�佷富绠¢儴闂ㄥ鎵樼涓夋柟鐩戠鍗曚綅銆佺ぞ浼氬叕浼椼�佹柊闂昏垎璁虹殑鐩戠潱銆�</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">&#xa0;</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:26.25pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">娉曚汉浠h〃鎴栬矗浠讳汉锛堢瀛楋級锛�</span>
+                            <#-- <span style="font-family:瀹嬩綋; font-size:12pt; margin-left: 150pt;">鍗曚綅锛堢洊绔狅級</span> -->
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:26.25pt; widows:0">
+                            <img src="${Sign}" style="width:100pt;height: 40pt;"/>
+                            <img src="${Seal}" style="width:70pt;height: 70pt;margin-left: 210pt;"/>
+                        </p>
+                        <p style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">&#xa0;</span></p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:right; text-indent:28.5pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">${Year}</span>
+                            <span style="font-family:瀹嬩綋; font-size:12pt">骞�</span>
+                            <span style="font-family:瀹嬩綋; font-size:12pt">${Month}</span>
+                            <span style="font-family:瀹嬩綋; font-size:12pt">鏈�</span>
+                            <span style="font-family:瀹嬩綋; font-size:12pt">${Day}</span>
+                            <span style="font-family:瀹嬩綋; font-size:12pt">鏃�</span>
+                        </p>
+                    </td>
+                </tr>
+                <tr style="height:0pt">
+                    <td style="width:42.3pt; border:none"></td>
+                    <td style="width:75.35pt; border:none"></td>
+                    <td style="width:144.35pt; border:none"></td>
+                    <td style="width:108.6pt; border:none"></td>
+                    <td style="width:130.35pt; border:none"></td>
+                </tr>
+            </table>
+        </div>
+        <p style="margin:0pt; orphans:0; text-align:justify; widows:0"><span
+                style="font-family:瀹嬩綋; font-size:10.5pt">&#xa0;</span></p>
+    </div>
+    <div class="cnzz" style="display: none;">
+        <script src="https://s23.cnzz.com/z_stat.php?id=1277655852&web_id=1277655852" language="JavaScript"></script>
+    </div>
+    <div class="docpe" style="position: absolute;color: white;margin-left:-450;">
+        <a target="_blank" href="http://www.docpe.com">妗i摵缃戔�斺�斿湪绾挎枃妗e厤璐瑰鐞�</a>
+    </div>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/src/main/resources/templates/commitment-laboratory.ftl b/src/main/resources/templates/commitment-laboratory.ftl
new file mode 100644
index 0000000..6e56115
--- /dev/null
+++ b/src/main/resources/templates/commitment-laboratory.ftl
@@ -0,0 +1,218 @@
+锘�<html>
+
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <meta http-equiv="Content-Style-Type" content="text/css" />
+    <meta name="generator" content="Aspose.Words for .NET 15.1.0.0" />
+    <title></title>
+</head>
+
+<body>
+    <div>
+        <p style="margin:0pt; orphans:0; text-align:center; widows:0">
+            <span style="font-family:瀹嬩綋; font-size:18pt; font-weight:bold">${City}${District}</span>
+            <span style="font-family:瀹嬩綋; font-size:18pt; font-weight:bold">瀹為獙瀹ょ幆澧冨畧娉曟壙璇轰功</span>
+        </p>
+        <div style="text-align:center">
+            <table cellspacing="0" cellpadding="0" style="border-collapse:collapse; margin:0 auto; width:501.7pt">
+                <tr style="height:24.6pt">
+                    <td colspan="2"
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-left-color:#000000; border-left-style:solid; border-left-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.03pt; padding-right:5.03pt; vertical-align:middle; width:106.85pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鍗曚綅鍚嶇О</span></p>
+                    </td>
+                    <td colspan="3"
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:middle; width:372.5pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">${Department}</span></p>
+                    </td>
+                </tr>
+                <tr style="height:25.75pt">
+                    <td colspan="2"
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-left-color:#000000; border-left-style:solid; border-left-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.03pt; padding-right:5.03pt; vertical-align:middle; width:106.85pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">缁熶竴绀句細淇$敤浠g爜</span></p>
+                    </td>
+                    <td
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:middle; width:133.55pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">${SocialCode}</span></p>
+                    </td>
+                    <td
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:middle; width:97.8pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鐜瘎瀹℃壒鏂囧彿</span></p>
+                    </td>
+                    <td
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:middle; width:119.55pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">${Number}</span></p>
+                    </td>
+                </tr>
+                <tr style="height:24.95pt">
+                    <td colspan="2"
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-left-color:#000000; border-left-style:solid; border-left-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.03pt; padding-right:5.03pt; vertical-align:middle; width:106.85pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">娉曚汉</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">浠h〃</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">濮撳悕</span></p>
+                    </td>
+                    <td
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:middle; width:133.55pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">${JuridicalPerson}</span></p>
+                    </td>
+                    <td
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:middle; width:97.8pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">娉曚汉</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">浠h〃</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">韬唤璇佸彿</span></p>
+                    </td>
+                    <td
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:middle; width:119.55pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">${IdNo}</span></p>
+                    </td>
+                </tr>
+                <tr style="height:507.1pt">
+                    <td
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-left-color:#000000; border-left-style:solid; border-left-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.03pt; padding-right:5.03pt; vertical-align:middle; width:31.5pt">
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:14pt">鎵�</span></p>
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:14pt">璇�</span></p>
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:14pt">浜�</span></p>
+                        <p style="margin:0pt; orphans:0; text-align:center; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:14pt">椤�</span></p>
+                    </td>
+                    <td colspan="4"
+                        style="border-bottom-color:#000000; border-bottom-style:solid; border-bottom-width:0.75pt; border-right-color:#000000; border-right-style:solid; border-right-width:0.75pt; border-top-color:#000000; border-top-style:solid; border-top-width:0.75pt; padding-left:5.4pt; padding-right:5.03pt; vertical-align:top; width:447.85pt">
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">涓鸿返琛岀豢鑹插彂灞曠悊蹇碉紝鍔姏钀ラ�犺瘹瀹炲畧淇$殑绀句細鐜锛岃惤瀹�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">瀹為獙瀹�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鐜繚璐d换锛岄檷浣庡洜鐜绛夊洜绱犻�犳垚鐨�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">瀹為獙瀹�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">瀹夊叏闅愭偅鍜屽眳姘戠籂绾凤紝纭繚</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">瀹為獙瀹�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鍋ュ悍鏈夊簭鍙戝睍锛屾湰鍗曚綅锛堟垨鏈汉锛夎嚜鎰夸綔鍑哄涓嬫壙璇猴細</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span
+                                style="font-family:瀹嬩綋; font-size:12pt">涓�銆佷弗鏍奸伒瀹堝浗瀹躲�佸競銆佸尯鏈夊叧鐜淇濇姢娉曞緥銆佹硶瑙勩�佽绔犮�佹爣鍑嗗拰鏀跨瓥瑙勫畾锛屽潥鎸佸畧娉曠敓浜х粡钀ワ紝绉瀬灞ヨ鐜淇濇姢绀句細璐d换銆�</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">浜屻��</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">寤虹珛鍋ュ叏绠$悊鍒跺害锛屽姞寮烘棩甯哥鐞嗭紝寤虹珛鍗遍櫓搴熺墿鍙拌处鍜岀鐞嗚鍒掋�佹薄鏌撻槻娌昏鏂借繍琛岀鐞嗗彴璐︼紝钀藉疄鐜鐩戞祴绛夊悇椤硅姹傦紝钀藉疄鍚勭被鐜椋庨櫓闃茶寖鎺柦</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">銆�</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">涓夈��</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">瀹為獙瀹ゆ竻娲�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">搴熸按鍏ㄩ儴鏀堕泦锛�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">涓ユ牸鎸夌幆璇勬枃浠惰繘琛屽缃�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">銆�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">瀹為獙瀹よ瘯鍓傛畫娑层�佹湭鍑�鍖栧鐞嗗簾姘达紝绂佹鎺掑叆涓嬫按绯荤粺銆�</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">鍥涖�佹秹鍙婁骇鐢熷簾姘旀帓鏀剧殑锛岄』瀹夎</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">搴熸皵鍑�鍖栬缃�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">锛�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鎺掓斁鐨勫悇绫诲ぇ姘旀薄鏌撶墿搴旇揪鍒�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鐜瘎鏂囦欢</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">瑙勫畾鐨勬帓鏀鹃檺鍊艰姹傘��</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">搴熸皵鍑�鍖栬缃畾</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt; text-decoration:none">鏈熺淮鎶�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">锛屽苟瀹氭湡鏇存崲鐩稿簲鑰楁潗锛堟椿鎬х偔绛夛級锛�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鍙婃椂璁板綍鐩稿叧鍙拌处锛岀‘淇濆叾姝e父浣跨敤锛岄槻姝㈠鍛ㄨ竟灞呮皯閫犳垚鐢熸椿鐜姹℃煋</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">銆�</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">瀹為獙瀹ゃ�侀泦涓竻娲楀尯銆佸嵄搴熶粨搴�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">绛�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鍖哄煙</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">浜х敓</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鐨�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">搴熸皵</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鍧囧簲鐙珛</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鏀堕泦锛屽苟缁忔椿鎬х偔鍚搁檮</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">绛夋柟寮忓鐞�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鍚庯紝閫氳繃鎺掓皵绛掗珮绌烘帓鏀俱�傛帓姘旂瓛楂樺害涓嶄綆浜�15绫�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">锛�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鍏蜂綋楂樺害鎸夌幆澧冨奖鍝嶈瘎浠疯姹傜‘瀹�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">銆�</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span
+                                style="font-family:瀹嬩綋; font-size:12pt">浜斻�佷笌鍏锋湁銆婂嵄闄╁簾鐗╃粡钀ヨ鍙瘉銆嬭祫璐ㄥ崟浣嶇璁㈠嵄搴熷缃悎鍚岋紝骞剁‘淇濆悎鍚岀殑鏈夋晥鎬с�傛寜鏃剁紪鍒跺嵄闄╁簾鐗╃鐞嗭紙杞Щ锛夎鍒掑苟鍙婃椂鍚戠幆淇濅富绠¢儴闂ㄥ妗堬紝</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">骞朵弗鏍艰惤瀹炲嵄闄╁簾鐗╄浆绉昏仈鍗曞埗搴︺�傚叾浠栦竴鑸浐浣撳簾鐗╂寜鐓ф湰甯傛湁鍏宠瀹氬Ε鍠勫缃��</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">瀹為獙瀹よ瘯鍓傛畫娑层�佸疄楠屾竻娲楀簾姘淬��</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鍖栧鍝佸鍣ㄦ垨灏忓寘瑁�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">銆佸簾娲绘�х偔銆佸簾婊よ姱绛変富瑕佸嵄搴熷簲绗﹀悎銆婂嵄闄╁簾鐗╄串瀛樻薄鏌撴帶鍒舵爣鍑嗐�嬶紙GB18597-2001锛夌殑鏈夊叧瑕佹眰锛屾敹闆嗐�佽串瀛樸�佽繍杈撱�佸埄鐢ㄣ�佸缃嵄闄╁簾鐗╃殑璁炬柦銆佸満鎵�锛屽繀椤昏缃嵄闄╁簾鐗╄绀烘爣蹇楀拰璇嗗埆鏍囧織锛屾寜鐓у嵄闄╁簾鐗╃壒鎬у垎绫昏繘琛屾敹闆嗐�佽串瀛橈紝涓嶅悓绫诲簾鐗╅棿鏈夋槑鏄剧殑闂撮殧锛�</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">璐瓨娑叉�佹垨鍗婃恫鎬佸嵄搴熺殑搴旇缃硠闇叉恫浣撴敹闆嗚缃紝鍗遍櫓</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">搴熺墿涓嶅緱娣峰叆闈炲嵄闄╁簾鐗╀腑璐瓨銆�</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">鍏��</span><span
+                                style="font-family:瀹嬩綋; font-size:12pt">鍚屾剰鏈壙璇哄悜绀句細鍏紑锛屽苟鑷鎺ュ彈鏀垮簻銆佽涓氱粍缁囥�佷富绠¢儴闂ㄥ鎵樼涓夋柟鐩戠鍗曚綅銆佺ぞ浼氬叕浼椼�佹柊闂昏垎璁虹殑鐩戠潱銆�</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:21pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">&#xa0;</span>
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:26.25pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">娉曚汉浠h〃鎴栬矗浠讳汉锛堢瀛楋級锛�</span>
+                            <#-- <span style="font-family:瀹嬩綋; font-size:12pt; margin-left: 150pt;">鍗曚綅锛堢洊绔狅級</span> -->
+                        </p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; text-indent:26.25pt; widows:0">
+                            <img src="${Sign}" style="width:100pt;height: 40pt;"/>
+                            <img src="${Seal}" style="width:70pt;height: 70pt;margin-left: 210pt;"/>
+                        </p>
+                        <p style="line-height:20pt; margin:0pt; orphans:0; text-align:justify; widows:0"><span
+                                style="font-family:瀹嬩綋; font-size:12pt">&#xa0;</span></p>
+                        <p
+                            style="line-height:20pt; margin:0pt; orphans:0; text-align:right; text-indent:28.5pt; widows:0">
+                            <span style="font-family:瀹嬩綋; font-size:12pt">${Year}</span>
+                            <span style="font-family:瀹嬩綋; font-size:12pt">骞�</span>
+                            <span style="font-family:瀹嬩綋; font-size:12pt">${Month}</span>
+                            <span style="font-family:瀹嬩綋; font-size:12pt">鏈�</span>
+                            <span style="font-family:瀹嬩綋; font-size:12pt">${Day}</span>
+                            <span style="font-family:瀹嬩綋; font-size:12pt">鏃�</span>
+                        </p>
+                    </td>
+                </tr>
+                <tr style="height:0pt">
+                    <td style="width:42.3pt; border:none"></td>
+                    <td style="width:75.35pt; border:none"></td>
+                    <td style="width:144.35pt; border:none"></td>
+                    <td style="width:108.6pt; border:none"></td>
+                    <td style="width:130.35pt; border:none"></td>
+                </tr>
+            </table>
+        </div>
+        <p style="margin:0pt; orphans:0; text-align:justify; widows:0"><span
+                style="font-family:瀹嬩綋; font-size:10.5pt">&#xa0;</span></p>
+    </div>
+    <div class="cnzz" style="display: none;">
+        <script src="https://s23.cnzz.com/z_stat.php?id=1277655852&web_id=1277655852" language="JavaScript"></script>
+    </div>
+    <div class="docpe" style="position: absolute;color: white;margin-left:-450;">
+        <a target="_blank" href="http://www.docpe.com">妗i摵缃戔�斺�斿湪绾挎枃妗e厤璐瑰鐞�</a>
+    </div>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/src/main/resources/templates/ledger-3206.html b/src/main/resources/templates/ledger-3206.html
new file mode 100644
index 0000000..f66513f
--- /dev/null
+++ b/src/main/resources/templates/ledger-3206.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head>
+    <meta http-equiv="Content-Type" content="application/msword; charset=utf-8"/>
+    <title>toWord</title>
+    <style type="text/css">
+        .bg {
+            font-size: 14.5px;
+            font-weight: bold;
+            color: #000;
+            background-color: #D7D7D7;
+        }
+
+        table {
+            border-width: 1px;
+            border-style: solid;
+            border-color: black;
+            table-layout: fixed;
+        }
+
+        tr {
+            height: 32px;
+            font-size: 12px;
+        }
+
+        td {
+            padding-left: 10px;
+            border-width: 1px;
+            border-style: solid;
+            border-color: black;
+            height: 32px;
+            overflow: hidden;
+            word-break: break-all;
+            word-wrap: break-word;
+            font-size: 14.5px;
+        }
+
+        .bg td {
+            font-size: 14.5px;
+        }
+
+        tr td {
+            font-size: 14.5px;
+        }
+
+        .specialHeight {
+            height: 40px;
+        }
+
+        .first_title {
+            height: 60px;
+            line-height: 60px;
+            margin: 0;
+            font-weight: bold;
+            font-size: 21px;
+        }
+
+        .second_title {
+            height: 40px;
+            line-height: 40px;
+            margin: 0;
+            font-size: 18.5px;
+        }
+
+        .doc_title {
+            font-size: 42.5px;
+            text-align: center;
+        }
+
+        body {
+            font-family: 鎬濇簮榛戜綋 Normal;
+        }
+
+        .flex {
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+        }
+
+    </style>
+</head>
+
+<body>
+<div style="width:600px; margin: 0 auto">
+    <div>
+        <!--        鍙拌处鐨勫悕绉颁綔涓烘爣棰橈紝闄勫甫鍙拌处瀵瑰簲鐨勬椂闂村拰鐢ㄦ埛鍚嶇О-->
+        <p class="doc_title" th:text="${info.title}"></p>
+        <div style="display: flex;align-items: center;justify-content: space-between;">
+            <p>鍗曚綅鍚嶇О锛�</p>
+            <p th:text="${info.userName}"></p>
+            <p>&nbsp&nbsp&nbsp&nbsp</p>
+            <p>鏈堜唤锛�</p>
+            <p th:text="${info.timeStamp}"></p>
+        </div>
+        <br />
+    </div>
+
+    <!--浣跨敤璁板綍-->
+    <table border="1" cellspacing="0" cellpadding="0" width="100%">
+        <tr class="bg">
+            <td width="5%">搴忓彿</td>
+            <td width="45%">瑁呯疆鍚嶇О</td>
+            <td width="12.5%">鏃ユ湡</td>
+            <th:block th:each="name:${info.stateNames}">
+                <td th:text="${name + '鏃堕棿'}"></td>
+            </th:block>
+
+        </tr>
+
+        <th:block th:each="record, stat:${table}">
+            <tr>
+                <td align="left" th:text="${stat.count}"></td>
+                <td align="left" th:text="${record.deviceName}"></td>
+                <td align="left" th:text="${record.date}"></td>
+                <th:block th:each="time:${record.stateTimes}">
+                    <td th:text="${time}"></td>
+                </th:block>
+            </tr>
+        </th:block>
+    </table>
+</div>
+</body>
+</html>
diff --git a/src/main/resources/templates/qr_code_bg.png b/src/main/resources/templates/qr_code_bg.png
new file mode 100644
index 0000000..d57f413
--- /dev/null
+++ b/src/main/resources/templates/qr_code_bg.png
Binary files differ
diff --git a/src/main/resources/templates/word.html b/src/main/resources/templates/word.html
index b055562..0fd7619 100644
--- a/src/main/resources/templates/word.html
+++ b/src/main/resources/templates/word.html
@@ -84,9 +84,9 @@
         <a class="download_btn" th:if="${download == 1}" th:href="${'/downloadWord?url='+ url}">涓嬭浇鏂囨。</a>
         <br>
     </div>
-    <div th:each="tableMap:${tableMap}" style="margin-bottom:20px;">
+    <div th:each="tableMap, tableMapStat:${tableMap}" style="margin-bottom:20px;">
         <!--杩欎釜鏄被鐨勮鏄�-->
-        <h4 class="first_title" th:text="${tableMap.count} + '. ' + ${tableMap.key}"></h4>
+        <h4 class="first_title" th:text="${tableMapStat.count} + '. ' + ${tableMap.key}"></h4>
         <div th:each="table,tableStat:${tableMap.value}">
 
             <!--杩欎釜鏄瘡涓姹傜殑璇存槑锛屾柟渚跨敓鎴愭枃妗e悗杩涜鏁寸悊-->
diff --git a/src/test/kotlin/cn/flightfeather/supervision/CommonTest.kt b/src/test/kotlin/cn/flightfeather/supervision/CommonTest.kt
index c72ed52..f4fab7a 100644
--- a/src/test/kotlin/cn/flightfeather/supervision/CommonTest.kt
+++ b/src/test/kotlin/cn/flightfeather/supervision/CommonTest.kt
@@ -1,17 +1,32 @@
 package cn.flightfeather.supervision
 
+import cn.flightfeather.supervision.common.docimport.UserExcelRule
+import cn.flightfeather.supervision.common.net.JinAnLianTongHttpService
 import cn.flightfeather.supervision.common.nlp.NlpController
+import cn.flightfeather.supervision.common.pdf.PdfUtil
+import cn.flightfeather.supervision.infrastructure.utils.DateUtil
+import cn.flightfeather.supervision.infrastructure.utils.FileUtil
 import cn.flightfeather.supervision.websocket.MsgType
 import cn.flightfeather.supervision.websocket.PersonalServerMsgVo
 import cn.flightfeather.supervision.websocket.WebSocketMsg
 import com.google.gson.Gson
+import org.apache.commons.codec.digest.DigestUtils
+import org.apache.commons.codec.digest.Md5Crypt
+import org.fit.pdfdom.PDFDomTreeConfig
 import org.junit.Test
 import org.springframework.boot.json.GsonJsonParser
+import java.io.File
+import java.io.FileInputStream
+import java.time.Duration
 import java.time.LocalDate
 import java.time.LocalDateTime
 import java.time.format.DateTimeFormatter
 import java.util.*
 import java.util.regex.Pattern
+import kotlin.random.Random
+import kotlin.random.nextInt
+import kotlin.reflect.jvm.internal.impl.load.kotlin.JvmType
+
 
 /**
  * @author riku
@@ -84,9 +99,10 @@
 
     @Test
     fun foo6() {
-        var a = 1667377808L
-        a*=1000
-        println(a)
+        repeat(20) {
+            val r = Random.nextInt(100..999)
+            println(r)
+        }
     }
 
     @Test
@@ -103,4 +119,43 @@
         println(st)
         println(et)
     }
+
+    @Test
+    @Throws(Exception::class)
+    open fun test_convert_pdf_to_html() {
+        val config = PDFDomTreeConfig.createDefaultConfig()
+        config.imageHandler = PDFDomTreeConfig.saveToDirectory(File("/target/res/"))
+        config.fontHandler = config.imageHandler
+        val html = PdfUtil.parseWithPdfDomTree(FileInputStream("C:\\work\\宸ヤ綔\\瀹堟硶鑷富灏忕▼搴廫\姹戒慨/2 澶ф皵姹℃煋鐗╃患鍚堟帓鏀炬爣鍑嗭紙DB31933鈥�2015锛�.pdf"), 0, 10, config)
+//        FileUtils.write(File("/mnt/test.html"), htmlOutput, "utf-8")
+        html?.toByteArray()?.let { FileUtil.uploadFile(it, "/target/", "test.html") }
+    }
+
+    @Test
+    fun foo8() {
+//        val now = Date().time / 1000
+        val now = 1667870335
+        val key = "${now}e6dc8bb9e1ff0ce973fb92b4af2e4c3f"
+        val sign = DigestUtils.md5Hex(key)
+        println(sign)
+    }
+
+    @Test
+    fun foo10() {
+        val clz = UserExcelRule::class.java
+        val params = mutableListOf<Any>()
+//        val u = clz.newInstance()
+//        println(u)
+        repeat(14) { params.add(it.toString()) }
+        println(params)
+//        val n = clz.constructors[0].newInstance("","","","","","","","","","","","","","")
+        val n = clz.constructors[0].newInstance(*params.toTypedArray())
+        println(n)
+    }
+
+    @Test
+    fun foo11(){
+        val s = DateUtil.getStartMonthByPeriod(5, 12)
+        println(s)
+    }
 }
\ No newline at end of file
diff --git a/src/test/kotlin/cn/flightfeather/supervision/CommonTest2.java b/src/test/kotlin/cn/flightfeather/supervision/CommonTest2.java
new file mode 100644
index 0000000..17afc80
--- /dev/null
+++ b/src/test/kotlin/cn/flightfeather/supervision/CommonTest2.java
@@ -0,0 +1,12 @@
+package cn.flightfeather.supervision;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CommonTest2 {
+
+    public void foo1() {
+        List<Integer> l = new ArrayList<Integer>();
+        l.size();
+    }
+}
diff --git a/src/test/kotlin/cn/flightfeather/supervision/SupervisionApplicationTests.kt b/src/test/kotlin/cn/flightfeather/supervision/SupervisionApplicationTests.kt
index 234d137..d2f2bcc 100644
--- a/src/test/kotlin/cn/flightfeather/supervision/SupervisionApplicationTests.kt
+++ b/src/test/kotlin/cn/flightfeather/supervision/SupervisionApplicationTests.kt
@@ -1,8 +1,15 @@
 package cn.flightfeather.supervision
 
 
-import cn.flightfeather.supervision.domain.mapper.ParticipantMapper
+import cn.flightfeather.supervision.domain.entity.Evaluation
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.domain.enumeration.UserType
+import cn.flightfeather.supervision.domain.mapper.*
 import cn.flightfeather.supervision.lightshare.service.DeviceService
+import cn.flightfeather.supervision.lightshare.service.EvaluationService
+import cn.flightfeather.supervision.lightshare.service.LedgerService
+import cn.flightfeather.supervision.lightshare.service.NotificationService
+import cn.flightfeather.supervision.lightshare.vo.NoticeReadStateVo
 import org.junit.Test
 import org.junit.jupiter.api.extension.ExtendWith
 import org.junit.runner.RunWith
@@ -10,6 +17,7 @@
 import org.springframework.boot.test.context.SpringBootTest
 import org.springframework.test.context.junit.jupiter.SpringExtension
 import org.springframework.test.context.junit4.SpringRunner
+import tk.mybatis.mapper.entity.Example
 
 @RunWith(SpringRunner::class)
 @ExtendWith(SpringExtension::class)
@@ -22,42 +30,70 @@
     @Autowired
     private lateinit var deviceService: DeviceService
 
+    @Autowired
+    private lateinit var ledgerRecordMapper: LedgerRecordMapper
+    @Autowired
+    private lateinit var ledgerService: LedgerService
+    @Autowired
+    private lateinit var evaluationMapper: EvaluationMapper
+    @Autowired
+    private lateinit var evaluService: EvaluationService
+    @Autowired
+    private lateinit var userinfoMapper: UserinfoMapper
+    @Autowired
+    private lateinit var notificationService: NotificationService
+
     @Test
     fun contextLoads() {
 
     }
 
-//    @Test
-//    @Throws(Exception::class)
-//    fun test1() {
-//        //manager.startServer(args[0]);
-//        val uuid = UUIDGenerator.generateUUID(4)
-//        print(uuid)
-//    }
-//
-//    @Test
-//    fun foo1() {
-//        val json = "{\"msgType\": 1, \"msgVoList\": [{\"time\": 2019-11-12}, {\"time\": 2019-11-13}]}"
-//        val m = GsonJsonParser().parseMap(json)
-//    }
-//
-//    @Test
-//    fun foo2() {
-//        val r = participantMapper.selectAsUserInfo("qwDEAdhNPvQh0yEp", "BfKQclliGvfKc91i")
-//        println(r)
-//    }
-//
-//    @org.junit.Test
-//    fun fetchData() {
-//        fetchController.run()
-////        val read = BufferedReader(InputStreamReader(System.`in`))
-////        val s = read.readLine()
-//    }
-
     @Test
     fun foo3() {
         val l = deviceService.getLatestHourValue("nVMiV6i1UvLqahOc")
         println(l)
     }
 
+    @Test
+    fun foo4() {
+        val timeList = listOf("2023-06-01","2023-07-01","2023-08-01")
+        val lList = listOf("ziYYMBiyZiKCj3Kw","bAdaVtgd8HF6NLAc","b9qhmvqYgXIVsGZS")
+        val timeList2 = listOf("2023/6-6","2023/7-7 ","2023/8-8")
+        val lList2 = listOf("h3s6FvnHoEizF0xp","WpZnJupKfZ8ovw1P","uUddc0pOrkaFgRFq")
+        userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
+            createCriteria().andEqualTo("usertypeid", UserType.Enterprise.value)
+                .andIsNotNull("uiLoginTime")
+            and(createCriteria().orIsNull("workno").orNotEqualTo("workno", "test"))
+        }).forEach {
+            it ?: return@forEach
+            it.guid ?: return@forEach
+            it.extension2 ?: return@forEach
+            for (y in timeList.indices) {
+                val t = timeList[y]
+                val l1 = ledgerService.getUserLedgerSummary(it.guid!!, it.extension2!!.toInt(), t)
+                for (i in l1.indices) {
+                    if (l1[i].upLoad && l1[i].involved) {
+                        notificationService.updateReadState(it.guid!!, listOf(NoticeReadStateVo(lList[y],
+                            hasRead = true,
+                            hasSigned = true)))
+                        break
+                    }
+                }
+            }
+            for (y in timeList2.indices) {
+                val t = timeList2[y]
+                val l = evaluationMapper.selectByExample(Example(Evaluation::class.java).apply {
+                    createCriteria().andEqualTo("evaluatorguid", it.guid)
+                        .andEqualTo("scensename", t)
+                })
+                if (l.isNotEmpty()) {
+                    notificationService.updateReadState(it.guid!!, listOf(NoticeReadStateVo(lList2[y],
+                        hasRead = true,
+                        hasSigned = true)))
+                }
+            }
+            println("")
+        }
+    }
+
 }
diff --git a/src/test/kotlin/cn/flightfeather/supervision/timingtask/PushFumeTest.kt b/src/test/kotlin/cn/flightfeather/supervision/bgtask/PushFumeTest.kt
similarity index 91%
rename from src/test/kotlin/cn/flightfeather/supervision/timingtask/PushFumeTest.kt
rename to src/test/kotlin/cn/flightfeather/supervision/bgtask/PushFumeTest.kt
index 30aac88..f9a531b 100644
--- a/src/test/kotlin/cn/flightfeather/supervision/timingtask/PushFumeTest.kt
+++ b/src/test/kotlin/cn/flightfeather/supervision/bgtask/PushFumeTest.kt
@@ -1,4 +1,4 @@
-package cn.flightfeather.supervision.timingtask
+package cn.flightfeather.supervision.bgtask
 
 import cn.flightfeather.supervision.SupervisionApplication
 import cn.flightfeather.supervision.domain.entity.AvgFumeMinuteValue
@@ -13,13 +13,9 @@
 import org.springframework.boot.test.context.SpringBootTest
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner
 import tk.mybatis.mapper.entity.Example
-import java.io.BufferedReader
-import java.io.InputStreamReader
 import java.time.LocalDateTime
 import java.time.ZoneId
 import java.util.*
-import java.util.concurrent.Executors
-import java.util.concurrent.TimeUnit
 
 @RunWith(SpringJUnit4ClassRunner::class)
 @SpringBootTest(classes = [SupervisionApplication::class])
@@ -36,17 +32,11 @@
 
     @Test
     fun doTask() {
-        var time = LocalDateTime.of(2021, 4, 16, 10, 0)
+        val end = LocalDateTime.of(2024, 4, 25, 12, 40)
+        var startTime = LocalDateTime.of(2024, 1, 3, 0, 0, 0)
+        var endTime = LocalDateTime.of(2024, 1, 3, 23, 59, 59)
 
-        val shecdule = Executors.newScheduledThreadPool(2)
-        shecdule.scheduleAtFixedRate({
-            pushFume.doTask(time)
-            time = time.plusMinutes(1)
-        }, 0, 60, TimeUnit.SECONDS)
-
-        val input = BufferedReader(InputStreamReader(System.`in`))
-        val reader: String = input.readLine()
-
+        pushFume.doTask(TaskPushFume.ZQ, mutableListOf(), startTime, endTime)
     }
 
     fun getSection(date: Date):String {
diff --git a/src/test/kotlin/cn/flightfeather/supervision/bgtask/TaskFetchVOCTest.kt b/src/test/kotlin/cn/flightfeather/supervision/bgtask/TaskFetchVOCTest.kt
new file mode 100644
index 0000000..bf7e209
--- /dev/null
+++ b/src/test/kotlin/cn/flightfeather/supervision/bgtask/TaskFetchVOCTest.kt
@@ -0,0 +1,22 @@
+package cn.flightfeather.supervision.bgtask
+
+import cn.flightfeather.supervision.SupervisionApplication
+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.test.context.junit4.SpringJUnit4ClassRunner
+import java.time.LocalDateTime
+
+@RunWith(SpringJUnit4ClassRunner::class)
+@SpringBootTest(classes = [SupervisionApplication::class])
+class TaskFetchVOCTest {
+
+    @Autowired
+    lateinit var fetchVOC: TaskFetchVOC
+
+    @Test
+    fun doTask() {
+        fetchVOC.doTask(LocalDateTime.now())
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnConstructionSiteInfoTest.kt b/src/test/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnConstructionSiteInfoTest.kt
new file mode 100644
index 0000000..c3da623
--- /dev/null
+++ b/src/test/kotlin/cn/flightfeather/supervision/bgtask/TaskJinAnConstructionSiteInfoTest.kt
@@ -0,0 +1,50 @@
+package cn.flightfeather.supervision.bgtask
+
+import org.junit.Test
+import org.junit.jupiter.api.extension.ExtendWith
+import org.junit.runner.RunWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.junit.jupiter.SpringExtension
+import org.springframework.test.context.junit4.SpringRunner
+import java.time.LocalDateTime
+
+@RunWith(SpringRunner::class)
+@ExtendWith(SpringExtension::class)
+@SpringBootTest
+internal class TaskJinAnConstructionSiteInfoTest {
+
+    @Autowired
+    lateinit var taskJinAnConstructionSiteInfo: TaskJinAnConstructionSiteInfo
+
+    @Autowired
+    lateinit var taskJinAnLampEnterBaseInfo: TaskJinAnLampEnterBaseInfo
+
+    @Autowired
+    lateinit var taskJinAnLampDeviceData: TaskJinAnLampDeviceData
+
+    @Autowired
+    lateinit var taskJinAnHourlyDustData: TaskJinAnHourlyDustData
+
+    @Test
+    fun doTask() {
+        taskJinAnConstructionSiteInfo.doTask(LocalDateTime.now())
+    }
+
+    @Test
+    fun doTask2() {
+        taskJinAnLampEnterBaseInfo.doTask(LocalDateTime.now())
+    }
+
+    @Test
+    fun doTask3() {
+        taskJinAnLampDeviceData.doTask(LocalDateTime.now())
+    }
+
+
+    @Test
+    fun doTask4() {
+        taskJinAnHourlyDustData.doTask(LocalDateTime.now())
+//        taskJinAnHourlyDustData.debugDoTask()
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/cn/flightfeather/supervision/timingtask/TaskLedgerCopyTest.kt b/src/test/kotlin/cn/flightfeather/supervision/bgtask/TaskLedgerCopyTest.kt
similarity index 87%
rename from src/test/kotlin/cn/flightfeather/supervision/timingtask/TaskLedgerCopyTest.kt
rename to src/test/kotlin/cn/flightfeather/supervision/bgtask/TaskLedgerCopyTest.kt
index b4f1f2e..42c12e3 100644
--- a/src/test/kotlin/cn/flightfeather/supervision/timingtask/TaskLedgerCopyTest.kt
+++ b/src/test/kotlin/cn/flightfeather/supervision/bgtask/TaskLedgerCopyTest.kt
@@ -1,7 +1,6 @@
-package cn.flightfeather.supervision.timingtask
+package cn.flightfeather.supervision.bgtask
 
 import org.junit.Test
-import org.junit.jupiter.api.Assertions.*
 import org.junit.jupiter.api.extension.ExtendWith
 import org.junit.runner.RunWith
 import org.springframework.beans.factory.annotation.Autowired
diff --git a/src/test/kotlin/cn/flightfeather/supervision/bgtask/maintenance/MTJinAnHourlyDustDataTest.kt b/src/test/kotlin/cn/flightfeather/supervision/bgtask/maintenance/MTJinAnHourlyDustDataTest.kt
new file mode 100644
index 0000000..e3ef1c3
--- /dev/null
+++ b/src/test/kotlin/cn/flightfeather/supervision/bgtask/maintenance/MTJinAnHourlyDustDataTest.kt
@@ -0,0 +1,42 @@
+package cn.flightfeather.supervision.bgtask.maintenance
+
+import org.junit.Test
+import org.junit.jupiter.api.extension.ExtendWith
+import org.junit.runner.RunWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.junit.jupiter.SpringExtension
+import org.springframework.test.context.junit4.SpringRunner
+import java.time.LocalDate
+import java.time.format.DateTimeFormatter
+
+@RunWith(SpringRunner::class)
+@ExtendWith(SpringExtension::class)
+@SpringBootTest
+class MTJinAnHourlyDustDataTest {
+
+    @Autowired
+    lateinit var mTJinAnHourlyDustData:MTJinAnHourlyDustData
+
+    @Test
+    fun handleMonth() {
+        mTJinAnHourlyDustData.handle(2024, 5)
+    }
+
+    @Test
+    fun handle() {
+        val start = LocalDate.of(2024, 5, 7).atStartOfDay()
+        val end = LocalDate.of(2024, 6, 1).atStartOfDay().minusSeconds(1)
+        mTJinAnHourlyDustData.handle(start, end)
+    }
+
+    @Test
+    fun findLostTime() {
+        val start = LocalDate.of(2024, 5, 7).atStartOfDay()
+        val end = start.plusMonths(1).minusSeconds(1)
+        mTJinAnHourlyDustData.findLostTime(start, end).forEach {
+            println(it.format(DateTimeFormatter.ISO_DATE))
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/cn/flightfeather/supervision/common/autoledger/AutoLedgerTest.kt b/src/test/kotlin/cn/flightfeather/supervision/common/autoledger/AutoLedgerTest.kt
new file mode 100644
index 0000000..aeab7cb
--- /dev/null
+++ b/src/test/kotlin/cn/flightfeather/supervision/common/autoledger/AutoLedgerTest.kt
@@ -0,0 +1,35 @@
+package cn.flightfeather.supervision.common.autoledger
+
+import cn.flightfeather.supervision.domain.mapper.UserinfoMapper
+import cn.flightfeather.supervision.domain.repository.PracticalOperationRep
+import cn.flightfeather.supervision.domain.repository.UserInfoRep
+import org.junit.Test
+import org.junit.jupiter.api.Assertions.*
+import org.junit.jupiter.api.extension.ExtendWith
+import org.junit.runner.RunWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.junit.jupiter.SpringExtension
+import org.springframework.test.context.junit4.SpringRunner
+
+@RunWith(SpringRunner::class)
+@ExtendWith(SpringExtension::class)
+@SpringBootTest
+class AutoLedgerTest {
+
+    @Autowired
+    lateinit var autoLedger: AutoLedger
+
+    @Autowired
+    lateinit var userInfoRep: UserInfoRep
+
+    @Autowired
+    lateinit var practicalOperationRep: PracticalOperationRep
+
+    @Test
+    fun create() {
+        val userInfo = userInfoRep.getUser("keKTLrmQCr1RLZWg")
+        val operations = practicalOperationRep.getOperation(listOf(18))
+        autoLedger.create(userInfo, operations, 2024, 3)
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/cn/flightfeather/supervision/common/creditcode/EnvCreditCodeTest.kt b/src/test/kotlin/cn/flightfeather/supervision/common/creditcode/EnvCreditCodeTest.kt
new file mode 100644
index 0000000..3ec21ff
--- /dev/null
+++ b/src/test/kotlin/cn/flightfeather/supervision/common/creditcode/EnvCreditCodeTest.kt
@@ -0,0 +1,29 @@
+package cn.flightfeather.supervision.common.creditcode
+
+import cn.flightfeather.supervision.domain.mapper.BaseInfoMapper
+import cn.flightfeather.supervision.lightshare.vo.BaseResponse
+import org.junit.Test
+import org.junit.jupiter.api.extension.ExtendWith
+import org.junit.runner.RunWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.junit.jupiter.SpringExtension
+import org.springframework.test.context.junit4.SpringRunner
+import java.io.File
+
+@RunWith(SpringRunner::class)
+@ExtendWith(SpringExtension::class)
+@SpringBootTest
+class EnvCreditCodeTest{
+
+    @Autowired
+    lateinit var baseInfoMapper: BaseInfoMapper
+
+    @Test
+    fun createQRCode() {
+        val info = baseInfoMapper.selectByPrimaryKey("1Qo1GHlHK3tHbcFK")
+        val supply = "${info.biCityName}${info.biDistrictName}鐢熸�佺幆澧冨眬"
+        val file = File("C:/default.png")
+        EnvCreditCode.createImage(info.biGuid, info.biName, info.ciName, supply, file.outputStream())
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/cn/flightfeather/supervision/common/net/JinAnLianTongHttpServiceTest.kt b/src/test/kotlin/cn/flightfeather/supervision/common/net/JinAnLianTongHttpServiceTest.kt
new file mode 100644
index 0000000..ae065ea
--- /dev/null
+++ b/src/test/kotlin/cn/flightfeather/supervision/common/net/JinAnLianTongHttpServiceTest.kt
@@ -0,0 +1,24 @@
+package cn.flightfeather.supervision.common.net
+
+import org.junit.Test
+import org.junit.jupiter.api.extension.ExtendWith
+import org.junit.runner.RunWith
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.junit.jupiter.SpringExtension
+import org.springframework.test.context.junit4.SpringRunner
+
+internal class JinAnLianTongHttpServiceTest {
+
+    @Test
+    fun getConstructionDustMonitorSiteInfo() {
+        val res = JinAnLianTongHttpService.getConstructionDustMonitorSiteInfo()
+        println(res)
+    }
+
+    @Test
+    fun headTimeStamp() {
+        JinAnLianTongHttpService.headTimeStamp().forEach {
+            println("${it.first}: ${it.second}")
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/cn/flightfeather/supervision/common/risk/RiskAnalysisTest.kt b/src/test/kotlin/cn/flightfeather/supervision/common/risk/RiskAnalysisTest.kt
new file mode 100644
index 0000000..176df2f
--- /dev/null
+++ b/src/test/kotlin/cn/flightfeather/supervision/common/risk/RiskAnalysisTest.kt
@@ -0,0 +1,109 @@
+package cn.flightfeather.supervision.common.risk
+
+import cn.flightfeather.supervision.domain.mapper.*
+import cn.flightfeather.supervision.lightshare.service.LedgerService
+import org.junit.Test
+import org.junit.jupiter.api.Assertions.*
+import org.junit.jupiter.api.extension.ExtendWith
+import org.junit.runner.RunWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.junit.jupiter.SpringExtension
+import org.springframework.test.context.junit4.SpringRunner
+import java.time.LocalDate
+
+@RunWith(SpringRunner::class)
+@ExtendWith(SpringExtension::class)
+@SpringBootTest
+class RiskAnalysisTest {
+
+    @Autowired
+    lateinit var userinfoMapper: UserinfoMapper
+
+    @Autowired
+    lateinit var userConfigMapper: UserConfigMapper
+
+    @Autowired
+    lateinit var userLoginLogMapper: UserLoginLogMapper
+
+    @Autowired
+    lateinit var ledgerRecordMapper: LedgerRecordMapper
+
+    @Autowired
+    lateinit var ledgerSubTypeMapper: LedgerSubTypeMapper
+
+    @Autowired
+    lateinit var evaluationMapper: EvaluationMapper
+
+    @Autowired
+    lateinit var evaluationruleMapper: EvaluationruleMapper
+
+    @Autowired
+    lateinit var baseInfoMapper: BaseInfoMapper
+
+    @Autowired
+    lateinit var companyMapper: CompanyMapper
+
+    @Autowired
+    lateinit var commitmentMapper: CommitmentMapper
+
+    @Autowired
+    lateinit var riskEvaluationMapper: RiskEvaluationMapper
+
+    @Autowired
+    lateinit var personalInfoMapper: PersonalInfoMapper
+
+    @Autowired
+    lateinit var userInfoWxMapper: UserInfoWxMapper
+
+    @Autowired
+    lateinit var ledgerService: LedgerService
+
+    @Autowired
+    lateinit var dbMapper: DbMapper
+
+    @Test
+    fun riskAnalysis() {
+        var startDate = LocalDate.of(2024, 6, 1)
+        val endDate = LocalDate.of(2024, 6, 1)
+        while (!startDate.isAfter(endDate)) {
+            val year = startDate.year
+            val month = startDate.monthValue
+            val list = mutableListOf<DataSource>().apply {
+                //鍖荤枟鏈烘瀯
+                add(DataSource(DataSource.Config("闈欏畨鍖�", "9", year, month, 2), dbMapper))
+
+                //涓囪揪
+//                add(DataSource(DataSource.Config("閲戝北鍖�", "1", year, month, 10), dbMapper))
+//                add(DataSource(DataSource.Config("閲戝北鍖�", "2", year, month, 3), dbMapper))
+//                //纰宠胺缁挎咕(宸ヤ笟浼佷笟)
+//                add(DataSource(DataSource.Config("閲戝北鍖�", "6", year, month, 8), dbMapper))
+//
+//                //澶ц瀺鍩�
+//                add(DataSource(DataSource.Config("闈欏畨鍖�", "1", year, month, 16), dbMapper))
+//                //澶ф偊鍩�
+//                add(DataSource(DataSource.Config("闈欏畨鍖�", "1", year, month, 17), dbMapper))
+//                //涔呭厜
+//                add(DataSource(DataSource.Config("闈欏畨鍖�", "1", year, month, 9), dbMapper))
+//                //889
+//                add(DataSource(DataSource.Config("闈欏畨鍖�", "1", year, month, 11), dbMapper))
+//                //X88
+//                add(DataSource(DataSource.Config("闈欏畨鍖�", "1", year, month, 15), dbMapper))
+//
+//                //澶╅挜妗�
+//                add(DataSource(DataSource.Config("寰愭眹鍖�", "1", year, month, 13), dbMapper))
+//                //鐢板皻鍧�
+//                add(DataSource(DataSource.Config("寰愭眹鍖�", "1", year, month, 14), dbMapper))
+//                //姹戒慨
+//                add(DataSource(DataSource.Config("寰愭眹鍖�", "7", year, month, 1), dbMapper))
+//
+//                add(DataSource(DataSource.Config("闀垮畞鍖�", "2", year, month, 19), dbMapper))
+            }
+            list.forEach {
+                val riskAnalysis = RiskAnalysis(it, toDatabase = true, toFile = true)
+                riskAnalysis.execute()
+            }
+            startDate = startDate.plusMonths(1)
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/cn/flightfeather/supervision/common/score/AutoScoreTest.kt b/src/test/kotlin/cn/flightfeather/supervision/common/score/AutoScoreTest.kt
index c4fbb32..3e5f20f 100644
--- a/src/test/kotlin/cn/flightfeather/supervision/common/score/AutoScoreTest.kt
+++ b/src/test/kotlin/cn/flightfeather/supervision/common/score/AutoScoreTest.kt
@@ -18,8 +18,16 @@
     @Autowired
     lateinit var autoScore: AutoScore
 
+    @Autowired
+    lateinit var scoreUtil: ScoreUtil
+
     @Test
     fun go() {
-        autoScore.go(2022, 7)
+        autoScore.go(2023, 10)
+    }
+
+    @Test
+    fun go2() {
+        scoreUtil.outPut()
     }
 }
\ No newline at end of file
diff --git a/src/test/kotlin/cn/flightfeather/supervision/common/wx/TemplateManagerTest.kt b/src/test/kotlin/cn/flightfeather/supervision/common/wx/TemplateManagerTest.kt
index 1330873..710ff8b 100644
--- a/src/test/kotlin/cn/flightfeather/supervision/common/wx/TemplateManagerTest.kt
+++ b/src/test/kotlin/cn/flightfeather/supervision/common/wx/TemplateManagerTest.kt
@@ -19,7 +19,14 @@
 
     @Test
     fun newTemplate() {
-        val msg = templateManager.newTemplate(0, "otZkc5cC55BtV2AFZdXMvBw0oJo8", listOf("value1", "value2", "value3", "value4"))
-        println(msg)
+        Thread.sleep(10000)
+//        val msg = templateManager.newTemplate(0, "otZkc5cC55BtV2AFZdXMvBw0oJo8", listOf("value1", "value2", "value3", "value4"))
+//        templateManager.sendMsg(1, "otZkc5cC55BtV2AFZdXMvBw0oJo8",
+//            listOf("鑷祴鏅鸿瘎", "浼佷笟鑷垜绠$悊", "鏍规嵁璇勪及琛ㄦ牸杩涜浼佷笟鑷垜娴嬭瘎", "2023骞�7鏈�5鏃�", "璇峰湪鏈堝簳鍓嶅強鏃跺畬鎴�"))
+//        templateManager.sendMsg(2, "otZkc5cC55BtV2AFZdXMvBw0oJo8",
+//            listOf("浼氳閫氱煡", "鍏充簬姹戒慨VOC涓撻」鏁存不鐨勯噸瑕佷細璁�", "2023骞�7鏈�5鏃�", "璇峰悇浼佷笟浠h〃绉瀬閰嶅悎鍙傚姞"))
+        templateManager.sendMsg(3, "otZkc5cC55BtV2AFZdXMvBw0oJo8",
+            listOf("灏忕▼搴忚璇�", "鍖呭惈浼佷笟璁よ瘉涓庝釜浜鸿璇�", "2023骞�7鏈�5鏃�", "褰撳墠杩樻湁涓汉璁よ瘉鏈畬鎴�", "1/2"))
+//        println(msg)
     }
 }
\ No newline at end of file
diff --git a/src/test/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/UserInfoRepositoryImplTest.kt b/src/test/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/UserInfoRepositoryImplTest.kt
new file mode 100644
index 0000000..649263a
--- /dev/null
+++ b/src/test/kotlin/cn/flightfeather/supervision/lightshare/repository/impl/UserInfoRepositoryImplTest.kt
@@ -0,0 +1,73 @@
+package cn.flightfeather.supervision.lightshare.repository.impl
+
+import cn.flightfeather.supervision.domain.entity.BaseInfo
+import cn.flightfeather.supervision.domain.entity.Userinfo
+import cn.flightfeather.supervision.domain.enumeration.DistrictType
+import cn.flightfeather.supervision.domain.mapper.BaseInfoMapper
+import cn.flightfeather.supervision.domain.mapper.UserinfoMapper
+import cn.flightfeather.supervision.domain.repository.UserInfoRep
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+import org.junit.Test
+import org.junit.jupiter.api.extension.ExtendWith
+import org.junit.runner.RunWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.junit.jupiter.SpringExtension
+import org.springframework.test.context.junit4.SpringRunner
+import tk.mybatis.mapper.entity.Example
+
+@RunWith(SpringRunner::class)
+@ExtendWith(SpringExtension::class)
+@SpringBootTest
+class UserInfoRepositoryImplTest() {
+
+    @Autowired
+    lateinit var userInfoRep: UserInfoRep
+
+    @Autowired
+    lateinit var userinfoMapper: UserinfoMapper
+
+    @Autowired
+    lateinit var baseInfoMapper: BaseInfoMapper
+
+    @Test
+    fun foo1() {
+        val c = UserSearchCondition().apply {
+//            provinceCode = "310000"
+//            cityCode = "310100"
+            districtName = "闈欏畨鍖�"
+//            townCode = "310106019"
+            area
+            mcName
+            userTypeId = 3
+            sceneTypes = listOf("1")
+        }
+        val r = userInfoRep.searchUser(c)
+        println(r)
+    }
+
+    @Test
+    fun foo2() {
+        userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
+            createCriteria().andEqualTo("usertype", "鏀垮簻閮ㄩ棬")
+        }).forEach {
+            val baseInfo = BaseInfo().apply {
+                biGuid = it?.guid
+                biName = it?.realname
+                biProvinceCode = "310000"
+                biProvinceName = "涓婃捣甯�"
+                biCityCode = "310100"
+                biCityName = "涓婃捣甯�"
+                biDistrictCode = DistrictType.getCode(it?.extension1)
+                biDistrictName = it?.extension1
+                biRemark = it?.usertype
+            }
+            val b = baseInfoMapper.selectOne(BaseInfo().apply { biGuid = it?.guid })
+            if (b == null) {
+                baseInfoMapper.insert(baseInfo)
+            } else {
+                baseInfoMapper.updateByPrimaryKey(baseInfo)
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ConfigServiceImplTest.kt b/src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ConfigServiceImplTest.kt
new file mode 100644
index 0000000..2d9b5d2
--- /dev/null
+++ b/src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/ConfigServiceImplTest.kt
@@ -0,0 +1,34 @@
+package cn.flightfeather.supervision.lightshare.service.Impl
+
+import cn.flightfeather.supervision.lightshare.service.ConfigService
+import cn.flightfeather.supervision.lightshare.vo.UserSearchCondition
+import org.junit.Test
+import org.junit.jupiter.api.extension.ExtendWith
+import org.junit.runner.RunWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.junit.jupiter.SpringExtension
+import org.springframework.test.context.junit4.SpringRunner
+
+@RunWith(SpringRunner::class)
+@ExtendWith(SpringExtension::class)
+@SpringBootTest
+class ConfigServiceImplTest() {
+
+    @Autowired
+    lateinit var configService: ConfigService
+
+    @Test
+    fun getSceneRange() {
+        val res = configService.getSceneRange("PgQc1Tj7WRsOcbOD")
+        println(res)
+    }
+
+    @Test
+    fun getCommitmentTemplate() {
+        val res = configService.getCommitmentTemplate(UserSearchCondition().apply {
+            sceneTypes = listOf("8")
+        })
+        println(res)
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EvaluationServiceImplTest.kt b/src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EvaluationServiceImplTest.kt
index 5c82ec9..4b056e6 100644
--- a/src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EvaluationServiceImplTest.kt
+++ b/src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/EvaluationServiceImplTest.kt
@@ -1,5 +1,6 @@
 package cn.flightfeather.supervision.lightshare.service.Impl
 
+import cn.flightfeather.supervision.domain.mapper.OverallEvaluationMapper
 import cn.flightfeather.supervision.lightshare.service.EvaluationService
 import org.junit.Test
 
@@ -10,6 +11,11 @@
 import org.springframework.boot.test.context.SpringBootTest
 import org.springframework.test.context.junit.jupiter.SpringExtension
 import org.springframework.test.context.junit4.SpringRunner
+import java.time.Instant
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.ZoneId
+import java.util.*
 
 @RunWith(SpringRunner::class)
 @ExtendWith(SpringExtension::class)
@@ -19,6 +25,9 @@
     @Autowired
     lateinit var evaluationService: EvaluationService
 
+    @Autowired
+    lateinit var overallEvaluationMapper: OverallEvaluationMapper
+
     @Test
     fun getTotalPoints() {
         val r = evaluationService.getTotalPoints("xB32EtpuxU5bOzq5", 2, "2021-01-01", "2021-04-01",7,"3mbioCjN6XAAHveR",null)
@@ -27,7 +36,30 @@
 
     @Test
     fun getCreditInfo() {
-        val r = evaluationService.getCreditInfo("UwTaWXneBoTby6bH")
+        val r = evaluationService.getCreditInfo("UwTaWXneBoTby6bH", "2022/10-12")
         println(r)
     }
+
+    @Test
+    fun refreshCreditCodeTime() {
+        overallEvaluationMapper.selectAll().forEach {
+            val period = it.oePeriod
+            if (period != null && period.isNotBlank()) {
+                val list1 = period.split("/")
+                val year = list1[0].toInt()
+                val list2 = list1[1].split("-")
+                val sMonth = list2[0].toInt()
+                val eMonth = list2[1].toInt()
+
+                val sTime = LocalDate.of(year, sMonth, 1)
+                val eTime = LocalDate.of(year, eMonth, 1).plusMonths(1).minusDays(1)
+
+                if (it.oeStartTime == null && it.oeEndTime == null) {
+                    it.oeStartTime = Date.from(sTime.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant())
+                    it.oeEndTime = Date.from(eTime.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant())
+                    overallEvaluationMapper.updateByPrimaryKeySelective(it)
+                }
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/LedgerServiceImplTest.kt b/src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/LedgerServiceImplTest.kt
index e20a0cf..e04aac3 100644
--- a/src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/LedgerServiceImplTest.kt
+++ b/src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/LedgerServiceImplTest.kt
@@ -25,7 +25,7 @@
 
     @Test
     fun getUserLedgerSummary() {
-        val r = ledgerService.getUserLedgerSummary("mriXrddyrVAyaakB", 7, "2020-11-10")
+        val r = ledgerService.getUserLedgerSummary("OFOldpjyvFu2ZUA2", 6, "2023-11-10")
         println(r)
     }
 
diff --git a/src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/WxUserServiceImplTest.kt b/src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/WxUserServiceImplTest.kt
index 52428a1..7489263 100644
--- a/src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/WxUserServiceImplTest.kt
+++ b/src/test/kotlin/cn/flightfeather/supervision/lightshare/service/Impl/WxUserServiceImplTest.kt
@@ -1,5 +1,8 @@
 package cn.flightfeather.supervision.lightshare.service.Impl
 
+import cn.flightfeather.supervision.domain.entity.UserInfoWx
+import cn.flightfeather.supervision.domain.mapper.PersonalInfoMapper
+import cn.flightfeather.supervision.domain.mapper.UserInfoWxMapper
 import cn.flightfeather.supervision.lightshare.service.WxUserService
 import org.junit.Test
 import org.junit.jupiter.api.extension.ExtendWith
@@ -8,6 +11,7 @@
 import org.springframework.boot.test.context.SpringBootTest
 import org.springframework.test.context.junit.jupiter.SpringExtension
 import org.springframework.test.context.junit4.SpringRunner
+import tk.mybatis.mapper.entity.Example
 
 @RunWith(SpringRunner::class)
 @ExtendWith(SpringExtension::class)
@@ -17,9 +21,30 @@
     @Autowired
     lateinit var wxUserService: WxUserService
 
+    @Autowired
+    lateinit var personalInfoMapper: PersonalInfoMapper
+
+    @Autowired
+    lateinit var userInfoWxMapper: UserInfoWxMapper
+
     @Test
     fun subscribeResult() {
         val msg = "{\"ToUserName\":\"gh_c60faa57000f\",\"FromUserName\":\"otZkc5cC55BtV2AFZdXMvBw0oJo8\",\"CreateTime\":1667377808,\"MsgType\":\"event\",\"Event\":\"subscribe_msg_popup_event\",\"List\":[{\"PopupScene\":\"0\",\"SubscribeStatusString\":\"accept\",\"TemplateId\":\"6JQFOJ12yBvKfRg_duSdwKiH5_J3LpICmz3Li-L1Cr8\"},{\"PopupScene\":\"0\",\"SubscribeStatusString\":\"accept\",\"TemplateId\":\"zPNMzF5WsshniJyl83DD-lDZtNvx7JyqLbKgqDl0qvU\"},{\"PopupScene\":\"0\",\"SubscribeStatusString\":\"accept\",\"TemplateId\":\"dqREi7vAd03OOirTgBGcm5aCihZJKBjVpiA8Kbu4B8w\"}]}"
         wxUserService.subscribeResult(msg)
     }
+
+    @Test
+    fun refreshPersonalInfo() {
+        personalInfoMapper.selectAll().forEach {
+            val uList = userInfoWxMapper.selectByExample(Example(UserInfoWx::class.java).apply {
+                createCriteria().andEqualTo("piGuid", it?.piGuid)
+            })
+            if (uList.isNotEmpty()) {
+                val u = uList[0]
+                it?.piWxId = u.uiOpenId
+                it?.piSceneId = u.uiGuid
+                personalInfoMapper.updateByPrimaryKeySelective(it)
+            }
+        }
+    }
 }
\ No newline at end of file

--
Gitblit v1.9.3