无关风月
2024-10-14 039a33d1bfa6ef041161666bbd120c34086fe7c1
课程代码
2 文件已重命名
102个文件已修改
54个文件已添加
7002 ■■■■■ 已修改文件
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/domain/Course.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/domain/CourseCategory.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/domain/CourseDTO.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/domain/OrderCourseVO.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/feign/RemoteCourseService.java 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/vo/StudyPageVO.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/domain/Meditation.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/domain/dto/MeditationDTO.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/domain/dto/MeditationHallDTO.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/domain/dto/MeditationQuestionDTO.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/domain/dto/UserAnswerDTO.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/domain/vo/NoticeDetailVO.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/factory/RemoteMeditationFallbackFactory.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/feign/RemoteMeditationService.java 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/domain/Order.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/domain/dto/OrderListDTO.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/domain/vo/OrderCountVO.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/factory/RemoteOrderFallbackFactory.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/feign/RemoteOrderService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/RemoteUserService.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/AppUser.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/AppUserBank.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/AppUserQuestion.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/AppUserTree.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/AppUserWalletRecord.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/AppUserWithdraw.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/MeditationQuestion.java 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/MeditationReport.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/NoticeRecord.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/Prize.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/PrizeRedemptionRecord.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysUser.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/Tag.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/AppUserDetailVO.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/AppUserEnergyRecordVO.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/AppUserInfoVO.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/AppUserVO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/HealingLevelVO.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/OrderDetailVO.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/OrderListVO.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/SysUserVO.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/UpdateAppUserDTO.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/UpdateTreeGroupVO.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/UpdateUserGroupVO.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/UpdateVipVO.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/WalletVO.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/factory/RemoteUserFallbackFactory.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/AppCaptchaBody.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/dto/AppUserManagementDTO.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/dto/PrizeRecordDTO.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/dto/UserBalanceDetailDTO.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/dto/UserEnergyDTO.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/dto/UserExchangeRecordDTO.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/vo/FreezingVO.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/vo/ViewReport.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/factory/RemoteAppUserFallbackFactory.java 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/feign/RemoteAppUserService.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/controller/TokenController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/service/SysLoginService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/CacheConstants.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/domain/BaseModel.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientCourseCategoryController.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientCourseChapterController.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientCourseController.java 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientTutorSpecialColumnController.java 57 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/CourseChapter.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/CourseUserFavorite.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/TutorSpecialColumn.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/vo/ClientCourseVO.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/CourseCategoryMapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/CourseUserFavoriteMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/CourseCategoryService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/CourseUserFavoriteService.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/CourseCategoryServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/CourseUserFavoriteServiceImpl.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/resources/mapper/course/CourseCategoryMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/controller/SysFileController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/utils/ObsUploadUtil.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientHomeController.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationCategoryController.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationController.java 309 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationEverydayController.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationHallController.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationMusicController.java 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationQuestionController.java 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationReportController.java 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/HomeBackgroundMusic.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationCategory.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationEveryday.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationHall.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationMusic.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationQuestionMapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationReportMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationQuestionService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationReportService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationQuestionServiceImpl.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationReportServiceImpl.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationQuestionMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/client/ClientOrderController.java 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/management/MgtOrderController.java 411 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/impl/OrderServiceImpl.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/pom.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/BannerController.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/CommissionRuleController.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/CommonQuestionController.java 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/ContentSettingController.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/HotWordsController.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/PageController.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysUserController.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/TreeLevelSettingController.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/UserLevelSettingController.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/VersionController.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/VipSettingController.java 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/Banner.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/CommissionRule.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/CommonQuestion.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/ContentSetting.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/HotWords.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/Page.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysUserDept.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/Version.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/VipSetting.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/CommissionRuleMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/PageMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysUserDeptMapper.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysUserMapper.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/BannerService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/CommissionRuleService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysUserDeptService.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysUserService.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/PageService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/BannerServiceImpl.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/CommissionRuleServiceImpl.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/PageServiceImpl.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysUserDeptServiceImpl.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysUserServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/utils/MyQrCodeUtil.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/utils/ObsUploadUtil.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/utils/QRCodeUtil.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/utils/UUIDUtil.java 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysUserDeptMapper.xml 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysUserMapper.xml 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/pom.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserController.java 742 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserTagController.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserTreeController.java 84 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserViewingHistoryController.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserWalletRecordController.java 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserWithdrawController.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientNoticeRecordController.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientPrizeController.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientPrizeRedemptionRecordController.java 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientTagController.java 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/MailConst.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/vo/ExchangeRecordVO.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserServiceImpl.java 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/utils/MailUtils.java 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/domain/Course.java
@@ -48,6 +48,10 @@
    @TableField("course_title")
    private String courseTitle;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "课程描述")
    @TableField("description")
    private String description;
@@ -115,5 +119,14 @@
    @ApiModelProperty(value = "学习人数")
    @TableField(exist = false)
    private Integer count;
    @ApiModelProperty(value = "章节数量")
    @TableField(exist = false)
    private Long courseChapterCount;
    @ApiModelProperty(value = "收藏数量")
    @TableField(exist = false)
    private Long collectCount;
   @ApiModelProperty(value = "课程分类名称")
    @TableField(exist = false)
    private String categoryName;
}
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/domain/CourseCategory.java
File was renamed from xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/CourseCategory.java
@@ -1,4 +1,4 @@
package com.xinquan.course.domain;
package com.xinquan.course.api.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -33,6 +33,9 @@
    @ApiModelProperty(value = "分类名称")
    @TableField("name")
    private String name;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "分类图片")
    @TableField("image_url")
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/domain/CourseDTO.java
New file
@@ -0,0 +1,30 @@
package com.xinquan.course.api.domain;
import com.xinquan.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.web.bind.annotation.RequestParam;
import java.math.BigDecimal;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "管理后台查询课程列表DTO")
public class CourseDTO extends BasePage {
    @ApiModelProperty(value = "课程类型1线上2线下")
    private Integer courseType;
    @ApiModelProperty(value = "价格设定 1=免费 2=会员免费 3=单独收费")
    private Integer chargeType;
    @ApiModelProperty(value = "上架状态 1=上架 2=下架")
    private Integer listingStatus;
    @ApiModelProperty(value = "课程分类id")
    private Long cateId;
    @ApiModelProperty(value = "课程/章节标题")
    private String courseTitle;
    @ApiModelProperty(value = "导师名称")
    private String tutor;
}
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/domain/OrderCourseVO.java
New file
@@ -0,0 +1,46 @@
package com.xinquan.course.api.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "课程视图对象")
public class OrderCourseVO {
    @ApiModelProperty(value = "课程/音频id")
    private Long businessId;
    @ApiModelProperty(value = "课程标题")
    private String courseTitle;
    @ApiModelProperty(value = "课程描述")
    private String description;
    @ApiModelProperty(value = "价格设定 1=免费 2=会员免费 3=单独收费")
    private Integer chargeType;
    @ApiModelProperty(value = "通用价格")
    private BigDecimal generalPrice;
    @ApiModelProperty(value = "IOS内购价格")
    private BigDecimal iosPrice;
    @ApiModelProperty(value = "列表封面图")
    private String coverUrl;
    @ApiModelProperty(value = "已学习人数")
    private Integer count;
    @ApiModelProperty(value = "支付状态 1待支付 2已支付")
    private Integer paymentStatus;
    @ApiModelProperty(value = "订单类型 1=冥想订单 2=课程订单")
    private Integer orderFrom;
}
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/feign/RemoteCourseService.java
@@ -3,12 +3,16 @@
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.constant.ServiceNameConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.course.api.domain.Course;
import com.xinquan.course.api.domain.CourseCategory;
import com.xinquan.course.api.domain.CourseDTO;
import com.xinquan.course.api.domain.OrderCourseVO;
import com.xinquan.course.api.factory.RemoteCourseFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * @author mitao
@@ -16,7 +20,8 @@
 */
@FeignClient(contextId = "remoteCourseService", value = ServiceNameConstants.COURSE_SERVICE, fallbackFactory = RemoteCourseFallbackFactory.class)
public interface RemoteCourseService {
    @PostMapping("/client/course/course/getCourseIdsByName/{name}")
    public R<List<Long>> getCourseIdsByName(@PathVariable("name") String name);
    /**
     * 根据id获取课程信息
     *
@@ -27,4 +32,12 @@
    @GetMapping("/inner/course/course/getCourseById/{targetId}")
    R<Course> getCourseById(@PathVariable("targetId") Long targetId,
            @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
    @PostMapping("/client/course/course/getCourseByCourseId/{courseId}")
    public R<OrderCourseVO> getCourseCategoryList(@RequestBody OrderCourseVO req);
    @GetMapping("/client/course/course/getCategoryById/{id}")
    R<CourseCategory> getCategoryById(@PathVariable("id") String id);
    @GetMapping("/client/course/course/cateList")
    R<List<CourseCategory>> cateList();
    @PostMapping("/client/course/course/courseList")
    R<PageDTO<Course>> courseList(@RequestBody CourseDTO courseDTO);
}
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/vo/StudyPageVO.java
@@ -20,7 +20,7 @@
    private static final long serialVersionUID = -7433787602665988956L;
    @ApiModelProperty(value = "已购买课程列表")
    private PageDTO<CourseVO> courseList;
    private List<CourseVO> courseList;
    @ApiModelProperty(value = "免费课程")
    private List<Course> freeCourseList;
}
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/domain/Meditation.java
@@ -4,10 +4,14 @@
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinquan.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import java.time.LocalTime;
import java.util.List;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -34,6 +38,27 @@
    @ApiModelProperty(value = "冥想音频分类id")
    @TableField("cate_id")
    private Long cateId;
    @ApiModelProperty(value = "分类名称")
    @TableField(exist = false)
    private String categoryName;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "选择标签的ids 逗号拼接 ")
    @TableField(exist = false)
    private String tagIds;
    @ApiModelProperty(value = "背景音频 多个逗号拼接")
    @TableField(exist = false)
    private String musicUrls;
    @ApiModelProperty(value = "背景音频时长 单位秒 多个逗号分割 与背景音频一一对应")
    @TableField(exist = false)
    private String musicSecond;
    @ApiModelProperty(value = "查看详情回显使用 背景音频")
    @TableField(exist = false)
    private List<String> musicList;
    @ApiModelProperty(value = "查看详情回显使用 所选的标签ids")
    @TableField(exist = false)
    private List<Long> tagList;
    @ApiModelProperty(value = "冥想标题")
    @TableField("meditation_title")
@@ -94,6 +119,10 @@
    @ApiModelProperty(value = "导师音频")
    @TableField("tutor_audio_url")
    private String tutorAudioUrl;
    @ApiModelProperty(value = "导师音频时长 单位秒")
    @TableField("tutor_audio_second")
    private String tutorAudioSecond;
    @ApiModelProperty(value = "被点赞数")
    @TableField("like_count")
@@ -102,6 +131,14 @@
    @ApiModelProperty(value = "被收藏数")
    @TableField("favorite_count")
    private Integer favoriteCount;
    @ApiModelProperty(value = "播放时间段开始")
    @TableField("start_play_time")
    @JsonFormat(pattern = "HH:mm:ss")
    private LocalTime startPlayTime;
    @ApiModelProperty(value = "播放时间段结束")
    @TableField("end_play_time")
    @JsonFormat(pattern = "HH:mm:ss")
    private LocalTime endPlayTime;
}
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/domain/dto/MeditationDTO.java
New file
@@ -0,0 +1,26 @@
package com.xinquan.meditation.api.domain.dto;
import com.xinquan.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "管理后台查询冥想音频DTO")
public class MeditationDTO extends BasePage {
    @ApiModelProperty(value = "价格设定 1=免费 2=会员免费 3=单独收费")
    private Integer chargeType;
    @ApiModelProperty(value = "是否梵文 0否1是 没有不传")
    private Integer sanskrit;
    @ApiModelProperty(value = "所属分类id")
    private Long cateId;
    @ApiModelProperty(value = "疗愈标题")
    private String meditationTitle;
    @ApiModelProperty(value = "疗愈标签")
    private String tagName;
}
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/domain/dto/MeditationHallDTO.java
New file
@@ -0,0 +1,19 @@
package com.xinquan.meditation.api.domain.dto;
import com.xinquan.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "冥想馆DTO")
public class MeditationHallDTO extends BasePage {
    @ApiModelProperty(value = "地址")
    private String address;
    @ApiModelProperty(value = "冥想馆名称")
    private String hallName;
}
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/domain/dto/MeditationQuestionDTO.java
New file
@@ -0,0 +1,25 @@
package com.xinquan.meditation.api.domain.dto;
import com.xinquan.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "提问管理DTO")
public class MeditationQuestionDTO extends BasePage {
    @ApiModelProperty(value = "用户名称/举报用户名称")
    private String userName;
    @ApiModelProperty(value = "疗愈名称")
    private String name;
    @ApiModelProperty(value = "提问内容")
    private String content;
    @ApiModelProperty(value = "是否回复 1是2否 全部不传")
    private Integer isReplay;
    @ApiModelProperty(value = "是否显示 1是2否 全部不传")
    private Integer showFlag;
}
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/domain/dto/UserAnswerDTO.java
New file
@@ -0,0 +1,23 @@
package com.xinquan.meditation.api.domain.dto;
import com.xinquan.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "用户提问DTO")
public class UserAnswerDTO extends BasePage {
    @ApiModelProperty(value = "是否显示 1= 是 2=否")
    private Integer show_flag;
    @ApiModelProperty(value = "提问内容")
    private String content;
    @ApiModelProperty(value = "用户名称")
    private String userName;
    @ApiModelProperty(value = "音频uid")
    private String uid;
}
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/domain/vo/NoticeDetailVO.java
New file
@@ -0,0 +1,52 @@
package com.xinquan.meditation.api.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "用户信息VO")
public class NoticeDetailVO implements Serializable {
    private static final long serialVersionUID = -6948932379350815750L;
    @ApiModelProperty(value = "通知类型 1=系统通知 2=回复通知")
    private Integer noticeType;
    @ApiModelProperty(value = "通知标题 当类型为系统通知时")
    private String title;
    @ApiModelProperty(value = "通知内容 当类型为系统通知时")
    private String reply;
    @ApiModelProperty(value = "消息时间 当类型为系统通知")
    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
    private LocalDateTime time;
    @ApiModelProperty(value = "冥想标题 当类型为回复通知时")
    private String meditationTitle;
    @ApiModelProperty(value = "冥想描述内容 当类型为回复通知时")
    private String coverDescription;
    @ApiModelProperty(value = "冥想封面图 当类型为回复通知时")
    private String iconUrl;
    @ApiModelProperty(value = "用户昵称 当类型为回复通知时")
    private String nickname;
    @ApiModelProperty(value = "姓名 当类型为回复通知时")
    private String realname;
    @ApiModelProperty(value = "头像 当类型为回复通知时")
    private String avatar;
    @ApiModelProperty(value = "提问内容 当类型为回复通知时")
    private String content;
    @ApiModelProperty(value = "平台回复内容 当类型为回复通知时")
    private String replyContent;
    @ApiModelProperty(value = "提问时间当类型为回复通知")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private LocalDateTime publishTime;
    @ApiModelProperty(value = "冥想提问id 前端忽略")
    private Long meditationQuestionId;
}
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/factory/RemoteMeditationFallbackFactory.java
@@ -1,9 +1,14 @@
package com.xinquan.meditation.api.factory;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.api.domain.vo.NoticeDetailVO;
import com.xinquan.meditation.api.feign.RemoteMeditationService;
import org.springframework.cloud.openfeign.FallbackFactory;
import java.util.List;
/**
 * @author mitao
@@ -15,9 +20,30 @@
    public RemoteMeditationService create(Throwable cause) {
        return new RemoteMeditationService() {
            @Override
            public R<List<Long>> getMeditationIdsByName(String name) {
                return R.fail("获远程调用 通过疗愈名字查询疗愈ids失败");
            }
            @Override
            public R<Meditation> getMeditationById(Long targetId, String source) {
                return R.fail("获取冥想音频失败");
            }
            @Override
            public R<NoticeDetailVO> noticeDetail(NoticeDetailVO req) {
                return R.fail("获取回复消息通知内容详情失败");
            }
            @Override
            public R<Meditation> getMeditationById(Long id) {
                return R.fail("根据冥想id 获取详情失败");
            }
            @Override
            public R<Page<Meditation>> getMeditationById(Integer pageCurr, Integer pageSize) {
                return R.fail("查询收藏冥想失败");
            }
        };
    }
}
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/feign/RemoteMeditationService.java
@@ -1,14 +1,17 @@
package com.xinquan.meditation.api.feign;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.constant.ServiceNameConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.api.domain.vo.NoticeDetailVO;
import com.xinquan.meditation.api.factory.RemoteMeditationFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * @author mitao
@@ -16,6 +19,12 @@
 */
@FeignClient(contextId = "remoteMeditationService", value = ServiceNameConstants.MEDITATION_SERVICE, fallbackFactory = RemoteMeditationFallbackFactory.class)
public interface RemoteMeditationService {
    /**
     * 远程调用 通过疗愈名字查询疗愈ids
     * @return
     */
    @PostMapping("/getMeditationIdsByName/{name}")
    public R<List<Long>> getMeditationIdsByName(@PathVariable("name") String name);
    /**
     * 根据id获取冥想音频
@@ -26,4 +35,15 @@
    @GetMapping("/inner/meditation/meditation/getMeditationById")
    R<Meditation> getMeditationById(@RequestParam("targetId") Long targetId,
            @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
    /**
     * 远程调用 查询回复通知消息内容
     * @return
     */
    @PostMapping("/client/user/notice-record/noticeDetail")
    public R<NoticeDetailVO> noticeDetail(NoticeDetailVO req);
    @GetMapping("/client/meditation/meditation/getMeditationById/{id}")
    public R<Meditation> getMeditationById(@PathVariable("id") Long id);
    @GetMapping("/client/meditation/meditation/getMeditationById/{pageCurr}/{pageSize}")
    public R<Page<Meditation>> getMeditationById(@PathVariable("pageCurr") Integer pageCurr, @PathVariable("pageSize") Integer pageSize);
}
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/domain/Order.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinquan.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -36,21 +37,115 @@
    @TableField("biz_order_no")
    private String bizOrderNo;
    @ApiModelProperty(value = "第三方业务流水号 前端忽略")
    @TableField(exist = false)
    private String payOrderNo;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "备注  前端忽略")
    @TableField(exist = false)
    private String remark;
    @ApiModelProperty(value = "用户名称")
    @TableField(exist = false)
    private String userName;
    @ApiModelProperty(value = "用户手机号")
    @TableField(exist = false)
    private String cellPhone;
    @ApiModelProperty(value = "用户头像")
    @TableField(exist = false)
    private String avatar;
    @ApiModelProperty(value = "购买内容-课程-所属分类名称")
    @TableField(exist = false)
    private String categoryCourseName;
    @ApiModelProperty(value = "购买内容-课程-课程标题")
    @TableField(exist = false)
    private String courseTitle;
    @ApiModelProperty(value = "购买内容-课程-封面图")
    @TableField(exist = false)
    private String coverUrl;
    @ApiModelProperty(value = "购买内容-课程-导师")
    @TableField(exist = false)
    private String tutor;
    @ApiModelProperty(value = "购买内容-课程-章节数")
    @TableField(exist = false)
    private Long courseChapterCount;
    @ApiModelProperty(value = "购买内容-课程-价格")
    @TableField(exist = false)
    private BigDecimal generalPriceCourse;
    @ApiModelProperty(value = "购买内容-课程-上架状态 1上架2下架")
    @TableField(exist = false)
    private Integer listingStatusCourse;
    @ApiModelProperty(value = "购买内容-课程-courseUid")
    @TableField(exist = false)
    private String courseUid;
    @ApiModelProperty(value = "购买内容-疗愈-所属分类名称")
    @TableField(exist = false)
    private String categoryMeditationName;
    @ApiModelProperty(value = "购买内容-疗愈-疗愈标题")
    @TableField(exist = false)
    private String meditationTitle;
    @ApiModelProperty(value = "购买内容-疗愈-icon")
    @TableField(exist = false)
    private String iconUrl;
    @ApiModelProperty(value = "购买内容-疗愈-描述文案")
    @TableField(exist = false)
    private String detailDescription;
    @ApiModelProperty(value = "购买内容-疗愈-价格")
    @TableField(exist = false)
    private BigDecimal generalPriceMeditation;
    @ApiModelProperty(value = "购买内容-疗愈-上架状态 1上架2下架")
    @TableField(exist = false)
    private Integer listingStatusMeditation;
    @ApiModelProperty(value = "购买内容-疗愈-meditationUid")
    @TableField(exist = false)
    private String meditationUid;
    @ApiModelProperty(value = "购买内容-会员-会员类型")
    @TableField(exist = false)
    private String vipType;
    @ApiModelProperty(value = "购买内容-会员-价格")
    @TableField(exist = false)
    private BigDecimal generalPriceVip;
    @ApiModelProperty(value = "购买内容")
    @TableField("buy_content")
    private String buyContent;
    @ApiModelProperty(value = "用户id")
    @TableField("app_user_id")
    private Long appUserId;
    @ApiModelProperty(value = "购买商品id")
    @ApiModelProperty(value = "购买商品id/购买内容id")
    @TableField("business_id")
    private Long businessId;
    @ApiModelProperty(value = "被赠送用户id")
    @TableField("give_user_id")
    private Long giveUserId;
    @ApiModelProperty(value = "订单类型 1=冥想订单 2=课程订单 3=会员订单")
    @ApiModelProperty(value = "被赠送用户头像")
    @TableField(exist = false)
    private String avatarGive;
    @ApiModelProperty(value = "被赠送用户名称")
    @TableField(exist = false)
    private String userNameGive;
    @ApiModelProperty(value = "被赠送用户电话")
    @TableField(exist = false)
    private String cellPhoneGive;
    @ApiModelProperty(value = "订单类型 1=冥想订单 2=课程订单 3=会员订单 4=充值")
    @TableField("order_from")
    private Integer orderFrom;
    @ApiModelProperty(value = "支付状态 1=待支付 2=已完成 3=已取消")
    @TableField("payment_status")
    private Integer paymentStatus;
    @ApiModelProperty(value = "支付方式 1微信 2支付宝 3余额 4内购 5微信+余额 6支付宝+余额 7内购加余额")
    @TableField("pay_type")
    private Integer payType;
    @ApiModelProperty(value = "总金额")
    @TableField("total_amount")
@@ -71,22 +166,46 @@
    @ApiModelProperty(value = "改价金额")
    @TableField("change_price")
    private BigDecimal changePrice;
    @ApiModelProperty(value = "平台总收益")
    @TableField(exist = false)
    private BigDecimal platformMoney;
    @ApiModelProperty(value = "改价时间")
    @TableField("change_price_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private LocalDateTime changePriceTime;
    @ApiModelProperty(value = "改价人id")
    @TableField("change_price_operator")
    private Long changePriceOperator;
    @ApiModelProperty(value = "改价人名称")
    @TableField(exist = false)
    private String changePriceOperatorName;
    @ApiModelProperty(value = "付款方式 微信(¥10.00) + 余额(¥100.00)")
    @TableField(exist = false)
    private String paymentType;
    @ApiModelProperty(value = "付款时间")
    @TableField("payment_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private LocalDateTime paymentTime;
    @ApiModelProperty(value = "取消时间")
    @TableField("cancel_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private LocalDateTime cancelTime;
    @ApiModelProperty(value = "退款时间")
    @TableField("refund_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private LocalDateTime refundTime;
    @ApiModelProperty(value = "退款流水号")
    @TableField("refund_code")
    private String refundCode;
    @ApiModelProperty(value = "退款业务订单号")
    @TableField("refund_order_no")
    private String refundOrderNo;
    @ApiModelProperty(value = "退款状态 1未退款 2退款中 3退款成功")
    @TableField("refund_status")
    private Integer refundStatus;
}
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/domain/dto/OrderListDTO.java
New file
@@ -0,0 +1,31 @@
package com.xinquan.order.api.domain.dto;
import com.xinquan.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "管理后台查询订单列表DTO")
public class OrderListDTO extends BasePage {
    @ApiModelProperty(value = "兑换时间 2020-01-01 - 2020-12-30")
    private String time;
    @ApiModelProperty(value = "支付方式 1微信 2支付宝 3余额 4内购")
    private Integer payType;
    @ApiModelProperty(value = "用户uid")
    private String uid;
//    @ApiModelProperty(value = "支付方式 1微信 2支付宝 3内购 4余额 5微信+余额 6支付宝+余额 7内购加余额")
//    private Integer status;
    @ApiModelProperty(value = "支付状态 1=待支付 2=已完成 3=已取消")
    private Integer paymentStatus;
    @ApiModelProperty(value = "订单类型 1=冥想订单 2=课程订单 3=会员订单 4=充值")
    private Integer orderFrom;
    @ApiModelProperty(value = "用户名称/手机号")
    private String userNameOrPhone;
    @ApiModelProperty(value = "订单编号/购买内容")
    private String buyContent;
}
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/domain/vo/OrderCountVO.java
New file
@@ -0,0 +1,28 @@
package com.xinquan.order.api.domain.vo;
import com.xinquan.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "管理后台查询订单上方合计数据DTO")
public class OrderCountVO {
    @ApiModelProperty(value = "总计")
    private Integer totalCount;
    @ApiModelProperty(value = "待支付")
    private Integer payCount;
    @ApiModelProperty(value = "已完成")
    private Integer completeCount;
    @ApiModelProperty(value = "已取消")
    private Integer cancelCount;
    @ApiModelProperty(value = "总计金额")
    private BigDecimal totalMoney;
}
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/factory/RemoteOrderFallbackFactory.java
@@ -25,6 +25,17 @@
            public R<String> getCommissionByUserIds(String userIds) {
                return R.fail("通过邀请人ids查询对应佣金失败");
            }
            @Override
            public R<String> queryChargeByUserId(Long userId) {
                return R.fail("通过用户id 查询充值记录失败");
            }
            @Override
            public R<Order> getOrderById(Long orderId) {
                return R.fail("通过订单id 查询订单明细失败");
            }
        };
    }
}
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/feign/RemoteOrderService.java
@@ -23,4 +23,10 @@
    @GetMapping("/client/order/order/getCommissionByUserIds/{userIds}")
    public R<String> getCommissionByUserIds(@PathVariable("userIds") String userIds);
    @PostMapping("/client/order/order/queryChargeByUserId/{userId}")
    public R<String> queryChargeByUserId(@PathVariable("userId") Long userId);
    @PostMapping("/client/order/order/getOrderById/{orderId}")
    public R<Order> getOrderById(@PathVariable("orderId") Long orderId);
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/RemoteUserService.java
@@ -6,12 +6,11 @@
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.system.api.factory.RemoteUserFallbackFactory;
import com.xinquan.system.api.model.LoginUser;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.*;
/**
 * 用户服务
@@ -21,6 +20,13 @@
@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class)
public interface RemoteUserService
{
    /**
     * 远程调用 根据系统用户id查询用户信息
     * @return
     */
    @PostMapping("/user/getSysUserById/{id}")
    public R<SysUser> getSysUserById(@PathVariable("id")String id);
    /**
     * 通过用户名查询用户信息
     *
@@ -49,4 +55,6 @@
     */
    @PostMapping("/user/app-register")
    public R<SysUser> registerAppUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
    @PostMapping("/system/content-setting/getCoursePageList")
    public R<String> getCourseList(@RequestParam(value = "contentType", required = true) int contentType);
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/AppUser.java
@@ -4,11 +4,14 @@
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinquan.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -21,7 +24,6 @@
 * @since 2024-08-21
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_app_user")
@ApiModel(value="AppUser对象", description="用户信息表")
public class AppUser extends BaseModel {
@@ -35,6 +37,9 @@
    @ApiModelProperty(value = "系统用户id")
    @TableField("user_id")
    private Long userId;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "手机号码")
    @TableField("cell_phone")
@@ -55,14 +60,23 @@
    @ApiModelProperty(value = "昵称")
    @TableField("nickname")
    private String nickname;
    @ApiModelProperty(value = "姓名")
    @TableField("realname")
    private String realname;
    @ApiModelProperty(value = "签名")
    @TableField("signature")
    private String signature;
    @ApiModelProperty(value = "用户code YH202010106666")
    @TableField("code")
    private String code;
    @ApiModelProperty(value = "性别 1=男 2=女 3=保密")
    @TableField("gender")
    private Integer gender;
    @ApiModelProperty(value = "会员类型 1月度2季度3年度 ")
    @TableField("vip_level")
    private Integer vipLevel;
    @ApiModelProperty(value = "生日")
    @TableField("birthday")
@@ -80,7 +94,7 @@
    @TableField("company")
    private String company;
    @ApiModelProperty(value = "职业")
    @ApiModelProperty(value = "职位")
    @TableField("occupation")
    private String occupation;
@@ -111,6 +125,9 @@
    @ApiModelProperty(value = "冻结操作人")
    @TableField("freezing_operator")
    private String freezingOperator;
    @ApiModelProperty(value = "冻结时间")
    @TableField("freezing_time")
    private LocalDateTime freezingTime;
    @ApiModelProperty(value = "梵文权限 1=是 2否")
    @TableField("sanskrit_flag")
@@ -134,6 +151,7 @@
    @ApiModelProperty(value = "注册时间")
    @TableField("register_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime registerTime;
    @ApiModelProperty(value = "注销时间")
@@ -150,16 +168,35 @@
    @ApiModelProperty(value = "标签id,多个id使用英文逗号拼接")
    @TableField("tag_id")
    private String tagId;
    @ApiModelProperty(value = "用户标签")
    @TableField(exist = false)
    private List<String> tags;
    @ApiModelProperty(value = "是否弹窗心泉之树提示 1是2否")
    @TableField("isFirst")
    private Integer isFirst;
    @ApiModelProperty(value = "当前剩余能量值")
    @TableField("energy_value")
    private Integer energyValue;
    @ApiModelProperty(value = "帮助人数")
    @TableField(exist = false)
    private Integer count;
    @ApiModelProperty(value = "佣金金额")
    @TableField(exist = false)
    private BigDecimal money;
    @ApiModelProperty(value = "是否是会员 1是2否")
    @TableField(exist = false)
    private Integer isVip;
    @ApiModelProperty(value = "疗愈等级")
    @TableField(exist = false)
    private Integer level;
    @ApiModelProperty(value = "疗愈等级名称")
    @TableField(exist = false)
    private String levelName;
    @ApiModelProperty(value = "疗愈等级图标")
    @TableField(exist = false)
    private String levelIcon;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/AppUserBank.java
@@ -53,6 +53,9 @@
    @ApiModelProperty(value = "手机号码")
    @TableField("cell_phone")
    private String cellPhone;
    @ApiModelProperty(value = "验证码")
    @TableField(exist = false)
    private String code;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/AppUserQuestion.java
@@ -33,7 +33,7 @@
    @TableField("type")
    private Integer type;
    @ApiModelProperty(value = "回答 1:是2:否3:偶尔有")
    @ApiModelProperty(value = "回答 1:是2:否3:偶尔有 当类型type=6 该字段存储的是纯文本补充内容")
    @TableField("answer")
    private String answer;
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/AppUserTree.java
@@ -41,8 +41,9 @@
    @ApiModelProperty(value = "当前树苗成长值")
    @TableField("growth_value")
    private Integer growthValue;
    @ApiModelProperty(value = "升到下一等级成长阈值")
    @TableField(exist = false)
    private Integer nextLevel;
    @ApiModelProperty(value = "是否重新播种 1=是 2=否")
    @TableField("sow_again")
    private Integer sowAgain;
@@ -58,8 +59,6 @@
    @ApiModelProperty(value = "是否完成签到 1是 2否")
    @TableField(exist = false)
    private Integer isSign;
    @ApiModelProperty(value = "升到下一等级成长阈值")
    @TableField(exist = false)
    private Integer nextLevel;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/AppUserWalletRecord.java
@@ -30,6 +30,9 @@
    @ApiModelProperty(value = "用户余额明细id")
    @TableId(value = "id",type = IdType.ASSIGN_ID)
    private Long id;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "用户id")
    @TableField("app_user_id")
@@ -50,6 +53,9 @@
    @ApiModelProperty(value = "下级用户id 变动原因为分佣时存")
    @TableField("child_app_user_id")
    private Long childAppUserId;
    @ApiModelProperty(value = "关联订单id")
    @TableField("order_id")
    private Long orderId;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/AppUserWithdraw.java
@@ -35,6 +35,9 @@
    @ApiModelProperty(value = "用户id")
    @TableField("app_user_id")
    private Long appUserId;
    @ApiModelProperty(value = "银行卡id")
    @TableField("bank_id")
    private Long bankId;
    @ApiModelProperty(value = "提现金额")
    @TableField("amount")
@@ -44,7 +47,7 @@
    @TableField("withdraw_type")
    private Integer withdrawType;
    @ApiModelProperty(value = "提现状态 1=已完成 2=提现失败")
    @ApiModelProperty(value = "提现状态 0=提现中 1=已完成 2=提现失败")
    @TableField("withdraw_status")
    private Integer withdrawStatus;
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/MeditationQuestion.java
File was renamed from xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationQuestion.java
@@ -1,9 +1,10 @@
package com.xinquan.meditation.domain;
package com.xinquan.system.api.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinquan.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -46,9 +47,31 @@
    @ApiModelProperty(value = "提问内容")
    @TableField("content")
    private String content;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "用户名称")
    @TableField(exist = false)
    private String userName;
    @ApiModelProperty(value = "用户头像")
    @TableField(exist = false)
    private String avatar;
    @ApiModelProperty(value = "用户手机号")
    @TableField(exist = false)
    private String cellPhone;
    @ApiModelProperty(value = "疗愈名称")
    @TableField(exist = false)
    private String meditationName;
    @ApiModelProperty(value = "关联疗愈所属分类名称")
    @TableField(exist = false)
    private String meditationCategoryName;
    @ApiModelProperty(value = "价格设定 1=免费 2=会员免费 3=单独收费")
    @TableField(exist = false)
    private Integer chargeType;
    @ApiModelProperty(value = "提问时间")
    @TableField("publish_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private LocalDateTime publishTime;
    @ApiModelProperty(value = "用户id")
@@ -61,6 +84,8 @@
    @ApiModelProperty(value = "回复时间")
    @TableField("reply_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private LocalDateTime replyTime;
    @ApiModelProperty(value = "是否显示 1= 是 2=否")
@@ -71,13 +96,7 @@
    @TableField("report_status")
    private Integer reportStatus;
    @ApiModelProperty(value = "举报原因")
    @TableField("report_content")
    private String reportContent;
    @ApiModelProperty(value = "举报人")
    @TableField("report_user_id")
    private Long reportUserId;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/MeditationReport.java
New file
@@ -0,0 +1,84 @@
package com.xinquan.system.api.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinquan.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
 * <p>
 * 冥想音频用户操作表
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_meditation_report")
@ApiModel(value="MeditationReport对象", description="冥想音频用户举报表")
public class MeditationReport extends BaseModel {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "id")
    @TableId(value = "id",type = IdType.ASSIGN_ID)
    private Long id;
    @ApiModelProperty(value = "冥想id")
    @TableField("meditation_id")
    private Long meditationId;
    @ApiModelProperty(value = "提问id")
    @TableField("question_id")
    private Long questionId;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "用户名称")
    @TableField(exist = false)
    private String userName;
    @ApiModelProperty(value = "用户头像")
    @TableField(exist = false)
    private String avatar;
    @ApiModelProperty(value = "用户手机号")
    @TableField(exist = false)
    private String cellPhone;
    @ApiModelProperty(value = "举报用户名称")
    @TableField(exist = false)
    private String userNameReport;
    @ApiModelProperty(value = "举报用户头像")
    @TableField(exist = false)
    private String avatarReport;
    @ApiModelProperty(value = "举报用户手机号")
    @TableField(exist = false)
    private String cellPhoneReport;
    @ApiModelProperty(value = "疗愈名称")
    @TableField(exist = false)
    private String meditationName;
    @ApiModelProperty(value = "关联疗愈所属分类名称")
    @TableField(exist = false)
    private String meditationCategoryName;
    @ApiModelProperty(value = "提问内容")
    @TableField(exist = false)
    private String content;
    @ApiModelProperty(value = "价格设定 1=免费 2=会员免费 3=单独收费")
    @TableField(exist = false)
    private Integer chargeType;
    @ApiModelProperty(value = "举报原因")
    @TableField("report_content")
    private String reportContent;
    @ApiModelProperty(value = "举报人")
    @TableField("report_user_id")
    private Long reportUserId;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/NoticeRecord.java
@@ -53,6 +53,9 @@
    @ApiModelProperty(value = "通知内容")
    @TableField("content")
    private String content;
    @ApiModelProperty(value = "消息收到时间")
    @TableField(exist = false)
    private String time;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/Prize.java
@@ -36,6 +36,9 @@
    @ApiModelProperty(value = "奖品名称")
    @TableField("`name`")
    private String name;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "封面图")
    @TableField("cover_url")
@@ -58,10 +61,9 @@
    @ApiModelProperty(value = "兑换状态 1=已兑换 2=未兑换")
    @TableField(exist = false)
    private Integer receiveStatus;
    @ApiModelProperty(value = "兑换时间")
    @TableField("redemption_time")
    private LocalDateTime redemptionTime;
    @ApiModelProperty(value = "兑换次数")
    @TableField(exist = false)
    private Long receiveCount;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/PrizeRedemptionRecord.java
@@ -36,11 +36,35 @@
    @ApiModelProperty(value = "奖品id")
    @TableField("prize_id")
    private Long prizeId;
    @ApiModelProperty(value = "奖品名称")
    @TableField(exist = false)
    private String name;
    @ApiModelProperty(value = "奖品价值")
    @TableField(exist = false)
    private BigDecimal worth;
    @ApiModelProperty(value = "奖品图标")
    @TableField(exist = false)
    private String coverUrl;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "用户名称")
    @TableField(exist = false)
    private String userName;
    @ApiModelProperty(value = "用户头像")
    @TableField(exist = false)
    private String avatar;
    @ApiModelProperty(value = "用户手机号")
    @TableField(exist = false)
    private String cellPhone;
    @ApiModelProperty(value = "用户id")
    @TableField("app_user_id")
    private Long appUserId;
    @ApiModelProperty(value = "兑换码")
    @TableField("code")
    private String code;
    @ApiModelProperty(value = "扣除能量值")
    @TableField("energy_value")
    private Integer energyValue;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysUser.java
@@ -1,6 +1,7 @@
package com.xinquan.system.api.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinquan.common.core.annotation.Excel;
import com.xinquan.common.core.annotation.Excel.ColumnType;
import com.xinquan.common.core.annotation.Excel.Type;
@@ -13,6 +14,8 @@
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.format.annotation.DateTimeFormat;
@@ -22,6 +25,7 @@
 * 
 * @author ruoyi
 */
@Data
public class SysUser extends BaseEntity
{
    private static final long serialVersionUID = 1L;
@@ -32,12 +36,12 @@
    private Long userId;
    /** 部门ID */
    @Excel(name = "部门编号", type = Type.IMPORT)
    @Excel(name = "部门id", type = Type.IMPORT)
    @TableField("dept_id")
    private Long deptId;
    /** 用户账号 */
    @Excel(name = "登录名称")
    @Excel(name = "登录名称/登录账号")
    @TableField("user_name")
    private String userName;
@@ -108,6 +112,7 @@
    /** 角色ID */
    @TableField(exist = false)
    @ApiModelProperty(value = "角色ids 逗号拼接")
    private Long roleId;
    @ApiModelProperty(value = "备注")
@@ -115,6 +120,12 @@
    @ApiModelProperty(value = "用户类型 00:管理后台用户 01:APP用户")
    private String userType;
    @ApiModelProperty(value = "禁用原因")
    @TableField("reason")
    private String reason;
    @ApiModelProperty(value = "禁用时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime disableTime;
    public String getUserType() {
        return userType;
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/Tag.java
@@ -38,4 +38,8 @@
    @TableField("tag_name")
    private String tagName;
    @ApiModelProperty(value = "用户是否选中 1是2否")
    @TableField(exist = false)
    private Integer isCheck;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/AppUserDetailVO.java
@@ -22,6 +22,8 @@
    private Long id;
    @ApiModelProperty(value = "手机号码")
    private String cellPhone;
    @ApiModelProperty(value = "姓名")
    private String realname;
    @ApiModelProperty(value = "头像")
    private String avatar;
    @ApiModelProperty(value = "昵称")
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/AppUserEnergyRecordVO.java
@@ -40,7 +40,7 @@
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private LocalDateTime createTime;
    @ApiModelProperty(value = "原因")
    @ApiModelProperty(value = "原因/操作内容")
    private String reason;
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/AppUserInfoVO.java
@@ -21,6 +21,8 @@
    private Long id;
    @ApiModelProperty(value = "手机号码")
    private String cellPhone;
    @ApiModelProperty(value = "姓名")
    private String realname;
    @ApiModelProperty(value = "头像")
    private String avatar;
    @ApiModelProperty(value = "昵称")
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/AppUserVO.java
@@ -31,7 +31,8 @@
    @ApiModelProperty(value = "微信openId")
    private String wxOpenId;
    @ApiModelProperty(value = "姓名")
    private String realname;
    @ApiModelProperty(value = "头像")
    private String avatar;
@@ -106,5 +107,4 @@
    @ApiModelProperty(value = "标签id,多个id使用英文逗号拼接")
    private String tagId;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/HealingLevelVO.java
New file
@@ -0,0 +1,36 @@
package com.xinquan.system.api.domain.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "个人中心-冥想等级VO")
public class HealingLevelVO implements Serializable {
    private static final long serialVersionUID = -6948932379350815750L;
    @ApiModelProperty(value = "疗愈等级")
    private Integer level;
    @ApiModelProperty(value = "疗愈等级名称")
    private String levelName;
    @ApiModelProperty(value = "疗愈等级图标")
    private String levelIcon;
    @ApiModelProperty(value = "当前经验值")
    @TableField("growth_value")
    private Integer growthValue;
    @ApiModelProperty(value = "升到下一等级成长阈值")
    private Integer nextLevel;
    @ApiModelProperty(value = "距离下一级还差XX经验值")
    private Integer differenceLevel;
    @ApiModelProperty(value = "心泉疗愈升级规则")
    private String content;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/OrderDetailVO.java
New file
@@ -0,0 +1,44 @@
package com.xinquan.system.api.domain.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * @author mitao
 * @date 2024/9/4
 */
@Data
@ApiModel(value = "余额明细列表-查看详情返回对象")
public class OrderDetailVO implements Serializable {
    private static final long serialVersionUID = -1776068531441762518L;
    @ApiModelProperty(value = "订单id")
    private Long id;
    @ApiModelProperty(value = "类型")
    private String type;
    @ApiModelProperty(value = "金额")
    private BigDecimal amount;
    @ApiModelProperty(value = "变动类型 1=增加 2=减少")
    private Integer changeType;
    @ApiModelProperty(value = "操作时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private LocalDateTime paymentTime;
    @ApiModelProperty(value = "流水单号")
    private String payOrderNo;
    @ApiModelProperty(value = "提现方式")
    private String withdraw;
    @ApiModelProperty(value = "备注")
    private String remark;
    @ApiModelProperty(value = "下级用户名称 当类型为佣金的时候展示")
    private String userName;
    @ApiModelProperty(value = "下级用户头像 当类型为佣金的时候展示")
    private String avatar;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/OrderListVO.java
New file
@@ -0,0 +1,34 @@
package com.xinquan.system.api.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * @author mitao
 * @date 2024/9/4
 */
@Data
@ApiModel(value = "余额明细列表返回对象")
public class OrderListVO implements Serializable {
    private static final long serialVersionUID = -1776068531441762518L;
    @ApiModelProperty(value = "明细id")
    private Long id;
    @ApiModelProperty(value = "明细类型")
    private String reason;
    @ApiModelProperty(value = "变动类型 1=增加 2=减少")
    private String changeType;
    @ApiModelProperty(value = "金额")
    private BigDecimal amount;
    @ApiModelProperty(value = "创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private LocalDateTime createTime;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/SysUserVO.java
New file
@@ -0,0 +1,30 @@
package com.xinquan.system.api.domain.vo;
import com.xinquan.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "查询管理后台人员列表DTO")
public class SysUserVO extends BasePage {
    @ApiModelProperty(value = "联系电话或姓名")
    private String phoneOrName;
    @ApiModelProperty(value = "登录状态(0正常 1停用)")
    private String  status;
    @ApiModelProperty(value = "角色ids")
    private List<Long> role;
    @ApiModelProperty(value = "部门ids")
    private List<Long> dept;
    @ApiModelProperty(value = "用户ids 前端忽略")
    private List<Long> userIds;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/UpdateAppUserDTO.java
@@ -18,11 +18,12 @@
    private static final long serialVersionUID = -6948932379350815750L;
    @ApiModelProperty(value = "头像")
    private String avatar;
    @ApiModelProperty(value = "昵称")
    private String nickname;
    @ApiModelProperty(value = "姓名")
    private String realname;
    @ApiModelProperty(value = "签名")
    private String signature;
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/UpdateTreeGroupVO.java
New file
@@ -0,0 +1,24 @@
package com.xinquan.system.api.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "修改树苗等级音频VO")
public class UpdateTreeGroupVO implements Serializable {
    private static final long serialVersionUID = -7433787602665988956L;
    @ApiModelProperty(value = "音频url")
    private String grow_up_music;
    @ApiModelProperty(value = "树苗等级类型 (1=种子 2=发芽 3=幼苗 4=小树苗 5=中等树苗 6=小树 7=中树 8=大树 9=成熟的大树 10=参天大树)")
    private Integer treeLevelType;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/UpdateUserGroupVO.java
New file
@@ -0,0 +1,24 @@
package com.xinquan.system.api.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "修改等级成长值管理VO")
public class UpdateUserGroupVO implements Serializable {
    private static final long serialVersionUID = -7433787602665988956L;
    @ApiModelProperty(value = "等级名称")
    private String levelName;
    @ApiModelProperty(value = "等级图标")
    private String levelIcon;
    @ApiModelProperty(value = "树苗等级类型 (1=种子 2=发芽 3=幼苗 4=小树苗 5=中等树苗 6=小树 7=中树 8=大树 9=成熟的大树 10=参天大树)")
    private Integer treeLevelType;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/UpdateVipVO.java
New file
@@ -0,0 +1,24 @@
package com.xinquan.system.api.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "编辑会员价格设置富文本内容")
public class UpdateVipVO implements Serializable {
    private static final long serialVersionUID = -7433787602665988956L;
    @ApiModelProperty(value = "富文本内容")
    private String content;
    @ApiModelProperty(value = "1=会员权益介绍 2=会员用户协议 3=续费管理说明")
    private Integer settingType;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/vo/WalletVO.java
New file
@@ -0,0 +1,34 @@
package com.xinquan.system.api.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "用户钱包VO")
public class WalletVO implements Serializable {
    private static final long serialVersionUID = -6948932379350815750L;
    @ApiModelProperty(value = "App用户id")
    private Long id;
    @ApiModelProperty(value = "余额")
    private BigDecimal balance;
    @ApiModelProperty(value = "收益")
    private BigDecimal income;
    @ApiModelProperty(value = "充值")
    private BigDecimal recharge;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/factory/RemoteUserFallbackFactory.java
@@ -26,6 +26,11 @@
        return new RemoteUserService()
        {
            @Override
            public R<SysUser> getSysUserById(String id) {
                return R.fail("根据系统用户id 查询用户信息:" + throwable.getMessage());
            }
            @Override
            public R<LoginUser> getUserInfo(String username, String source)
            {
                return R.fail("获取用户失败:" + throwable.getMessage());
@@ -40,6 +45,11 @@
            public R<SysUser> registerAppUserInfo(SysUser sysUser, String source) {
                return R.fail("注册APP用户失败:" + throwable.getMessage());
            }
            @Override
            public R<String> getCourseList(int contentType) {
                return R.fail("获取协议失败:" + throwable.getMessage());
            }
        };
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/AppCaptchaBody.java
@@ -23,4 +23,8 @@
    @ApiModelProperty(value = "验证码", required = true)
    @NotBlank(message = "验证码不能为空")
    private String captcha;
    @ApiModelProperty(value = "邮箱", required = false)
    private String email;
    @ApiModelProperty(value = "姓名", required = false)
    private String name;
}
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/dto/AppUserManagementDTO.java
New file
@@ -0,0 +1,31 @@
package com.xinquan.user.api.domain.dto;
import com.xinquan.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "管理后台查询用户列表DTO")
public class AppUserManagementDTO extends BasePage {
    @ApiModelProperty(value = "用户昵称")
    private String nickname;
    @ApiModelProperty(value = "用户手机号")
    private String cellPhone;
    @ApiModelProperty(value = "性别 1男2女")
    private String gender;
    @ApiModelProperty(value = "会员类型 1非会员2月度3季度4年度 多个逗号拼接")
    private String vipType;
    @ApiModelProperty(value = "会员到期时间 2020-11-11 - 2022-11-11")
    private String vipExpireTime;
    @ApiModelProperty(value = "疗愈等级 多个逗号拼接")
    private String level;
    @ApiModelProperty(value = "用户状态 1=正常 2=冻结 3=注销")
    private Integer userStatus;
    @ApiModelProperty(value = "注册时间 2020-11-11 - 2022-11-11")
    private String registerTime;
}
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/dto/PrizeRecordDTO.java
New file
@@ -0,0 +1,23 @@
package com.xinquan.user.api.domain.dto;
import com.xinquan.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "管理后台查询奖品兑换记录DTO")
public class PrizeRecordDTO extends BasePage {
    @ApiModelProperty(value = "兑换时间 2020-01-01 - 2020-12-30")
    private String time;
    @ApiModelProperty(value = "兑换状态1兑换中2已兑换")
    private Integer status;
    @ApiModelProperty(value = "兑换用户名称/手机号")
    private String userNameOrPhone;
    @ApiModelProperty(value = "奖品名称")
    private String name;
}
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/dto/UserBalanceDetailDTO.java
New file
@@ -0,0 +1,22 @@
package com.xinquan.user.api.domain.dto;
import com.xinquan.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "管理后台用户余额明细DTO")
public class UserBalanceDetailDTO extends BasePage {
    @ApiModelProperty(value = "明细内容")
    private String reason;
    @ApiModelProperty(value = "操作时间 2020-11-11 - 2021-11-11")
    private String time;
    @ApiModelProperty(value = "用户uid")
    private String uid;
}
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/dto/UserEnergyDTO.java
New file
@@ -0,0 +1,24 @@
package com.xinquan.user.api.domain.dto;
import com.xinquan.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "管理后台用户能量值明细DTO")
public class UserEnergyDTO extends BasePage {
    @ApiModelProperty(value = "操作内容")
    private String content;
    @ApiModelProperty(value = "类型 1=增加 2=减少 全部不传")
    private Integer state;
    @ApiModelProperty(value = "操作时间 2020-11-11 - 2021-11-11")
    private String time;
    @ApiModelProperty(value = "用户uid")
    private String uid;
}
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/dto/UserExchangeRecordDTO.java
New file
@@ -0,0 +1,24 @@
package com.xinquan.user.api.domain.dto;
import com.xinquan.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author mitao
 * @date 2024/9/7
 */
@Data
@ApiModel(value = "管理后台用户兑换记录明细DTO")
public class UserExchangeRecordDTO extends BasePage {
    @ApiModelProperty(value = "奖品名称")
    private String name;
    @ApiModelProperty(value = "兑换状态 1待领取2已兑换")
    private Integer state;
    @ApiModelProperty(value = "操作时间 2020-11-11 - 2021-11-11")
    private String time;
    @ApiModelProperty(value = "用户uid")
    private String uid;
}
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/vo/FreezingVO.java
New file
@@ -0,0 +1,32 @@
package com.xinquan.user.api.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * @author mitao
 * @date 2024/8/21
 */
@Data
@ApiModel(value = "用户冻结信息")
public class FreezingVO implements Serializable {
    private static final long serialVersionUID = -3850851853092651572L;
    @ApiModelProperty(value = "冻结时间")
    private String freezingTime;
    @ApiModelProperty(value = "冻结原因")
    private String freezingReason;
    @ApiModelProperty(value = "操作人")
    private String freezingOperator;
}
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/vo/ViewReport.java
New file
@@ -0,0 +1,28 @@
package com.xinquan.user.api.domain.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.xinquan.system.api.domain.AppUserQuestion;
import com.xinquan.system.api.domain.Tag;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
 * @author mitao
 * @date 2024/8/21
 */
@Data
@ApiModel(value = "用户详情-查看报告实体类")
public class ViewReport implements Serializable {
    private static final long serialVersionUID = -3850851853092651572L;
    @ApiModelProperty(value = "1:您是否内心纠结敏感多疑?2:您是否辗转反侧彻夜难眠?3:您是否情绪失控暴躁易怒?4:您是否沉迷情感倍受伤害?5:您是否人生迷茫踌躇彷徨?6:其它补充说明")
    private List<AppUserQuestion> questions;
    @ApiModelProperty(value = "你在这方空间最想解决和收获的问题是哪方面")
    private List<Tag> tags;
}
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/factory/RemoteAppUserFallbackFactory.java
@@ -2,14 +2,12 @@
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.system.api.domain.AppUserCourse;
import com.xinquan.system.api.domain.*;
import com.xinquan.system.api.domain.vo.AppUserVO;
import com.xinquan.system.api.model.AppCaptchaBody;
import com.xinquan.system.api.model.AppLoginUser;
import com.xinquan.system.api.model.AppVerifyCellPhoneBody;
import com.xinquan.system.api.model.AppWXLoginBody;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.AppUserViewingHistory;
import com.xinquan.user.api.domain.dto.AppUserDTO;
import com.xinquan.user.api.feign.RemoteAppUserService;
import java.util.Collection;
@@ -30,6 +28,31 @@
    public RemoteAppUserService create(Throwable cause) {
        return new RemoteAppUserService() {
            @Override
            public R addNoticeReplay(NoticeRecord noticeRecord) {
                return R.fail("后台远程调用 新增回复消息失败");
            }
            @Override
            public R<AppUser> getAppUserById(String id) {
                return R.fail("远程调用 根据用户id查询用户信息失败");
            }
            @Override
            public R<List<Long>> getAppUserByName(String name) {
                return R.fail("远程调用根据用户名称 查询用户失败");
            }
            @Override
            public R<List<Long>> getAppUserByNameOrPhone(String name) {
                return R.fail("远程调用根据用户名称或者电话 查询用户失败");
            }
            @Override
            public R<List<Tag>> queryTag(String name) {
                return R.fail("远程调用 模糊查询标签列表失败");
            }
            @Override
            public R<AppUserVO> getCurrentUser() {
                return null;
            }
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/feign/RemoteAppUserService.java
@@ -4,14 +4,12 @@
import com.xinquan.common.core.constant.ServiceNameConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.system.api.domain.AppUserCourse;
import com.xinquan.system.api.domain.*;
import com.xinquan.system.api.domain.vo.AppUserVO;
import com.xinquan.system.api.model.AppCaptchaBody;
import com.xinquan.system.api.model.AppLoginUser;
import com.xinquan.system.api.model.AppVerifyCellPhoneBody;
import com.xinquan.system.api.model.AppWXLoginBody;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.AppUserViewingHistory;
import com.xinquan.user.api.domain.dto.AppUserDTO;
import com.xinquan.user.api.factory.RemoteAppUserFallbackFactory;
import java.util.Collection;
@@ -28,6 +26,26 @@
@FeignClient(contextId = "remoteAppUserService", value = ServiceNameConstants.APP_USER_SERVICE, fallbackFactory = RemoteAppUserFallbackFactory.class)
public interface RemoteAppUserService {
    /**
     * 后台远程调用 新增回复消息
     * @return
     */
    @PostMapping("/client/user/notice-record/addNoticeReplay")
    public R addNoticeReplay(@RequestBody NoticeRecord noticeRecord);
    /**
     * 远程调用根据用户id 查询用户
     */
    @PostMapping("/client/app-user/getAppUserById/{id}")
    public R<AppUser> getAppUserById(@PathVariable("id")String id);
    /**
     * 远程调用根据用户名称 查询用户
     */
    @PostMapping("/client/app-user/getAppUserByName/{name}")
    public R<List<Long>> getAppUserByName(@PathVariable("name")String name);
    @PostMapping("/getAppUserByNameOrPhone/{name}")
    public R<List<Long>> getAppUserByNameOrPhone(@PathVariable("name")String name);
    @PostMapping("/client/tag/queryTag/{name}")
    public R<List<Tag>> queryTag(@PathVariable("name") String name);
    @PostMapping("/client/app-user/getCurrentUser")
    public R<AppUserVO> getCurrentUser();
    @GetMapping("/client/app-user-course/getPayCourse/{pageCurr}/{pageSize}")
xinquan-auth/src/main/java/com/xinquan/auth/controller/TokenController.java
@@ -64,7 +64,7 @@
    @ApiOperation(value = "发送验证码",tags = {"APP端"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cellPhone", value = "手机号码", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "类型 1=注册 2=验证码登录 3=找回密码 4=第三方登录后验证手机 5=切换手机号", required = true, dataType = "Integer", paramType = "query")})
            @ApiImplicitParam(name = "type", value = "类型 1=注册 2=验证码登录 3=找回密码 4=第三方登录后验证手机 5=切换手机号 6= 添加银行卡", required = true, dataType = "Integer", paramType = "query")})
    public R<?> sendCaptchaCode(
            @RequestParam(value = "cellPhone", required = true) String cellPhone,
            @RequestParam("type") Integer type) {
@@ -159,7 +159,9 @@
    @ApiOperation(value = "苹果登录", tags = {"APP端"})
    @PostMapping("/app/appleLogin")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "appleId", value = "苹果ID", required = true, dataType = "String", paramType = "query")})
            @ApiImplicitParam(name = "appleId", value = "苹果ID", required = true, dataType = "String", paramType = "query"),
    }
    )
    public R<AppLoginUser> appleLogin(
            @RequestParam(value = "appleId", required = true) String appleId) {
        AppLoginUser appLoginUser = sysLoginService.appleLogin(appleId);
xinquan-auth/src/main/java/com/xinquan/auth/service/SysLoginService.java
@@ -264,6 +264,8 @@
                return CacheConstants.APP_PASSWORD_CAPTCHA_CODE_PREFIX;
            case 4:
                return CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX;
            case 5:
                return CacheConstants.APP_CHANGE_PHONE_CODE_PREFIX;
            default:
                return "";
        }
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/CacheConstants.java
@@ -78,6 +78,10 @@
     */
    public static final String APP_VERIFY_CAPTCHA_CODE_PREFIX = "app_verify_captcha_code:";
    /**
     * 更换绑定手机号 redis key
     */
    public static final String APP_CHANGE_PHONE_CODE_PREFIX = "app_change_phone_code:";
    /**
     * APP第三方登录手机号校验验证码修改密码秘钥 redis key
     */
    public static final String APP_PASSWORD_SECRET_PREFIX = "app_password_secret:";
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/domain/BaseModel.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.time.LocalDateTime;
@@ -23,7 +24,7 @@
    /** 创建时间 */
    @ApiModelProperty(value = "记录创建时间,前端忽略")
    // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private LocalDateTime createTime;
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientCourseCategoryController.java
@@ -1,8 +1,23 @@
package com.xinquan.course.controller.client;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.course.api.domain.CourseCategory;
import com.xinquan.course.service.CourseCategoryService;
import com.xinquan.course.service.CourseCategoryService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.Arrays;
/**
 * <p>
@@ -15,6 +30,50 @@
@RestController
@RequestMapping("/client/course/course-category")
public class ClientCourseCategoryController {
    @Autowired
    private CourseCategoryService courseCategoryService;
    @PostMapping("/courseCategoryManagementList")
    @ApiOperation(value = "分类列表-分页", tags = {"管理后台-分类管理"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageCurr", value = "分页参数,当前页码", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量", dataType = "Integer", required = true)
    })
    public R<PageDTO<CourseCategory>> courseCategoryManagementList(@RequestParam(value = "pageCurr")Integer pageCurr,
                                                                  @RequestParam(value = "pageSize")Integer pageSize) {
        LambdaQueryWrapper<CourseCategory> courseLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseLambdaQueryWrapper.orderByDesc(CourseCategory::getSortNum);
        Page<CourseCategory> page = courseCategoryService.page(new Page<>(pageCurr, pageSize), courseLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())) {
            return R.ok(PageDTO.empty(page));
        }
        for (CourseCategory record : page.getRecords()) {
            record.setUid(record.getId()+"");
        }
        return R.ok(PageDTO.of(page, CourseCategory.class));
    }
    @PostMapping("/addCourseCategory")
    @ApiOperation(value = "新增分类管理", notes = "管理后台-分类管理")
    public R addCourseCategory(@RequestBody CourseCategory homeBackgroundMusic) {
        homeBackgroundMusic.setCreateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setCreateTime(LocalDateTime.now());
        return R.ok(courseCategoryService.save(homeBackgroundMusic));
    }
    @GetMapping("/detailCourseCategory")
    @ApiOperation(value = "查看详情分类管理", notes = "管理后台-分类管理")
    public R<CourseCategory> detailCourseCategory(String uid) {
        return R.ok(courseCategoryService.getById(uid));
    }
    @PostMapping("/updateCourseCategory")
    @ApiOperation(value = "修改分类管理", notes = "管理后台-分类管理")
    public R updateCourseCategory(@RequestBody CourseCategory homeBackgroundMusic) {
        homeBackgroundMusic.setUpdateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setUpdateTime(LocalDateTime.now());
        return R.ok(courseCategoryService.updateById(homeBackgroundMusic));
    }
    @PostMapping("/deleteCourseCategory")
    @ApiOperation(value = "批量删除", notes = "管理后台-分类管理")
    public R deleteCourseCategory(String ids) {
        return R.ok(courseCategoryService.removeBatchByIds(Arrays.asList(ids.split(","))));
    }
}
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientCourseChapterController.java
@@ -1,12 +1,31 @@
package com.xinquan.course.controller.client;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.course.domain.CourseChapter;
import com.xinquan.course.service.CourseChapterService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
 * <p>
 * 在线课程章节表 前端控制器
 * 在线章节章节表 前端控制器
 * </p>
 *
 * @author mitao
@@ -15,6 +34,50 @@
@RestController
@RequestMapping("/client/course/course-chapter")
public class ClientCourseChapterController {
    @Autowired
    private CourseChapterService courseChapterService;
    @PostMapping("/courseChapterManagementList")
    @ApiOperation(value = "章节列表-分页", tags = {"管理后台-章节管理"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageCurr", value = "分页参数,当前页码", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量", dataType = "Integer", required = true)
    })
    public R<PageDTO<CourseChapter>> courseChapterManagementList(@RequestParam(value = "pageCurr")Integer pageCurr,
                                                                 @RequestParam(value = "pageSize")Integer pageSize) {
        LambdaQueryWrapper<CourseChapter> courseLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseLambdaQueryWrapper.orderByDesc(CourseChapter::getSortNum);
        Page<CourseChapter> page = courseChapterService.page(new Page<>(pageCurr, pageSize), courseLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())) {
            return R.ok(PageDTO.empty(page));
        }
        for (CourseChapter record : page.getRecords()) {
            record.setUid(record.getId()+"");
        }
        return R.ok(PageDTO.of(page, CourseChapter.class));
    }
    @PostMapping("/addChapter")
    @ApiOperation(value = "新增章节管理", notes = "管理后台-章节管理")
    public R addCourseChapter(@RequestBody CourseChapter homeBackgroundMusic) {
        homeBackgroundMusic.setCreateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setCreateTime(LocalDateTime.now());
        return R.ok(courseChapterService.save(homeBackgroundMusic));
    }
    @GetMapping("/detailCourseChapter")
    @ApiOperation(value = "查看详情章节管理", notes = "管理后台-章节管理")
    public R<CourseChapter> detailCourseChapter(String uid) {
        return R.ok(courseChapterService.getById(uid));
    }
    @PostMapping("/updateCourseChapter")
    @ApiOperation(value = "修改章节管理", notes = "管理后台-章节管理")
    public R updateCourseChapter(@RequestBody CourseChapter homeBackgroundMusic) {
        homeBackgroundMusic.setUpdateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setUpdateTime(LocalDateTime.now());
        return R.ok(courseChapterService.updateById(homeBackgroundMusic));
    }
    @PostMapping("/deleteCourseChapter")
    @ApiOperation(value = "批量删除", notes = "管理后台-章节管理")
    public R deleteCourseChapter(String ids) {
        return R.ok(courseChapterService.removeBatchByIds(Arrays.asList(ids.split(","))));
    }
}
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientCourseController.java
@@ -2,6 +2,8 @@
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.domain.R;
@@ -10,20 +12,27 @@
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.course.api.domain.Course;
import com.xinquan.course.api.domain.CourseDTO;
import com.xinquan.course.api.vo.CourseVO;
import com.xinquan.course.api.vo.StudyPageVO;
import com.xinquan.course.api.domain.CourseCategory;
import com.xinquan.course.domain.CourseChapter;
import com.xinquan.course.domain.CourseUserFavorite;
import com.xinquan.course.domain.vo.ClientCourseCategoryVO;
import com.xinquan.course.domain.vo.ClientCourseVO;
import com.xinquan.course.service.CourseCategoryService;
import com.xinquan.course.service.CourseChapterService;
import com.xinquan.course.service.CourseService;
import com.xinquan.course.service.CourseUserFavoriteService;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.api.feign.RemoteMeditationService;
import com.xinquan.system.api.RemoteBannerService;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.AppUserCourse;
import com.xinquan.system.api.domain.AppUserViewingHistory;
import com.xinquan.system.api.domain.vo.AppUserVO;
import com.xinquan.system.api.domain.vo.BannerVO;
import com.xinquan.course.api.domain.OrderCourseVO;
import com.xinquan.user.api.feign.RemoteAppUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
@@ -32,12 +41,13 @@
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import io.swagger.models.auth.In;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.jaxb.SpringDataJaxb;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@@ -60,9 +70,210 @@
    private final CourseService courseService;
    private final RemoteBannerService remoteBannerService;
    private final RemoteAppUserService remoteAppUserService;
    @Resource
    private CourseChapterService courseChapterService;
    @Resource
    private CourseUserFavoriteService courseUserFavoriteService;
    @Resource
    private RemoteMeditationService remoteMeditationService;
    /**
     * 远程调用 通过课程名字查询课程ids
     * @return
     */
    @PostMapping("/getCourseIdsByName/{name}")
    public R<List<Long>> getCourseIdsByName(@PathVariable("name") String name) {
        List<Long> collect = courseService.lambdaQuery().like(Course::getCourseTitle, name)
                .list().stream().map(Course::getId)
                .collect(Collectors.toList());
        return R.ok(collect);
    }
    @PostMapping("/courseManagementList")
    @ApiOperation(value = "课程管理列表-分页", tags = {"管理后台-课程管理"})
    public R<PageDTO<Course>> courseManagementList(@RequestBody CourseDTO courseDTO) {
        List<Long> longs = new ArrayList<>();
        LambdaQueryWrapper<Course> courseLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseLambdaQueryWrapper.like(StringUtils.isNotBlank(courseDTO.getTutor()), Course::getTutor, courseDTO.getTutor())
                .eq(Objects.nonNull(courseDTO.getCateId()), Course::getCateId, courseDTO.getCateId())
                .eq(Objects.nonNull(courseDTO.getCourseType()), Course::getCourseType, courseDTO.getCourseType())
                .eq(Objects.nonNull(courseDTO.getChargeType()), Course::getChargeType, courseDTO.getChargeType())
                .eq(Objects.nonNull(courseDTO.getListingStatus()), Course::getListingStatus, courseDTO.getListingStatus())
                .orderByDesc(Course::getSortNum);
        if (org.springframework.util.StringUtils.hasLength(courseDTO.getCourseTitle())){
            List<Long> collect = courseService.lambdaQuery().like(Course::getCourseTitle, courseDTO.getCourseTitle()).list()
                    .stream().map(Course::getId).collect(Collectors.toList());
            longs.addAll(collect);
            List<Long> collect1 = courseChapterService.lambdaQuery().like(CourseChapter::getChapterTitle, courseDTO.getCourseTitle()).list()
                    .stream().map(CourseChapter::getCourseId).collect(Collectors.toList());
            longs.addAll(collect1);
            if (longs.isEmpty()){
                longs.add(-1L);
            }
            courseLambdaQueryWrapper.in(Course::getId, longs);
        }
        Page<Course> page = courseService.page(new Page<>(courseDTO.getPageCurr(), courseDTO.getPageSize()), courseLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())) {
            return R.ok(PageDTO.empty(page));
        }
        for (Course record : page.getRecords()) {
            CourseCategory byId = courseCategoryService.getById(record.getCateId());
            if (Objects.nonNull(byId)){
                record.setCategoryName(byId.getName());
            }
            record.setUid(record.getId().toString());
            long count = courseChapterService.count(new LambdaQueryWrapper<CourseChapter>().eq(CourseChapter::getCourseId, record.getId()));
            record.setCourseChapterCount(count);
            // 查询收藏数量
            long count1 = courseUserFavoriteService.count(new LambdaQueryWrapper<CourseUserFavorite>()
                    .eq(CourseUserFavorite::getCourseId, record.getId()));
            record.setCollectCount(count1);
        }
        return R.ok(PageDTO.of(page, Course.class));
    }
    @PostMapping("/addCourse")
    @ApiOperation(value = "新增课程管理", notes = "管理后台-课程管理")
    public R addCourse(@RequestBody Course homeBackgroundMusic) {
        homeBackgroundMusic.setCreateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setCreateTime(LocalDateTime.now());
        return R.ok(courseService.save(homeBackgroundMusic));
    }
    @GetMapping("/detailCourse")
    @ApiOperation(value = "查看详情课程管理", notes = "管理后台-课程管理")
    public R<Course> detailCourse(String uid) {
        return R.ok(courseService.getById(uid));
    }
    @GetMapping("/updateState")
    @ApiOperation(value = "修改课程上下架状态", notes = "管理后台-课程管理")
    public R updateState(String uid) {
        Course byId = courseService.getById(uid);
        if (byId.getListingStatus() == 1){
            byId.setListingStatus(2);
        }else {
            byId.setListingStatus(1);
        }
        return R.ok();
    }
    @PostMapping("/updateCourse")
    @ApiOperation(value = "修改课程管理", notes = "管理后台-课程管理")
    public R updateCourse(@RequestBody Course homeBackgroundMusic) {
        homeBackgroundMusic.setUpdateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setUpdateTime(LocalDateTime.now());
        return R.ok(courseService.updateById(homeBackgroundMusic));
    }
    @PostMapping("/deleteCourse")
    @ApiOperation(value = "批量删除", notes = "管理后台-课程管理")
    public R deleteCourse(String ids) {
        return R.ok(courseService.removeBatchByIds(Arrays.asList(ids.split(","))));
    }
    @PostMapping("/cateList")
    public R<List<CourseCategory>> cateList() {
        List<CourseCategory> list = courseCategoryService.list();
        for (CourseCategory courseCategory : list) {
            courseCategory.setUid(courseCategory.getId().toString());
        }
        return R.ok(list);
    }
    @PostMapping("/courseList")
    public R<PageDTO<Course>> courseList(@RequestBody CourseDTO courseDTO) {
        Page<Course> page = courseService.lambdaQuery()
                .like(StringUtils.isNotBlank(courseDTO.getCourseTitle()), Course::getCourseTitle, courseDTO.getCourseTitle())
                .like(StringUtils.isNotBlank(courseDTO.getTutor()), Course::getTutor, courseDTO.getTutor())
                .eq(Objects.nonNull(courseDTO.getCateId()), Course::getCateId, courseDTO.getCateId())
                .eq(Objects.nonNull(courseDTO.getCourseType()), Course::getCourseType, courseDTO.getCourseType())
                .orderByDesc(Course::getSortNum)
                .page(new Page<>(courseDTO.getPageCurr(), courseDTO.getPageSize()));
        if (CollUtils.isEmpty(page.getRecords())) {
            return R.ok(PageDTO.empty(page));
        }
        for (Course record : page.getRecords()) {
            CourseCategory byId = courseCategoryService.getById(record.getCateId());
            if (Objects.nonNull(byId)){
                record.setCategoryName(byId.getName());
            }
            record.setUid(record.getId().toString());
        }
        return R.ok(PageDTO.of(page, Course.class));
    }
    @PostMapping("/myCollect")
    @ApiOperation(value = "我的收藏")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "state", value = "1冥想 2课程", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageCurr", value = "分页参数,当前页码", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量", dataType = "Integer", required = true)
    })
    public R<PageDTO<OrderCourseVO>> myCollect(@RequestParam(value = "state")Integer state,
                                               @RequestParam(value = "pageCurr")Integer pageCurr,
                                               @RequestParam(value = "pageSize")Integer pageSize) {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        switch (state){
            case 1:
                Page<Meditation> data = remoteMeditationService.getMeditationById(pageCurr, pageSize)
                        .getData();
                for (Meditation meditation : data.getRecords()) {
                }
                break;
            case 2:
                Page<CourseUserFavorite> page = courseUserFavoriteService.lambdaQuery()
                        .eq(CourseUserFavorite::getAppUserId, userId)
                        .page(new Page<>(pageCurr, pageSize));
                PageDTO<OrderCourseVO> courseChapterPageDTO = PageDTO.of(page, OrderCourseVO.class);
                for (CourseUserFavorite record : page.getRecords()) {
                }
                break;
        }
        return R.ok();
    }
    @PostMapping("/collectCourse")
    @ApiOperation(value = "收藏/取消课程")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "课程id", name = "id", required = true, dataType = "Long"),
    })
    public R collectCourse(@RequestParam(value = "id")Long id) {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        CourseUserFavorite one = courseUserFavoriteService.lambdaQuery()
                .eq(CourseUserFavorite::getAppUserId, userId)
                .eq(CourseUserFavorite::getCourseId, id).one();
        if (one==null){
            // 收藏课程
            CourseUserFavorite courseUserFavorite = new CourseUserFavorite();
            courseUserFavorite.setAppUserId(userId);
            courseUserFavorite.setCourseId(id);
            courseUserFavoriteService.save(courseUserFavorite);
        }else{
            // 取消收藏
            courseUserFavoriteService.removeById(one);
        }
        return R.ok();
    }
    /**
     * 远程调用 根据课程id查询课程信息
     *
     * @return 课程分类列表
     */
    @PostMapping("/getCourseByCourseId/{courseId}")
    public R<OrderCourseVO> getCourseCategoryList(@RequestBody OrderCourseVO req) {
        Course byId = courseService.getById(req.getBusinessId());
        List<AppUser> data = remoteAppUserService.getUserByCourseId(req.getBusinessId()).getData();
        if (data!=null){
            req.setCount(data.size());
            req.setCourseTitle(byId.getCourseTitle());
            req.setDescription(byId.getDescription());
            req.setGeneralPrice(byId.getGeneralPrice());
            req.setIosPrice(byId.getIosPrice());
            req.setCoverUrl(byId.getCoverUrl());
        }
        return R.ok(req);
    }
    /**
     * 获取轮播图列表
@@ -84,6 +295,15 @@
    @ApiOperation(value = "获取课程分类列表")
    public R<List<ClientCourseCategoryVO>> getCourseCategoryList() {
        return R.ok(courseCategoryService.getCourseCategoryList());
    }
    /**
     * 远程调用 根据分类id 获取分类对象
     *
     * @return 课程分类列表
     */
    @GetMapping("/getCategoryById/{id}")
    public R<CourseCategory> getCategoryById(@PathVariable("id") String id) {
        return R.ok(courseCategoryService.getById(id));
    }
    /**
     * 课程详情
@@ -155,6 +375,10 @@
            }
        }
        clientCourseVO.setList2(courses);
        // 查询是否已收藏课程
        clientCourseVO.setIsCollect(courseUserFavoriteService.lambdaQuery()
                .eq(CourseUserFavorite::getAppUserId, userId)
                .eq(CourseUserFavorite::getCourseId, id) == null ? 2 : 1);
        return R.ok(clientCourseVO);
    }
@@ -258,29 +482,25 @@
    }
    @GetMapping("/studyPage")
    @ApiOperation(value = "学习")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "分页参数,当前页码", name = "pageCurr", required = true, dataType = "Integer"),
            @ApiImplicitParam(value = "分页参数,每页数量", name = "pageSize", required = true, dataType = "Integer")
    })
    public R<StudyPageVO> studyPage(@RequestParam(value = "pageCurr", defaultValue = "1") Integer pageCurr,
                               @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
    public R<StudyPageVO> studyPage() {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        StudyPageVO studyPageVO = new StudyPageVO();
        List<CourseVO> courseVOS = new ArrayList<>();
        PageDTO<AppUserCourse> data = remoteAppUserService.getPayCourse(pageCurr, pageSize).getData();
        PageDTO<AppUserCourse> data = remoteAppUserService.getPayCourse(1, 909999).getData();
        List<AppUserCourse> list = data.getList();
        if (CollUtils.isNotEmpty(list)) {
            List<Long> courseIds = list.stream().map(AppUserCourse::getCourseId).collect(Collectors.toList());
            Page<Course> page = courseService.lambdaQuery()
            List<Course> page = courseService.lambdaQuery()
                    .in(Course::getId, courseIds)
                    .page(new Page<>(pageCurr, pageSize));
            if (CollUtils.isEmpty(page.getRecords())) {
                PageDTO<CourseVO> empty = PageDTO.empty(page);
                studyPageVO.setCourseList(empty);
            }else{
                PageDTO<CourseVO> courseChapterPageDTO = PageDTO.of(page, CourseVO.class);
                studyPageVO.setCourseList(courseChapterPageDTO);
                    .list();
            for (Course course : page) {
                CourseVO courseVO = new CourseVO();
                BeanUtils.copyProperties(course, courseVO);
                courseVOS.add(courseVO);
                studyPageVO.setCourseList(courseVOS);
            }
        }
        // 查询两个相同类型的线上免费课程
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientTutorSpecialColumnController.java
@@ -1,13 +1,14 @@
package com.xinquan.course.controller.client;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.BeanUtils;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.course.api.domain.Course;
import com.xinquan.course.api.domain.CourseCategory;
import com.xinquan.course.domain.TutorSpecialColumn;
import com.xinquan.course.domain.TutorSpecialColumnCourse;
import com.xinquan.course.domain.vo.ClientCourseVO;
@@ -20,12 +21,11 @@
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -54,7 +54,6 @@
    private CourseService courseService;
    @PostMapping("/getCoursePageList")
    @ApiOperation(value = "导师专栏",tags = "导师专栏")
    public R<TutorVo> getCourseList() {
        TutorVo tutorVo = new TutorVo();
        TutorSpecialColumn one = tutorSpecialColumnService.lambdaQuery().one();
@@ -77,7 +76,51 @@
            return R.ok(tutorVo);
        }
    }
    @GetMapping("/detailTutor")
    @ApiOperation(value = "查看详情导师专栏", notes = "管理后台-导师专栏")
    public R<TutorSpecialColumn> detailTutor() {
        TutorSpecialColumn one = tutorSpecialColumnService.getOne(null);
        if (one!=null){
            List<Long> collect = tutorSpecialColumnCourseService.lambdaQuery().eq(TutorSpecialColumnCourse::getTutorSpecialColumnId, one.getId())
                    .list().stream().map(TutorSpecialColumnCourse::getId).collect(Collectors.toList());
            if (!collect.isEmpty()){
                List<Course> list = courseService.lambdaQuery().in(Course::getId, collect).list();
                one.setCourses(list);
            }
        }
        return R.ok(one);
    }
    @PostMapping("/updateTutor")
    @ApiOperation(value = "修改分类导师专栏", notes = "管理后台-导师专栏")
    public R updateTutor(@RequestBody TutorSpecialColumn homeBackgroundMusic) {
        TutorSpecialColumn one = tutorSpecialColumnService.getOne(null);
        if (one == null){
            tutorSpecialColumnService.save(homeBackgroundMusic);
        }
        homeBackgroundMusic.setUpdateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setUpdateTime(LocalDateTime.now());
        List<Long> collect = tutorSpecialColumnCourseService.lambdaQuery()
                .eq(TutorSpecialColumnCourse::getTutorSpecialColumnId, homeBackgroundMusic.getId())
                .list().stream().map(TutorSpecialColumnCourse::getId)
                .collect(Collectors.toList());
        tutorSpecialColumnCourseService.removeBatchByIds(collect);
        List<TutorSpecialColumnCourse> tutorSpecialColumnCourses = new ArrayList<>();
        if (StringUtils.hasLength(homeBackgroundMusic.getCourseIds())){
            String[] split = homeBackgroundMusic.getCourseIds().split(",");
            for (int i = 0; i < split.length; i++) {
                TutorSpecialColumnCourse tutorSpecialColumnCourse = new TutorSpecialColumnCourse();
                tutorSpecialColumnCourse.setCourseId(split[i]);
                tutorSpecialColumnCourse.setTutorSpecialColumnId(homeBackgroundMusic.getId());
                tutorSpecialColumnCourse.setCreateBy(SecurityUtils.getUsername());
                tutorSpecialColumnCourse.setCreateTime(LocalDateTime.now());
                tutorSpecialColumnCourse.setUpdateBy(SecurityUtils.getUsername());
                tutorSpecialColumnCourse.setUpdateTime(LocalDateTime.now());
                tutorSpecialColumnCourses.add(tutorSpecialColumnCourse);
            }
            tutorSpecialColumnCourseService.saveBatch(tutorSpecialColumnCourses);
        }
        return R.ok(tutorSpecialColumnService.updateById(homeBackgroundMusic));
    }
}
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/CourseChapter.java
@@ -34,6 +34,9 @@
    @ApiModelProperty(value = "在线课程id")
    @TableField("course_id")
    private Long courseId;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "章节标题")
    @TableField("chapter_title")
@@ -46,8 +49,11 @@
    @ApiModelProperty(value = "录屏文件")
    @TableField("video_url")
    private String videoUrl;
    @ApiModelProperty(value = "录屏文件名称")
    @TableField("video_url_name")
    private String videoUrlName;
    @ApiModelProperty(value = "实际已学习人数")
    @ApiModelProperty(value = "实际已学习人数/当前已学习人数")
    @TableField("real_learned_num")
    private Integer realLearnedNum;
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/CourseUserFavorite.java
New file
@@ -0,0 +1,51 @@
package com.xinquan.course.domain;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
 * <p>
 * 冥想用户操作表
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
@Data
@TableName("t_course_user_favorite")
@ApiModel(value="CourseUserFavorite对象", description="用户课程收藏记录")
public class CourseUserFavorite implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "id")
    @TableId(value = "id",type = IdType.ASSIGN_ID)
    private Long id;
    @ApiModelProperty(value = "课程id")
    @TableField("course_id")
    private Long courseId;
    @ApiModelProperty(value = "用户id")
    @TableField("app_user_id")
    private Long appUserId;
    /**
     * 创建者
     */
    @ApiModelProperty(value = "记录创建人,前端忽略")
    @TableField(value = "create_by", fill = FieldFill.INSERT)
    private String createBy;
    /**
     * 创建时间
     */
    @ApiModelProperty(value = "记录创建时间,前端忽略")
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private LocalDateTime createTime;
}
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/TutorSpecialColumn.java
@@ -5,10 +5,13 @@
import com.xinquan.common.core.web.domain.BaseModel;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import com.xinquan.course.api.domain.Course;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
 * <p>
@@ -40,6 +43,12 @@
    @ApiModelProperty(value = "导师简介")
    @TableField("tutor_introduction")
    private String tutorIntroduction;
    @ApiModelProperty(value = "已选择课程ids 逗号分割")
    @TableField(exist = false)
    private String courseIds;
    @ApiModelProperty(value = "已选课程列表 查看详情回显使用")
    @TableField(exist = false)
    private List<Course> courses;
}
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/vo/ClientCourseVO.java
@@ -1,5 +1,6 @@
package com.xinquan.course.domain.vo;
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.C;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.course.api.domain.Course;
import com.xinquan.course.domain.CourseChapter;
@@ -23,7 +24,8 @@
    @ApiModelProperty(value = "课程类型 1=线上课程 2=线下课程")
    private Integer courseType;
    @ApiModelProperty(value = "是否收藏 1是 2否")
    private Integer isCollect;
    @ApiModelProperty(value = "课程分类id")
    private Long cateId;
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/CourseCategoryMapper.java
@@ -1,6 +1,6 @@
package com.xinquan.course.mapper;
import com.xinquan.course.domain.CourseCategory;
import com.xinquan.course.api.domain.CourseCategory;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/CourseUserFavoriteMapper.java
New file
@@ -0,0 +1,17 @@
package com.xinquan.course.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xinquan.course.api.domain.Course;
import com.xinquan.course.domain.CourseUserFavorite;
/**
 * <p>
 * 线上课程表 Mapper 接口
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
public interface CourseUserFavoriteMapper extends BaseMapper<CourseUserFavorite> {
}
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/CourseCategoryService.java
@@ -1,7 +1,7 @@
package com.xinquan.course.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.course.domain.CourseCategory;
import com.xinquan.course.api.domain.CourseCategory;
import com.xinquan.course.domain.vo.ClientCourseCategoryVO;
import java.util.List;
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/CourseUserFavoriteService.java
New file
@@ -0,0 +1,18 @@
package com.xinquan.course.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.course.api.domain.Course;
import com.xinquan.course.domain.CourseUserFavorite;
import com.xinquan.course.domain.vo.ClientCourseVO;
/**
 * <p>
 * 线上课程表 服务类
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
public interface CourseUserFavoriteService extends IService<CourseUserFavorite> {
}
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/CourseCategoryServiceImpl.java
@@ -3,7 +3,7 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinquan.common.core.enums.DisabledEnum;
import com.xinquan.common.core.utils.page.BeanUtils;
import com.xinquan.course.domain.CourseCategory;
import com.xinquan.course.api.domain.CourseCategory;
import com.xinquan.course.domain.vo.ClientCourseCategoryVO;
import com.xinquan.course.mapper.CourseCategoryMapper;
import com.xinquan.course.service.CourseCategoryService;
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/CourseUserFavoriteServiceImpl.java
New file
@@ -0,0 +1,30 @@
package com.xinquan.course.service.impl;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.course.api.domain.Course;
import com.xinquan.course.domain.CourseUserFavorite;
import com.xinquan.course.domain.vo.ClientCourseVO;
import com.xinquan.course.mapper.CourseMapper;
import com.xinquan.course.mapper.CourseUserFavoriteMapper;
import com.xinquan.course.service.CourseService;
import com.xinquan.course.service.CourseUserFavoriteService;
import org.springframework.stereotype.Service;
import java.util.Objects;
/**
 * <p>
 * 线上课程表 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
@Service
public class CourseUserFavoriteServiceImpl extends ServiceImpl<CourseUserFavoriteMapper, CourseUserFavorite> implements CourseUserFavoriteService {
}
xinquan-modules/xinquan-course/src/main/resources/mapper/course/CourseCategoryMapper.xml
@@ -3,7 +3,7 @@
<mapper namespace="com.xinquan.course.mapper.CourseCategoryMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xinquan.course.domain.CourseCategory">
    <resultMap id="BaseResultMap" type="com.xinquan.course.api.domain.CourseCategory">
        <id column="id" property="id" />
        <result column="del_flag" property="delFlag" />
        <result column="create_by" property="createBy" />
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/controller/SysFileController.java
@@ -5,6 +5,7 @@
import com.xinquan.file.service.ISysFileService;
import com.xinquan.file.utils.ObsUploadUtil;
import com.xinquan.system.api.domain.SysFile;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -52,6 +53,7 @@
     * 文件上传请求
     */
    @PostMapping("obs-upload")
    @ApiOperation(value = "文件上传111",tags = "管理后台-文件上传1")
    public R<String> uploadOSS(@RequestPart("file") MultipartFile file) {
        try {
            // 上传并返回访问地址
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/utils/ObsUploadUtil.java
@@ -10,11 +10,11 @@
public class ObsUploadUtil {
    // OBS图片访问域名 TODO 修改正式参数
    public static String endPoint = "obs.cn-southwest-2.myhuaweicloud.com";
    public static String accessKeyId = "IZB26ZHC7C5MWIOH1TGE";
    public static String accessKeySecret = "y5PXhFMDOHiPH0nnQMz4gkvA63oqKAC621zXzOPk";
    public static String bucketName = "mimishejiao";
    public static String oss_domain = "https://mimishejiao.obs.cn-southwest-2.myhuaweicloud.com/";
    public static String endPoint = "obs.cn-south-1.myhuaweicloud.com";
    public static String accessKeyId = "HNZKSJL5LKM2NZVJPE8O";
    public static String accessKeySecret = "VjKImAoCB8Q2lEcwGO9xIemirpOVZuij9DVRSXcr";
    public static String bucketName = "xqgwzh";
    public static String oss_domain = "https://xqgwzh.obs.cn-south-1.myhuaweicloud.com/";
    // 创建ObsClient实例
    public static ObsClient obsClient = new ObsClient(accessKeyId, accessKeySecret, endPoint);
@@ -34,7 +34,7 @@
            obsClient.putObject(bucketName, "xinquan/" + fileName, content, meta);// 上传Object.
            if (fileName != null && !"".equals(fileName)) {
                System.out.println(fileName);
                fileName = oss_domain + "admin/" + fileName;
                fileName = oss_domain + "xinquan/" + fileName;
            }
        }
        return fileName;
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientHomeController.java
@@ -1,9 +1,12 @@
package com.xinquan.meditation.controller.client;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.domain.HomeBackgroundMusic;
import com.xinquan.meditation.domain.vo.ClientHomeBackgroundMusicVO;
import com.xinquan.meditation.domain.vo.ClientMeditationAndCateVO;
import com.xinquan.meditation.domain.vo.ClientMeditationCategoryVO;
@@ -17,17 +20,18 @@
import com.xinquan.meditation.service.MeditationQuestionService;
import com.xinquan.meditation.service.MeditationService;
import com.xinquan.system.api.RemoteHotWordsService;
import com.xinquan.system.api.domain.AppUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
/**
 * <p>
@@ -50,6 +54,49 @@
    private final RemoteHotWordsService remoteHotWordsService;
    private final MeditationQuestionService meditationQuestionService;
    @PostMapping("/listHomeBackgroundMusic")
    @ApiOperation(value = "背景音乐列表查询-分页", notes = "管理后台-首页背景音乐管理")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageCurr", value = "分页参数,当前页码", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量", dataType = "Integer", required = true)})
    public R<PageDTO<HomeBackgroundMusic>> listHomeBackgroundMusic(@RequestParam Integer pageCurr, @RequestParam Integer pageSize) {
        PageDTO<HomeBackgroundMusic> pageDTO = PageDTO.empty(0L, 0L);
        // 查询
        Page<HomeBackgroundMusic> page = homeBackgroundMusicService.lambdaQuery()
                .orderByDesc(HomeBackgroundMusic::getSortNum)
                .page(new Page<>(pageCurr, pageSize));
        // 如果没有查到数据直接返回
        if (Optional.ofNullable(page.getRecords()).isPresent()) {
            return R.ok(pageDTO);
        }
        // 将实体类转换为VO
        pageDTO = PageDTO.of(page, HomeBackgroundMusic.class);
        for (HomeBackgroundMusic homeBackgroundMusic : pageDTO.getList()) {
            homeBackgroundMusic.setUid(homeBackgroundMusic.getId() + "");
        }
        return R.ok(pageDTO);
    }
    @PostMapping("/addHomeBackgroundMusic")
    @ApiOperation(value = "新增背景", notes = "管理后台-首页背景音乐管理")
    public R addHomeBackgroundMusic(@RequestBody HomeBackgroundMusic homeBackgroundMusic) {
        return R.ok(homeBackgroundMusicService.save(homeBackgroundMusic));
    }
    @GetMapping("/detailHomeBackgroundMusic")
    @ApiOperation(value = "查看详情", notes = "管理后台-首页背景音乐管理")
    public R detailHomeBackgroundMusic(String uid) {
        return R.ok(homeBackgroundMusicService.getById(uid));
    }
    @PostMapping("/updateHomeBackgroundMusic")
    @ApiOperation(value = "修改背景", notes = "管理后台-首页背景音乐管理")
    public R updateHomeBackgroundMusic(@RequestBody HomeBackgroundMusic homeBackgroundMusic) {
        return R.ok(homeBackgroundMusicService.updateById(homeBackgroundMusic));
    }
    @PostMapping("/deleteHomeBackgroundMusic")
    @ApiOperation(value = "批量删除", notes = "管理后台-首页背景音乐管理")
    public R deleteHomeBackgroundMusic(String ids) {
        return R.ok(homeBackgroundMusicService.removeBatchByIds(Arrays.asList(ids.split(","))));
    }
    /**
     * 获取首页背景音乐列表
     *
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationCategoryController.java
@@ -1,13 +1,26 @@
package com.xinquan.meditation.controller.client;
import org.springframework.web.bind.annotation.RequestMapping;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.meditation.domain.MeditationCategory;
import com.xinquan.meditation.service.MeditationCategoryService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.Arrays;
/**
 * <p>
 * 冥想分类表 前端控制器
 * 冥想冥想分类表 前端控制器
 * </p>
 *
 * @author mitao
@@ -16,6 +29,50 @@
@RestController
@RequestMapping("/client/meditation/meditation-category")
public class ClientMeditationCategoryController {
    @Autowired
    private MeditationCategoryService meditationCategoryService;
    @PostMapping("/meditationCategoryManagementList")
    @ApiOperation(value = "冥想分类列表-分页", tags = {"管理后台-冥想分类管理"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageCurr", value = "分页参数,当前页码", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量", dataType = "Integer", required = true)
    })
    public R<PageDTO<MeditationCategory>> meditationCategoryManagementList(@RequestParam(value = "pageCurr")Integer pageCurr,
                                                                       @RequestParam(value = "pageSize")Integer pageSize) {
        LambdaQueryWrapper<MeditationCategory> meditationLambdaQueryWrapper = new LambdaQueryWrapper<>();
        meditationLambdaQueryWrapper.orderByDesc(MeditationCategory::getSortNum);
        Page<MeditationCategory> page = meditationCategoryService.page(new Page<>(pageCurr, pageSize), meditationLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())) {
            return R.ok(PageDTO.empty(page));
        }
        for (MeditationCategory record : page.getRecords()) {
            record.setUid(record.getId()+"");
        }
        return R.ok(PageDTO.of(page, MeditationCategory.class));
    }
    @PostMapping("/addMeditationCategory")
    @ApiOperation(value = "新增冥想分类管理", notes = "管理后台-冥想分类管理")
    public R addMeditationCategory(@RequestBody MeditationCategory homeBackgroundMusic) {
        homeBackgroundMusic.setCreateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setCreateTime(LocalDateTime.now());
        return R.ok(meditationCategoryService.save(homeBackgroundMusic));
    }
    @GetMapping("/detailMeditationCategory")
    @ApiOperation(value = "查看详情冥想分类管理", notes = "管理后台-冥想分类管理")
    public R<MeditationCategory> detailMeditationCategory(String uid) {
        return R.ok(meditationCategoryService.getById(uid));
    }
    @PostMapping("/updateMeditationCategory")
    @ApiOperation(value = "修改冥想分类管理", notes = "管理后台-冥想分类管理")
    public R updateMeditationCategory(@RequestBody MeditationCategory homeBackgroundMusic) {
        homeBackgroundMusic.setUpdateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setUpdateTime(LocalDateTime.now());
        return R.ok(meditationCategoryService.updateById(homeBackgroundMusic));
    }
    @PostMapping("/deleteMeditationCategory")
    @ApiOperation(value = "批量删除", notes = "管理后台-冥想分类管理")
    public R deleteMeditationCategory(String ids) {
        return R.ok(meditationCategoryService.removeBatchByIds(Arrays.asList(ids.split(","))));
    }
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationController.java
@@ -1,19 +1,38 @@
package com.xinquan.meditation.controller.client;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.course.api.domain.Course;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.domain.MeditationHall;
import com.xinquan.meditation.domain.vo.ClientMeditationQuestionVO;
import com.xinquan.meditation.service.MeditationHallService;
import com.xinquan.meditation.service.MeditationService;
import com.xinquan.meditation.api.domain.dto.MeditationDTO;
import com.xinquan.meditation.api.domain.dto.UserAnswerDTO;
import com.xinquan.meditation.domain.*;
import com.xinquan.meditation.service.*;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.MeditationQuestion;
import com.xinquan.system.api.domain.NoticeRecord;
import com.xinquan.system.api.domain.Tag;
import com.xinquan.user.api.feign.RemoteAppUserService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
@@ -28,8 +47,61 @@
@RequestMapping("/client/meditation/meditation")
public class ClientMeditationController {
    private final MeditationService meditationService;
    private final MeditationHallService meditationHallService;
    @Autowired
    private  MeditationService meditationService;
    @Autowired
    private  MeditationHallService meditationHallService;
    @Autowired
    private  MeditationUserFavoriteService meditationUserFavoriteService;
    @Autowired
    private MeditationTagService  meditationTagService;
    @Autowired
    private MeditationMusicService meditationMusicService;
    @Autowired
    private MeditationCategoryService meditationCategoryService;
    @Autowired
    private MeditationQuestionService meditationQuestionService;
    @Resource
    private RemoteAppUserService remoteAppUserService;
    /**
     * 远程调用 通过疗愈名字查询疗愈ids
     * @return
     */
    @PostMapping("/getMeditationIdsByName/{name}")
    public R<List<Long>> getMeditationIdsByName(@PathVariable("name") String name) {
        List<Long> collect = meditationService.lambdaQuery().like(Meditation::getMeditationTitle, name)
                .list().stream().map(Meditation::getId)
                .collect(Collectors.toList());
        return R.ok(collect);
    }
    @GetMapping("/getMeditationById/{pageCurr}/{pageSize}")
    public R<Page<Meditation>> getMeditationById(@PathVariable("pageCurr") Integer pageCurr,@PathVariable("pageSize") Integer pageSize)
    {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        List<Long> collect = meditationUserFavoriteService
                .lambdaQuery()
                .eq(MeditationUserFavorite::getAppUserId, userId).list().stream()
                .map(MeditationUserFavorite::getId).collect(Collectors.toList());
        Page<Meditation> page = meditationService
                .lambdaQuery()
                .in(Meditation::getId, collect)
                .page(new Page<>(pageCurr, pageSize));
        if (page.getRecords().isEmpty()){
            return R.ok(page);
        }
        return R.ok(page);
    }
    @GetMapping("/getMeditationById/{id}")
    public R<Meditation> getMeditationById(@PathVariable("id") Long id)
    {
        Meditation byId = meditationService.getById(id);
        MeditationCategory byId1 = meditationCategoryService.getById(byId.getCateId());
        byId.setCategoryName(byId1.getCategoryName());
        return R.ok(byId);
    }
    /**
     * 获取冥想馆列表
     */
@@ -62,5 +134,230 @@
        MeditationHall byId = meditationHallService.getById(id);
        return R.ok(byId);
    }
    @PostMapping("/meditationManagementList")
    @ApiOperation(value = "冥想音频列表-分页", tags = {"管理后台-冥想音频管理"})
    public R<PageDTO<Meditation>> meditationManagementList(@RequestBody MeditationDTO dto) {
        List<Long> longs = new ArrayList<>();
        if (!dto.getTagName().isEmpty()){
            List<Tag> data = remoteAppUserService.queryTag(dto.getTagName()).getData();
            if (data.isEmpty()){
                longs.add(-1L);
            }else{
                longs.addAll(data.stream().map(Tag::getId).collect(Collectors.toList()));
            }
        }
        List<Long> collect = meditationTagService.lambdaQuery().in(MeditationTag::getTagId)
                .list().stream().map(MeditationTag::getMeditationId)
                .collect(Collectors.toList());
        if (collect.isEmpty()){
            collect.add(-1L);
        }
        LambdaQueryWrapper<Meditation> courseLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseLambdaQueryWrapper.eq(dto.getSanskrit()!=null,Meditation::getSanskrit, dto.getSanskrit());
        courseLambdaQueryWrapper.in(Meditation::getId, collect);
        courseLambdaQueryWrapper.eq(dto.getChargeType()!=null,Meditation::getChargeType, dto.getChargeType());
        courseLambdaQueryWrapper.eq(dto.getCateId()!=null,Meditation::getCateId, dto.getCateId());
        courseLambdaQueryWrapper.eq(dto.getMeditationTitle()!=null&& !dto.getMeditationTitle().isEmpty(),Meditation::getMeditationTitle, dto.getMeditationTitle());
        courseLambdaQueryWrapper.orderByDesc(Meditation::getSortNum);
        Page<Meditation> page = meditationService.page(new Page<>(dto.getPageCurr(), dto.getPageSize()), courseLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())) {
            return R.ok(PageDTO.empty(page));
        }
        for (Meditation record : page.getRecords()) {
            record.setUid(record.getId()+"");
            MeditationCategory byId = meditationCategoryService.getById(record.getCateId());
            if (byId!=null){
                record.setCategoryName(byId.getCategoryName());
            }
        }
        return R.ok(PageDTO.of(page, Meditation.class));
    }
    @PostMapping("/addMeditation")
    @ApiOperation(value = "新增冥想音频管理", notes = "管理后台-冥想音频管理")
    public R addMeditation(@RequestBody Meditation homeBackgroundMusic) {
        homeBackgroundMusic.setCreateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setCreateTime(LocalDateTime.now());
        meditationService.save(homeBackgroundMusic);
        if (!homeBackgroundMusic.getTagIds().isEmpty()){
            String[] split = homeBackgroundMusic.getTagIds().split(",");
            List<MeditationTag> meditationTags = new ArrayList<>();
            for (int i = 0; i < split.length; i++) {
                MeditationTag meditationTag = new MeditationTag();
                meditationTag.setMeditationId(homeBackgroundMusic.getId());
                meditationTag.setTagId(Long.valueOf(split[i]));
                meditationTags.add(meditationTag);
            }
            meditationTagService.saveBatch(meditationTags);
        }
        if (!homeBackgroundMusic.getMusicUrls().isEmpty()){
            String[] split = homeBackgroundMusic.getMusicUrls().split(",");
            List<MeditationMusic> meditationTags = new ArrayList<>();
            for (int i = 0; i < split.length; i++) {
                MeditationMusic meditationTag = new MeditationMusic();
                meditationTag.setMeditationId(homeBackgroundMusic.getId());
                meditationTag.setMusicUrl(split[i]);
                meditationTag.setMusicSecond(Integer.valueOf(homeBackgroundMusic.getMusicSecond().split(",")[i]));
                meditationTags.add(meditationTag);
            }
            meditationMusicService.saveBatch(meditationTags);
        }
        return R.ok();
    }
    @GetMapping("/detailMeditation")
    @ApiOperation(value = "查看详情冥想音频管理", notes = "管理后台-冥想音频管理")
    public R<Meditation> detailMeditation(String uid) {
        Meditation byId = meditationService.getById(uid);
        List<Long> collect = meditationTagService.list(new LambdaQueryWrapper<MeditationTag>()
                        .eq(MeditationTag::getMeditationId, uid))
                .stream().map(MeditationTag::getTagId)
                .collect(Collectors.toList());
        List<String> collect1 = meditationMusicService.list(new LambdaQueryWrapper<MeditationMusic>()
                        .eq(MeditationMusic::getMeditationId, uid))
                .stream().map(MeditationMusic::getMusicUrl)
                .collect(Collectors.toList());
        byId.setMusicList(collect1);
        byId.setTagList(collect);
        MeditationCategory byId1 = meditationCategoryService.getById(byId.getCateId());
        if (byId1!=null){
            byId.setCategoryName(byId1.getCategoryName());
        }
        return R.ok(byId);
    }
    @PostMapping("/userAnswer")
    @ApiOperation(value = "查看详情冥想音频-用户提问-分页", notes = "管理后台-冥想音频管理")
    public R<PageDTO<MeditationQuestion>> userAnswer(@RequestBody UserAnswerDTO dto) {
        LambdaQueryWrapper<MeditationQuestion> courseLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.hasLength(dto.getUserName())){
            List<Long> data = remoteAppUserService.getAppUserByName(dto.getUserName()).getData();
            if (data.isEmpty()){
                data.add(-1L);
            }
            courseLambdaQueryWrapper.in(MeditationQuestion::getAppUserId, data);
        }
        courseLambdaQueryWrapper.eq(dto.getShow_flag()!=null,MeditationQuestion::getShowFlag, dto.getShow_flag());
        courseLambdaQueryWrapper.like(dto.getContent()!=null&& (!dto.getContent().isEmpty()),MeditationQuestion::getContent, dto.getContent());
        courseLambdaQueryWrapper.eq(dto.getUid()!=null,MeditationQuestion::getMeditationId, dto.getUid());
        courseLambdaQueryWrapper.orderByDesc(MeditationQuestion::getCreateTime);
        Page<MeditationQuestion> page = meditationQuestionService.page(new Page<>(dto.getPageCurr(), dto.getPageSize()), courseLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())) {
            return R.ok(PageDTO.empty(page));
        }
        for (MeditationQuestion record : page.getRecords()) {
            record.setUid(record.getId() + "");
            AppUser data = remoteAppUserService.getAppUserById(record.getAppUserId() + "").getData();
            if (data!=null){
                record.setUserName(data.getNickname());
                record.setAvatar(data.getAvatar());
                record.setCellPhone(data.getCellPhone());
            }
        }
        return R.ok(PageDTO.of(page, MeditationQuestion.class));
    }
    @GetMapping("/updateUserAnswerState")
    @ApiOperation(value = "查看详情冥想音频-用户提问-修改显示状态", notes = "管理后台-冥想音频管理")
    public R updateUserAnswerState(String uid) {
        MeditationQuestion byId = meditationQuestionService.getById(uid);
        if (byId.getShowFlag() == 1){
            byId.setShowFlag(2);
        }else {
            byId.setShowFlag(1);
        }
        return R.ok();
    }
    @GetMapping("/detailUserAnswer")
    @ApiOperation(value = "查看详情冥想音频-用户提问", notes = "管理后台-冥想音频管理")
    public R<MeditationQuestion> detailUserAnswer(String uid) {
        MeditationQuestion byId = meditationQuestionService.getById(uid);
        AppUser data = remoteAppUserService.getAppUserById(byId.getAppUserId().toString()).getData();
        byId.setUserName(data.getNickname());
        byId.setAvatar(data.getAvatar());
        byId.setCellPhone(data.getCellPhone());
        return R.ok(byId);
    }
    @GetMapping("/updateUserAnswer")
    @ApiOperation(value = "查看详情冥想音频-用户提问-编辑", notes = "管理后台-冥想音频管理")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uid", value = "uid", dataType = "String", required = true),
            @ApiImplicitParam(name = "content", value = "回复内容", dataType = "String", required = false),
            @ApiImplicitParam(name = "showFlag", value = "是否显示1是2否", dataType = "Integer", required = true),
    })
    public R<MeditationQuestion> updateUserAnswer(String uid,String content,Integer showFlag) {
        MeditationQuestion byId = meditationQuestionService.getById(uid);
        if (StringUtils.hasLength(content)){
            // 给用户发一条消息 只有第一次回复发送
            if (StringUtils.hasLength(byId.getReplyContent())){
                NoticeRecord noticeRecord = new NoticeRecord();
                noticeRecord.setAppUserId(byId.getAppUserId());
                noticeRecord.setMeditationQuestionId(byId.getId());
                noticeRecord.setReadStatus(1);
                noticeRecord.setNoticeType(2);
                noticeRecord.setTitle("回复消息");
                noticeRecord.setContent(content);
                noticeRecord.setCreateBy(SecurityUtils.getUsername());
                noticeRecord.setCreateTime(LocalDateTime.now());
                remoteAppUserService.addNoticeReplay(noticeRecord);
            }
        }
        LambdaUpdateWrapper<MeditationQuestion> meditationQuestionLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        meditationQuestionLambdaUpdateWrapper.set(MeditationQuestion::getReplyContent, content);
        meditationQuestionLambdaUpdateWrapper.set(StringUtils.hasLength(content),MeditationQuestion::getReplyTime, LocalDateTime.now());
        meditationQuestionLambdaUpdateWrapper.set(MeditationQuestion::getShowFlag, showFlag);
        meditationQuestionService.update(meditationQuestionLambdaUpdateWrapper);
        return R.ok(byId);
    }
    @GetMapping("/updateState")
    @ApiOperation(value = "修改冥想音频上下架状态", notes = "管理后台-冥想音频管理")
    public R updateState(String uid) {
        Meditation byId = meditationService.getById(uid);
        if (byId.getListingStatus() == 1){
            byId.setListingStatus(2);
        }else {
            byId.setListingStatus(1);
        }
        return R.ok();
    }
    @PostMapping("/updateMeditation")
    @ApiOperation(value = "修改冥想音频管理", notes = "管理后台-冥想音频管理")
    public R updateMeditation(@RequestBody Meditation homeBackgroundMusic) {
        homeBackgroundMusic.setUpdateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setUpdateTime(LocalDateTime.now());
        meditationService.updateById(homeBackgroundMusic);
        meditationTagService.remove(new LambdaQueryWrapper<MeditationTag>()
                .eq(MeditationTag::getMeditationId,homeBackgroundMusic.getId()));
        meditationMusicService.remove(new LambdaQueryWrapper<MeditationMusic>()
                .eq(MeditationMusic::getMeditationId,homeBackgroundMusic.getId()));
        if (!homeBackgroundMusic.getTagIds().isEmpty()){
            meditationTagService.remove(new LambdaQueryWrapper<MeditationTag>().eq(MeditationTag::getMeditationId,homeBackgroundMusic.getId()));
            String[] split = homeBackgroundMusic.getTagIds().split(",");
            List<MeditationTag> meditationTags = new ArrayList<>();
            for (int i = 0; i < split.length; i++) {
                MeditationTag meditationTag = new MeditationTag();
                meditationTag.setMeditationId(homeBackgroundMusic.getId());
                meditationTag.setTagId(Long.valueOf(split[i]));
                meditationTags.add(meditationTag);
            }
            meditationTagService.saveBatch(meditationTags);
        }
        if (!homeBackgroundMusic.getMusicUrls().isEmpty()){
            meditationMusicService.remove(new LambdaQueryWrapper<MeditationMusic>().eq(MeditationMusic::getMeditationId,homeBackgroundMusic.getId()));
            String[] split = homeBackgroundMusic.getMusicUrls().split(",");
            List<MeditationMusic> meditationTags = new ArrayList<>();
            for (int i = 0; i < split.length; i++) {
                MeditationMusic meditationTag = new MeditationMusic();
                meditationTag.setMeditationId(homeBackgroundMusic.getId());
                meditationTag.setMusicUrl(split[i]);
                meditationTag.setMusicSecond(Integer.valueOf(homeBackgroundMusic.getMusicSecond().split(",")[i]));
                meditationTags.add(meditationTag);
            }
            meditationMusicService.saveBatch(meditationTags);
        }
        return R.ok();
    }
    @PostMapping("/deleteMeditation")
    @ApiOperation(value = "批量删除", notes = "管理后台-冥想音频管理")
    public R deleteMeditation(String ids) {
        return R.ok(meditationService.removeBatchByIds(Arrays.asList(ids.split(","))));
    }
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationEverydayController.java
@@ -1,9 +1,28 @@
package com.xinquan.meditation.controller.client;
import org.springframework.web.bind.annotation.RequestMapping;
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.C;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.domain.MeditationEveryday;
import com.xinquan.meditation.domain.MeditationEveryday;
import com.xinquan.meditation.service.MeditationEverydayService;
import com.xinquan.meditation.service.MeditationEverydayService;
import com.xinquan.meditation.service.MeditationService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
/**
 * <p>
@@ -16,6 +35,63 @@
@RestController
@RequestMapping("/client/meditation/meditation-everyday")
public class ClientMeditationEverydayController {
    @Autowired
    private MeditationEverydayService meditationEverydayService;
    @Autowired
    private MeditationService meditationService;
    @PostMapping("/meditationCategoryManagementList")
    @ApiOperation(value = "每日冥想库列表-分页", tags = {"管理后台-每日冥想库管理"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageCurr", value = "分页参数,当前页码", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量", dataType = "Integer", required = true)
    })
    public R<PageDTO<MeditationEveryday>> meditationCategoryManagementList(@RequestParam(value = "pageCurr")Integer pageCurr,
                                                                           @RequestParam(value = "pageSize")Integer pageSize) {
        LambdaQueryWrapper<MeditationEveryday> meditationLambdaQueryWrapper = new LambdaQueryWrapper<>();
        meditationLambdaQueryWrapper.orderByDesc(MeditationEveryday::getCreateTime);
        Page<MeditationEveryday> page = meditationEverydayService.page(new Page<>(pageCurr, pageSize), meditationLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())) {
            return R.ok(PageDTO.empty(page));
        }
        for (MeditationEveryday record : page.getRecords()) {
            record.setUid(record.getId()+"");
        }
        return R.ok(PageDTO.of(page, MeditationEveryday.class));
    }
    @PostMapping("/meditationList")
    @ApiOperation(value = "疗愈音频下拉列表-不分页", tags = {"管理后台-每日冥想库管理"})
    public R<List<Meditation>> meditationList() {
        List<Meditation> list = meditationService.lambdaQuery()
                .eq(Meditation::getListingStatus, 1)
                .orderByDesc(Meditation::getSortNum).list();
        for (Meditation meditation : list) {
            meditation.setUid(meditation.getId()+"");
        }
        return R.ok(list);
    }
    @PostMapping("/addMeditationEveryday")
    @ApiOperation(value = "新增每日冥想库管理", notes = "管理后台-每日冥想库管理")
    public R addMeditationEveryday(@RequestBody MeditationEveryday homeBackgroundMusic) {
        homeBackgroundMusic.setCreateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setCreateTime(LocalDateTime.now());
        return R.ok(meditationEverydayService.save(homeBackgroundMusic));
    }
    @GetMapping("/detailMeditationEveryday")
    @ApiOperation(value = "查看详情每日冥想库管理", notes = "管理后台-每日冥想库管理")
    public R<MeditationEveryday> detailMeditationEveryday(String uid) {
        return R.ok(meditationEverydayService.getById(uid));
    }
    @PostMapping("/updateMeditationEveryday")
    @ApiOperation(value = "修改每日冥想库管理", notes = "管理后台-每日冥想库管理")
    public R updateMeditationEveryday(@RequestBody MeditationEveryday homeBackgroundMusic) {
        homeBackgroundMusic.setUpdateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setUpdateTime(LocalDateTime.now());
        return R.ok(meditationEverydayService.updateById(homeBackgroundMusic));
    }
    @PostMapping("/deleteMeditationEveryday")
    @ApiOperation(value = "批量删除", notes = "管理后台-每日冥想库管理")
    public R deleteMeditationEveryday(String ids) {
        return R.ok(meditationEverydayService.removeBatchByIds(Arrays.asList(ids.split(","))));
    }
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationHallController.java
@@ -1,9 +1,29 @@
package com.xinquan.meditation.controller.client;
import org.springframework.web.bind.annotation.RequestMapping;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.course.api.domain.Course;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.api.domain.dto.MeditationHallDTO;
import com.xinquan.meditation.domain.MeditationHall;
import com.xinquan.meditation.domain.MeditationHall;
import com.xinquan.meditation.service.MeditationHallService;
import com.xinquan.meditation.service.MeditationHallService;
import com.xinquan.meditation.service.MeditationService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
/**
 * <p>
@@ -16,6 +36,59 @@
@RestController
@RequestMapping("/client/meditation/meditation-hall")
public class ClientMeditationHallController {
    @Autowired
    private MeditationHallService meditationHallService;
    @PostMapping("/meditationCategoryManagementList")
    @ApiOperation(value = "冥想馆列表-分页", tags = {"管理后台-冥想馆管理"})
    public R<PageDTO<MeditationHall>> meditationCategoryManagementList(@RequestBody MeditationHallDTO dto) {
        LambdaQueryWrapper<MeditationHall> meditationLambdaQueryWrapper = new LambdaQueryWrapper<>();
        meditationLambdaQueryWrapper.like(MeditationHall::getHallName, dto.getHallName());
        meditationLambdaQueryWrapper.like(MeditationHall::getAddress, dto.getAddress());
        meditationLambdaQueryWrapper.orderByDesc(MeditationHall::getCreateTime);
        Page<MeditationHall> page = meditationHallService.page(new Page<>(dto.getPageCurr(), dto.getPageSize()), meditationLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())) {
            return R.ok(PageDTO.empty(page));
        }
        for (MeditationHall record : page.getRecords()) {
            record.setUid(record.getId()+"");
        }
        return R.ok(PageDTO.of(page, MeditationHall.class));
    }
    @PostMapping("/addMeditationHall")
    @ApiOperation(value = "新增冥想馆管理", notes = "管理后台-冥想馆管理")
    public R addMeditationHall(@RequestBody MeditationHall homeBackgroundMusic) {
        homeBackgroundMusic.setCreateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setCreateTime(LocalDateTime.now());
        return R.ok(meditationHallService.save(homeBackgroundMusic));
    }
    @GetMapping("/updateState")
    @ApiOperation(value = "修改课程上下架状态", notes = "管理后台-课程管理")
    public R updateState(String uid) {
        MeditationHall byId = meditationHallService.getById(uid);
        if (byId.getListingStatus() == 1){
            byId.setListingStatus(2);
        }else {
            byId.setListingStatus(1);
        }
        return R.ok();
    }
    @GetMapping("/detailMeditationHall")
    @ApiOperation(value = "查看详情冥想馆管理", notes = "管理后台-冥想馆管理")
    public R<MeditationHall> detailMeditationHall(String uid) {
        return R.ok(meditationHallService.getById(uid));
    }
    @PostMapping("/updateMeditationHall")
    @ApiOperation(value = "修改冥想馆管理", notes = "管理后台-冥想馆管理")
    public R updateMeditationHall(@RequestBody MeditationHall homeBackgroundMusic) {
        homeBackgroundMusic.setUpdateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setUpdateTime(LocalDateTime.now());
        return R.ok(meditationHallService.updateById(homeBackgroundMusic));
    }
    @PostMapping("/deleteMeditationHall")
    @ApiOperation(value = "批量删除", notes = "管理后台-冥想馆管理")
    public R deleteMeditationHall(String ids) {
        return R.ok(meditationHallService.removeBatchByIds(Arrays.asList(ids.split(","))));
    }
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationMusicController.java
@@ -1,9 +1,31 @@
package com.xinquan.meditation.controller.client;
import org.springframework.web.bind.annotation.RequestMapping;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.api.domain.dto.MeditationQuestionDTO;
import com.xinquan.meditation.api.domain.vo.NoticeDetailVO;
import com.xinquan.meditation.domain.MeditationCategory;
import com.xinquan.meditation.service.MeditationCategoryService;
import com.xinquan.meditation.service.MeditationQuestionService;
import com.xinquan.meditation.service.MeditationService;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.MeditationQuestion;
import com.xinquan.user.api.feign.RemoteAppUserService;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
@@ -16,6 +38,5 @@
@RestController
@RequestMapping("/client/meditation/meditation-music")
public class ClientMeditationMusicController {
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationQuestionController.java
@@ -1,9 +1,34 @@
package com.xinquan.meditation.controller.client;
import org.springframework.web.bind.annotation.RequestMapping;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.api.domain.dto.MeditationQuestionDTO;
import com.xinquan.meditation.domain.MeditationCategory;
import com.xinquan.meditation.service.MeditationCategoryService;
import com.xinquan.meditation.service.MeditationQuestionService;
import com.xinquan.meditation.service.MeditationQuestionService;
import com.xinquan.meditation.service.MeditationService;
import com.xinquan.system.api.RemoteUserService;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.MeditationQuestion;
import com.xinquan.meditation.api.domain.vo.NoticeDetailVO;
import com.xinquan.user.api.feign.RemoteAppUserService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
@@ -16,6 +41,135 @@
@RestController
@RequestMapping("/client/meditation/meditation-question")
public class ClientMeditationQuestionController {
    @Resource
    private MeditationQuestionService meditationQuestionService;
    @Resource
    private MeditationService meditationService;
    @Resource
    private MeditationCategoryService meditationCategoryService;
    @Resource
    private RemoteAppUserService remoteAppUserService;
    /**
     * 远程调用 查询回复通知消息内容
     * @return
     */
    @PostMapping("/noticeDetail")
    public R<NoticeDetailVO> noticeDetail(NoticeDetailVO req) {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        MeditationQuestion byId = meditationQuestionService.getById(req.getMeditationQuestionId());
        if (byId!=null){
            Meditation byId1 = meditationService.getById(byId.getMeditationId());
            req.setMeditationTitle(byId1.getMeditationTitle());
            req.setCoverDescription(byId1.getCoverDescription());
            req.setIconUrl(byId1.getIconUrl());
            req.setContent(byId.getContent());
            req.setReplyContent(byId.getReplyContent());
        }
        return R.ok(req);
    }
    @PostMapping("/meditationQuestionManagementList")
    @ApiOperation(value = "提问列表-分页", tags = {"管理后台-提问管理"})
    public R<PageDTO<MeditationQuestion>> meditationQuestionManagementList(@RequestBody MeditationQuestionDTO dto) {
        LambdaQueryWrapper<MeditationQuestion> meditationLambdaQueryWrapper = new LambdaQueryWrapper<>();
        meditationLambdaQueryWrapper.eq(dto.getShowFlag()!=null,MeditationQuestion::getShowFlag, dto.getShowFlag());
        if (dto.getIsReplay()!=null){
            if (dto.getIsReplay() == 1){
                meditationLambdaQueryWrapper.isNotNull(MeditationQuestion::getReplyTime);
            }else{
                meditationLambdaQueryWrapper.isNull(MeditationQuestion::getReplyTime);
            }
        }
        if (StringUtils.hasLength(dto.getUserName())){
            List<Long> data = remoteAppUserService.getAppUserByName(dto.getUserName()).getData();
            if (data.isEmpty()){
                data.add(-1L);
            }
            meditationLambdaQueryWrapper.in(MeditationQuestion::getAppUserId,data);
        }
        if (StringUtils.hasLength(dto.getName())){
            List<Long> collect = meditationService.lambdaQuery()
                    .like(Meditation::getMeditationTitle, dto.getName())
                    .list().stream().map(Meditation::getId).collect(Collectors.toList());
            if (collect.isEmpty()){
                collect.add(-1L);
            }
            meditationLambdaQueryWrapper.in(MeditationQuestion::getMeditationId,collect);
        }
        meditationLambdaQueryWrapper.orderByDesc(MeditationQuestion::getCreateTime);
        Page<MeditationQuestion> page = meditationQuestionService.page(new Page<>(dto.getPageCurr(), dto.getPageSize()), meditationLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())) {
            return R.ok(PageDTO.empty(page));
        }
        for (MeditationQuestion record : page.getRecords()) {
            record.setUid(record.getId()+"");
            AppUser data = remoteAppUserService.getAppUserById(record.getAppUserId().toString()).getData();
            if (data!=null){
                record.setUserName(data.getNickname());
                record.setAvatar(data.getAvatar());
                record.setCellPhone(data.getCellPhone());
            }
            Meditation byId = meditationService.getById(record.getMeditationId());
            if (byId!=null){
                record.setMeditationName(byId.getMeditationTitle());
            }
        }
        return R.ok(PageDTO.of(page, MeditationQuestion.class));
    }
    @PostMapping("/addMeditationQuestion")
    @ApiOperation(value = "新增提问管理", notes = "管理后台-提问管理")
    public R addMeditationQuestion(@RequestBody MeditationQuestion homeBackgroundMusic) {
        homeBackgroundMusic.setCreateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setCreateTime(LocalDateTime.now());
        return R.ok(meditationQuestionService.save(homeBackgroundMusic));
    }
    @GetMapping("/updateState")
    @ApiOperation(value = "修改提问显示状态", notes = "管理后台-提问管理")
    public R updateState(String uid) {
        MeditationQuestion byId = meditationQuestionService.getById(uid);
        if (byId.getShowFlag() == 1){
            byId.setShowFlag(2);
        }else {
            byId.setShowFlag(1);
        }
        return R.ok();
    }
    @GetMapping("/detailMeditationQuestion")
    @ApiOperation(value = "查看详情提问管理", notes = "管理后台-提问管理")
    public R<MeditationQuestion> detailMeditationQuestion(String uid) {
        MeditationQuestion byId = meditationQuestionService.getById(uid);
        AppUser data = remoteAppUserService.getAppUserById(byId.getAppUserId().toString()).getData();
        if (data!=null){
            byId.setUserName(data.getNickname());
            byId.setAvatar(data.getAvatar());
            byId.setCellPhone(data.getCellPhone());
        }
        Meditation byId1 = meditationService.getById(byId.getMeditationId());
        if (byId1!=null){
            byId.setMeditationName(byId1.getMeditationTitle());
            byId.setChargeType(byId1.getChargeType());
        }
        MeditationCategory byId2 = meditationCategoryService.getById(byId1.getCateId());
        if (byId2!=null){
            byId.setMeditationCategoryName(byId2.getCategoryName());
        }
        return R.ok();
    }
    @PostMapping("/updateMeditationQuestion")
    @ApiOperation(value = "修改提问管理", notes = "管理后台-提问管理")
    public R updateMeditationQuestion(@RequestBody MeditationQuestion homeBackgroundMusic) {
        homeBackgroundMusic.setUpdateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setUpdateTime(LocalDateTime.now());
        return R.ok(meditationQuestionService.updateById(homeBackgroundMusic));
    }
    @PostMapping("/deleteMeditationQuestion")
    @ApiOperation(value = "批量删除", notes = "管理后台-提问管理")
    public R deleteMeditationQuestion(String ids) {
        return R.ok(meditationQuestionService.removeBatchByIds(Arrays.asList(ids.split(","))));
    }
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationReportController.java
New file
@@ -0,0 +1,151 @@
package com.xinquan.meditation.controller.client;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.api.domain.dto.MeditationQuestionDTO;
import com.xinquan.meditation.domain.MeditationCategory;
import com.xinquan.meditation.service.MeditationCategoryService;
import com.xinquan.meditation.service.MeditationQuestionService;
import com.xinquan.meditation.service.MeditationReportService;
import com.xinquan.meditation.service.MeditationService;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.MeditationQuestion;
import com.xinquan.system.api.domain.MeditationReport;
import com.xinquan.system.api.domain.MeditationReport;
import com.xinquan.user.api.feign.RemoteAppUserService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
 * 冥想音频背景音乐表 前端控制器
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
@RestController
@RequestMapping("/client/meditation/meditation-report")
public class ClientMeditationReportController {
    @Autowired
    private MeditationReportService meditationReportService;
    @Resource
    private MeditationService meditationService;
    @Resource
    private MeditationQuestionService meditationQuestionService;
    @Resource
    private MeditationCategoryService meditationCategoryService;
    @Resource
    private RemoteAppUserService remoteAppUserService;
    @PostMapping("/meditationReportManagementList")
    @ApiOperation(value = "提问举报列表-分页", tags = {"管理后台-提问举报管理"})
    public R<PageDTO<MeditationReport>> meditationCategoryManagementList(@RequestBody MeditationQuestionDTO dto) {
        LambdaQueryWrapper<MeditationReport> meditationLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.hasLength(dto.getUserName())){
            List<Long> data = remoteAppUserService.getAppUserByName(dto.getUserName()).getData();
            if (data.isEmpty()){
                data.add(-1L);
            }
            meditationLambdaQueryWrapper.in(MeditationReport::getReportUserId,data);
        }
        if (StringUtils.hasLength(dto.getName())){
            List<Long> collect = meditationService.lambdaQuery()
                    .like(Meditation::getMeditationTitle, dto.getName())
                    .list().stream().map(Meditation::getId).collect(Collectors.toList());
            if (collect.isEmpty()){
                collect.add(-1L);
            }
            meditationLambdaQueryWrapper.in(MeditationReport::getMeditationId,collect);
        }
        if (StringUtils.hasLength(dto.getContent())){
            List<Long> collect = meditationQuestionService.lambdaQuery()
                    .like(MeditationQuestion::getContent, dto.getContent())
                    .list().stream().map(MeditationQuestion::getId).collect(Collectors.toList());
            if (collect.isEmpty()){
                collect.add(-1L);
            }
            meditationLambdaQueryWrapper.in(MeditationReport::getQuestionId,collect);
        }
        meditationLambdaQueryWrapper.orderByDesc(MeditationReport::getCreateTime);
        Page<MeditationReport> page = meditationReportService.page(new Page<>(dto.getPageCurr(), dto.getPageSize()), meditationLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())) {
            return R.ok(PageDTO.empty(page));
        }
        for (MeditationReport record : page.getRecords()) {
            record.setUid(record.getId()+"");
            MeditationQuestion byId1 = meditationQuestionService.getById(record.getQuestionId());
            if (byId1!=null){
                record.setContent(byId1.getContent());
                AppUser data = remoteAppUserService.getAppUserById(byId1.getAppUserId().toString()).getData();
                if (data!=null){
                    record.setUserName(data.getNickname());
                    record.setAvatar(data.getAvatar());
                    record.setCellPhone(data.getCellPhone());
                }
            }
            AppUser data = remoteAppUserService.getAppUserById(record.getReportUserId().toString()).getData();
            if (data!=null){
                record.setUserNameReport(data.getNickname());
                record.setAvatarReport(data.getAvatar());
                record.setCellPhoneReport(data.getCellPhone());
            }
            Meditation byId = meditationService.getById(record.getMeditationId());
            if (byId!=null){
                record.setMeditationName(byId.getMeditationTitle());
            }
        }
        return R.ok(PageDTO.of(page, MeditationReport.class));
    }
    @GetMapping("/detailMeditationReportQuestion")
    @ApiOperation(value = "查看详情提问举报管理", notes = "管理后台-提问举报管理")
    public R<MeditationReport> detailMeditationReport(String uid) {
        MeditationReport byId = meditationReportService.getById(uid);
        MeditationQuestion byId3 = meditationQuestionService.getById(byId.getQuestionId());
        AppUser data = remoteAppUserService.getAppUserById(byId3.getAppUserId().toString()).getData();
        AppUser data1 = remoteAppUserService.getAppUserById(byId.getReportUserId().toString()).getData();
        if (data!=null){
            byId.setUserName(data.getNickname());
            byId.setAvatar(data.getAvatar());
            byId.setCellPhone(data.getCellPhone());
        }
        if (data1!=null){
            byId.setUserNameReport(data1.getNickname());
            byId.setAvatarReport(data1.getAvatar());
            byId.setCellPhoneReport(data1.getCellPhone());
        }
        Meditation byId1 = meditationService.getById(byId.getMeditationId());
        if (byId1!=null){
            byId.setMeditationName(byId1.getMeditationTitle());
            byId.setChargeType(byId1.getChargeType());
        }
        MeditationCategory byId2 = meditationCategoryService.getById(byId1.getCateId());
        if (byId2!=null){
            byId.setMeditationCategoryName(byId2.getCategoryName());
        }
        return R.ok();
    }
    @PostMapping("/deleteMeditationReportQuestion")
    @ApiOperation(value = "批量删除", notes = "管理后台-提问举报管理")
    public R deleteMeditationReport(String ids) {
        return R.ok(meditationReportService.removeBatchByIds(Arrays.asList(ids.split(","))));
    }
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/HomeBackgroundMusic.java
@@ -33,6 +33,9 @@
    @ApiModelProperty(value = "背景图片")
    @TableField("image_url")
    private String imageUrl;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "音频文件")
    @TableField("audio_file")
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationCategory.java
@@ -33,6 +33,9 @@
    @ApiModelProperty(value = "冥想分类课程")
    @TableField("category_name")
    private String categoryName;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "分类描述")
    @TableField("description")
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationEveryday.java
@@ -35,6 +35,9 @@
    @ApiModelProperty(value = "冥想id")
    @TableField("meditation_id")
    private Long meditationId;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "播放时间段开始")
    @TableField("start_play_time")
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationHall.java
@@ -36,6 +36,10 @@
    @TableField("hall_name")
    private String hallName;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "上架状态 1=上架 2=下架")
    @TableField("listing_status")
    private Integer listingStatus;
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationMusic.java
@@ -35,6 +35,9 @@
    @ApiModelProperty(value = "音频文件")
    @TableField("music_url")
    private String musicUrl;
    @ApiModelProperty(value = "音频文件时长 单位秒")
    @TableField("music_second")
    private Integer musicSecond;
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationQuestionMapper.java
@@ -1,6 +1,6 @@
package com.xinquan.meditation.mapper;
import com.xinquan.meditation.domain.MeditationQuestion;
import com.xinquan.system.api.domain.MeditationQuestion;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationReportMapper.java
New file
@@ -0,0 +1,17 @@
package com.xinquan.meditation.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xinquan.system.api.domain.MeditationQuestion;
import com.xinquan.system.api.domain.MeditationReport;
/**
 * <p>
 * 冥想音频用户操作表 Mapper 接口
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
public interface MeditationReportMapper extends BaseMapper<MeditationReport> {
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationQuestionService.java
@@ -1,7 +1,7 @@
package com.xinquan.meditation.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.meditation.domain.MeditationQuestion;
import com.xinquan.system.api.domain.MeditationQuestion;
/**
 * <p>
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationReportService.java
New file
@@ -0,0 +1,17 @@
package com.xinquan.meditation.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.system.api.domain.MeditationQuestion;
import com.xinquan.system.api.domain.MeditationReport;
/**
 * <p>
 * 冥想音频用户操作表 服务类
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
public interface MeditationReportService extends IService<MeditationReport> {
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationQuestionServiceImpl.java
@@ -4,14 +4,21 @@
import com.xinquan.common.core.enums.ReportStatusEnum;
import com.xinquan.common.core.exception.ServiceException;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.meditation.domain.MeditationQuestion;
import com.xinquan.meditation.mapper.MeditationReportMapper;
import com.xinquan.meditation.service.MeditationReportService;
import com.xinquan.system.api.domain.MeditationQuestion;
import com.xinquan.meditation.domain.MeditationQuestionLike;
import com.xinquan.meditation.mapper.MeditationQuestionMapper;
import com.xinquan.meditation.service.MeditationQuestionLikeService;
import com.xinquan.meditation.service.MeditationQuestionService;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.Optional;
import com.xinquan.system.api.domain.MeditationReport;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
@@ -26,7 +33,10 @@
@RequiredArgsConstructor
public class MeditationQuestionServiceImpl extends ServiceImpl<MeditationQuestionMapper, MeditationQuestion> implements MeditationQuestionService {
    private final MeditationQuestionLikeService meditationQuestionLikeService;
    @Autowired
    private MeditationQuestionLikeService meditationQuestionLikeService;
    @Autowired
    private MeditationReportMapper meditationReportMapper;
    /**
     * 举报提问
@@ -38,10 +48,15 @@
    public void report(Long id, String content) {
        MeditationQuestion meditationQuestion = this.getById(id);
        if (Optional.ofNullable(meditationQuestion).isPresent()) {
            meditationQuestion.setReportStatus(ReportStatusEnum.REPORTED.getCode());
            meditationQuestion.setReportUserId(SecurityUtils.getUserId());
            meditationQuestion.setReportContent(content);
            meditationQuestion.setReportStatus(2);
            this.updateById(meditationQuestion);
            MeditationReport meditationReport = new MeditationReport();
            meditationReport.setMeditationId(meditationQuestion.getMeditationId());
            meditationReport.setQuestionId(meditationQuestion.getId());
            meditationReport.setReportContent(content);
            meditationReport.setReportUserId(SecurityUtils.getUserId());
            meditationReport.setCreateTime(LocalDateTime.now());
            meditationReportMapper.insert(meditationReport);
        }
    }
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationReportServiceImpl.java
New file
@@ -0,0 +1,33 @@
package com.xinquan.meditation.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinquan.common.core.enums.ReportStatusEnum;
import com.xinquan.common.core.exception.ServiceException;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.meditation.domain.MeditationQuestionLike;
import com.xinquan.meditation.mapper.MeditationQuestionMapper;
import com.xinquan.meditation.mapper.MeditationReportMapper;
import com.xinquan.meditation.service.MeditationQuestionLikeService;
import com.xinquan.meditation.service.MeditationQuestionService;
import com.xinquan.meditation.service.MeditationReportService;
import com.xinquan.system.api.domain.MeditationQuestion;
import com.xinquan.system.api.domain.MeditationReport;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Objects;
import java.util.Optional;
/**
 * <p>
 * 冥想音频用户操作表 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
@Service
@RequiredArgsConstructor
public class MeditationReportServiceImpl extends ServiceImpl<MeditationReportMapper, MeditationReport> implements MeditationReportService {
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationServiceImpl.java
@@ -29,6 +29,7 @@
import com.xinquan.order.api.domain.Order;
import com.xinquan.order.api.feign.RemoteOrderService;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.MeditationQuestion;
import com.xinquan.user.api.domain.dto.AppUserDTO;
import com.xinquan.user.api.feign.RemoteAppUserService;
import java.util.Arrays;
@@ -331,9 +332,7 @@
                Wrappers.lambdaQuery(MeditationQuestion.class)
                        .eq(MeditationQuestion::getMeditationId, id)
                        .eq(MeditationQuestion::getShowFlag, DisabledEnum.YES)
                        .orderByDesc(MeditationQuestion::getPublishTime)
        );
                        .orderByDesc(MeditationQuestion::getPublishTime));
        if (CollUtils.isEmpty(questionPage.getRecords())) {
            return PageDTO.empty(questionPage);
        }
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationQuestionMapper.xml
@@ -3,7 +3,7 @@
<mapper namespace="com.xinquan.meditation.mapper.MeditationQuestionMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xinquan.meditation.domain.MeditationQuestion">
    <resultMap id="BaseResultMap" type="com.xinquan.system.api.domain.MeditationQuestion">
        <id column="id" property="id" />
        <result column="meditation_id" property="meditationId"/>
        <result column="del_flag" property="delFlag" />
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/client/ClientOrderController.java
@@ -1,10 +1,22 @@
package com.xinquan.order.controller.client;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.BeanUtils;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.core.web.domain.BaseModel;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.course.api.feign.RemoteCourseService;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.api.feign.RemoteMeditationService;
import com.xinquan.order.api.domain.Order;
import com.xinquan.order.domain.OrderPaymentRecord;
import com.xinquan.order.domain.vo.ClientPlaceOrderVO;
import com.xinquan.order.service.OrderPaymentRecordService;
import com.xinquan.order.service.OrderService;
import com.xinquan.course.api.domain.OrderCourseVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
@@ -12,6 +24,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
@@ -29,7 +42,55 @@
@RequestMapping("/client/order/order")
public class ClientOrderController {
    @Resource
    private OrderService orderService;
    @Resource
    private OrderPaymentRecordService orderPaymentRecordService;
    @Resource
    private RemoteCourseService remoteCourseService;
    @Resource
    private RemoteMeditationService remoteMeditationService;
    @PostMapping("/myOrderCourse")
    @ApiOperation(value = "我的已购",tags = "我的已购")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "state", value = "1冥想 2课程", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageCurr", value = "分页参数,当前页码", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量", dataType = "Integer", required = true)
    })
    public R<PageDTO<OrderCourseVO>> balanceList(Integer state, Integer pageCurr, Integer pageSize) {
        Long userId = SecurityUtils.getUserId();
        if (userId==0)return R.tokenError("登录失效");
        Page<Order> page = orderService.lambdaQuery()
                .eq(Order::getAppUserId, userId)
                .eq(Order::getOrderFrom, state)
                .ne(Order::getPaymentStatus, 3)
                .orderByDesc(BaseModel::getCreateTime).page(new Page<>(pageCurr, pageSize));
        if (CollUtils.isEmpty(page.getRecords())){
            PageDTO<OrderCourseVO> empty = PageDTO.empty(page);
            return R.ok(empty);
        }
        PageDTO<OrderCourseVO> res = PageDTO.of(page, OrderCourseVO.class);
        for (OrderCourseVO orderCourseVO : res.getList()) {
            switch (orderCourseVO.getChargeType()){
                case 1:
                    Meditation data1 = remoteMeditationService.getMeditationById(orderCourseVO.getBusinessId()).getData();
                    orderCourseVO.setCourseTitle(data1.getMeditationTitle());
                    orderCourseVO.setDescription(data1.getCoverDescription());
                    orderCourseVO.setCoverUrl(data1.getCoverUrl());
                    orderCourseVO.setGeneralPrice(data1.getGeneralPrice());
                    orderCourseVO.setIosPrice(data1.getIosPrice());
                    orderCourseVO.setCount(data1.getRealLearnedNum()+data1.getVirtualLearnedNum());
                    break;
                case 2:
                    OrderCourseVO data = remoteCourseService.getCourseCategoryList(orderCourseVO).getData();
                    BeanUtils.copyProperties(data, orderCourseVO);
                    break;
            }
        }
        return R.ok(res);
    }
    /**
     * 根据邀请用户ids 查询对应佣金
     */
@@ -65,10 +126,10 @@
    @ApiOperation(value = "创建待支付订单", notes = "微信|支付宝")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "targetId", value = "目标id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "orderFrom", value = "订单来源 1=冥想音频 2=课程", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "orderFrom", value = "订单来源 1=冥想音频 2=课程 3=购买会员 4充值", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "receiverId", value = "被赠送课程APP用户id", dataType = "Long", required = false),
            @ApiImplicitParam(name = "balanceFlag", value = "是否使用余额抵扣 1=是 2=否", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "payType", value = "支付方式 1=微信 2=支付宝", dataType = "Integer", required = true)
            @ApiImplicitParam(name = "balanceFlag", value = "是否使用余额抵扣 1=是 2=否", dataType = "Integer", required = false),
            @ApiImplicitParam(name = "payType", value = "支付方式 1=微信 2=支付宝", dataType = "Integer", required = false)
    })
    public R<ClientPlaceOrderVO> placeOrder(
            @RequestParam(value = "targetId") Long targetId,
@@ -84,5 +145,66 @@
            throw new RuntimeException(e);
        }
    }
    /**
     * 远程调用 根据用户id 查询充值金额
     */
    @PostMapping("/queryChargeByUserId/{userId}")
    public R<String> queryChargeByUserId(@PathVariable("userId") Long userId) {
        BigDecimal reduce = orderService.lambdaQuery()
                .eq(Order::getAppUserId, userId)
                .eq(Order::getOrderFrom, 4)
                .eq(Order::getPaymentStatus, 2)
                .list().stream().filter(t -> t.getTotalAmount() != null)
                .map(Order::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        return R.ok(reduce.toString());
    }
    /**
     * 远程调用 根据订单id 查询订单明细
     */
    @PostMapping("/getOrderById/{orderId}")
    public R<Order> getOrderById(@PathVariable("orderId") Long orderId) {
        Long userId = SecurityUtils.getUserId();
        if (userId==0)return R.tokenError("登录失效");
        Order one = orderService.lambdaQuery()
                .eq(Order::getId, orderId).one();
        if (one!=null){
            OrderPaymentRecord two = orderPaymentRecordService.lambdaQuery()
                    .eq(OrderPaymentRecord::getOrderId, orderId)
                    .ne(OrderPaymentRecord::getPaymentType, 4)
                    .eq(OrderPaymentRecord::getPaymentStatus, 2).one();
            if (two==null){
                one.setRemark("余额支付");
            }else{
                switch (two.getPaymentType()){
                    case 1:
                        one.setRemark("微信支付");
                        break;
                    case 2:
                        one.setRemark("支付宝支付");
                        break;
                    case 3:
                        one.setRemark("苹果内购");
                }
            }
            if (one.getCommissionId()!=null){
                switch (one.getOrderFrom()){
                    case 1:
                        one.setRemark("购买疗愈");
                        break;
                    case 2:
                        one.setRemark("购买课程");
                        break;
                    case 3:
                        one.setRemark("购买会员");
                        case 4:
                        one.setRemark("充值");
                }
            }
            return R.ok(one);
        }
        return R.ok();
    }
}
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/management/MgtOrderController.java
@@ -1,8 +1,36 @@
package com.xinquan.order.controller.management;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.course.api.domain.Course;
import com.xinquan.course.api.feign.RemoteCourseService;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.api.feign.RemoteMeditationService;
import com.xinquan.order.api.domain.Order;
import com.xinquan.order.api.domain.dto.OrderListDTO;
import com.xinquan.order.api.domain.vo.OrderCountVO;
import com.xinquan.order.domain.OrderPaymentRecord;
import com.xinquan.order.service.OrderPaymentRecordService;
import com.xinquan.order.service.OrderService;
import com.xinquan.system.api.RemoteUserService;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.user.api.feign.RemoteAppUserService;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
 * <p>
@@ -15,6 +43,385 @@
@RestController
@RequestMapping("/mgt/order/order")
public class MgtOrderController {
    @Resource
    private OrderService orderService;
    @Resource
    private OrderPaymentRecordService orderPaymentRecordService;
    @Resource
    private RemoteAppUserService remoteAppUserService;
    @Resource
    private RemoteCourseService remoteCourseService;
    @Resource
    private RemoteMeditationService remoteMeditationService;
    @Resource
    private RemoteUserService remoteUserService;
    @PostMapping("/orderList")
    @ApiOperation(value = "订单列表管理列表-分页", tags = {"管理后台-订单列表管理"})
    public R<PageDTO<Order>> orderList(@RequestBody OrderListDTO courseDTO) {
        String startTime = null;
        String endTime = null;
        if (org.springframework.util.StringUtils.hasLength(courseDTO.getTime())){
            String[] split = courseDTO.getTime().split(" - ");
            startTime = split[0]+"00:00:00";
            endTime = split[1]+"23:59:59";
        }
        List<Integer> payType1 = new ArrayList<>();
        payType1.add(1);
        payType1.add(5);
        List<Integer> payType2 = new ArrayList<>();
        payType2.add(2);
        payType2.add(6);
        List<Integer> payType3 = new ArrayList<>();
        payType3.add(4);
        payType3.add(7);
        LambdaQueryWrapper<Order> courseLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseLambdaQueryWrapper.between(Order::getCreateTime, startTime, endTime);
        if (courseDTO.getPayType()!=null){
            switch (courseDTO.getPayType()){
                case 1:
                    courseLambdaQueryWrapper.in(Order::getPayType,payType1);
                    break;
                case 2:
                    courseLambdaQueryWrapper.in(Order::getPayType,payType2);
                    break;
                case 3:
                    courseLambdaQueryWrapper.eq(Order::getPayType,courseDTO.getPayType());
                    break;
                case 4:
                    courseLambdaQueryWrapper.in(Order::getPayType,payType3);
                    break;
            }
        }
        courseLambdaQueryWrapper.eq(courseDTO.getPaymentStatus()!=null,Order::getPaymentStatus, courseDTO.getPaymentStatus());
        courseLambdaQueryWrapper.eq(courseDTO.getOrderFrom()!=null,Order::getOrderFrom, courseDTO.getOrderFrom());
        courseLambdaQueryWrapper.eq(courseDTO.getUid()!=null&&(!courseDTO.getUid().isEmpty()),Order::getAppUserId, courseDTO.getUid());
        if (org.springframework.util.StringUtils.hasLength(courseDTO.getBuyContent())){
            // 查询购买内容
            List<Long> collect1 = orderService.lambdaQuery().like(Order::getVipType, courseDTO.getBuyContent()).list().stream()
                    .map(Order::getId).collect(Collectors.toList());
            List<Long> collect2 = orderService.lambdaQuery().like(Order::getBizOrderNo, courseDTO.getBuyContent()).list().stream()
                    .map(Order::getId).collect(Collectors.toList());
            List<Long> data = remoteCourseService.getCourseIdsByName(courseDTO.getBuyContent()).getData();
            if (!data.isEmpty()){
                List<Long> collect3 = orderService.lambdaQuery().in(Order::getBusinessId, data)
                        .eq(Order::getOrderFrom, 2)
                        .list().stream()
                        .map(Order::getId).collect(Collectors.toList());
                if (!collect3.isEmpty()){
                    collect1.addAll(collect3);
                }
            }
            List<Long> data1 = remoteMeditationService.getMeditationIdsByName(courseDTO.getBuyContent()).getData();
            if (!data1.isEmpty()){
                List<Long> collect3 = orderService.lambdaQuery().in(Order::getBusinessId, data1)
                        .eq(Order::getOrderFrom, 1)
                        .list().stream()
                        .map(Order::getId).collect(Collectors.toList());
                if (!collect3.isEmpty()){
                    collect1.addAll(collect3);
                }
            }
            collect1.addAll(collect2);
            List<Long> collect = collect1.stream().distinct().collect(Collectors.toList());
            if (collect.isEmpty()){
                collect.add(-1L);
            }
            courseLambdaQueryWrapper.in(Order::getId,collect);
        }
        courseLambdaQueryWrapper.orderByDesc(Order::getCreateTime);
        if (org.springframework.util.StringUtils.hasLength(courseDTO.getUserNameOrPhone())){
            List<Long> collect = remoteAppUserService.getAppUserByNameOrPhone(courseDTO.getUserNameOrPhone()).getData();
            if (collect.isEmpty()){
                collect.add(-1L);
            }
            courseLambdaQueryWrapper.in(Order::getAppUserId, collect);
        }
        Page<Order> page = orderService.page(new Page<>(courseDTO.getPageCurr(), courseDTO.getPageSize()), courseLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())) {
            return R.ok(PageDTO.empty(page));
        }
        for (Order record : page.getRecords()) {
            record.setUid(record.getId().toString());
            AppUser byId1 = remoteAppUserService.getAppUserById(record.getAppUserId()+"").getData();
            if (Objects.nonNull(byId1)){
                record.setUserName(byId1.getNickname());
                record.setCellPhone(byId1.getCellPhone());
            }
            if (record.getOrderFrom()!=null){
                switch (record.getOrderFrom()){
                    case 1:
                        Meditation data = remoteMeditationService.getMeditationById(record.getBusinessId()).getData();
                        if (data!=null){
                            record.setCategoryMeditationName(data.getCategoryName());
                            record.setMeditationTitle(data.getMeditationTitle());
                            record.setIconUrl(data.getIconUrl());
                            record.setDetailDescription(data.getDetailDescription());
                            record.setGeneralPriceMeditation(data.getGeneralPrice());
                            record.setListingStatusMeditation(data.getListingStatus());
                            record.setMeditationUid(data.getId()+"");
                        }
                        break;
                    case 2:
                        Course data1 = remoteCourseService.getCourseById(record.getBusinessId(),"").getData();
                        if (data1!=null){
                            record.setCategoryCourseName(data1.getCategoryName());
                            record.setCourseTitle(data1.getCourseTitle());
                            record.setCoverUrl(data1.getCoverUrl());
                            record.setTutor(data1.getTutor());
                            record.setCourseChapterCount(data1.getCourseChapterCount());
                            record.setGeneralPriceCourse(data1.getGeneralPrice());
                            record.setListingStatusCourse(data1.getListingStatus());
                            record.setCourseUid(data1.getId()+"");
                        }
                        break;
                    case 3:
                        record.setBuyContent(record.getVipType());
                        record.setGeneralPriceVip(record.getRealPayAmount());
                        break;
                }
            }
        }
        return R.ok(PageDTO.of(page, Order.class));
    }
    @PostMapping("/orderCount")
    @ApiOperation(value = "订单列表管理列表上方合计数据", tags = {"管理后台-订单列表管理"})
    public R<OrderCountVO> orderCount(@RequestBody OrderListDTO courseDTO) {
        OrderCountVO orderCountVO = new OrderCountVO();
        String startTime = null;
        String endTime = null;
        if (org.springframework.util.StringUtils.hasLength(courseDTO.getTime())){
            String[] split = courseDTO.getTime().split(" - ");
            startTime = split[0]+"00:00:00";
            endTime = split[1]+"23:59:59";
        }
        List<Integer> payType1 = new ArrayList<>();
        payType1.add(1);
        payType1.add(5);
        List<Integer> payType2 = new ArrayList<>();
        payType2.add(2);
        payType2.add(6);
        List<Integer> payType3 = new ArrayList<>();
        payType3.add(4);
        payType3.add(7);
        LambdaQueryWrapper<Order> courseLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseLambdaQueryWrapper.between(Order::getCreateTime, startTime, endTime);
        if (courseDTO.getPayType()!=null){
            switch (courseDTO.getPayType()){
                case 1:
                    courseLambdaQueryWrapper.in(Order::getPayType,payType1);
                    break;
                case 2:
                    courseLambdaQueryWrapper.in(Order::getPayType,payType2);
                    break;
                case 3:
                    courseLambdaQueryWrapper.eq(Order::getPayType,courseDTO.getPayType());
                    break;
                case 4:
                    courseLambdaQueryWrapper.in(Order::getPayType,payType3);
                    break;
            }
        }
        courseLambdaQueryWrapper.eq(courseDTO.getPaymentStatus()!=null,Order::getPaymentStatus, courseDTO.getPaymentStatus());
        courseLambdaQueryWrapper.eq(courseDTO.getOrderFrom()!=null,Order::getOrderFrom, courseDTO.getOrderFrom());
        if (org.springframework.util.StringUtils.hasLength(courseDTO.getBuyContent())){
            // 查询购买内容
            List<Long> collect1 = orderService.lambdaQuery().like(Order::getVipType, courseDTO.getBuyContent()).list().stream()
                    .map(Order::getId).collect(Collectors.toList());
            List<Long> collect2 = orderService.lambdaQuery().like(Order::getBizOrderNo, courseDTO.getBuyContent()).list().stream()
                    .map(Order::getId).collect(Collectors.toList());
            List<Long> data = remoteCourseService.getCourseIdsByName(courseDTO.getBuyContent()).getData();
            if (!data.isEmpty()){
                List<Long> collect3 = orderService.lambdaQuery().in(Order::getBusinessId, data)
                        .eq(Order::getOrderFrom, 2)
                        .list().stream()
                        .map(Order::getId).collect(Collectors.toList());
                if (!collect3.isEmpty()){
                    collect1.addAll(collect3);
                }
            }
            List<Long> data1 = remoteMeditationService.getMeditationIdsByName(courseDTO.getBuyContent()).getData();
            if (!data1.isEmpty()){
                List<Long> collect3 = orderService.lambdaQuery().in(Order::getBusinessId, data1)
                        .eq(Order::getOrderFrom, 1)
                        .list().stream()
                        .map(Order::getId).collect(Collectors.toList());
                if (!collect3.isEmpty()){
                    collect1.addAll(collect3);
                }
            }
            collect1.addAll(collect2);
            List<Long> collect = collect1.stream().distinct().collect(Collectors.toList());
            if (collect.isEmpty()){
                collect.add(-1L);
            }
            courseLambdaQueryWrapper.in(Order::getId,collect);
        }
        courseLambdaQueryWrapper.orderByDesc(Order::getCreateTime);
        if (org.springframework.util.StringUtils.hasLength(courseDTO.getUserNameOrPhone())){
            List<Long> collect = remoteAppUserService.getAppUserByNameOrPhone(courseDTO.getUserNameOrPhone()).getData();
            if (collect.isEmpty()){
                collect.add(-1L);
            }
            courseLambdaQueryWrapper.in(Order::getAppUserId, collect);
        }
        List<Order> page = orderService.list(courseLambdaQueryWrapper);
        Integer payCount = 0;
        Integer completeCount = 0;
        Integer cancelCount = 0;
        BigDecimal totalMoney = new BigDecimal("0");
        for (Order record : page) {
            if (record.getPaymentStatus()!=null){
                switch (record.getPaymentStatus()){
                    case 1:
                        payCount++;
                        break;
                    case 2:
                        completeCount++;
                        break;
                    case 3:
                        cancelCount++;
                        break;
                }
            }
            if (record.getRealPayAmount()!=null && record.getRefundStatus()!=3){
                totalMoney = totalMoney.add(record.getRealPayAmount());
            }
        }
        orderCountVO.setTotalCount(page.size());
        orderCountVO.setPayCount(payCount);
        orderCountVO.setCompleteCount(completeCount);
        orderCountVO.setCancelCount(cancelCount);
        orderCountVO.setTotalMoney(totalMoney);
        return R.ok(orderCountVO);
    }
    @GetMapping("/detailOrder")
    @ApiOperation(value = "查看详情订单列表管理", notes = "管理后台-订单列表管理")
    public R<Order> detailOrder(String uid) {
        Order record = orderService.getById(uid);
        if (record.getOrderFrom()!=null){
            switch (record.getOrderFrom()){
                case 1:
                    Meditation data = remoteMeditationService.getMeditationById(record.getBusinessId()).getData();
                    if (data!=null){
                        record.setCategoryMeditationName(data.getCategoryName());
                        record.setMeditationTitle(data.getMeditationTitle());
                        record.setIconUrl(data.getIconUrl());
                        record.setDetailDescription(data.getDetailDescription());
                        record.setGeneralPriceMeditation(data.getGeneralPrice());
                        record.setListingStatusMeditation(data.getListingStatus());
                        record.setMeditationUid(data.getId()+"");
                    }
                    break;
                case 2:
                    Course data1 = remoteCourseService.getCourseById(record.getBusinessId(),"").getData();
                    if (data1!=null){
                        record.setCategoryCourseName(data1.getCategoryName());
                        record.setCourseTitle(data1.getCourseTitle());
                        record.setCoverUrl(data1.getCoverUrl());
                        record.setTutor(data1.getTutor());
                        record.setCourseChapterCount(data1.getCourseChapterCount());
                        record.setGeneralPriceCourse(data1.getGeneralPrice());
                        record.setListingStatusCourse(data1.getListingStatus());
                        record.setCourseUid(data1.getId()+"");
                    }
                    break;
                case 3:
                    record.setBuyContent(record.getVipType());
                    record.setGeneralPriceVip(record.getRealPayAmount());
                    break;
            }
        }
        record.setUid(record.getId().toString());
        AppUser byId2 = remoteAppUserService.getAppUserById(record.getAppUserId()+"").getData();
        AppUser byId3 = remoteAppUserService.getAppUserById(record.getGiveUserId()+"").getData();
        if (Objects.nonNull(byId2)){
            record.setUserName(byId2.getNickname());
            record.setAvatar(byId2.getAvatar());
            record.setCellPhone(byId2.getCellPhone());
        }
        if (Objects.nonNull(byId3)){
            record.setUserNameGive(byId3.getNickname());
            record.setAvatarGive(byId3.getAvatar());
            record.setCellPhoneGive(byId3.getCellPhone());
        }
        if (record.getChangePriceOperator()!=null){
            SysUser data = remoteUserService.getSysUserById(record.getChangePriceOperator() + "").getData();
            record.setChangePriceOperatorName(data.getNickName()+"("+data.getUserName()+")");
        }
        if (record.getPayType()!=null){
            List<OrderPaymentRecord> list = orderPaymentRecordService.list(new LambdaQueryWrapper<OrderPaymentRecord>()
                    .eq(OrderPaymentRecord::getOrderId, record.getId())
                    .orderByDesc(OrderPaymentRecord::getPaymentType)
            );
            if (record.getPayType() ==5 || record.getPayType()==6 || record.getPayType()==7){
                if(record.getRealPayAmount()!=null){
                    switch (record.getPayType()){
                        case 5:
                            if (!list.isEmpty()){
                                OrderPaymentRecord orderPaymentRecord = list.get(1);
                                OrderPaymentRecord orderPaymentRecord1 = list.get(0);
                                switch (orderPaymentRecord.getPaymentType()){
                                    case 1:
                                        record.setPaymentType("微信(¥"+(orderPaymentRecord.getPayAmount()==null?"":orderPaymentRecord.getPayAmount())+")"
                                        +" + 余额(¥"+orderPaymentRecord1.getPayAmount()+")");
                                        break;
                                    case 2:
                                        record.setPaymentType("支付宝(¥"+(orderPaymentRecord.getPayAmount()==null?"":orderPaymentRecord.getPayAmount())+")"
                                                +" + 余额(¥"+orderPaymentRecord1.getPayAmount()+")");
                                        break;
                                    case 3:
                                        record.setPaymentType("内购(¥"+(orderPaymentRecord.getPayAmount()==null?"":orderPaymentRecord.getPayAmount())+")"
                                                +" + 余额(¥"+orderPaymentRecord1.getPayAmount()+")");
                                        break;
                                }
                            }
                            break;
                        case 6:
                            record.setPaymentType("支付宝(¥"+record.getRealPayAmount()+")");
                            break;
                        case 7:
                            record.setPaymentType("内购(¥"+record.getRealPayAmount()+")");
                            break;
                    }
                }
            }else{
                if(record.getRealPayAmount()!=null){
                    switch (record.getPayType()){
                        case 1:
                            record.setPaymentType("微信(¥"+record.getRealPayAmount()+")");
                            break;
                        case 2:
                            record.setPaymentType("支付宝(¥"+record.getRealPayAmount()+")");
                            break;
                        case 3:
                            record.setPaymentType("余额(¥"+record.getRealPayAmount()+")");
                            break;
                        case 4:
                            record.setPaymentType("内购(¥"+record.getRealPayAmount()+")");
                            break;
                    }
                }
            }
        }
        return R.ok(record);
    }
    @GetMapping("/cancel")
    @ApiOperation(value = "取消订单", notes = "管理后台-订单列表管理")
    public R updateState(String uid) {
        Order byId = orderService.getById(uid);
        byId.setPaymentStatus(3);
        orderService.updateById(byId);
        return R.ok();
    }
}
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/impl/OrderServiceImpl.java
@@ -96,16 +96,26 @@
            clientPlaceOrderVO.setOrderNo(orderNo);
            clientPlaceOrderVO.setId(orderId);
            // 如果冥想音频价格设定为单独收费,且需要使用余额抵扣
            if (balanceFlag.equals(1) && meditation.getChargeType()
                    .equals(ChargeTypeEnum.SEPARATE_CHARGE.getCode())) {
            if (balanceFlag.equals(1) && meditation.getChargeType().equals(ChargeTypeEnum.SEPARATE_CHARGE.getCode())) {
                BigDecimal needPayAmount = handleBalancePayment(appUser,
                        meditation.getGeneralPrice(),
                        orderId);
                if (needPayAmount.compareTo(BigDecimal.ZERO) <= 0) {
                    clientPlaceOrderVO.setZeroFlag(DisabledEnum.YES.getCode());
                    // 抵扣后金额为0 为余额支付
                    order.setPayType(3);
                    order.setRealPayAmount(meditation.getGeneralPrice());
                    this.updateById(order);
                    return clientPlaceOrderVO;
                }
                if (payType==1){
                    // 微信+余额
                    order.setPayType(5);
                }else{
                    // 支付宝+余额
                    order.setPayType(6);
                }
                this.updateById(order);
                // 创建支付订单
                createPayment(payType, orderNo, needPayAmount, meditationTitle, detailDescription,
                        wxOpenId, orderId, clientPlaceOrderVO);
@@ -114,7 +124,7 @@
                createPayment(payType, orderNo, meditation.getGeneralPrice(), meditationTitle,
                        detailDescription, wxOpenId, orderId, clientPlaceOrderVO);
            }
        } else {
        } else if (orderFrom == 2){
            // 购买课程
            Course course = remoteCourseService.getCourseById(targetId,
                    SecurityConstants.INNER).getData();
@@ -151,6 +161,10 @@
                createPayment(payType, orderNo, course.getGeneralPrice(), courseTitle,
                        description, wxOpenId, orderId, clientPlaceOrderVO);
            }
        }else if (orderFrom == 3){
            // 购买会员
        }else {
            // 充值
        }
        return clientPlaceOrderVO;
    }
xinquan-modules/xinquan-system/pom.xml
@@ -16,6 +16,21 @@
    </description>
    
    <dependencies>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.3.9</version>
        </dependency>
        <!--system feign模块-->
        <dependency>
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/BannerController.java
@@ -1,9 +1,22 @@
package com.xinquan.system.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.course.api.domain.Course;
import com.xinquan.course.api.domain.CourseCategory;
import com.xinquan.course.api.domain.CourseDTO;
import com.xinquan.course.api.feign.RemoteCourseService;
import com.xinquan.system.domain.Banner;
import com.xinquan.system.service.BannerService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
/**
 * <p>
@@ -17,5 +30,106 @@
@RequestMapping("/system/banner")
public class BannerController {
    @Autowired
    private BannerService bannerService;
    @Autowired
    private RemoteCourseService remoteCourseService;
    @PostMapping("/bannerList")
    @ApiOperation(value = "获取banner列表-分页",tags = "管理后台banner")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "分页参数,当前页码", name = "pageCurr", required = true, dataType = "Integer"),
            @ApiImplicitParam(value = "分页参数,每页数量", name = "pageSize", required = true, dataType = "Integer")
    })
    public R<PageDTO<Banner>> bannerList(
            @RequestParam(value = "pageCurr", defaultValue = "1") Integer pageCurr,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        return R.ok(bannerService.bannerList(pageCurr, pageSize));
    }
    @PostMapping("/cateList")
    @ApiOperation(value = "课程分类下拉选择列表-不分页",tags = "管理后台banner")
    public R<List<CourseCategory>> cateList() {
        List<CourseCategory> data = remoteCourseService.cateList().getData();
        return R.ok(data);
    }
    @PostMapping("/courseList")
    @ApiOperation(value = "选择课程-分页",tags = "管理后台banner")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "分页参数,当前页码", name = "pageCurr", required = false, dataType = "Integer"),
            @ApiImplicitParam(value = "分页参数,每页数量", name = "pageSize", required = false, dataType = "Integer"),
            @ApiImplicitParam(value = "课程类型1线上2线下", name = "courseType", required = false, dataType = "Integer"),
            @ApiImplicitParam(value = "课程分类id", name = "cateId", required = false, dataType = "Long"),
            @ApiImplicitParam(value = "课程标题", name = "courseTitle", required = false, dataType = "String"),
            @ApiImplicitParam(value = "导师名称", name = "tutor", required = false, dataType = "String"),
    })
    public R<PageDTO<Banner>> courseList(
            @RequestParam(value = "pageCurr", defaultValue = "1") Integer pageCurr,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
            @RequestParam(value = "courseType") Integer courseType,
            @RequestParam(value = "cateId") Long cateId,
            @RequestParam(value = "courseTitle")String courseTitle,
            @RequestParam(value = "tutor") String tutor
            ) {
        CourseDTO courseDTO = new CourseDTO();
        courseDTO.setPageCurr(pageCurr);
        courseDTO.setPageSize(pageSize);
        courseDTO.setCourseType(courseType);
        courseDTO.setCateId(cateId);
        courseDTO.setCourseTitle(courseTitle);
        courseDTO.setTutor(tutor);
        remoteCourseService.courseList(courseDTO);
        return R.ok();
    }
    @PostMapping("/deleteBatch")
    @ApiOperation(value = "批量删除banner",tags = "管理后台banner")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "ids", name = "ids", required = true, dataType = "String"),
    })
    public R deleteBatch(
            @RequestParam(value = "ids") String ids)
    {
        List<String> list = Arrays.asList(ids.split(","));
        bannerService.removeBatchByIds(list);
        return R.ok();
    }
    @PostMapping("/addBanner")
    @ApiOperation(value = "添加banner",tags = "管理后台banner")
    public R addBanner(@RequestBody Banner banner)
    {
        bannerService.save(banner);
        return R.ok();
    }
    @PostMapping("/updateBanner")
    @ApiOperation(value = "修改banner",tags = "管理后台banner")
    public R updateBanner(@RequestBody Banner banner)
    {
        bannerService.updateById(banner);
        return R.ok();
    }
    @PostMapping("/bannerDetail")
    @ApiOperation(value = "查看详情",tags = "管理后台banner")
    public R<Banner> bannerDetail(String uid)
    {
        Banner byId = bannerService.getById(uid);
        if (byId.getCourseId()!=null){
            Course data = remoteCourseService.getCourseById(byId.getCourseId(), "").getData();
            if (data!=null){
                byId.setCourseTitle(data.getCourseTitle());
                byId.setCoverUrl(data.getCoverUrl());
                byId.setTutor(data.getTutor());
                byId.setPrice(data.getGeneralPrice());
                if (data.getCateId()!=null){
                    CourseCategory data1 = remoteCourseService.getCategoryById(data.getCateId().toString()).getData();
                    byId.setCate(data1.getName());
                }
            }
        }
        return R.ok(byId);
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/CommissionRuleController.java
New file
@@ -0,0 +1,56 @@
package com.xinquan.system.controller;
import com.xinquan.common.core.domain.R;
import com.xinquan.system.api.domain.vo.UpdateTreeGroupVO;
import com.xinquan.system.domain.CommissionRule;
import com.xinquan.system.domain.TreeLevelSetting;
import com.xinquan.system.service.CommissionRuleService;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
 * <p>
 * 分佣规则 前端控制器
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
@RestController
@RequestMapping("/system/commission/rule")
public class CommissionRuleController {
    @Resource
    private CommissionRuleService commissionRuleService;
    @PostMapping("/updateCommission")
    @ApiOperation(value = "保存",tags = "管理后台-分享设置")
    public R updateTreeGroup(@RequestBody CommissionRule commissionRule) {
        CommissionRule one1 = commissionRuleService.lambdaQuery().one();
        if (one1==null){
            commissionRuleService.save(commissionRule);
        }else{
            one1.setProportion(commissionRule.getProportion());
            one1.setPoster(commissionRule.getPoster());
            one1.setRules(commissionRule.getRules());
            commissionRuleService.updateById(one1);
        }
        return R.ok();
    }
    @PostMapping("/getCommission")
    @ApiOperation(value = "获取",tags = "管理后台-树苗音频设置")
    public R<CommissionRule> getTreeGroup() {
        CommissionRule one1 = commissionRuleService.lambdaQuery().one();
        if (one1==null){
            return R.ok(new CommissionRule());
        }else{
            return R.ok(one1);
        }
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/CommonQuestionController.java
@@ -1,19 +1,42 @@
package com.xinquan.system.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.system.api.RemoteUserService;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.vo.InviteRankListVO;
import com.xinquan.system.domain.CommissionRule;
import com.xinquan.system.domain.CommonQuestion;
import com.xinquan.system.service.CommissionRuleService;
import com.xinquan.system.service.CommonQuestionService;
import com.xinquan.system.utils.MyQrCodeUtil;
import com.xinquan.system.utils.ObsUploadUtil;
import com.xinquan.system.utils.QRCodeUtil;
import com.xinquan.system.utils.UUIDUtil;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream;
import org.omg.CORBA.PRIVATE_MEMBER;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
@@ -28,6 +51,10 @@
public class CommonQuestionController {
    @Resource
    private CommonQuestionService commonQuestionService;
    @Resource
    private CommissionRuleService commissionRuleService;
    @Resource
    private RemoteUserService remoteUserService;
    @PostMapping("/getQrCode")
    @ApiOperation(value = "获取客服微信二维码",tags = "获取客服微信二维码")
    public R getQrCode() {
@@ -36,5 +63,113 @@
        CommonQuestion one = commonQuestionService.lambdaQuery().eq(CommonQuestion::getType, 2).one();
        return R.ok(one.getCustomerServiceQrCode());
    }
    @PostMapping("/commonQuestion")
    @ApiOperation(value = "常见问题列表", tags = {"联系客服"})
    @ApiImplicitParams({
            @ApiImplicitParam(value = "分页参数,当前页码", name = "pageCurr", required = true, dataType = "Integer"),
            @ApiImplicitParam(value = "分页参数,每页数量", name = "pageSize", required = true, dataType = "Integer")
    })
    public R<PageDTO<CommonQuestion>> myInviteRankList(
            @RequestParam(value = "pageCurr", defaultValue = "1") Integer pageCurr,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        Page<CommonQuestion> page = commonQuestionService.lambdaQuery()
                .orderByDesc(CommonQuestion::getSortNum)
                .page(new Page<>(pageCurr, pageSize));
        if (page.getRecords().isEmpty()){
            return R.ok(PageDTO.empty(page));
        }
        return R.ok(PageDTO.of(page, CommonQuestion.class));
    }
    @PostMapping("/commonQuestionList")
    @ApiOperation(value = "常见问题列表-分页", tags = {"管理后台-常见问题"})
    @ApiImplicitParams({
            @ApiImplicitParam(value = "分页参数,当前页码", name = "pageCurr", required = true, dataType = "Integer"),
            @ApiImplicitParam(value = "分页参数,每页数量", name = "pageSize", required = true, dataType = "Integer")
    })
    public R<PageDTO<CommonQuestion>> commonQuestionList(
            @RequestParam(value = "pageCurr", defaultValue = "1") Integer pageCurr,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        Page<CommonQuestion> page = commonQuestionService.lambdaQuery()
                .eq(CommonQuestion::getType,1)
                .orderByDesc(CommonQuestion::getSortNum)
                .page(new Page<>(pageCurr, pageSize));
        if (page.getRecords().isEmpty()){
            return R.ok(PageDTO.empty(page));
        }
        for (CommonQuestion record : page.getRecords()) {
            record.setUid(record.getId() + "");
        }
        return R.ok(PageDTO.of(page, CommonQuestion.class));
    }
    @PostMapping("/addCommonQuestion")
    @ApiOperation(value = "新增常见问题", notes = "管理后台-常见问题")
    public R addCommonQuestion(@RequestBody CommonQuestion homeBackgroundMusic) {
        return R.ok(commonQuestionService.save(homeBackgroundMusic));
    }
    @GetMapping("/detailCommonQuestion")
    @ApiOperation(value = "查看详情常见问题", notes = "管理后台-常见问题")
    public R<CommonQuestion> detailCommonQuestion(String uid) {
        return R.ok(commonQuestionService.getById(uid));
    }
    @PostMapping("/updateCommonQuestion")
    @ApiOperation(value = "修改常见问题", notes = "管理后台-常见问题")
    public R updateCommonQuestion(@RequestBody CommonQuestion homeBackgroundMusic) {
        return R.ok(commonQuestionService.updateById(homeBackgroundMusic));
    }
    @PostMapping("/deleteCommonQuestion")
    @ApiOperation(value = "批量删除", notes = "管理后台-常见问题")
    public R deleteCommonQuestion(String ids) {
        return R.ok(commonQuestionService.removeBatchByIds(Arrays.asList(ids.split(","))));
    }
    @PostMapping("/getQuestionById")
    @ApiOperation(value = "常见问题列表-查看详情", tags = {"联系客服"})
    @ApiImplicitParams({
            @ApiImplicitParam(value = "id", name = "id", required = true, dataType = "Integer"),
    })
    public R<CommonQuestion> myInviteRankList(Long id) {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        CommonQuestion byId = commonQuestionService.getById(id);
        return R.ok(byId);
    }
    @PostMapping("/getCommissionRule")
    @ApiOperation(value = "推广活动页",tags = "推广活动页")
    public R<CommissionRule> getCommissionRule() throws Exception {
        Long userId = SecurityUtils.getUserId();
        if (userId==0)return R.tokenError("登录失效");
        CommissionRule one = commissionRuleService.lambdaQuery().one();
        HashMap<String, String> blueCode = new HashMap<>();
        blueCode.put("user_id", userId + "");
        String blueS = "{\"user_id\": " + userId + "}";
        MyQrCodeUtil.createCodeToFile(blueS);
        BufferedImage blueImage = QRCodeUtil.createImage(blueS);
        MultipartFile blueFile = convert(blueImage, new Date().getTime() + UUIDUtil.getRandomCode(3) + ".PNG");
        String s = ObsUploadUtil.obsUpload(blueFile);
        one.setQrCode(s);
        return R.ok(one);
    }
    public static MultipartFile convert(BufferedImage bufferedImage, String fileName) throws IOException {
        // 将 BufferedImage 转换为字节数组
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "png", baos);
        byte[] bytes = baos.toByteArray();
        // 创建 ByteArrayResource
        ByteArrayResource resource = new ByteArrayResource(bytes);
        // 创建 MockMultipartFile
        MockMultipartFile multipartFile = new MockMultipartFile(
                "file",
                fileName,
                "image/png",
                resource.getInputStream()
        );
        return multipartFile;
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/ContentSettingController.java
@@ -4,6 +4,7 @@
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.system.domain.ContentSetting;
import com.xinquan.system.domain.VipSetting;
import com.xinquan.system.service.ContentSettingService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
@@ -15,6 +16,7 @@
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.time.LocalDateTime;
/**
 * <p>
@@ -34,9 +36,9 @@
     *
     */
    @PostMapping("/getCoursePageList")
    @ApiOperation(value = "获取内容、协议1=用户协议 2=隐私协议 3=关于心泉 4= 新手冥想指南 5=课程/冥想音频购买协议 6=能量规则说明",tags = "富文本规则说明")
    @ApiOperation(value = "获取内容、协议1=用户协议 2=隐私协议 3=关于心泉 4= 新手冥想指南 5=课程/冥想音频购买协议 6=能量规则说明 7等级经验值说明",tags = "富文本规则说明")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "内容类型 1=用户协议 2=隐私协议 3=关于心泉 4= 新手冥想指南 5=课程/冥想音频购买协议 6=能量规则说明", name = "contentType", required = true, dataType = "int"),
            @ApiImplicitParam(value = "内容类型 1=用户协议 2=隐私协议 3=关于心泉 4= 新手冥想指南 5=课程/冥想音频购买协议 6=能量规则说明 7等级经验值说明", name = "contentType", required = true, dataType = "int"),
    })
    public R<String> getCourseList(@RequestParam(value = "contentType", required = true) int contentType) {
        ContentSetting one = contentSettingService.lambdaQuery().eq(ContentSetting::getContentType, contentType).one();
@@ -47,5 +49,26 @@
        }
    }
    @PostMapping("/saveOrupdateContent")
    @ApiOperation(value = "保存修改富文本内容",tags = "管理后台-富文本规则说明")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "内容类型 1=用户协议 2=隐私协议 3=关于心泉 4= 新手冥想指南 5=课程/冥想音频购买协议 6=能量规则说明 7等级经验值规则说明", name = "type", required = true, dataType = "int"),
            @ApiImplicitParam(value = "富文本内容", name = "content", required = true, dataType = "String"),
    })
    public R saveOrupdateContent(Integer type,String content) {
        ContentSetting one = contentSettingService.lambdaQuery().eq(ContentSetting::getContentType, type).one();
        if (one!=null){
            one.setContent(content);
            contentSettingService.updateById(one);
        }else{
            ContentSetting contentSetting = new ContentSetting();
            contentSetting.setContentType(type);
            contentSetting.setContent(content);
            contentSetting.setCreateTime(LocalDateTime.now());
            contentSettingService.save(contentSetting);
        }
        return R.ok();
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/HotWordsController.java
@@ -1,9 +1,20 @@
package com.xinquan.system.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.system.domain.CommonQuestion;
import com.xinquan.system.domain.HotWords;
import com.xinquan.system.service.HotWordsService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
 * <p>
@@ -16,6 +27,61 @@
@RestController
@RequestMapping("/system/hot-words")
public class HotWordsController {
    @Resource
    private HotWordsService hotWordsService;
    @PostMapping("/list")
    @ApiOperation(value = "热词管理-列表查询", tags = {"运营中心"})
    @ApiImplicitParams({
            @ApiImplicitParam(value = "分页参数,当前页码", name = "pageCurr", required = true, dataType = "Integer"),
            @ApiImplicitParam(value = "分页参数,每页数量", name = "pageSize", required = true, dataType = "Integer")
    })
    public R<PageDTO<HotWords>> list(
            @RequestParam(value = "pageCurr", defaultValue = "1") Integer pageCurr,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        Page<HotWords> page = hotWordsService.lambdaQuery()
                .orderByDesc(HotWords::getSortNum)
                .page(new Page<>(pageCurr, pageSize));
        if (page.getRecords().isEmpty()){
            return R.ok(PageDTO.empty(page));
        }
        for (HotWords record : page.getRecords()) {
            record.setUid(record.getId()+"");
        }
        return R.ok(PageDTO.of(page, HotWords.class));
    }
    @PostMapping("/add")
    @ApiOperation(value = "热词管理-添加热词", tags = {"管理后台-运营中心"})
    public R add(@RequestBody HotWords hotWords) {
        hotWordsService.save(hotWords);
        return R.ok();
    }
    @PostMapping("/update")
    @ApiOperation(value = "热词管理-编辑热词", tags = {"管理后台-运营中心"})
    public R update(@RequestBody HotWords hotWords) {
        LambdaUpdateWrapper<HotWords> hotWordsLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        if (hotWords.getSortNum()==null){
            hotWordsLambdaUpdateWrapper.set(HotWords::getSortNum,null);
        }else{
            hotWordsLambdaUpdateWrapper.set(HotWords::getSortNum,hotWords.getSortNum());
        }
        hotWordsLambdaUpdateWrapper.set(HotWords::getWordName,hotWords.getWordName());
        hotWordsLambdaUpdateWrapper.eq(HotWords::getId,hotWords.getId());
        hotWordsService.update(hotWordsLambdaUpdateWrapper);
        return R.ok();
    }
    @DeleteMapping("/add")
    @ApiOperation(value = "热词管理-删除热词", tags = {"管理后台-运营中心"})
    public R add(String id) {
        hotWordsService.removeById(id);
        return R.ok();
    }
    @DeleteMapping("/queryAddCount")
    @ApiOperation(value = "热词管理-查询还可以上传多少个热词", tags = {"管理后台-运营中心"})
    public R queryAddCount() {
        int i = 20 - hotWordsService.lambdaQuery().list().size();
        return R.ok(i);
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/PageController.java
New file
@@ -0,0 +1,74 @@
package com.xinquan.system.controller;
import com.xinquan.common.core.domain.R;
import com.xinquan.system.domain.CommissionRule;
import com.xinquan.system.domain.Page;
import com.xinquan.system.service.CommissionRuleService;
import com.xinquan.system.service.PageService;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
 * <p>
 * 用户信息表 前端控制器
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
@RestController
@RequestMapping("/system/page")
public class PageController {
    @Resource
    private PageService pageService;
    @PostMapping("/getPage")
    @ApiOperation(value = "获取启动页",tags = "获取启动页")
    public R<String> getPage() {
        Page one = pageService.lambdaQuery().eq(Page::getType,1).one();
        if (one!=null){
            return R.ok(one.getImg());
        }
        return R.ok();
    }
    @GetMapping("/saveOrUpdate")
    @ApiOperation(value = "保存/修改启动页",tags = "管理后台-启动页")
    public R saveOrUpdate(String img) {
        Page one = pageService.lambdaQuery().eq(Page::getType,1).one();
        if(one == null){
            Page page = new Page();
            page.setImg(img);
            pageService.save(page);
        }else{
            one.setImg(img);
            pageService.updateById(one);
        }
        return R.ok();
    }
    @PostMapping("/saveOrUpdatePlan")
    @ApiOperation(value = "获取计划引导设置",tags = "计划引导设置")
    public R<String> saveOrUpdatePlan() {
        Page one = pageService.lambdaQuery().eq(Page::getType,2).one();
        if (one!=null){
            return R.ok(one.getImg());
        }
        return R.ok();
    }
    @GetMapping("/saveOrUpdatePlan")
    @ApiOperation(value = "保存/修改计划引导设置",tags = "计划引导设置")
    public R saveOrUpdatePlan(String img) {
        Page one = pageService.lambdaQuery().eq(Page::getType,2).one();
        if(one == null){
            Page page = new Page();
            page.setImg(img);
            pageService.save(page);
        }else{
            one.setImg(img);
            pageService.updateById(one);
        }
        return R.ok();
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysUserController.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sun.org.apache.bcel.internal.generic.NEW;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.StringUtils;
import com.xinquan.common.core.utils.poi.ExcelUtil;
@@ -16,34 +17,21 @@
import com.xinquan.system.api.domain.SysDept;
import com.xinquan.system.api.domain.SysRole;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.system.api.domain.vo.SysUserVO;
import com.xinquan.system.api.model.LoginUser;
import com.xinquan.system.domain.SysUserDept;
import com.xinquan.system.domain.SysUserRole;
import com.xinquan.system.service.ISysConfigService;
import com.xinquan.system.service.ISysDeptService;
import com.xinquan.system.service.ISysPermissionService;
import com.xinquan.system.service.ISysPostService;
import com.xinquan.system.service.ISysRoleService;
import com.xinquan.system.service.ISysUserRoleService;
import com.xinquan.system.service.ISysUserService;
import com.xinquan.system.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
/**
@@ -78,18 +66,17 @@
    @Autowired
    private ISysUserRoleService sysUserRoleService;
    /**
     * 获取用户列表
     * 远程调用 根据系统用户id查询用户信息
     * @return
     */
    @GetMapping("/list")
    @ApiOperation("管理员列表")
    public AjaxResult list(String phonenumber, int pageNumber, int pageSize) {
        PageInfo<SysUser> pageInfo = new PageInfo<>(pageNumber, pageSize);
        PageInfo<SysUser> page = userService.getList(pageInfo, phonenumber);
        return AjaxResult.success(page);
    @PostMapping("/getSysUserById/{id}")
    public R<SysUser> getSysUserById(@PathVariable("id")String id) {
        SysUser byId = userService.getById(id);
        return R.ok(byId);
    }
    /**
     * 新增用户
     */
@@ -101,11 +88,11 @@
        if(!org.springframework.util.StringUtils.hasLength(user.getNickName())){
            user.setNickName(user.getPhonenumber());
        }
        if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
            return error("手机号已开通账号");
        if (StringUtils.isNotEmpty(user.getUserName()) && !userService.checkPhoneUnique(user)) {
            return error("登陆账号已存在");
        }
        user.setCreateBy(SecurityUtils.getUsername());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        user.setPassword(SecurityUtils.encryptPassword("123456"));
        int i = userService.insertUser(user);
        SysUserRole sysUserRole = new SysUserRole();
        sysUserRole.setRoleId(1l);
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/TreeLevelSettingController.java
@@ -1,9 +1,22 @@
package com.xinquan.system.controller;
import com.xinquan.common.core.domain.R;
import com.xinquan.system.api.domain.vo.UpdateTreeGroupVO;
import com.xinquan.system.domain.TreeLevelSetting;
import com.xinquan.system.domain.VipSetting;
import com.xinquan.system.service.TreeLevelSettingService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
 * <p>
@@ -16,6 +29,22 @@
@RestController
@RequestMapping("/system/tree-level-setting")
public class TreeLevelSettingController {
    @Resource
    private TreeLevelSettingService treeLevelSettingService;
    @PostMapping("/updateTreeGroup")
    @ApiOperation(value = "修改树苗等级音频",tags = "管理后台-树苗音频设置")
    public R updateTreeGroup(@RequestBody UpdateTreeGroupVO vo) {
        TreeLevelSetting one = treeLevelSettingService.lambdaQuery()
                .eq(TreeLevelSetting::getTreeLevelType, vo.getTreeLevelType()).one();
        vo.setGrow_up_music(vo.getGrow_up_music());
        treeLevelSettingService.updateById(one);
        return R.ok();
    }
    @PostMapping("/getTreeGroup")
    @ApiOperation(value = "获取树苗音频等级列表",tags = "管理后台-树苗音频设置")
    public R<List<TreeLevelSetting>> getTreeGroup() {
        List<TreeLevelSetting> list = treeLevelSettingService.lambdaQuery().list();
        return R.ok(list);
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/UserLevelSettingController.java
@@ -1,13 +1,21 @@
package com.xinquan.system.controller;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xinquan.common.core.domain.R;
import com.xinquan.system.api.domain.vo.AppUserVO;
import com.xinquan.system.api.domain.UserLevelSetting;
import com.xinquan.system.api.domain.vo.UpdateTreeGroupVO;
import com.xinquan.system.api.domain.vo.UpdateUserGroupVO;
import com.xinquan.system.domain.TreeLevelSetting;
import com.xinquan.system.service.UserLevelSettingService;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
/**
 * <p>
@@ -34,5 +42,24 @@
                .eq(UserLevelSetting::getTreeLevelType, level).one();
        return R.ok(one);
    }
    @PostMapping("/updateUserGroup")
    @ApiOperation(value = "修改等级经验值",tags = "管理后台-树苗音频设置")
    public R updateTreeGroup(@RequestBody UpdateUserGroupVO vo) {
        UserLevelSetting one = userLevelSettingService.lambdaQuery()
                .eq(UserLevelSetting::getTreeLevelType, vo.getTreeLevelType()).one();
        LambdaUpdateWrapper<UserLevelSetting> userLevelSettingLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        userLevelSettingLambdaUpdateWrapper.set(UserLevelSetting::getLevelName,vo.getLevelName());
        userLevelSettingLambdaUpdateWrapper.set(UserLevelSetting::getLevelIcon,vo.getLevelIcon());
        userLevelSettingLambdaUpdateWrapper.set(UserLevelSetting::getUpdateTime, LocalDateTime.now());
        userLevelSettingService.update(userLevelSettingLambdaUpdateWrapper);
        return R.ok();
    }
    @PostMapping("/getUserGroup")
    @ApiOperation(value = "获取等级经验值列表",tags = "管理后台-等级经验值管理")
    public R<List<UserLevelSetting>> getTreeGroup() {
        List<UserLevelSetting> list = userLevelSettingService.lambdaQuery().list();
        return R.ok(list);
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/VersionController.java
@@ -1,9 +1,22 @@
package com.xinquan.system.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.A;
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.C;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.system.domain.Version;
import com.xinquan.system.service.VersionService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.Arrays;
/**
 * <p>
@@ -16,6 +29,53 @@
@RestController
@RequestMapping("/system/version")
public class VersionController {
    @Autowired
    private VersionService versionService;
    @PostMapping("/versionList")
    @ApiOperation(value = "版本管理列表-分页", tags = {"管理后台-版本管理"})
    @ApiImplicitParams({
            @ApiImplicitParam(value = "分页参数,当前页码", name = "pageCurr", required = true, dataType = "Integer"),
            @ApiImplicitParam(value = "分页参数,每页数量", name = "pageSize", required = true, dataType = "Integer")
    })
    public R<PageDTO<Version>> versionList(
            @RequestParam(value = "pageCurr", defaultValue = "1") Integer pageCurr,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        Page<Version> page = versionService.lambdaQuery()
                .orderByDesc(Version::getCreateTime)
                .page(new Page<>(pageCurr, pageSize));
        if (page.getRecords().isEmpty()){
            return R.ok(PageDTO.empty(page));
        }
        for (Version record : page.getRecords()) {
            record.setUid(record.getId() + "");
        }
        return R.ok(PageDTO.of(page, Version.class));
    }
    @PostMapping("/addVersion")
    @ApiOperation(value = "新增版本管理", notes = "管理后台-版本管理")
    public R addVersion(@RequestBody Version homeBackgroundMusic) {
        homeBackgroundMusic.setCreateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setCreateTime(LocalDateTime.now());
        return R.ok(versionService.save(homeBackgroundMusic));
    }
    @GetMapping("/detailVersion")
    @ApiOperation(value = "查看详情版本管理", notes = "管理后台-版本管理")
    public R<Version> detailVersion(String uid) {
        return R.ok(versionService.getById(uid));
    }
    @PostMapping("/updateVersion")
    @ApiOperation(value = "修改版本管理", notes = "管理后台-版本管理")
    public R updateVersion(@RequestBody Version homeBackgroundMusic) {
        homeBackgroundMusic.setUpdateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setUpdateTime(LocalDateTime.now());
        return R.ok(versionService.updateById(homeBackgroundMusic));
    }
    @PostMapping("/deleteVersion")
    @ApiOperation(value = "批量删除", notes = "管理后台-版本管理")
    public R deleteVersion(String ids) {
        return R.ok(versionService.removeBatchByIds(Arrays.asList(ids.split(","))));
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/VipSettingController.java
@@ -1,19 +1,17 @@
package com.xinquan.system.controller;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xinquan.common.core.domain.R;
import com.xinquan.system.domain.ContentSetting;
import com.xinquan.system.domain.HotWords;
import com.xinquan.system.domain.VipSetting;
import com.xinquan.system.service.VipSettingService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.omg.CORBA.PRIVATE_MEMBER;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@@ -30,22 +28,49 @@
public class VipSettingController {
    @Resource
    private VipSettingService vipSettingService;
    @PostMapping("/queryVip")
    @ApiOperation(value = "获取会员价格设置", tags = {"管理后台-会员设置"})
    public R<VipSetting> queryVip() {
        VipSetting one = vipSettingService.lambdaQuery()
                .eq(VipSetting::getSettingType, 1).one();
        return R.ok(one);
    }
    @PostMapping("/saveVip")
    @ApiOperation(value = "保存会员价格设置", tags = {"管理后台-会员设置"})
    public R<VipSetting> saveVip(@RequestBody VipSetting vipSetting) {
        vipSettingService.updateById(vipSetting);
        return R.ok();
    }
    @PostMapping("/updateVipContent")
    @ApiOperation(value = "修改会员权益介绍/获取会员用户协议/获取续费管理说明",tags = "管理后台-会员设置")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "内容类型 1=会员权益介绍 2=会员用户协议 3=续费管理说明", name = "type", required = true, dataType = "int"),
            @ApiImplicitParam(value = "富文本内容", name = "content", required = true, dataType = "String"),
    })
    public R updateVipContent(Integer type,String content) {
        VipSetting one = vipSettingService.lambdaQuery()
                .eq(VipSetting::getSettingType, type+1).one();
        one.setContent(content);
        vipSettingService.updateById(one);
        return R.ok();
    }
    @PostMapping("/getVipPrice")
    @ApiOperation(value = "安卓-获取月度 季度 年度会员价格",tags = "会员")
    @ApiOperation(value = "安卓-获取月度 季度 年度会员价格",tags = "APP-会员")
    public R<VipSetting> getVipPrice() {
        VipSetting one = vipSettingService.lambdaQuery().eq(VipSetting::getClientType, 1)
                .eq(VipSetting::getSettingType, 1).one();
        return R.ok(one);
    }
    @PostMapping("/getVipPriceApple")
    @ApiOperation(value = "苹果-获取月度 季度 年度会员价格",tags = "会员")
    @ApiOperation(value = "苹果-获取月度 季度 年度会员价格",tags = "APP-会员")
    public R<VipSetting> getVipPriceApple() {
        VipSetting one = vipSettingService.lambdaQuery().eq(VipSetting::getClientType, 2)
                .eq(VipSetting::getSettingType, 1).one();
        return R.ok(one);
    }
    @PostMapping("/getVipContent")
    @ApiOperation(value = "获取会员权益介绍/获取会员用户协议/获取续费管理说明",tags = "会员")
    @ApiOperation(value = "获取会员权益介绍/获取会员用户协议/获取续费管理说明",tags = "APP/管理后台通用-会员")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "内容类型 1=会员权益介绍 2=会员用户协议 3=续费管理说明", name = "type", required = true, dataType = "int"),
    })
@@ -54,5 +79,6 @@
                .eq(VipSetting::getSettingType, type+1).one();
        return R.ok(one.getContent());
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/Banner.java
@@ -10,6 +10,8 @@
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
/**
 * <p>
 * 用户信息表
@@ -29,6 +31,9 @@
    @ApiModelProperty(value = "轮播图id")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "删除/编辑/查看详情取uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "轮播图")
    @TableField("image_url")
@@ -40,7 +45,24 @@
    @ApiModelProperty(value = "跳转课程id")
    @TableField("course_id")
    private Integer courseId;
    private Long courseId;
    @ApiModelProperty(value = "是否跳转 0否1是")
    @TableField("is_jump")
    private Integer isJump;
    @ApiModelProperty(value = "所属分类")
    @TableField(exist = false)
    private String cate;
    @ApiModelProperty(value = "课程标题")
    @TableField(exist = false)
    private String courseTitle;
    @ApiModelProperty(value = "封面图")
    @TableField(exist = false)
    private String coverUrl;
    @ApiModelProperty(value = "导师")
    @TableField(exist = false)
    private String tutor;
    @ApiModelProperty(value = "价格")
    @TableField(exist = false)
    private BigDecimal price;
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/CommissionRule.java
New file
@@ -0,0 +1,50 @@
package com.xinquan.system.domain;
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.C;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xinquan.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
/**
 * <p>
 * 版本表
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_commission_rule")
@ApiModel(value="CommissionRule对象", description="奋勇规则表")
public class CommissionRule extends BaseModel {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "id")
    @TableId("id")
    private Long id;
    @ApiModelProperty(value = "分佣比例")
    @TableField("proportion")
    private BigDecimal proportion;
    @ApiModelProperty(value = "海报")
    @TableField("poster")
    private String poster;
    @ApiModelProperty(value = "规则")
    @TableField("rules")
    private String rules;
    @ApiModelProperty(value = "推广二维码")
    @TableField(exist = false)
    private String qrCode;
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/CommonQuestion.java
@@ -33,6 +33,9 @@
    @ApiModelProperty(value = "问题")
    @TableField("question_name")
    private String questionName;
    @ApiModelProperty(value = "uid")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "排序权重")
    @TableField("sort_num")
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/ContentSetting.java
@@ -30,7 +30,7 @@
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "内容类型 1=用户协议 2=隐私协议 3=关于心泉 4= 新手冥想指南 5=课程/冥想音频购买协议")
    @ApiModelProperty(value = "内容类型 1=用户协议 2=隐私协议 3=关于心泉 4= 新手冥想指南 5=课程/冥想音频购买协议 6=能量规则说明 7等级经验值规则说明")
    @TableField("content_type")
    private Integer contentType;
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/HotWords.java
@@ -29,7 +29,9 @@
    @ApiModelProperty(value = "热词id")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "编辑删除使用该字段 赋值到id上")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "排序权重")
    @TableField("sort_num")
    private Integer sortNum;
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/Page.java
New file
@@ -0,0 +1,39 @@
package com.xinquan.system.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xinquan.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * <p>
 * 用户信息表
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
@Data
@TableName("t_page")
@ApiModel(value="启动页", description="启动页/计划引导设置")
public class Page  {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "轮播图id")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "轮播图")
    @TableField("img")
    private String img;
    @ApiModelProperty(value = "type=1 启动页 type=2计划引导设置")
    @TableField("type")
    private Integer type;
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysUserDept.java
New file
@@ -0,0 +1,49 @@
package com.xinquan.system.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
 * 用户和部门关联 sys_user_role
 *
 * @author ruoyi
 */
public class SysUserDept
{
    /** 用户ID */
    @TableField("user_id")
    private Long userId;
    /** 角色ID */
    @TableField("dept_id")
    private Long deptId;
    public Long getUserId()
    {
        return userId;
    }
    public void setUserId(Long userId)
    {
        this.userId = userId;
    }
    public Long getDeptId()
    {
        return deptId;
    }
    public void setDeptId(Long deptId)
    {
        this.deptId = deptId;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("userId", getUserId())
            .append("roleId", getDeptId())
            .toString();
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/Version.java
@@ -32,6 +32,9 @@
    @ApiModelProperty(value = "版本号")
    @TableField("version_no")
    private String versionNo;
    @ApiModelProperty(value = "版本号")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "安卓版本文件")
    @TableField("android_file")
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/VipSetting.java
@@ -30,7 +30,9 @@
    @ApiModelProperty(value = "VIP设置id")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "uid 不会丢失精度的id 编辑时将值复制到id字段上")
    @TableField(exist = false)
    private String uid;
    @ApiModelProperty(value = "设置类型 1=会员费设置 2=会员权益设置3=会员用户协议 4=续费管理说明")
    @TableField("setting_type")
    private Integer settingType;
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/CommissionRuleMapper.java
New file
@@ -0,0 +1,17 @@
package com.xinquan.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xinquan.system.domain.Banner;
import com.xinquan.system.domain.CommissionRule;
/**
 * <p>
 * 用户信息表 Mapper 接口
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
public interface CommissionRuleMapper extends BaseMapper<CommissionRule> {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/PageMapper.java
New file
@@ -0,0 +1,17 @@
package com.xinquan.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xinquan.system.domain.Banner;
import com.xinquan.system.domain.Page;
/**
 * <p>
 * 用户信息表 Mapper 接口
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
public interface PageMapper extends BaseMapper<Page> {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysUserDeptMapper.java
New file
@@ -0,0 +1,115 @@
package com.xinquan.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xinquan.system.domain.SysUserDept;
import com.xinquan.system.domain.SysUserRole;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 用户与角色关联表 数据层
 *
 * @author ruoyi
 */
public interface SysUserDeptMapper extends BaseMapper<SysUserDept>
{
    /**
     * 通过用户ID删除用户和角色关联
     *
     * @param userId 用户ID
     * @return 结果
     */
    public int deleteUserRoleByUserId(Long userId);
    /**
     * 批量删除用户和角色关联
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    public int deleteUserRole(Long[] ids);
    /**
     * 通过角色ID查询角色使用数量
     *
     * @param roleId 角色ID
     * @return 结果
     */
    public int countUserRoleByRoleId(Long roleId);
    /**
     * 批量新增用户角色信息
     *
     * @param userRoleList 用户角色列表
     * @return 结果
     */
    public int batchUserRole(List<SysUserRole> userRoleList);
    /**
     * 删除用户和角色关联信息
     *
     * @param userRole 用户和角色关联信息
     * @return 结果
     */
    public int deleteUserRoleInfo(SysUserRole userRole);
    /**
     * 批量取消授权用户角色
     *
     * @param roleId 角色ID
     * @param userIds 需要删除的用户数据ID
     * @return 结果
     */
    public int deleteUserRoleInfos(@Param("roleId") Long roleId, @Param("userIds") Long[] userIds);
    /**
     * 查询用户和角色关联
     *
     * @param userId 用户和角色关联主键
     * @return 用户和角色关联
     */
    public SysUserRole selectSysUserRoleByUserId(Long userId);
    /**
     * 查询用户和角色关联列表
     *
     * @param sysUserRole 用户和角色关联
     * @return 用户和角色关联集合
     */
    public List<SysUserRole> selectSysUserRoleList(SysUserRole sysUserRole);
    /**
     * 新增用户和角色关联
     *
     * @param sysUserRole 用户和角色关联
     * @return 结果
     */
    public int insertSysUserRole(SysUserRole sysUserRole);
    /**
     * 修改用户和角色关联
     *
     * @param sysUserRole 用户和角色关联
     * @return 结果
     */
    public int updateSysUserRole(SysUserRole sysUserRole);
    /**
     * 删除用户和角色关联
     *
     * @param userId 用户和角色关联主键
     * @return 结果
     */
    public int deleteSysUserRoleByUserId(Long userId);
    /**
     * 批量删除用户和角色关联
     *
     * @param userIds 需要删除的数据主键集合
     * @return 结果
     */
    public int deleteSysUserRoleByUserIds(Long[] userIds);
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysUserMapper.java
@@ -5,6 +5,8 @@
import com.xinquan.system.api.domain.SysUser;
import java.util.ArrayList;
import java.util.List;
import com.xinquan.system.api.domain.vo.SysUserVO;
import org.apache.ibatis.annotations.Param;
/**
@@ -136,7 +138,7 @@
     */
    public SysUser checkEmailUnique(String email);
    PageInfo<SysUser> getList(@Param("pageInfo") PageInfo<SysUser> pageInfo, @Param("phonenumber") String phonenumber);
    PageInfo<SysUser> getList(@Param("pageInfo") PageInfo<SysUser> pageInfo, @Param("request") SysUserVO request);
    PageInfo<SysUser> getAllList(@Param("pageInfo") PageInfo<SysUser> pageInfo, @Param("ids") List<Integer> collect);
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/BannerService.java
@@ -1,6 +1,7 @@
package com.xinquan.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.system.api.domain.vo.BannerVO;
import com.xinquan.system.domain.Banner;
import java.util.List;
@@ -21,4 +22,8 @@
     * @return 轮播图列表
     */
    List<BannerVO> getBannerList();
    PageDTO<Banner> bannerList(Integer pageCurr, Integer pageSize);
    PageDTO<Banner> courseList(Integer pageCurr, Integer pageSize, Integer courseType, Long cateId, String courseTitle, String tutor);
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/CommissionRuleService.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.system.api.domain.vo.BannerVO;
import com.xinquan.system.domain.Banner;
import com.xinquan.system.domain.CommissionRule;
import java.util.List;
/**
 * <p>
 * 用户信息表 服务类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
public interface CommissionRuleService extends IService<CommissionRule> {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysUserDeptService.java
New file
@@ -0,0 +1,65 @@
package com.xinquan.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.system.domain.SysUserDept;
import com.xinquan.system.domain.SysUserRole;
import java.util.List;
/**
 * 用户和角色关联Service接口
 *
 * @author xiaochen
 * @date 2023-06-12
 */
public interface ISysUserDeptService extends IService<SysUserDept>
{
    /**
     * 查询用户和角色关联
     *
     * @param userId 用户和角色关联主键
     * @return 用户和角色关联
     */
    public SysUserRole selectSysUserRoleByUserId(Long userId);
    /**
     * 查询用户和角色关联列表
     *
     * @param sysUserRole 用户和角色关联
     * @return 用户和角色关联集合
     */
    public List<SysUserRole> selectSysUserRoleList(SysUserRole sysUserRole);
    /**
     * 新增用户和角色关联
     *
     * @param sysUserRole 用户和角色关联
     * @return 结果
     */
    public int insertSysUserRole(SysUserRole sysUserRole);
    /**
     * 修改用户和角色关联
     *
     * @param sysUserRole 用户和角色关联
     * @return 结果
     */
    public int updateSysUserRole(SysUserRole sysUserRole);
    /**
     * 批量删除用户和角色关联
     *
     * @param userIds 需要删除的用户和角色关联主键集合
     * @return 结果
     */
    public int deleteSysUserRoleByUserIds(Long[] userIds);
    /**
     * 删除用户和角色关联信息
     *
     * @param userId 用户和角色关联主键
     * @return 结果
     */
    public int deleteSysUserRoleByUserId(Long userId);
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysUserService.java
@@ -3,6 +3,8 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.common.core.web.page.PageInfo;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.system.api.domain.vo.SysUserVO;
import java.util.ArrayList;
import java.util.List;
@@ -215,7 +217,7 @@
     */
    public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName);
    PageInfo<SysUser> getList(PageInfo<SysUser> pageInfo, String phonenumber);
    PageInfo<SysUser> getList(PageInfo<SysUser> pageInfo, SysUserVO sysUserVO);
    PageInfo<SysUser> getAllList(PageInfo<SysUser> pageInfo, List<Integer> collect);
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/PageService.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.system.api.domain.vo.BannerVO;
import com.xinquan.system.domain.Banner;
import com.xinquan.system.domain.Page;
import java.util.List;
/**
 * <p>
 * 用户信息表 服务类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
public interface PageService extends IService<Page> {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/BannerServiceImpl.java
@@ -1,12 +1,20 @@
package com.xinquan.system.service.impl;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinquan.common.core.utils.page.BeanUtils;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.course.api.domain.Course;
import com.xinquan.course.api.domain.CourseDTO;
import com.xinquan.system.api.domain.vo.BannerVO;
import com.xinquan.system.domain.Banner;
import com.xinquan.system.mapper.BannerMapper;
import com.xinquan.system.service.BannerService;
import java.util.List;
import java.util.Objects;
import org.springframework.stereotype.Service;
/**
@@ -30,4 +38,32 @@
        List<Banner> list = this.lambdaQuery().orderByDesc(Banner::getSortNum).list();
        return BeanUtils.copyList(list, BannerVO.class);
    }
    @Override
    public PageDTO<Banner> bannerList(Integer pageCurr, Integer pageSize) {
        Page<Banner> page = this.lambdaQuery()
                .orderByDesc(Banner::getSortNum)
                .page(new Page<>(pageCurr, pageSize));
        if (CollUtils.isEmpty(page.getRecords())) {
            return PageDTO.empty(page);
        }
        for (Banner record : page.getRecords()) {
        }
        return PageDTO.of(page, Banner.class);
    }
    @Override
    public PageDTO<Banner> courseList(Integer pageCurr, Integer pageSize, Integer courseType, Long cateId, String courseTitle, String tutor) {
        CourseDTO courseDTO = new CourseDTO();
        courseDTO.setCourseType(courseType);
        courseDTO.setCateId(cateId);
        courseDTO.setCourseTitle(courseTitle);
        courseDTO.setTutor(tutor);
        courseDTO.setPageCurr(pageCurr);
        courseDTO.setPageSize(pageSize);
        return null;
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/CommissionRuleServiceImpl.java
New file
@@ -0,0 +1,28 @@
package com.xinquan.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinquan.common.core.utils.page.BeanUtils;
import com.xinquan.system.api.domain.vo.BannerVO;
import com.xinquan.system.domain.Banner;
import com.xinquan.system.domain.CommissionRule;
import com.xinquan.system.mapper.BannerMapper;
import com.xinquan.system.mapper.CommissionRuleMapper;
import com.xinquan.system.service.BannerService;
import com.xinquan.system.service.CommissionRuleService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
@Service
public class CommissionRuleServiceImpl extends ServiceImpl<CommissionRuleMapper, CommissionRule> implements CommissionRuleService {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/PageServiceImpl.java
New file
@@ -0,0 +1,28 @@
package com.xinquan.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinquan.common.core.utils.page.BeanUtils;
import com.xinquan.system.api.domain.vo.BannerVO;
import com.xinquan.system.domain.Banner;
import com.xinquan.system.domain.Page;
import com.xinquan.system.mapper.BannerMapper;
import com.xinquan.system.mapper.PageMapper;
import com.xinquan.system.service.BannerService;
import com.xinquan.system.service.PageService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
@Service
public class PageServiceImpl extends ServiceImpl<PageMapper, Page> implements PageService {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysUserDeptServiceImpl.java
New file
@@ -0,0 +1,98 @@
package com.xinquan.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinquan.system.domain.SysUserDept;
import com.xinquan.system.domain.SysUserRole;
import com.xinquan.system.mapper.SysUserDeptMapper;
import com.xinquan.system.mapper.SysUserRoleMapper;
import com.xinquan.system.service.ISysUserDeptService;
import com.xinquan.system.service.ISysUserRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * 用户和角色关联Service业务层处理
 *
 * @author xiaochen
 * @date 2023-06-12
 */
@Service
public class SysUserDeptServiceImpl extends ServiceImpl<SysUserDeptMapper, SysUserDept> implements ISysUserDeptService
{
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    /**
     * 查询用户和角色关联
     *
     * @param userId 用户和角色关联主键
     * @return 用户和角色关联
     */
    @Override
    public SysUserRole selectSysUserRoleByUserId(Long userId)
    {
        return sysUserRoleMapper.selectSysUserRoleByUserId(userId);
    }
    /**
     * 查询用户和角色关联列表
     *
     * @param sysUserRole 用户和角色关联
     * @return 用户和角色关联
     */
    @Override
    public List<SysUserRole> selectSysUserRoleList(SysUserRole sysUserRole)
    {
        return sysUserRoleMapper.selectSysUserRoleList(sysUserRole);
    }
    /**
     * 新增用户和角色关联
     *
     * @param sysUserRole 用户和角色关联
     * @return 结果
     */
    @Override
    public int insertSysUserRole(SysUserRole sysUserRole)
    {
        return sysUserRoleMapper.insertSysUserRole(sysUserRole);
    }
    /**
     * 修改用户和角色关联
     *
     * @param sysUserRole 用户和角色关联
     * @return 结果
     */
    @Override
    public int updateSysUserRole(SysUserRole sysUserRole)
    {
        return sysUserRoleMapper.updateSysUserRole(sysUserRole);
    }
    /**
     * 批量删除用户和角色关联
     *
     * @param userIds 需要删除的用户和角色关联主键
     * @return 结果
     */
    @Override
    public int deleteSysUserRoleByUserIds(Long[] userIds)
    {
        return sysUserRoleMapper.deleteSysUserRoleByUserIds(userIds);
    }
    /**
     * 删除用户和角色关联信息
     *
     * @param userId 用户和角色关联主键
     * @return 结果
     */
    @Override
    public int deleteSysUserRoleByUserId(Long userId)
    {
        return sysUserRoleMapper.deleteSysUserRoleByUserId(userId);
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysUserServiceImpl.java
@@ -11,6 +11,7 @@
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.system.api.domain.SysRole;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.system.api.domain.vo.SysUserVO;
import com.xinquan.system.domain.SysPost;
import com.xinquan.system.domain.SysUserPost;
import com.xinquan.system.domain.SysUserRole;
@@ -204,7 +205,7 @@
    public boolean checkPhoneUnique(SysUser user)
    {
        Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
        SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber());
        SysUser info = userMapper.checkPhoneUnique(user.getUserName());
        if (StringUtils.isNotNull(info) )
        {
            return UserConstants.NOT_UNIQUE;
@@ -561,7 +562,7 @@
    }
    @Override
    public PageInfo<SysUser> getList(PageInfo<SysUser> pageInfo, String phonenumber) {
    public PageInfo<SysUser> getList(PageInfo<SysUser> pageInfo, SysUserVO phonenumber) {
        return this.baseMapper.getList(pageInfo,phonenumber);
    }
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/utils/MyQrCodeUtil.java
New file
@@ -0,0 +1,93 @@
package com.xinquan.system.utils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
public class MyQrCodeUtil {
    //CODE_WIDTH:二维码宽度,单位像素
    private static final int CODE_WIDTH = 400;
    //CODE_HEIGHT:二维码高度,单位像素
    private static final int CODE_HEIGHT = 400;
    //FRONT_COLOR:二维码前景色,0x000000 表示黑色
    private static final int FRONT_COLOR = 0x000000;
    //BACKGROUND_COLOR:二维码背景色,0xFFFFFF 表示白色
    //演示用 16 进制表示,和前端页面 CSS 的取色是一样的,注意前后景颜色应该对比明显,如常见的黑白
    private static final int BACKGROUND_COLOR = 0xFFFFFF;
    public static BufferedImage createCodeToFile(String content) {
        try {
            content = content.trim();
            //核心代码-生成二维码
            BufferedImage bufferedImage = getBufferedImage(content);
            return bufferedImage;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 生成二维码并输出到输出流, 通常用于输出到网页上进行显示,输出到网页与输出到磁盘上的文件中,区别在于最后一句 ImageIO.write
     * write(RenderedImage im,String formatName,File output):写到文件中
     * write(RenderedImage im,String formatName,OutputStream output):输出到输出流中
     * @param content  :二维码内容
     * @param outputStream :输出流,比如 HttpServletResponse 的 getOutputStream
     */
    public static void createCodeToOutputStream(String content, OutputStream outputStream) {
        try {
            if (StringUtils.isBlank(content)) {
                return;
            }
            content = content.trim();
            //核心代码-生成二维码
            BufferedImage bufferedImage = getBufferedImage(content);
            //区别就是这一句,输出到输出流中,如果第三个参数是 File,则输出到文件中
            ImageIO.write(bufferedImage, "png", outputStream);
            System.out.println("二维码图片生成到输出流成功...");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //核心代码-生成二维码
    private static BufferedImage getBufferedImage(String content) throws WriterException {
        //com.google.zxing.EncodeHintType:编码提示类型,枚举类型
        Map<EncodeHintType, Object> hints = new HashMap();
        //EncodeHintType.CHARACTER_SET:设置字符编码类型
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        //EncodeHintType.ERROR_CORRECTION:设置误差校正
        //ErrorCorrectionLevel:误差校正等级,L = ~7% correction、M = ~15% correction、Q = ~25% correction、H = ~30% correction
        //不设置时,默认为 L 等级,等级不一样,生成的图案不同,但扫描的结果是一样的
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        //EncodeHintType.MARGIN:设置二维码边距,单位像素,值越小,二维码距离四周越近
        hints.put(EncodeHintType.MARGIN, 1);
        MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
        BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_HEIGHT, hints);
        BufferedImage bufferedImage = new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_BGR);
        for (int x = 0; x < CODE_WIDTH; x++) {
            for (int y = 0; y < CODE_HEIGHT; y++) {
                bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? FRONT_COLOR : BACKGROUND_COLOR);
            }
        }
        return bufferedImage;
    }
//    public static void main(String[] args) {
//        String param = "{\n" +
//                "    \"scan_type\": 1,\n" +
//                "    \"space_id\": 2,\n" +
//                "    \"sutu_id\": 3\n" +
//                "}";
//        createCodeToFile(param);
//    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/utils/ObsUploadUtil.java
New file
@@ -0,0 +1,81 @@
package com.xinquan.system.utils;
import com.obs.services.ObsClient;
import com.obs.services.model.ObjectMetadata;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
public class ObsUploadUtil {
    public static String endPoint = "obs.cn-north-4.myhuaweicloud.com";
    public static String accessKeyId = "X3V6GPYUK1VQ03K0JG4G";
    public static String accessKeySecret = "CustHR4B9XKdT7hGcEYEpV9UVUoc4pmUhnHckU9h";
    public static String bucketName = "jkjianshen";
    public static String oss_domain = "https://jkjianshen.obs.cn-north-4.myhuaweicloud.com/";
//    public static String oss_domain = "http://cdn.jkcyl.cn/";
    // 创建ObsClient实例
    public static ObsClient obsClient = new ObsClient(accessKeyId, accessKeySecret, endPoint);
    public static String obsUpload(MultipartFile file) throws IOException{
        //CommonsMultipartFile file = (CommonsMultipartFile)multipartFile;
        String fileName = "";
        if(file!=null && !"".equals(file.getOriginalFilename()) && file.getOriginalFilename()!=null){
            InputStream content = file.getInputStream();//获得指定文件的输入流
            ObjectMetadata meta = new ObjectMetadata();// 创建上传Object的Metadata
            meta.setContentLength(file.getSize());  // 必须设置ContentLength
            String originalFilename = file.getOriginalFilename();
            if (originalFilename.contains("apk")){
                fileName = "bf2fe5c5499341e5bc0d56c0c7d5fb2e.apk";
                System.err.println("apk");
            }else{
                fileName =  UUID.randomUUID().toString().replaceAll("-","") + originalFilename.subSequence(originalFilename.lastIndexOf("."), originalFilename.length());
            }
            obsClient.putObject(bucketName,"admin/"+fileName,content,meta);// 上传Object.
            if(fileName != null && !"".equals(fileName)){
                System.out.println(fileName);
                fileName = oss_domain+"admin/"+fileName;
            }
        }
        return fileName;
    }
    /**
     * 删除某个Object
     *
     * @param bucketUrl
     * @return
     */
    public static boolean deleteObject(String bucketUrl) {
        try {
            bucketUrl=bucketUrl.replace(oss_domain+"web","");
            // 删除Object.
            obsClient.deleteObject(bucketName, bucketUrl);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            //ossClient.shutdown();
        }
        return true;
    }
//     public static void createBucket(String bucketName)
//     {
//         //初始化 OSSClient
////          ossClient = new OssClient(endPoint, accessKeyId, accessKeySecret);
//
//         // 新建一个Bucket
//         Bucket bucket = ossClient.createBucket(bucketName);
//         System.out.println(bucket.getName());
//         System.out.println(bucket.getCreationDate());
//     }
//
//     public static void main(String[] args) {
//         OssUploadUtil.createBucket("ssfdfsd");
//    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/utils/QRCodeUtil.java
New file
@@ -0,0 +1,50 @@
package com.xinquan.system.utils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.awt.image.BufferedImage;
import java.util.Hashtable;
/**
 * @author chengst
 * @date 2019/11/4
 **/
public class QRCodeUtil {
    private final static String CHARSET = "utf-8";
    private final static int QRSIZEE = 300;
    // 二维码颜色
    private static final int BLACK = 0xFF000000;
    // 二维码颜色
    private static final int WHITE = 0xFFFFFFFF;
    public static BufferedImage createImage(String content){
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
        hints.put(EncodeHintType.MARGIN, 1);
        BitMatrix bitMatrix = null;
        try {
            bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRSIZEE, QRSIZEE,hints);
        }catch (Exception e){
            e.printStackTrace();
        }
        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, bitMatrix.get(x, y) ? BLACK : WHITE);
            }
        }
        return image;
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/utils/UUIDUtil.java
New file
@@ -0,0 +1,101 @@
package com.xinquan.system.utils;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
/**
 * 定义生成随机码的工具类
 */
public class UUIDUtil {
    private int i = 1;
    /**
     * 定义生成原生的UUID随机码
     * @return
     */
    public static String getNativeUUID(){
        return UUID.randomUUID().toString();
    }
    /**
     * 生成32位随机码
     * @return
     */
    public static String getRandomCode(){
        return UUIDUtil.getNativeUUID().replaceAll("-", "");
    }
    /**
     * 获取给定长度的随机码
     * @param num
     * @return
     * @throws Exception
     */
    public static String getRandomCode(Integer num) throws Exception{
        String str = null;
        if(0 < num){
            if(num % 32 > 0){
                Integer s = num / 32;
                Integer l = num % 32;
                StringBuffer sb = new StringBuffer();
                for(int i = 0; i < s; i++){
                    sb.append(UUIDUtil.getRandomCode());
                }
                sb.append(UUIDUtil.getRandomCode().substring(0, l));
                str = sb.toString();
            }else if(num % 32 == 0){
                Integer s = num / 32;
                StringBuffer sb = new StringBuffer();
                for(int i = 0; i < s; i++){
                    sb.append(UUIDUtil.getRandomCode());
                }
                str = sb.toString();
            }else{
                str = UUIDUtil.getRandomCode().substring(0, num);
            }
        }else{
            throw new Exception("参数只能大于0");
        }
        return str;
    }
    /**
     * 获取根据当前时间的字符串数据
     * @return
     */
    public synchronized static String getTimeStr(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmssS");
        return simpleDateFormat.format(new Date());
    }
    /**
     * @Description: 获取数字随机码
     * @Author pzb
     * @Date 2021/8/11 16:52
     * @Param
     * @Return
     * @Exception
     */
    public static String getNumberRandom(Integer num){
        if(null == num){
            num = 32;
        }
        StringBuffer sb = new StringBuffer();
        for(int i = 0; i < num; i++){
            sb.append(Double.valueOf(Math.random() * 10).intValue());
        }
        return sb.toString();
    }
}
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysUserDeptMapper.xml
New file
@@ -0,0 +1,90 @@
<?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="com.xinquan.system.mapper.SysUserDeptMapper">
    <resultMap type="com.xinquan.system.domain.SysUserDept" id="SysUserRoleResult">
        <result property="userId"     column="user_id"      />
        <result property="deptId"     column="dept_id"      />
    </resultMap>
    <sql id="selectSysUserRoleVo">
        select user_id, role_id from sys_user_role
    </sql>
    <delete id="deleteUserRoleByUserId" parameterType="Long">
        delete from sys_user_role where user_id=#{userId}
    </delete>
    <select id="countUserRoleByRoleId" resultType="Integer">
        select count(1) from sys_user_role where role_id=#{roleId}
    </select>
    <delete id="deleteUserRole" parameterType="Long">
         delete from sys_user_role where user_id in
         <foreach collection="array" item="userId" open="(" separator="," close=")">
             #{userId}
        </foreach>
     </delete>
    <insert id="batchUserRole">
        insert into sys_user_role(user_id, role_id) values
        <foreach item="item" index="index" collection="list" separator=",">
            (#{item.userId},#{item.roleId})
        </foreach>
    </insert>
    <delete id="deleteUserRoleInfo" parameterType="com.xinquan.system.domain.SysUserRole">
        delete from sys_user_role where user_id=#{userId} and role_id=#{roleId}
    </delete>
    <delete id="deleteUserRoleInfos">
        delete from sys_user_role where role_id=#{roleId} and user_id in
         <foreach collection="userIds" item="userId" open="(" separator="," close=")">
             #{userId}
            </foreach>
    </delete>
    <select id="selectSysUserRoleList" parameterType="com.xinquan.system.domain.SysUserRole" resultMap="SysUserRoleResult">
        <include refid="selectSysUserRoleVo"/>
        <where>
        </where>
    </select>
    <select id="selectSysUserRoleByUserId" parameterType="Long" resultMap="SysUserRoleResult">
        <include refid="selectSysUserRoleVo"/>
        where user_id = #{userId}
    </select>
    <insert id="insertSysUserRole" parameterType="com.xinquan.system.domain.SysUserRole">
        insert into sys_user_role
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="userId != null">user_id,</if>
            <if test="roleId != null">role_id,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="userId != null">#{userId},</if>
            <if test="roleId != null">#{roleId},</if>
        </trim>
    </insert>
    <update id="updateSysUserRole" parameterType="com.xinquan.system.domain.SysUserRole">
        update sys_user_role
        <trim prefix="SET" suffixOverrides=",">
            <if test="roleId != null">role_id = #{roleId},</if>
        </trim>
        where user_id = #{userId}
    </update>
    <delete id="deleteSysUserRoleByUserId" parameterType="Long">
        delete from sys_user_role where user_id = #{userId}
    </delete>
    <delete id="deleteSysUserRoleByUserIds" parameterType="String">
        delete from sys_user_role where user_id in
        <foreach item="userId" collection="array" open="(" separator="," close=")">
            #{userId}
        </foreach>
    </delete>
</mapper>
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -124,15 +124,30 @@
        select user_id, email from sys_user where email = #{email} and del_flag = '0' limit 1
    </select>
    <select id="getList" resultType="com.xinquan.system.api.domain.SysUser">
        select *,nick_name nickName,login_date loginDate,create_time createTime,user_id userId from sys_user where 1=1
        <if test="phonenumber !=null and phonenumber !=''">
            and phonenumber like concat("%", #{phonenumber},"%")
        select *,nick_name nickName,login_date loginDate,create_time createTime,user_id userId
        from sys_user where 1=1
        <if test="req.phoneOrName !=null and req.phoneOrName !=''">
            and (phonenumber like concat("%", #{req.phoneOrName},"%") or phonenumber like concat("%", #{req.phoneOrName},"%"))
        </if>
         and del_flag = '0'
        order by create_time desc
        <if test="req.dept != null and req.dept.size()>0">
            AND t_coach.id IN
            <foreach collection="req.dept" separator="," item="id" open="(" close=")">
                #{id}
            </foreach>
        </if>
        <if test="req.role != null and req.dept.size()>0">
            AND t_coach.id IN
            <foreach collection="req.dept" separator="," item="id" open="(" close=")">
                #{id}
            </foreach>
        </if>
    </select>
    <select id="getAllList" resultType="com.xinquan.system.api.domain.SysUser">
        select *,user_id userId,nick_name userName ,create_time createTime ,login_date loginDate from sys_user where roleType=3 and user_id in
        select *,user_id userId,nick_name userName ,create_time createTime ,login_date loginDate
        from sys_user
        where roleType=3 and user_id in
        <foreach collection="ids" separator="," open="(" item="id" index="index" close=")" >
            #{id}
xinquan-modules/xinquan-user/pom.xml
@@ -18,6 +18,17 @@
  </properties>
  <dependencies>
    <!--网易邮件-->
    <dependency>
      <groupId>javax.mail</groupId>
      <artifactId>javax.mail-api</artifactId>
      <version>1.6.2</version>
    </dependency>
    <dependency>
      <groupId>com.sun.mail</groupId>
      <artifactId>jakarta.mail</artifactId>
      <version>1.6.5</version>
    </dependency>
    <!--user feign模块-->
    <dependency>
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserController.java
@@ -1,45 +1,63 @@
package com.xinquan.user.controller.client;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.BeanUtils;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.core.web.domain.BaseModel;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.course.api.domain.Course;
import com.xinquan.course.api.domain.CourseCategory;
import com.xinquan.course.api.domain.CourseDTO;
import com.xinquan.order.api.feign.RemoteOrderService;
import com.xinquan.system.api.RemoteBannerService;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.AppUserTree;
import com.xinquan.system.api.domain.AppUserViewingHistory;
import com.xinquan.system.api.domain.UserLevelSetting;
import com.xinquan.system.api.RemoteUserService;
import com.xinquan.system.api.domain.*;
import com.xinquan.system.api.domain.vo.*;
import com.xinquan.user.api.domain.dto.AppUserManagementDTO;
import com.xinquan.user.api.domain.vo.FreezingVO;
import com.xinquan.user.api.domain.vo.ViewReport;
import com.xinquan.user.domain.dto.UserAnswerDTO;
import com.xinquan.user.domain.vo.TagVO;
import com.xinquan.user.service.AppUserService;
import com.xinquan.user.service.AppUserTreeService;
import com.xinquan.user.service.AppUserViewingHistoryService;
import com.xinquan.user.service.*;
import com.xinquan.user.utils.MailUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import io.swagger.models.auth.In;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
import static com.xinquan.common.core.enums.TreeLevelEnum.TOWERING_TREES;
@@ -61,18 +79,549 @@
    private final AppUserService appUserService;
    @Resource
    private AppUserViewingHistoryService appUserViewingHistoryService;
    @Resource
    private AppUserEnergyRecordService appUserEnergyRecordService;
    @Resource
    private AppUserTreeService appUserTreeService;
    @Resource
    private AppUserQuestionService appUserQuestionService;
    @Resource
    private TagService tagService;
    @Resource
    private RemoteBannerService remoteBannerService;
    @Resource
    private RemoteOrderService remoteOrderService;
    @Resource
    private RemoteUserService remoteUserService;
    public static void main(String[] args) {
        LocalDateTime dateTime = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String formattedDateTime = dateTime.format(formatter);
        System.err.println(formattedDateTime);
//        LocalDateTime dateTime = LocalDateTime.now();
//        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
//        String formattedDateTime = dateTime.format(formatter);
//        System.err.println(formattedDateTime);
        // 收件人电子邮箱,TODO 换成自己的收件箱
        String to = "443237572@qq.com";
        // 发件人电子邮箱,TODO 换成自己的发件箱
        String from = "13281306557@163.com";
        // 指定发送邮件的主机为
        String host = "smtp.163.com";
        // 获取系统属性
        //Properties properties = System.getProperties();
        Properties properties = new Properties();
        // 设置邮件服务器
        properties.setProperty("mail.smtp.host", host);
        // 邮件发送协议
        properties.setProperty("mail.transport.protocol", "smtp");
        //是否启用调试模式(启用调试模式可打印客户端与服务器交互过程时一问一答的响应消息)
        properties.setProperty("mail.debug","true");
        properties.setProperty("mail.smtp.auth", "true");
        // 获取默认session对象
        Session session = Session.getDefaultInstance(properties,new Authenticator(){
            @Override
            public PasswordAuthentication getPasswordAuthentication()
            {
                //发件人邮件用户名、授权码,换成自己的发件箱及授权码
                return new PasswordAuthentication("13281306557@163.com", "NUSdxDQqadYvVek2");
            }
        });
        try{
            // 创建默认的 MimeMessage 对象
            MimeMessage message = new MimeMessage(session);
            // Set From,设置发件人
            InternetAddress fromMail = new InternetAddress(from);
            //设置发件人名称,TODO 换成自己的发件箱
            fromMail.setPersonal(MimeUtility.encodeText("明星电力<13281306557@163.com>"));
            message.setFrom(fromMail);
            // Set To: 设置收件人
            InternetAddress toMail = new InternetAddress(to);
            // TODO 换成自己的收件箱
            InternetAddress toMail2 = new InternetAddress("443237572@qq.com");
            //发一个邮箱
//            message.setRecipient(Message.RecipientType.TO, toMail);
            //发多个邮箱
            Address[] allRecipients = {toMail, toMail2};
            message.setRecipients(Message.RecipientType.TO, allRecipients);
            // Set Subject: 邮件主体
            message.setSubject("明星电力");
            // 设置消息体
            message.setSentDate(new Date());
            // 指定为混合关系
            MimeMultipart msgMultipart = new MimeMultipart("mixed");
            message.setContent(msgMultipart);
            // 邮件信息组装
            //组装的顺序非常重要,一定要先组装文本域,再组装文件
            MimeBodyPart htmlPart = new MimeBodyPart();
            // 组装内容
            htmlPart.setContent("This is message content", "text/html;charset=UTF-8");
            msgMultipart.addBodyPart(htmlPart);
            // 组装附件
            MimeBodyPart filePart = new MimeBodyPart();
            String imageUrl = "http://221.182.45.100:8090/2024-10-10/04-18-09-0466d831fc6365571080.pdf";
            try {
                // 下载数据
                URL url = new URL(imageUrl);
                InputStream inputStream = url.openStream();
                byte[] imageBytes = IOUtils.toByteArray(inputStream);
                // 创建临时文件
                // 截取imageUrl后缀名
                String fileExtension = imageUrl.substring(imageUrl.lastIndexOf("."));
                File tempFile = File.createTempFile("tempImage", fileExtension);
                try (FileOutputStream fos = new FileOutputStream(tempFile)) {
                    fos.write(imageBytes);
                }
                // 创建 FileDataSource
                FileDataSource fileDataSource = new FileDataSource(tempFile);
                System.out.println("FileDataSource created: " + fileDataSource.getName());
                // 如果需要,可以使用 DataHandler 进行进一步处理
                DataHandler dh = new DataHandler(fileDataSource);
                // 清理:删除临时文件(如果不再需要)
                 tempFile.deleteOnExit(); // 可根据需要保留或删除
//                DataHandler dh = new DataHandler(dataSource);
                filePart.setDataHandler(dh);
                // 附件区别内嵌内容的一个特点是有文件名,为防止中文乱码要编码
                filePart.setFileName(MimeUtility.encodeText(dh.getName()));
                msgMultipart.addBodyPart(filePart);
                message.saveChanges();
                //发送
                //Transport.send(message, message.getAllRecipients());
                Transport.send(message);
                System.out.println("Sent mail successfully....");
            } catch (Exception e) {
                e.printStackTrace();
            }
            //TODO 换成自己的附件地址
        }catch (MessagingException | UnsupportedEncodingException mex) {
            mex.printStackTrace();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @PostMapping("/userDetail")
    @ApiOperation(value = "用户详情-基础信息", notes = "管理后台-用户管理")
    public R userDetail(String uid) {
        AppUser byId = appUserService.getById(uid);
        // 判断是不是会员
        if (byId.getVipExpireTime() == null){
            byId.setIsVip(2);
        }else if (byId.getVipExpireTime().isBefore(LocalDateTime.now())){
            byId.setIsVip(2);
        }else{
            byId.setIsVip(1);
        }
        List<AppUserTree> list1 = appUserTreeService.lambdaQuery().eq(AppUserTree::getAppUserId, byId.getId())
                .list();
        // 查询用户等级最高的那颗树苗
        AppUserTree tree = list1.stream().max((o1, o2) -> {
            if (o1.getTreeLevelType() > o2.getTreeLevelType()) {
                return 1;
            } else if (o1.getTreeLevelType() < o2.getTreeLevelType()) {
                return -1;
            } else {
                return 0;
            }
        }).orElse(null);
        // 查询疗愈等级 名称 图标
        int level = 1;
        if (tree != null){
            level = tree.getTreeLevelType();
        }
        // 根据等级查询疗愈名称和图标
        UserLevelSetting data = remoteBannerService.getIconNameByLevel(level).getData();
        byId.setLevel(level);
        byId.setLevelIcon(data.getLevelIcon());
        byId.setLevelName(data.getLevelName());
        byId.setUid(byId.getId().toString());
        if (org.springframework.util.StringUtils.hasLength(byId.getTagId())){
            List<String> list = Arrays.asList(byId.getTagId().split(","));
            List<String> collect = tagService.lambdaQuery().in(Tag::getId, list).list().stream()
                    .map(Tag::getTagName).collect(Collectors.toList());
            byId.setTags(collect);
        }
        return R.ok();
    }
    @GetMapping("/viewReport")
    @ApiOperation(value = "用户详情-查看报告", notes = "管理后台-用户管理")
    public R<ViewReport> viewReport(String uid) {
        ViewReport viewReport = new ViewReport();
        String tagId = appUserService.getById(uid).getTagId();
        List<AppUserQuestion> list = appUserQuestionService.lambdaQuery().eq(AppUserQuestion::getAppUserId, uid).list();
        List<Tag> list1 = tagService.lambdaQuery().list();
        String[] split = tagId.split(",");
        List<String> list2 = Arrays.asList(split);
        if (!list2.isEmpty()){
            for (Tag tag : list1) {
                if (list2.contains(tag.getId().toString())){
                    tag.setIsCheck(1);
                }
            }
        }else{
            for (Tag tag : list1) {
                    tag.setIsCheck(2);
            }
        }
        viewReport.setQuestions(list);
        viewReport.setTags(list1);
        return R.ok(viewReport);
    }
    @GetMapping("/freezing")
    @ApiOperation(value = "冻结用户", notes = "管理后台-用户管理")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uid", value = "uid", dataType = "String", required = true),
            @ApiImplicitParam(name = "freezingReason", value = "冻结原因", dataType = "String", required = true),
    })
    public R freezingDetail(String uid,String freezingReason) {
        AppUser byId = appUserService.getById(uid);
        byId.setFreezingTime(LocalDateTime.now());
        byId.setFreezingReason(freezingReason);
        byId.setUserStatus(2);
        byId.setFreezingOperator(SecurityUtils.getUserId()+"");
        appUserService.updateById(byId);
        return R.ok();
    }
    @GetMapping("/detail")
    @ApiOperation(value = "用户详情", notes = "管理后台-用户管理")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uid", value = "uid", dataType = "String", required = true),
    })
    public R<AppUser> detail(String uid) {
        AppUser byId = appUserService.getById(uid);
        List<AppUserTree> list1 = appUserTreeService.lambdaQuery().eq(AppUserTree::getAppUserId, byId.getId())
                .list();
        // 查询用户等级最高的那颗树苗
        AppUserTree tree = list1.stream().max((o1, o2) -> {
            if (o1.getTreeLevelType() > o2.getTreeLevelType()) {
                return 1;
            } else if (o1.getTreeLevelType() < o2.getTreeLevelType()) {
                return -1;
            } else {
                return 0;
            }
        }).orElse(null);
        // 查询疗愈等级 名称 图标
        int level = 1;
        if (tree != null){
            level = tree.getTreeLevelType();
        }
        byId.setLevel(level);
        // 根据等级查询疗愈名称和图标
        UserLevelSetting data = remoteBannerService.getIconNameByLevel(level).getData();
        if (data!=null){
            byId.setLevelName(data.getLevelName());
            byId.setLevelIcon(data.getLevelIcon());
        }
        return R.ok();
    }
    @GetMapping("/unFreezing")
    @ApiOperation(value = "解冻用户", notes = "管理后台-用户管理")
    public R unFreezing(String uid) {
        AppUser byId = appUserService.getById(uid);
        byId.setUserStatus(1);
        appUserService.updateById(byId);
        return R.ok(byId.getFreezingReason());
    }
    @GetMapping("/setSanskritFlag")
    @ApiOperation(value = "设置梵文权限", notes = "管理后台-用户管理")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uid", value = "用户uid 多个逗号拼接", dataType = "String", required = true),
            @ApiImplicitParam(name = "setSanskritFlag", value = "梵文权限 1是2否", dataType = "int", required = true),
    })
    public R setSanskritFlag(String uid,Integer setSanskritFlag) {
        List<String> list = Arrays.asList(uid.split(","));
        List<AppUser> list1 = appUserService.lambdaQuery().in(AppUser::getId, list).list();
        for (AppUser appUser : list1) {
            appUser.setSanskritFlag(setSanskritFlag);
        }
        appUserService.updateBatchById(list1);
        return R.ok();
    }
    @GetMapping("/setTotalEnergyValue")
    @ApiOperation(value = "能量值修改", notes = "管理后台-用户管理")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uid", value = "用户uid 多个逗号拼接", dataType = "String", required = true),
            @ApiImplicitParam(name = "energyValue", value = "能量值", dataType = "int", required = true),
            @ApiImplicitParam(name = "reason", value = "备注", dataType = "int", required = true),
    })
    public R setTotalEnergyValue(String uid,Integer energyValue,String remark) {
        AppUser byId = appUserService.getById(uid);
        byId.setTotalEnergyValue(byId.getTotalEnergyValue()+energyValue);
        appUserService.updateById(byId);
        AppUserEnergyRecord appUserEnergyRecord = new AppUserEnergyRecord();
        appUserEnergyRecord.setAppUserId(byId.getId());
        if (energyValue<0){
            appUserEnergyRecord.setChangeType(2);
            appUserEnergyRecord.setEnergyValue(-energyValue);
        }else{
            appUserEnergyRecord.setChangeType(1);
            appUserEnergyRecord.setEnergyValue(energyValue);
        }
        appUserEnergyRecord.setReason(remark);
        appUserEnergyRecord.setCreateBy(SecurityUtils.getUsername());
        appUserEnergyRecord.setCreateTime(LocalDateTime.now());
        appUserEnergyRecordService.save(appUserEnergyRecord);
        return R.ok();
    }
    @GetMapping("/setVip")
    @ApiOperation(value = "设置会员", notes = "管理后台-用户管理")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uid", value = "uid", dataType = "String", required = true),
            @ApiImplicitParam(name = "vipType", value = "会员类型 1非 2月 3季 4年", dataType = "Integer", required = true),
    })
    public R setVip(String uid, Integer vipType) {
        LambdaUpdateWrapper<AppUser> appUserLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        AppUser byId = appUserService.getById(uid);
        switch (vipType){
            case 1:
                appUserLambdaUpdateWrapper.set(AppUser::getVipExpireTime,null);
                appUserLambdaUpdateWrapper.set(AppUser::getVipLevel,null);
                appUserService.update(appUserLambdaUpdateWrapper);
                break;
            case 2:
                if (byId.getVipExpireTime() == null){
                    byId.setVipLevel(1);
                    byId.setVipExpireTime(LocalDateTime.now().plusDays(30));
                }else if (byId.getVipExpireTime().isAfter(LocalDateTime.now())){
                    byId.setVipExpireTime(byId.getVipExpireTime().plusDays(30));
                }else{
                    byId.setVipExpireTime(LocalDateTime.now().plusDays(30));
                }
                break;
            case 3:
                if (byId.getVipExpireTime() == null){
                    byId.setVipLevel(2);
                    byId.setVipExpireTime(LocalDateTime.now().plusMonths(90));
                }else if (byId.getVipExpireTime().isAfter(LocalDateTime.now())){
                    // 如果当前用户的会员等级大于设置的会员等级那么不管
                    if (byId.getVipLevel()<2){
                        byId.setVipLevel(2);
                    }
                    byId.setVipExpireTime(byId.getVipExpireTime().plusDays(90));
                }else{
                    if (byId.getVipLevel()<2){
                        byId.setVipLevel(2);
                    }
                    byId.setVipExpireTime(LocalDateTime.now().plusDays(90));
                }
                break;
            case 4:
                byId.setVipLevel(3);
                if (byId.getVipExpireTime() == null){
                    byId.setVipExpireTime(LocalDateTime.now().plusMonths(365));
                }else if (byId.getVipExpireTime().isAfter(LocalDateTime.now())){
                    byId.setVipExpireTime(byId.getVipExpireTime().plusDays(365));
                }else{
                    byId.setVipExpireTime(LocalDateTime.now().plusDays(365));
                }
                break;
        }
        appUserService.updateById(byId);
        return R.ok();
    }
    @GetMapping("/freezingDetail")
    @ApiOperation(value = "冻结详情", notes = "管理后台-用户管理")
    public R<FreezingVO> freezingDetail(String uid) {
        AppUser byId = appUserService.getById(uid);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = simpleDateFormat.format(byId.getFreezingTime());
        FreezingVO freezingVO = new FreezingVO();
        freezingVO.setFreezingTime(format);
        freezingVO.setFreezingReason(byId.getFreezingReason());
        SysUser data = remoteUserService.getSysUserById(byId.getFreezingOperator()).getData();
        freezingVO.setFreezingOperator(data.getNickName()+"("+data.getUserName()+")");
        return R.ok(freezingVO);
    }
    @PostMapping("/userManagementList")
    @ApiOperation(value = "用户管理列表-分页", tags = {"管理后台-用户管理"})
    public R<PageDTO<AppUser>> userManagementList(@RequestBody AppUserManagementDTO courseDTO) {
        String startTime = null;
        String endTime = null;
        if (org.springframework.util.StringUtils.hasLength(courseDTO.getVipExpireTime())){
            String[] split = courseDTO.getVipExpireTime().split(" - ");
            startTime = split[0]+"00:00:00";
            endTime = split[1]+"23:59:59";
        }
        String startTime1 = null;
        String endTime1 = null;
        if (org.springframework.util.StringUtils.hasLength(courseDTO.getRegisterTime())){
            String[] split = courseDTO.getRegisterTime().split(" - ");
            startTime1 = split[0]+"00:00:00";
            endTime1 = split[1]+"23:59:59";
        }
        List<Long> longs = new ArrayList<>();
        LambdaQueryWrapper<AppUser> courseLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseLambdaQueryWrapper
                .like(StringUtils.isNotBlank(courseDTO.getNickname()), AppUser::getNickname, courseDTO.getNickname())
                .like(StringUtils.isNotBlank(courseDTO.getCellPhone()), AppUser::getCellPhone, courseDTO.getCellPhone())
                .eq(Objects.nonNull(courseDTO.getGender()), AppUser::getGender, courseDTO.getGender())
                .eq(Objects.nonNull(courseDTO.getUserStatus()), AppUser::getUserStatus, courseDTO.getUserStatus())
                .isNotNull(AppUser::getVipExpireTime)
                .between(Objects.nonNull(startTime),AppUser::getVipExpireTime,startTime,endTime)
                .between(Objects.nonNull(startTime1),AppUser::getRegisterTime,startTime1,endTime1)
                .orderByDesc(AppUser::getRegisterTime);
        if (org.springframework.util.StringUtils.hasLength(courseDTO.getVipType())){
            String[] split = courseDTO.getVipType().split(",");
            List<String> list1 = Arrays.asList(split);
            List<AppUser> appUsers = new ArrayList<>();
            List<AppUser> list = appUserService.lambdaQuery().gt(AppUser::getVipExpireTime, LocalDateTime.now()).list();
            for (AppUser appUser : list) {
                if(appUser.getVipLevel()!=null){
                    if (list1.contains(appUser.getVipLevel().toString())){
                        appUsers.add(appUser);
                    }
                }
            }
            List<Long> collect = appUsers.stream().map(AppUser::getId).collect(Collectors.toList());
            if (collect.isEmpty()){
                collect.add(-1L);
            }
            courseLambdaQueryWrapper.in(AppUser::getId, longs);
        }
        if (org.springframework.util.StringUtils.hasLength(courseDTO.getLevel())){
            List<String> list2 = Arrays.asList(courseDTO.getLevel().split(","));
            List<AppUser> list = appUserService.lambdaQuery().list();
            List<AppUser> appUsers = new ArrayList<>();
            for (AppUser appUser : list) {
                List<AppUserTree> list1 = appUserTreeService.lambdaQuery().eq(AppUserTree::getAppUserId, appUser.getId())
                        .list();
                // 查询用户等级最高的那颗树苗
                AppUserTree tree = list1.stream().max((o1, o2) -> {
                    if (o1.getTreeLevelType() > o2.getTreeLevelType()) {
                        return 1;
                    } else if (o1.getTreeLevelType() < o2.getTreeLevelType()) {
                        return -1;
                    } else {
                        return 0;
                    }
                }).orElse(null);
                // 查询疗愈等级 名称 图标
                int level = 1;
                if (tree != null){
                    level = tree.getTreeLevelType();
                }
                if (list2.contains(level+"")){
                    appUsers.add(appUser);
                }
            }
            List<Long> collect = appUsers.stream().map(AppUser::getId).collect(Collectors.toList());
            if (collect.isEmpty()){
                collect.add(-1L);
            }
            courseLambdaQueryWrapper.in(AppUser::getId, collect);
        }
        Page<AppUser> page = appUserService.page(new Page<>(courseDTO.getPageCurr(), courseDTO.getPageSize()), courseLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())) {
            return R.ok(PageDTO.empty(page));
        }
        for (AppUser record : page.getRecords()) {
            // 判断是不是会员
            if (record.getVipExpireTime() == null){
                record.setIsVip(2);
            }else if (record.getVipExpireTime().isBefore(LocalDateTime.now())){
                record.setIsVip(2);
            }else{
                record.setIsVip(1);
            }
            List<AppUserTree> list1 = appUserTreeService.lambdaQuery().eq(AppUserTree::getAppUserId, record.getId())
                    .list();
            // 查询用户等级最高的那颗树苗
            AppUserTree tree = list1.stream().max((o1, o2) -> {
                if (o1.getTreeLevelType() > o2.getTreeLevelType()) {
                    return 1;
                } else if (o1.getTreeLevelType() < o2.getTreeLevelType()) {
                    return -1;
                } else {
                    return 0;
                }
            }).orElse(null);
            // 查询疗愈等级 名称 图标
            int level = 1;
            if (tree != null){
                level = tree.getTreeLevelType();
            }
            // 根据等级查询疗愈名称和图标
            UserLevelSetting data = remoteBannerService.getIconNameByLevel(level).getData();
            record.setLevel(level);
            record.setLevelIcon(data.getLevelIcon());
            record.setLevelName(data.getLevelName());
            record.setUid(record.getId().toString());
        }
        return R.ok(PageDTO.of(page, AppUser.class));
    }
    private static String getImageFormat(String url) {
        String extension = url.substring(url.lastIndexOf('.') + 1).toLowerCase();
        switch (extension) {
            case "png":
                return "image/png";
            case "jpg":
            case "jpeg":
                return "image/jpeg";
            case "gif":
                return "image/gif";
            default:
                return "unknown format";
        }
    }
    public static DataSource convertImageToDataSource(String imageUrl) throws Exception {
        URL url = new URL(imageUrl);
        try (InputStream inputStream = url.openStream()) {
            byte[] imageBytes = IOUtils.toByteArray(inputStream);
            // 使用 ImageIO 读取图片,以检测格式
            BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
            String formatName = ImageIO.getImageReaders(image).next().getFormatName();
            return new ByteArrayDataSource(imageBytes, "image/" + formatName);
        }
    }
    @PostMapping("/changePhone")
    @ApiOperation(value = "更换绑定手机号", tags = {"设置"})
    public R changePhone(String phone,String code) {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        return R.ok();
    }
    @PostMapping("/deleteUser")
    @ApiOperation(value = "注销账号", tags = {"设置"})
    public R deleteUser() {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        return R.ok();
    }
    @PostMapping("/wallet")
    @ApiOperation(value = "我的钱包", tags = {"个人中心"})
    public R<WalletVO> wallet(UpdateAppUserDTO dto) {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        AppUser byId = appUserService.getById(userId);
        WalletVO walletVO = new WalletVO();
        walletVO.setId(userId);
        walletVO.setBalance(byId.getBalance());
        walletVO.setIncome(byId.getIncome());
        // 查询用户充值
        String data = remoteOrderService.queryChargeByUserId(userId).getData();
        BigDecimal bigDecimal = new BigDecimal(data);
        walletVO.setRecharge(bigDecimal);
        return R.ok(walletVO);
    }
    /**
     * 爱心助力榜单-分页
@@ -95,6 +644,9 @@
        Page<AppUser> page = appUserService.lambdaQuery().ne(AppUser::getUserStatus, 3)
                .eq(AppUser::getInviteUserId, userId)
                .page(new Page<>(pageCurr, pageSize));
        if (page.getRecords().isEmpty()){
            return R.ok(PageDTO.empty(page));
        }
        // 查询登录用户邀请了哪些人
        List<Long> collect = page.getRecords().stream().map(AppUser::getId).collect(Collectors.toList());
        if (collect.isEmpty())return R.ok(PageDTO.empty(page));
@@ -224,7 +776,95 @@
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        AppUser appUser = appUserService.lambdaQuery().eq(AppUser::getId, userId).one();
        if (appUser.getVipExpireTime() == null){
            appUser.setIsVip(2);
        }else if (appUser.getVipExpireTime().isAfter(LocalDateTime.now())){
            appUser.setIsVip(1);
        }else{
            appUser.setIsVip(2);
        }
        return R.ok(appUser);
    }
    @PostMapping("/healingLevel")
    @ApiOperation(value = "冥想等级", tags = {"个人中心"})
    public R<HealingLevelVO> healingLevel() {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        List<AppUserTree> list1 = appUserTreeService.lambdaQuery().eq(AppUserTree::getAppUserId, userId)
                .list();
        // 查询用户等级最高的那颗树苗
        AppUserTree tree = list1.stream().max((o1, o2) -> {
            if (o1.getTreeLevelType() > o2.getTreeLevelType()) {
                return 1;
            } else if (o1.getTreeLevelType() < o2.getTreeLevelType()) {
                return -1;
            } else {
                return 0;
            }
        }).orElse(null);
        // 查询疗愈等级 名称 图标
        int level = 1;
        if (tree != null){
            level = tree.getTreeLevelType();
        }
        HealingLevelVO healingLevelVO = new HealingLevelVO();
        healingLevelVO.setLevel(level);
        // 根据等级查询疗愈名称和图标
        UserLevelSetting data = remoteBannerService.getIconNameByLevel(level).getData();
        healingLevelVO.setLevelName(data.getLevelName());
        healingLevelVO.setLevelIcon(data.getLevelIcon());
        if (level==10){
            healingLevelVO.setNextLevel(2400);
        }else{
            switch (level){
                case 1:
                    healingLevelVO.setNextLevel(1000);
                    healingLevelVO.setDifferenceLevel(1000-tree.getGrowthValue());
                    break;
                case 2:
                    healingLevelVO.setNextLevel(1000);
                    healingLevelVO.setDifferenceLevel(1000-tree.getGrowthValue());
                    break;
                case 3:
                    healingLevelVO.setNextLevel(1000);
                    healingLevelVO.setDifferenceLevel(1000-tree.getGrowthValue());
                    break;
                case 4:
                    healingLevelVO.setNextLevel(1000);
                    healingLevelVO.setDifferenceLevel(1000-tree.getGrowthValue());
                    break;
                case 5:
                    healingLevelVO.setNextLevel(2000);
                    healingLevelVO.setDifferenceLevel(2000-tree.getGrowthValue());
                    break;
                case 6:
                    healingLevelVO.setNextLevel(2000);
                    healingLevelVO.setDifferenceLevel(2000-tree.getGrowthValue());
                    break;
                case 7:
                    healingLevelVO.setNextLevel(2000);
                    healingLevelVO.setDifferenceLevel(2000-tree.getGrowthValue());
                    break;
                case 8:
                    healingLevelVO.setNextLevel(2000);
                    healingLevelVO.setDifferenceLevel(2000-tree.getGrowthValue());
                    break;
                case 9:
                    healingLevelVO.setNextLevel(2400);
                    healingLevelVO.setDifferenceLevel(2400-tree.getGrowthValue());
                    break;
                case 10:
                    healingLevelVO.setNextLevel(2400);
                    healingLevelVO.setDifferenceLevel(2400-tree.getGrowthValue());
                    break;
            }
        }
        healingLevelVO.setGrowthValue(tree.getGrowthValue());
        String data1 = remoteUserService.getCourseList(7).getData();
        healingLevelVO.setContent(data1);
        return R.ok(healingLevelVO);
    }
    @PostMapping("/getTotalEnergyValue")
    @ApiOperation(value = "获取用户当前累计能量值",tags = "树苗打卡站")
@@ -240,20 +880,30 @@
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        AppUser byId = appUserService.getById(userId);
        BeanUtils.copyProperties(dto, byId);
//        LambdaUpdateWrapper<AppUser> updateWrapper = new LambdaUpdateWrapper<>(AppUser.class);
//        updateWrapper.set(AppUser::getNickname, byId.getNickname());
//        updateWrapper.set(AppUser::getSignature, byId.getSignature());
//        updateWrapper.set(AppUser::getAvatar, byId.getAvatar());
//        updateWrapper.set(AppUser::getGender, byId.getGender());
//        updateWrapper.set(AppUser::getBirthday, byId.getBirthday());
//        updateWrapper.set(AppUser::getEducation, byId.getEducation());
//        updateWrapper.set(AppUser::getIndustry, byId.getIndustry());
//        updateWrapper.set(AppUser::getCompany, byId.getCompany());
//        updateWrapper.set(AppUser::getOccupation, byId.getOccupation());
//        updateWrapper.set(AppUser::getLocation, byId.getLocation());
//        updateWrapper.set(AppUser::getHometown, byId.getHometown());
//        appUserService.update(byId, )
        LambdaUpdateWrapper<AppUser> updateWrapper = new LambdaUpdateWrapper<>(AppUser.class);
        updateWrapper.set(AppUser::getNickname, dto.getNickname());
        updateWrapper.set(AppUser::getRealname, dto.getRealname());
        updateWrapper.set(AppUser::getSignature, dto.getSignature());
        updateWrapper.set(AppUser::getGender, dto.getGender());
        updateWrapper.set(AppUser::getBirthday, dto.getBirthday());
        updateWrapper.set(AppUser::getEducation, dto.getEducation());
        updateWrapper.set(AppUser::getIndustry, dto.getIndustry());
        updateWrapper.set(AppUser::getCompany, dto.getCompany());
        updateWrapper.set(AppUser::getOccupation, dto.getOccupation());
        updateWrapper.set(AppUser::getLocation, dto.getLocation());
        updateWrapper.set(AppUser::getHometown, dto.getHometown());
        updateWrapper.set(AppUser::getEmail, dto.getEducation());
        appUserService.update(byId, updateWrapper);
        return R.ok();
    }
    @PostMapping("/updateUserAvatar")
    @ApiOperation(value = "修改头像", tags = {"个人中心"})
    public R updateUserDetail(String avatar) {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        AppUser byId = appUserService.getById(userId);
        byId.setAvatar(avatar);
        appUserService.updateById(byId);
        return R.ok();
    }
    /**
@@ -318,6 +968,42 @@
        appUserService.saveUserAnswers(dto);
        return R.ok();
    }
    /**
     * 远程调用根据用户id 查询用户
     */
    @PostMapping("/getAppUserById/{id}")
    public R<AppUser> getAppUserById(@PathVariable("id")String id) {
        AppUser byId = appUserService.getById(id);
        return R.ok(byId);
    }
    /**
     * 远程调用根据用户名称 查询用户
     */
    @PostMapping("/getAppUserByName/{name}")
    public R<List<Long>> getAppUserByName(@PathVariable("name")String name) {
        List<Long> collect = appUserService.lambdaQuery()
                .like(AppUser::getNickname, name)
                .list()
                .stream().map(AppUser::getId).collect(Collectors.toList());
        return R.ok(collect);
    }
    /**
     * 远程调用根据用户名称 查询用户
     */
    @PostMapping("/getAppUserByNameOrPhone/{name}")
    public R<List<Long>> getAppUserByNameOrPhone(@PathVariable("name")String name) {
        List<Long> collect = appUserService.lambdaQuery()
                .like(AppUser::getNickname, name)
                .list()
                .stream().map(AppUser::getId).collect(Collectors.toList());
        List<Long> collect1 = appUserService.lambdaQuery()
                .like(AppUser::getCellPhone, name)
                .list()
                .stream().map(AppUser::getId).collect(Collectors.toList());
        collect1.addAll(collect);
        List<Long> collect2 = collect1.stream().distinct().collect(Collectors.toList());
        return R.ok(collect2);
    }
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserTagController.java
@@ -1,10 +1,18 @@
package com.xinquan.user.controller.client;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.meditation.api.domain.Meditation;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
/**
 * <p>
 * 用户标签关系表 前端控制器
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserTreeController.java
@@ -14,17 +14,16 @@
import com.xinquan.system.api.domain.*;
import com.xinquan.system.api.domain.vo.AppUserEnergyRecordVO;
import com.xinquan.system.api.domain.vo.WateringVO;
import com.xinquan.user.api.domain.dto.UserEnergyDTO;
import com.xinquan.user.api.domain.dto.UserExchangeRecordDTO;
import com.xinquan.user.domain.vo.EnergyVO;
import com.xinquan.user.domain.vo.ExchangeRecordVO;
import com.xinquan.user.service.*;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.Mapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.time.LocalDateTime;
@@ -62,7 +61,8 @@
        Long userId = SecurityUtils.getUserId();
        if (userId==0)return R.tokenError("登录失效");
        AppUser byId = appUserService.getById(userId);
        byId.setIsFirst(2);
        appUserService.updateById(byId);
        // 查询用户今日观看疗愈多少秒
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startOfDay = now.toLocalDate().atStartOfDay();
@@ -76,7 +76,6 @@
        for (AppUserViewingHistory appUserViewingHistory : list) {
            temp += appUserViewingHistory.getTimeLook();
        }
        AppUserTree one = appUserTreeService.lambdaQuery().eq(AppUserTree::getAppUserId, userId)
                .eq(AppUserTree::getSowAgain,2).one();
        if (one == null){
@@ -307,6 +306,68 @@
            return R.ok(false);
        }
    }
    @PostMapping("/userEnergyDetail")
    @ApiOperation(value = "用户详情-能量值明细 ",tags = "管理后台-用户管理")
    public R<PageDTO<AppUserEnergyRecordVO>> userEnergyDetail(@RequestBody UserEnergyDTO dto) {
        String startTime = null;
        String endTime = null;
        if (org.springframework.util.StringUtils.hasLength(dto.getTime())){
            String[] split = dto.getTime().split(" - ");
            startTime = split[0]+"00:00:00";
            endTime = split[1]+"23:59:59";
        }
        String userId = dto.getUid();
        EnergyVO energyVO = new EnergyVO();
        energyVO.setEnergyTotal(appUserService.getById(userId).getTotalEnergyValue());
        LambdaQueryWrapper<AppUserEnergyRecord> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (dto.getState()!=null){
            switch (dto.getState()){
                case 1:
                    lambdaQueryWrapper.eq(AppUserEnergyRecord::getChangeType, 1);
                    break;
                case 2:
                    lambdaQueryWrapper.eq(AppUserEnergyRecord::getChangeType, 2);
                    break;
            }
        }
        lambdaQueryWrapper.like(StringUtils.hasLength(dto.getContent()),AppUserEnergyRecord::getReason,dto.getContent());
        lambdaQueryWrapper.between(startTime!=null,BaseModel::getCreateTime,startTime,endTime);
        lambdaQueryWrapper.eq(AppUserEnergyRecord::getAppUserId, userId).orderByDesc(BaseModel::getCreateTime);
        Page<AppUserEnergyRecord> page = appUserEnergyRecordService.page(new Page<>(dto.getPageCurr(), dto.getPageSize()), lambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())){
            PageDTO<AppUserEnergyRecordVO> empty = PageDTO.empty(page);
            energyVO.setList(new ArrayList<AppUserEnergyRecordVO>());
            return R.ok(empty);
        }
        PageDTO<AppUserEnergyRecordVO> appUserEnergyRecordVOPageDTO = PageDTO.of(page, AppUserEnergyRecordVO.class);
        energyVO.setList(appUserEnergyRecordVOPageDTO.getList());
        return R.ok(appUserEnergyRecordVOPageDTO);
    }
    @PostMapping("/userExchangeRecordList")
    @ApiOperation(value = "用户详情-兑换记录 ",tags = "管理后台-用户管理")
    public R<PageDTO<ExchangeRecordVO>> userExchangeRecordList(@RequestBody UserExchangeRecordDTO dto) {
        Long userId = SecurityUtils.getUserId();
        if (userId==0)return R.tokenError("登录失效");
        Page<PrizeRedemptionRecord> page = prizeRedemptionRecordService.lambdaQuery()
                .eq(PrizeRedemptionRecord::getAppUserId, userId)
                .orderByDesc(BaseModel::getCreateTime).page(new Page<>(dto.getPageCurr(), dto.getPageSize()));
        if (CollUtils.isEmpty(page.getRecords())){
            PageDTO<ExchangeRecordVO> empty = PageDTO.empty(page);
            return R.ok(empty);
        }
        PageDTO<ExchangeRecordVO> res = PageDTO.of(page, ExchangeRecordVO.class);
        for (ExchangeRecordVO record : res.getList()) {
            Prize temp = prizeService.lambdaQuery()
                    .eq(Prize::getId, record.getId()).one();
            if (temp != null){
                record.setName(temp.getName());
                record.setCoverUrl(temp.getCoverUrl());
                record.setWorth(temp.getWorth());
                record.setEnergyValue(temp.getEnergyValue());
            }
        }
        return R.ok(res);
    }
    @PostMapping("/energyDetail")
    @ApiOperation(value = "能量值明细 ",tags = "树苗打卡站")
    @ApiImplicitParams({
@@ -390,6 +451,7 @@
        }
        PrizeRedemptionRecord prizeRedemptionRecord = new PrizeRedemptionRecord();
        prizeRedemptionRecord.setStatus(1);
        prizeRedemptionRecord.setEnergyValue(byId.getEnergyValue());
        prizeRedemptionRecord.setPrizeId(prizeId);
        prizeRedemptionRecord.setAppUserId(userId);
        prizeRedemptionRecord.setCreateTime(LocalDateTime.now());
@@ -405,19 +467,17 @@
            @ApiImplicitParam(name = "pageCurr", value = "分页参数,当前页码", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量", dataType = "Integer", required = true)
    })
    public R<PageDTO<ExchangeRecordVO>> exchangeRecordList(Integer pageCurr, Integer pageSize) {
    public R<List<ExchangeRecordVO>> exchangeRecordList(Integer pageCurr, Integer pageSize) {
        Long userId = SecurityUtils.getUserId();
        if (userId==0)return R.tokenError("登录失效");
        Page<PrizeRedemptionRecord> page = prizeRedemptionRecordService.lambdaQuery()
                .eq(PrizeRedemptionRecord::getAppUserId, userId)
                .orderByDesc(BaseModel::getCreateTime).page(new Page<>(pageCurr, pageSize));
        if (CollUtils.isEmpty(page.getRecords())){
            PageDTO<ExchangeRecordVO> empty = PageDTO.empty(page);
            return R.ok(empty);
            return R.ok(new ArrayList<ExchangeRecordVO>());
        }
        PageDTO<ExchangeRecordVO> res = PageDTO.of(page, ExchangeRecordVO.class);
        for (ExchangeRecordVO record : res.getList()) {
            Prize temp = prizeService.lambdaQuery()
                    .eq(Prize::getId, record.getId()).one();
@@ -428,7 +488,7 @@
                record.setEnergyValue(temp.getEnergyValue());
            }
        }
        return R.ok(res);
        return R.ok(res.getList());
    }
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserViewingHistoryController.java
@@ -1,11 +1,14 @@
package com.xinquan.user.controller.client;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.core.web.domain.BaseModel;
import com.xinquan.common.security.service.TokenService;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.course.api.domain.OrderCourseVO;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.AppUserTree;
import com.xinquan.system.api.domain.AppUserViewingHistory;
@@ -49,6 +52,27 @@
    private AppUserTreeService appUserTreeService;
    @Resource
    private AppUserService appUserService;
    @PostMapping("/lookHistory")
    @ApiOperation(value = "观看历史")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "state", value = "1冥想 2课程", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageCurr", value = "分页参数,当前页码", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量", dataType = "Integer", required = true)
    })
    public R<PageDTO<OrderCourseVO>> lookHistory(Integer state, Integer pageCurr, Integer pageSize) {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        switch (state){
            case 1:
                break;
            case 2:
                break;
        }
        return R.ok();
    }
    /**
     * 记录用户观看记录
     *
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserWalletRecordController.java
@@ -1,9 +1,33 @@
package com.xinquan.user.controller.client;
import org.springframework.web.bind.annotation.RequestMapping;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.core.web.domain.BaseModel;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.order.api.domain.Order;
import com.xinquan.order.api.feign.RemoteOrderService;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.AppUserWalletRecord;
import com.xinquan.system.api.domain.vo.InviteRankListVO;
import com.xinquan.system.api.domain.vo.OrderDetailVO;
import com.xinquan.system.api.domain.vo.OrderListVO;
import com.xinquan.user.api.domain.dto.UserBalanceDetailDTO;
import com.xinquan.user.service.AppUserService;
import com.xinquan.user.service.AppUserWalletRecordService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
@@ -16,6 +40,172 @@
@RestController
@RequestMapping("/client/app-user-wallet-record")
public class ClientAppUserWalletRecordController {
    @Resource
    private AppUserService appUserService;
    @Resource
    private AppUserWalletRecordService walletRecordService;
    @Resource
    private RemoteOrderService remoteOrderService;
    @PostMapping("/userBalanceList")
    @ApiOperation(value = "用户详情-余额明细",tags = "管理后台-用户管理")
    public R<PageDTO<OrderListVO>> userBalanceList(@RequestBody UserBalanceDetailDTO dto) {
        String startTime = null;
        String endTime = null;
        if (org.springframework.util.StringUtils.hasLength(dto.getTime())){
            String[] split = dto.getTime().split(" - ");
            startTime = split[0]+"00:00:00";
            endTime = split[1]+"23:59:59";
        }
        String userId = dto.getUid();
        LambdaQueryWrapper<AppUserWalletRecord> appUserWalletRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appUserWalletRecordLambdaQueryWrapper.between(startTime!=null,BaseModel::getCreateTime,startTime,endTime);
        appUserWalletRecordLambdaQueryWrapper.eq(AppUserWalletRecord::getAppUserId, userId);
        appUserWalletRecordLambdaQueryWrapper.like(StringUtils.hasLength(dto.getReason()),AppUserWalletRecord::getReason,dto.getReason());
        appUserWalletRecordLambdaQueryWrapper.orderByDesc(BaseModel::getCreateTime);
        Page<AppUserWalletRecord> page = walletRecordService
                .page(new Page<>(dto.getPageCurr(), dto.getPageSize()),appUserWalletRecordLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())){
            PageDTO<OrderListVO> empty = PageDTO.empty(page);
            return R.ok(empty);
        }
        return R.ok(PageDTO.of(page, OrderListVO.class));
    }
    /**
     * 爱心助力榜单-分页
     *
     * @param pageCurr    分页参数,当前页码
     * @param pageSize    分页参数,每页数量
     * @return 课程分页列表
     */
    @PostMapping("/balanceList")
    @ApiOperation(value = "余额明细列表",tags = "钱包")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "state", value = "1全部 2收入 3支出", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "分页参数,当前页码", name = "pageCurr", required = true, dataType = "Integer"),
            @ApiImplicitParam(value = "分页参数,每页数量", name = "pageSize", required = true, dataType = "Integer")
    })
    public R<PageDTO<OrderListVO>> balanceList(Integer state,Integer pageCurr, Integer pageSize) {
        Long userId = SecurityUtils.getUserId();
        if (userId==0)return R.tokenError("登录失效");
        LambdaQueryWrapper<AppUserWalletRecord> appUserWalletRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (state!=1){
            appUserWalletRecordLambdaQueryWrapper.eq(AppUserWalletRecord::getChangeType, state);
        }
        appUserWalletRecordLambdaQueryWrapper.eq(AppUserWalletRecord::getAppUserId, userId);
        appUserWalletRecordLambdaQueryWrapper.orderByDesc(BaseModel::getCreateTime);
        Page<AppUserWalletRecord> page = walletRecordService
                .page(new Page<>(pageCurr, pageSize),appUserWalletRecordLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())){
            PageDTO<OrderListVO> empty = PageDTO.empty(page);
            return R.ok(empty);
        }
        for (AppUserWalletRecord record : page.getRecords()) {
            record.setUid(record.getId()+"");
        }
        return R.ok(PageDTO.of(page, OrderListVO.class));
    }
    @PostMapping("/userBalanceDetail")
    @ApiOperation(value = "用户详情-余额明细-详情",tags = "管理后台-用户管理")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uid", value = "uid", dataType = "Long", required = true),
    })
    public R<OrderDetailVO> userBalanceDetail(String uid) {
        OrderDetailVO orderDetailVO = new OrderDetailVO();
        AppUserWalletRecord byId = walletRecordService.getById(uid);
        if (byId.getOrderId()!=null){
            if (byId.getReason().equals("提现")){
                // 远程查询提现记录
                orderDetailVO.setType("提现");
            }else if (byId.getReason().equals("充值")){
                Order one = remoteOrderService.getOrderById(byId.getOrderId()).getData();
                if (byId.getChildAppUserId() == null && one!=null){
                    if (one.getOrderFrom()!=null){
                        switch (one.getOrderFrom()){
                            case 1:
                                orderDetailVO.setType("购买疗愈");
                                break;
                            case 2:
                                orderDetailVO.setType("购买课程");
                                break;
                            case 3:
                                orderDetailVO.setType("购买会员");
                                break;
                            case 4:
                                orderDetailVO.setType("充值");
                                break;
                        }
                    }
                    orderDetailVO.setRemark(one.getRemark());
                    orderDetailVO.setPaymentTime(one.getPaymentTime());
                    return R.ok(orderDetailVO);
                }else if (byId.getChildAppUserId()!=null && one!=null){
                    orderDetailVO.setType("分佣");
                    orderDetailVO.setPayOrderNo(one.getPayOrderNo());
                    if (one.getCommissionId()!=null){
                        AppUser appUserById = appUserService.getById(one.getCommissionId());
                        orderDetailVO.setUserName(appUserById.getNickname());
                        orderDetailVO.setAvatar(appUserById.getAvatar());
                    }
                    return R.ok(new OrderDetailVO());
                }
            }else if (byId.getReason().equals("分佣收益")){
            }else if (byId.getReason().equals("提现回退")){
        }
        }
        return R.ok();
    }
    @PostMapping("/balanceDetail")
    @ApiOperation(value = "余额明细列表-查看详情",tags = "钱包")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", dataType = "Long", required = true),
    })
    public R<OrderDetailVO> balanceDetail(Long id) {
        Long userId = SecurityUtils.getUserId();
        if (userId==0)return R.tokenError("登录失效");
        OrderDetailVO orderDetailVO = new OrderDetailVO();
        AppUserWalletRecord byId = walletRecordService.getById(id);
        if (byId.getOrderId()!=null){
            if (byId.getReason().equals("提现")){
                // 远程查询提现记录
                orderDetailVO.setType("提现");
            }else{
                Order one = remoteOrderService.getOrderById(byId.getOrderId()).getData();
                if (byId.getChildAppUserId() == null && one!=null){
                    orderDetailVO.setId(id);
                    if (one.getOrderFrom()!=null){
                        switch (one.getOrderFrom()){
                            case 1:
                                orderDetailVO.setType("购买疗愈");
                                break;
                            case 2:
                                orderDetailVO.setType("购买课程");
                                break;
                            case 3:
                                orderDetailVO.setType("购买会员");
                                break;
                            case 4:
                                orderDetailVO.setType("充值");
                                break;
                        }
                    }
                    orderDetailVO.setRemark(one.getRemark());
                    orderDetailVO.setPaymentTime(one.getPaymentTime());
                    return R.ok(orderDetailVO);
                }else if (byId.getChildAppUserId()!=null && one!=null){
                    orderDetailVO.setType("分佣");
                    orderDetailVO.setPayOrderNo(one.getPayOrderNo());
                    if (one.getCommissionId()!=null){
                        AppUser appUserById = appUserService.getById(one.getCommissionId());
                        orderDetailVO.setUserName(appUserById.getNickname());
                        orderDetailVO.setAvatar(appUserById.getAvatar());
                    }
                    return R.ok(new OrderDetailVO());
                }
            }
        }
        return R.ok();
    }
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserWithdrawController.java
@@ -1,9 +1,32 @@
package com.xinquan.user.controller.client;
import com.alibaba.fastjson2.util.UUIDUtils;
import com.alibaba.nacos.common.utils.UuidUtils;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.datascope.annotation.DataScope;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.AppUserBank;
import com.xinquan.system.api.domain.AppUserWithdraw;
import com.xinquan.system.api.domain.vo.UpdateAppUserDTO;
import com.xinquan.system.api.domain.vo.WalletVO;
import com.xinquan.user.service.AppUserBankService;
import com.xinquan.user.service.AppUserService;
import com.xinquan.user.service.AppUserWithdrawService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
/**
 * <p>
@@ -16,6 +39,61 @@
@RestController
@RequestMapping("/client/app-user-withdraw")
public class ClientAppUserWithdrawController {
    @Resource
    private AppUserService appUserService;
    @Resource
    private AppUserWithdrawService withdrawService;
    @Resource
    private AppUserBankService appUserBankService;
    @PostMapping("/withdraw")
    @ApiOperation(value = "提现", tags = {"钱包"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "bankId", value = "银行卡id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "money", value = "提现金额", dataType = "String", required = true)
    })
    public R withdraw(Long bankId,String money) {
        Long userId = SecurityUtils.getUserId();
        if (userId==0)return R.tokenError("登录失效");
        BigDecimal bigDecimal = new BigDecimal(money);
        AppUserWithdraw appUserWithdraw = new AppUserWithdraw();
        appUserWithdraw.setAppUserId(userId);
        appUserWithdraw.setBankId(bankId);
        appUserWithdraw.setAmount(bigDecimal);
        appUserWithdraw.setWithdrawType(1);
        appUserWithdraw.setWithdrawStatus(0);
        // todo 提现流水号
        appUserWithdraw.setSerialNo(UuidUtils.generateUuid());
        appUserWithdraw.setWithdrawTime(LocalDateTime.now());
        appUserWithdraw.setCreateTime(LocalDateTime.now());
        withdrawService.save(appUserWithdraw);
        return R.ok();
    }
    @PostMapping("/addBank")
    @ApiOperation(value = "提现-添加银行卡", tags = {"钱包"})
    public R wallet(@RequestBody AppUserBank appUserWithdraw) {
        Long userId = SecurityUtils.getUserId();
        if (userId==0)return R.tokenError("登录失效");
        appUserWithdraw.setAppUserId(userId);
        appUserBankService.save(appUserWithdraw);
        return R.ok();
    }
    @PostMapping("/deleteBank")
    @ApiOperation(value = "提现-删除银行卡", tags = {"钱包"})
    public R deleteBank(Long id) {
        Long userId = SecurityUtils.getUserId();
        if (userId==0)return R.tokenError("登录失效");
        appUserBankService.removeById(id);
        return R.ok();
    }
    @PostMapping("/bankList")
    @ApiOperation(value = "提现-获取银行卡列表", tags = {"钱包"})
    public R<List<AppUserBank>> bankList() {
        Long userId = SecurityUtils.getUserId();
        if (userId==0)return R.tokenError("登录失效");
        List<AppUserBank> list = appUserBankService.lambdaQuery()
                .eq(AppUserBank::getAppUserId, userId).list();
        return R.ok(list);
    }
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientNoticeRecordController.java
@@ -1,8 +1,29 @@
package com.xinquan.user.controller.client;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.BeanUtils;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.core.web.domain.BaseModel;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.meditation.api.feign.RemoteMeditationService;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.NoticeRecord;
import com.xinquan.meditation.api.domain.vo.NoticeDetailVO;
import com.xinquan.user.service.AppUserService;
import com.xinquan.user.service.NoticeRecordService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.time.format.DateTimeFormatter;
/**
 * <p>
@@ -16,5 +37,77 @@
@RequestMapping("/client/user/notice-record")
public class ClientNoticeRecordController {
    @Resource
    private NoticeRecordService noticeRecordService;
    @Resource
    private AppUserService appUserService;
    @Resource
    private RemoteMeditationService remoteMeditationService;
    @PostMapping("/noticeList")
    @ApiOperation(value = "系统消息列表",tags = "系统消息")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "分页参数,当前页码", name = "pageCurr", required = true, dataType = "Integer"),
            @ApiImplicitParam(value = "分页参数,每页数量", name = "pageSize", required = true, dataType = "Integer")
    })
    public R<PageDTO<NoticeRecord>> noticeList(Integer pageCurr, Integer pageSize) {
        Long userId = SecurityUtils.getUserId();
        if (userId==0)return R.tokenError("登录失效");
        Page<NoticeRecord> page = noticeRecordService.lambdaQuery()
                .eq(NoticeRecord::getAppUserId, userId)
                .orderByDesc(BaseModel::getCreateTime)
                .page(new Page<>(pageCurr, pageSize));
        if (CollUtils.isEmpty(page.getRecords())){
            PageDTO<NoticeRecord> empty = PageDTO.empty(page);
            return R.ok(empty);
        }
        PageDTO<NoticeRecord> noticeRecordPageDTO = PageDTO.of(page, NoticeRecord.class);
        for (NoticeRecord noticeRecord : noticeRecordPageDTO.getList()) {
            noticeRecord.setTime(noticeRecord.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        }
        return R.ok(noticeRecordPageDTO);
    }
    @PostMapping("/noticeDetail")
    @ApiOperation(value = "系统消息列表-查看详情",tags = "系统消息")
    public R<NoticeDetailVO> wallet(Long id) {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        NoticeRecord noticeRecord = noticeRecordService.getById(id);
        // 设置为已读
        noticeRecord.setReadStatus(2);
        noticeRecordService.updateById(noticeRecord);
        NoticeDetailVO noticeDetailVO = new NoticeDetailVO();
        BeanUtils.copyProperties(noticeRecord,noticeDetailVO);
        if (noticeRecord!=null && noticeRecord.getMeditationQuestionId()!=null){
            // 远程调用 根据冥想提问id 查询数据
            noticeDetailVO.setMeditationQuestionId(noticeRecord.getMeditationQuestionId());
//            NoticeDetailVO data = remoteMeditationService.noticeDetail(noticeDetailVO).getData();
            AppUser byId = appUserService.getById(userId);
            noticeDetailVO.setNickname(byId.getNickname());
            noticeDetailVO.setAvatar(byId.getAvatar());
            noticeDetailVO.setRealname(byId.getRealname());
        }
        return R.ok(noticeDetailVO);
    }
    @PostMapping("/queryNotice")
    @ApiOperation(value = "是否有未读消息 true是 false否",tags = "系统消息")
    public R<Boolean> queryNotice() {
        Long userId = SecurityUtils.getUserId();
        if (userId == 0)return R.tokenError("登录失效");
        int size = noticeRecordService.lambdaQuery()
                .eq(NoticeRecord::getAppUserId, userId)
                .eq(NoticeRecord::getReadStatus, 1).list().size();
        if (size>0)return R.ok(true);
        return R.ok(false);
    }
    /**
     * 后台远程调用 新增回复消息
     * @return
     */
    @PostMapping("/addNoticeReplay")
    public R addNoticeReplay(@RequestBody NoticeRecord noticeRecord) {
        noticeRecordService.save(noticeRecord);
        return R.ok();
    }
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientPrizeController.java
@@ -1,9 +1,27 @@
package com.xinquan.user.controller.client;
import org.springframework.web.bind.annotation.RequestMapping;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.system.api.domain.MeditationQuestion;
import com.xinquan.system.api.domain.Prize;
import com.xinquan.system.api.domain.PrizeRedemptionRecord;
import com.xinquan.user.service.PrizeRedemptionRecordService;
import com.xinquan.user.service.PrizeService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
/**
 * <p>
@@ -16,6 +34,68 @@
@RestController
@RequestMapping("/client/prize")
public class ClientPrizeController {
    @Autowired
    private PrizeService prizeService;
    @Autowired
    private PrizeRedemptionRecordService prizeRedemptionRecordService;
    @PostMapping("/prizeManagementList")
    @ApiOperation(value = "奖品列表-分页", tags = {"管理后台-奖品管理"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageCurr", value = "分页参数,当前页码", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量", dataType = "Integer", required = true)
    })
    public R<PageDTO<Prize>> prizeManagementList(@RequestParam(value = "pageCurr")Integer pageCurr,
                                                              @RequestParam(value = "pageSize")Integer pageSize) {
        LambdaQueryWrapper<Prize> meditationLambdaQueryWrapper = new LambdaQueryWrapper<>();
        meditationLambdaQueryWrapper.orderByDesc(Prize::getSortNum);
        Page<Prize> page = prizeService.page(new Page<>(pageCurr, pageSize), meditationLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())) {
            return R.ok(PageDTO.empty(page));
        }
        for (Prize record : page.getRecords()) {
            record.setUid(record.getId()+"");
            long count = prizeRedemptionRecordService.count(new LambdaQueryWrapper<PrizeRedemptionRecord>()
                    .eq(PrizeRedemptionRecord::getPrizeId, record.getId()));
            record.setReceiveCount(count);
        }
        return R.ok(PageDTO.of(page, Prize.class));
    }
    @PostMapping("/addPrize")
    @ApiOperation(value = "新增奖品管理", notes = "管理后台-奖品管理")
    public R addPrize(@RequestBody Prize homeBackgroundMusic) {
        homeBackgroundMusic.setCreateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setCreateTime(LocalDateTime.now());
        return R.ok(prizeService.save(homeBackgroundMusic));
    }
    @GetMapping("/detailPrize")
    @ApiOperation(value = "查看详情奖品管理", notes = "管理后台-奖品管理")
    public R<Prize> detailPrize(String uid) {
        return R.ok(prizeService.getById(uid));
    }
    @GetMapping("/updateState")
    @ApiOperation(value = "修改奖品管理上下架状态", notes = "管理后台-奖品管理")
    public R updateState(String uid) {
        Prize byId = prizeService.getById(uid);
        if (byId.getStatus() == 1){
            byId.setStatus(2);
        }else {
            byId.setStatus(1);
        }
        return R.ok();
    }
    @PostMapping("/updatePrize")
    @ApiOperation(value = "修改奖品管理", notes = "管理后台-奖品管理")
    public R updatePrize(@RequestBody Prize homeBackgroundMusic) {
        homeBackgroundMusic.setUpdateBy(SecurityUtils.getUsername());
        homeBackgroundMusic.setUpdateTime(LocalDateTime.now());
        return R.ok(prizeService.updateById(homeBackgroundMusic));
    }
    @PostMapping("/deletePrize")
    @ApiOperation(value = "批量删除", notes = "管理后台-奖品管理")
    public R deletePrize(String ids) {
        return R.ok(prizeService.removeBatchByIds(Arrays.asList(ids.split(","))));
    }
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientPrizeRedemptionRecordController.java
@@ -1,9 +1,34 @@
package com.xinquan.user.controller.client;
import org.springframework.web.bind.annotation.RequestMapping;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import org.springframework.web.bind.annotation.RestController;
import com.xinquan.meditation.api.feign.RemoteMeditationService;
import com.xinquan.system.api.RemoteUserService;
import com.xinquan.system.api.domain.AppUser;
import com.xinquan.system.api.domain.Prize;
import com.xinquan.system.api.domain.PrizeRedemptionRecord;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.user.api.domain.dto.PrizeRecordDTO;
import com.xinquan.user.service.AppUserService;
import com.xinquan.user.service.PrizeRedemptionRecordService;
import com.xinquan.user.service.PrizeService;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
 * <p>
@@ -16,6 +41,109 @@
@RestController
@RequestMapping("/client/prize-redemption-record")
public class ClientPrizeRedemptionRecordController {
    @Resource
    private PrizeService prizeService;
    @Resource
    private PrizeRedemptionRecordService prizeRedemptionRecordService;
    @Resource
    private AppUserService appUserService;
    @Resource
    private RemoteUserService remoteUserService;
    @PostMapping("/prizeRedemptionRecordList")
    @ApiOperation(value = "兑换记录管理列表-分页", tags = {"管理后台-兑换记录管理"})
    public R<PageDTO<PrizeRedemptionRecord>> prizeRedemptionRecordList(@RequestBody PrizeRecordDTO courseDTO) {
        String startTime = null;
        String endTime = null;
        if (org.springframework.util.StringUtils.hasLength(courseDTO.getTime())){
            String[] split = courseDTO.getTime().split(" - ");
            startTime = split[0]+"00:00:00";
            endTime = split[1]+"23:59:59";
        }
        List<Long> longs = new ArrayList<>();
        LambdaQueryWrapper<PrizeRedemptionRecord> courseLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseLambdaQueryWrapper.between(PrizeRedemptionRecord::getCreateTime, startTime, endTime);
        courseLambdaQueryWrapper.eq(courseDTO.getStatus()!=null,PrizeRedemptionRecord::getStatus, courseDTO.getStatus());
        courseLambdaQueryWrapper.orderByDesc(PrizeRedemptionRecord::getCreateTime);
        if (org.springframework.util.StringUtils.hasLength(courseDTO.getUserNameOrPhone())){
            List<Long> collect = appUserService.lambdaQuery().like(AppUser::getNickname, courseDTO.getUserNameOrPhone()).list()
                    .stream().map(AppUser::getId).collect(Collectors.toList());
            longs.addAll(collect);
            List<Long> collect1 = appUserService.lambdaQuery().like(AppUser::getCellPhone, courseDTO.getUserNameOrPhone()).list()
                    .stream().map(AppUser::getId).collect(Collectors.toList());
            longs.addAll(collect1);
            if (longs.isEmpty()){
                longs.add(-1L);
            }
            courseLambdaQueryWrapper.in(PrizeRedemptionRecord::getAppUserId, longs);
        }
        if (org.springframework.util.StringUtils.hasLength(courseDTO.getName())){
            List<Long> collect = prizeService.lambdaQuery().like(Prize::getName, courseDTO.getName()).list()
                    .stream().map(Prize::getId).collect(Collectors.toList());
            if (collect.isEmpty()){
                collect.add(-1L);
            }
            courseLambdaQueryWrapper.in(PrizeRedemptionRecord::getPrizeId, collect);
        }
        Page<PrizeRedemptionRecord> page = prizeRedemptionRecordService.page(new Page<>(courseDTO.getPageCurr(), courseDTO.getPageSize()), courseLambdaQueryWrapper);
        if (CollUtils.isEmpty(page.getRecords())) {
            return R.ok(PageDTO.empty(page));
        }
        for (PrizeRedemptionRecord record : page.getRecords()) {
            Prize byId = prizeService.getById(record.getPrizeId());
            if (Objects.nonNull(byId)){
                record.setName(byId.getName());
                record.setWorth(byId.getWorth());
                record.setEnergyValue(byId.getEnergyValue());
            }
            record.setUid(record.getId().toString());
            AppUser byId1 = appUserService.getById(record.getAppUserId());
            if (Objects.nonNull(byId1)){
                record.setUserName(byId1.getNickname());
                record.setAvatar(byId1.getAvatar());
                record.setCellPhone(byId1.getCellPhone());
            }
        }
        return R.ok(PageDTO.of(page, PrizeRedemptionRecord.class));
    }
    @GetMapping("/detailPrizeRedemptionRecord")
    @ApiOperation(value = "查看详情兑换记录管理", notes = "管理后台-兑换记录管理")
    public R<PrizeRedemptionRecord> detailPrizeRedemptionRecord(String uid) {
        PrizeRedemptionRecord byId = prizeRedemptionRecordService.getById(uid);
        Prize byId1 = prizeService.getById(byId.getPrizeId());
        if (Objects.nonNull(byId1)){
            byId.setName(byId1.getName());
            byId.setWorth(byId1.getWorth());
            byId.setEnergyValue(byId1.getEnergyValue());
        }
        byId.setUid(byId.getId().toString());
        AppUser byId2 = appUserService.getById(byId.getAppUserId());
        if (Objects.nonNull(byId2)){
            byId.setUserName(byId2.getNickname());
            byId.setAvatar(byId2.getAvatar());
            byId.setCellPhone(byId2.getCellPhone());
        }
        return R.ok();
    }
    @GetMapping("/confirm")
    @ApiOperation(value = "确认兑换", notes = "管理后台-兑换记录管理")
    public R updateState(String uid,String code) {
        PrizeRedemptionRecord byId = prizeRedemptionRecordService.getById(uid);
        if (!byId.getCode().equals(code)){
            return R.fail("兑换码错误");
        }else{
            byId.setStatus(2);
            byId.setUpdateTime(LocalDateTime.now());
            SysUser data = remoteUserService.getSysUserById(SecurityUtils.getUserId() + "").getData();
            byId.setUpdateBy(SecurityUtils.getUsername()+data.getNickName()+"("+data.getUserName()+")");
            prizeRedemptionRecordService.updateById(byId);
        }
        return R.ok();
    }
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientTagController.java
@@ -2,18 +2,17 @@
import com.xinquan.common.core.domain.R;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.system.api.domain.Tag;
import com.xinquan.user.domain.dto.UserAnswerDTO;
import com.xinquan.user.service.TagService;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
/**
@@ -36,5 +35,17 @@
        return R.ok(list);
    }
    @PostMapping("/tagList")
    @ApiOperation(value = "标签列表", tags = {"管理后台-标签列表"})
    public R<List<Tag>> tagList() {
        List<Tag> list = tagService.lambdaQuery().list();
        return R.ok(list);
    }
    // 远程调用查询tag列表
    @PostMapping("/queryTag/{name}")
    public R<List<Tag>> queryTag(@PathVariable("name") String name) {
        List<Tag> list = tagService.lambdaQuery().like(Tag::getTagName, name).list();
        return R.ok(list);
    }
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/MailConst.java
New file
@@ -0,0 +1,12 @@
package com.xinquan.user.domain;
public class MailConst {
    //发送邮件的邮箱-- 替换成你的邮箱
    public static final String USER_NAME = "13281306557@163.com";
    //授权密码 -- 替换成你的 PWD_CODE
    public static final String  PWD_CODE = "NUSdxDQqadYvVek2";
    // 替换一下 smtp.yeah.net / smtp.163.com 跟你的发送邮件相关
    public static final String MAIL_HOST = "smtp.163.com";
    public static final String MAIL_SMTP_AUTH = "true";
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/vo/ExchangeRecordVO.java
@@ -1,11 +1,14 @@
package com.xinquan.user.domain.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * @author mitao
@@ -29,6 +32,16 @@
    private Integer energyValue;
    @ApiModelProperty(value = "1待领取 2已领取")
    private Integer status;
    @ApiModelProperty(value = "兑换码")
    private String code;
    @ApiModelProperty(value = "兑换时间")
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private LocalDateTime createTime;
    @ApiModelProperty(value = "操作时间")
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "操作人")
    private String updateBy;
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserServiceImpl.java
@@ -37,11 +37,9 @@
import com.xinquan.user.service.AppUserTreeService;
import com.xinquan.user.service.TagService;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -82,6 +80,10 @@
                .ne(AppUser::getUserStatus, AppUserStatusEnum.LOGOUT.getCode()).oneOpt();
    }
    public static void main(String[] args) {
        String randomCode = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
        System.err.println(randomCode);
    }
    /**
     * app用户注册
     * @param appUserDTO
@@ -90,6 +92,11 @@
    @Override
    public AppUser registerAppUser(AppUserDTO appUserDTO) {
        AppUser appUser = BeanUtils.copyBean(appUserDTO, AppUser.class);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = simpleDateFormat.format(new Date());
        // 生成四位随机数字
        String randomCode = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
        appUser.setCode("YH"+format+randomCode);
        this.save(appUser);
        return appUser;
    }
@@ -130,6 +137,11 @@
            SysUser sysUserRes = registerResult.getData();
            appUser = new AppUser();
            appUser.setUserId(sysUserRes.getUserId());
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            String format = simpleDateFormat.format(new Date());
            // 生成四位随机数字
            String randomCode = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
            appUser.setCode("YH"+format+randomCode);
            appUser.setWxOpenId(body.getWxOpenId());
            appUser.setNickname(body.getNickname());
            appUser.setAvatar(body.getHeadImgUrl());
@@ -193,6 +205,11 @@
            appUser.setTotalEnergyValue(0);
            appUser.setRegisterTime(LocalDateTime.now());
            appUser.setLevelSettingId(TreeLevelEnum.SEED.getCode());
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            String format = simpleDateFormat.format(new Date());
            // 生成四位随机数字
            String randomCode = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
            appUser.setCode("YH"+format+randomCode);
            this.save(appUser);
            // 初始化用户树苗
            initUserTree(appUser.getId());
@@ -254,6 +271,11 @@
            appUser.setTotalEnergyValue(0);
            appUser.setRegisterTime(LocalDateTime.now());
            appUser.setLevelSettingId(TreeLevelEnum.SEED.getCode());
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            String format = simpleDateFormat.format(new Date());
            // 生成四位随机数字
            String randomCode = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
            appUser.setCode("YH"+format+randomCode);
            this.save(appUser);
            // 初始化用户树苗
            initUserTree(appUser.getId());
@@ -304,6 +326,8 @@
            } else {
                appUser.setAppleId(wxOrAppleId);
            }
            appUser.setEmail(body.getEmail());
            appUser.setNickname(body.getName());
            // 查询系统用户
            sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData();
            if (Objects.isNull(sysUser)) {
@@ -321,6 +345,8 @@
            }
            appUser = userOptional.get();
            appUser.setCellPhone(body.getCellPhone());
            appUser.setEmail(body.getEmail());
            appUser.setNickname(body.getName());
            // 更新系统用户
            sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData();
            if (Objects.isNull(sysUser)) {
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/utils/MailUtils.java
New file
@@ -0,0 +1,122 @@
package com.xinquan.user.utils;
import com.xinquan.user.domain.MailConst;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.ArrayList;
import java.util.Properties;
public class MailUtils {
    //建立服务器的邮件连接,从而可以进行发送邮件
    public static Session getMailSession(){
        //0.1 确定连接位置
        Properties properties = new Properties();
        //获取163邮箱smtp服务器的地址,
        properties.setProperty("mail.host", MailConst.MAIL_HOST);
        //是否进行权限验证。
        properties.setProperty("mail.smtp.auth", MailConst.MAIL_SMTP_AUTH);
        //0.2确定权限(账号和密码)
        Authenticator authenticator = new Authenticator() {
            @Override
            public PasswordAuthentication getPasswordAuthentication() {
                //填写自己的163邮箱的登录帐号和授权密码(不是登录密码)。
                return new PasswordAuthentication(MailConst.USER_NAME,MailConst.PWD_CODE);
            }
        };
        //1 获得连接
        /**
         * properties:包含配置信息的对象,Properties类型
         *         配置邮箱服务器地址、配置是否进行权限验证(帐号密码验证)等
         *
         * authenticator:确定权限(帐号和密码)
         *
         * 所以就要在上面构建这两个对象。
         */
        Session session = Session.getDefaultInstance(properties, authenticator);
        return session;
    }
    /**
     *  指定一个人发送邮件,单个发送
     * @Param toEmailAddress  单个接受邮件的邮箱地址
     * @Param title 主题
     * @Param content  内容
     **/
    public static void sendMailTOSingleUser(String toEmailAddress,String title, String content){
        //获得邮箱服务器的连接
        Session session = getMailSession();
        //2 创建消息
        Message message = new MimeMessage(session);
        // 2.1 发件人 我们自己的邮箱地址,就是名称
        try {
            message.setFrom(new InternetAddress(MailConst.USER_NAME));
            /**
             * 2.2 收件人
             *         第一个参数:
             *             RecipientType.TO    代表收件人
             *             RecipientType.CC    抄送
             *             RecipientType.BCC    暗送
             *         比如A要给B发邮件,但是A觉得有必要给要让C也看看其内容,就在给B发邮件时,
             *         将邮件内容抄送给C,那么C也能看到其内容了,但是B也能知道A给C抄送过该封邮件
             *         而如果是暗送(密送)给C的话,那么B就不知道A给C发送过该封邮件。
             *     第二个参数
             *         收件人的地址,或者是一个Address[],用来装抄送或者暗送人的名单。或者用来群发。可以是相同邮箱服务器的,也可以是不同的
             *         这里我们发送给我们的qq邮箱
             */
            message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(toEmailAddress));
            //设置抄送人,这里设置自己的是抄送人,免得被网易邮箱列为垃圾邮件
            message.setRecipient(Message.RecipientType.CC, new InternetAddress( MailConst.USER_NAME ));
            // 2.3 主题(标题)
            message.setSubject(title);
            //设置编码,防止发送的内容中文乱码。
            message.setContent(content, "text/html;charset=UTF-8");
            //3发送消息
            Transport.send(message);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
    /**
     * 群发邮件,也可以只发一个人。可设置主题和邮件内容,无附件
     * @Param toEmailAddressArray 接受邮件的所有邮箱地址
     * @Param title 主题
     * @Param content  内容
     **/
    public static void sendMailToUserArray(ArrayList<String> toEmailAddressArrayList , String title, String content) {
        String[] toEmailAddressArray = (String[]) toEmailAddressArrayList.toArray(new String[0]);
        //获得邮箱服务器的连接
        Session session = getMailSession();
        //2 创建消息
        Message message = new MimeMessage(session);
        // 2.1 发件人 我们自己的邮箱地址,就是名称
        try {
            message.setFrom(new InternetAddress(MailConst.USER_NAME));
            if (toEmailAddressArray != null) {
                // 为每个邮件接收者创建一个地址
                Address[] toEmailRecipients = null;
                toEmailRecipients = new InternetAddress[toEmailAddressArray.length];
                for (int i = 0; i < toEmailAddressArray.length; i++) {
                    toEmailRecipients[i] = new InternetAddress(toEmailAddressArray[i]);
                }
                message.setRecipients(MimeMessage.RecipientType.TO, toEmailRecipients);
            }
            //设置抄送人,这里设置自己的是抄送人,免得被网易邮箱列为垃圾邮件
            message.setRecipient(Message.RecipientType.CC, new InternetAddress( MailConst.USER_NAME ));
            // 2.3 主题(标题)
            message.setSubject(title);
            //设置编码,防止发送的内容中文乱码。
            message.setContent(content, "text/html;charset=UTF-8");
            //3发送消息
            Transport.send(message);
        } catch (MessagingException ex) {
            ex.printStackTrace();
        }
    }
}