基于mall4j产品的二开项目后端
lee
2024-12-19 31c663b67dbc2c3a3025c88405eec3f62fa71edd
init
237 files added
19385 ■■■■■ changed files
yami-shop-distribution/pom.xml 26 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/pom.xml 30 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/config/SwaggerConfiguration.java 34 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionBasicController.java 40 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionBindUserController.java 89 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionMsgController.java 56 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionProdController.java 79 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionQrCodeController.java 131 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionRecruitSetController.java 49 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionRegisterController.java 249 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionUserController.java 117 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionUserIncomeController.java 94 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionUserWalletController.java 74 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionWithdrawCashController.java 142 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/linstener/UpdateDistributionUserListener.java 50 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/param/DistributionUserParam.java 45 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/param/DistributionWithdrawCashParam.java 37 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/param/DistributionWithdrawCashSaceParam.java 28 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/pom.xml 22 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/BasicSetDistributionSwitchEnum.java 41 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/BindEnum.java 32 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DUserType.java 24 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DistributionAudit.java 35 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DistributionBindAttributionEnum.java 37 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DistributionProdStateEnum.java 45 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DistributionUserIncomeStateEnum.java 44 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DistributionUserIncomeTypeEnum.java 47 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DistributionUserStateEnum.java 46 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DistributionWithdrawCashStateEnum.java 41 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionAuditingMapper.java 37 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionMsgMapper.java 45 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionProdBindMapper.java 30 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionProdMapper.java 81 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionUserBanMapper.java 31 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionUserBindMapper.java 96 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionUserGroupMapper.java 37 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionUserIncomeMapper.java 156 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionUserMapper.java 131 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionUserWalletBillMapper.java 52 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionUserWalletMapper.java 72 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionWithdrawCashMapper.java 63 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/AchievementDataDto.java 43 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/BindUserInfoDto.java 48 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionAuditingDto.java 148 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionConfigDTO.java 86 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionLevelDto.java 40 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionMsgDto.java 80 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionOrderDto.java 44 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionOrderItemDto.java 39 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionProdDto.java 44 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionRecruitConfigDTO.java 41 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionRecruitSetDto.java 36 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionSettlementDto.java 36 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserAchievementDataDto.java 77 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserDto.java 53 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserIncomeDto.java 36 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserIncomeOrderDto.java 44 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserOrderItemDTO.java 19 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserSimpleDto.java 39 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserWalletBillDto.java 53 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserWalletDto.java 47 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionWithdrawCashDto.java 83 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionWithdrawCashSetDto.java 56 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/StatisticsDisUserIncomeDto.java 26 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/listener/CategoryDistributionListener.java 34 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/listener/OpenShopInitListener.java 50 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/listener/OrderSettlementListener.java 55 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/listener/PaySuccessOrderListener.java 583 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/listener/ProdChangeListener.java 117 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/listener/ShopChangeStatusListener.java 52 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionAuditing.java 76 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionMsg.java 75 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionProd.java 73 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionProdBind.java 50 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionProdLog.java 64 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionUser.java 119 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionUserBan.java 67 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionUserBind.java 69 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionUserGroup.java 48 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionUserIncome.java 95 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionUserWallet.java 60 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionUserWalletBill.java 122 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionWithdrawCash.java 80 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/param/AuditWithdrawCashParam.java 34 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/param/RangeTimeParam.java 54 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/param/UpdateDistributionUserParam.java 33 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/po/DistributionProdPO.java 79 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionAuditingService.java 43 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionBindUserService.java 49 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionMsgService.java 47 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionProdBindService.java 24 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionProdService.java 129 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionUserBanService.java 33 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionUserBindService.java 36 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionUserGroupService.java 32 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionUserIncomeService.java 89 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionUserService.java 135 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionUserWalletBillService.java 43 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionUserWalletService.java 55 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionWithdrawCashService.java 79 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionAuditingServiceImpl.java 128 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionBindUserServiceImpl.java 157 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionMsgServiceImpl.java 47 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionProdBindServiceImpl.java 34 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionProdServiceImpl.java 231 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionUserBanServiceImpl.java 57 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionUserBindServiceImpl.java 68 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionUserGroupServiceImpl.java 36 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionUserIncomeServiceImpl.java 221 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionUserServiceImpl.java 360 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionUserWalletBillServiceImpl.java 71 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionUserWalletServiceImpl.java 146 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionWithdrawCashServiceImpl.java 235 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionAmountAndWalletVO.java 40 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionAuditingConditionsVO.java 58 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionAuditingInfoVO.java 42 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionAwardDataVO.java 36 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionBindSceneVO.java 38 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionBindSetRobVO.java 33 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionConfigVO.java 76 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionLevelConditionDataVO.java 94 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionLevelConditionsSwitchVO.java 77 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionLevelVO.java 31 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionOrdersVO.java 55 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionRecruitConfigVO.java 37 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionUserIncomeVO.java 38 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionUserInfoVO.java 44 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionUserVO.java 44 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionAuditingMapper.xml 124 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionMsgMapper.xml 100 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionProdBindMapper.xml 28 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionProdMapper.xml 216 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionUserBanMapper.xml 78 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionUserBindMapper.xml 156 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionUserGroupMapper.xml 49 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionUserIncomeMapper.xml 310 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionUserMapper.xml 413 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionUserWalletBillMapper.xml 99 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionUserWalletMapper.xml 94 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionWithdrawCashMapper.xml 165 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-multishop/pom.xml 30 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-multishop/src/main/java/com/yami/shop/distribution/multishop/config/SwaggerConfiguration.java 35 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-multishop/src/main/java/com/yami/shop/distribution/multishop/controller/DistributionProdController.java 376 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-multishop/src/main/java/com/yami/shop/distribution/multishop/listener/OrderRefundListener.java 117 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/pom.xml 30 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/config/SwaggerConfiguration.java 34 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionAuditingController.java 88 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionConfigController.java 111 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionMsgController.java 89 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionProdBindController.java 75 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionProdController.java 193 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionUserBanController.java 91 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionUserBindController.java 91 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionUserController.java 149 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionUserGroupController.java 90 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionUserIncomeController.java 99 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionUserWalletBillController.java 82 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionUserWalletController.java 90 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionWithdrawCashController.java 124 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/listener/EnterprisePayListener.java 84 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/pom.xml 26 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-api/pom.xml 36 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-api/src/main/java/com/yami/shop/groupbuy/api/config/SwaggerConfiguration.java 34 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-api/src/main/java/com/yami/shop/groupbuy/api/controller/GroupController.java 51 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-api/src/main/java/com/yami/shop/groupbuy/api/controller/GroupOrderController.java 259 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-api/src/main/java/com/yami/shop/groupbuy/api/controller/GroupTeamController.java 139 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-api/src/main/java/com/yami/shop/groupbuy/api/listener/CheckGroupOrderListener.java 52 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-api/src/main/java/com/yami/shop/groupbuy/api/listener/LoadProdActivistListener.java 103 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/pom.xml 22 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupActivityDto.java 99 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupOrderSubmitResultDto.java 24 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupProdDto.java 83 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupSkuDto.java 51 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupSkuInfoDto.java 94 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupTeamDto.java 70 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupUserDto.java 47 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupUserOrderDto.java 100 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiJoinGroupTeamDto.java 31 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/param/ApiGroupOrderSubmitParam.java 28 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/param/GroupOrderParam.java 35 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/vo/ApiGroupTeamInfoVo.java 44 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/bo/GroupOrderBO.java 67 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dao/GroupActivityMapper.java 115 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dao/GroupOrderMapper.java 77 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dao/GroupSkuMapper.java 61 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dao/GroupTeamMapper.java 120 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dto/GroupActivityDto.java 64 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dto/GroupOrderDTO.java 59 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dto/GroupProdAndSkuListDto.java 58 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dto/GroupProdDto.java 102 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dto/GroupRefundOrder.java 44 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dto/GroupTeamDto.java 66 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dto/GroupUserActivityDto.java 32 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/enums/ActivityStatusEnum.java 66 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/enums/GroupActivityStatusEnum.java 70 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/enums/GroupOrderStatusEnum.java 42 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/enums/GroupProdStatusEnum.java 51 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/enums/TeamStatusEnum.java 47 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/CancelOrderListener.java 52 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/CategoryGroupbuyListener.java 34 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/EsProductActivityInfoListener.java 73 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/EsProductListener.java 123 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/InvalidGroupProdListener.java 56 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/PaySuccessOrderListener.java 52 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/ProcessActivityProdPriceListener.java 67 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/ProdChangeListener.java 70 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/ShopChangeStatusListener.java 42 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/model/GroupActivity.java 107 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/model/GroupOrder.java 62 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/model/GroupSku.java 61 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/model/GroupTeam.java 76 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/param/GroupProdParam.java 30 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/GroupActivityService.java 138 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/GroupOrderService.java 98 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/GroupPayService.java 27 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/GroupSkuService.java 34 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/GroupTeamService.java 105 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/impl/GroupActivityServiceImpl.java 350 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/impl/GroupOrderServiceImpl.java 159 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/impl/GroupPayServiceImpl.java 152 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/impl/GroupSkuServiceImpl.java 46 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/impl/GroupTeamServiceImpl.java 344 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/utils/GroupActivityUtil.java 51 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/resources/mapper/GroupActivityMapper.xml 130 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/resources/mapper/GroupOrderMapper.xml 67 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/resources/mapper/GroupSkuMapper.xml 74 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/resources/mapper/GroupTeamMapper.xml 184 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-multishop/pom.xml 29 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-multishop/src/main/java/com/yami/shop/groupbuy/multishop/config/SwaggerConfiguration.java 35 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-multishop/src/main/java/com/yami/shop/groupbuy/multishop/controller/GroupActivityController.java 246 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-multishop/src/main/java/com/yami/shop/groupbuy/multishop/controller/GroupOrderController.java 78 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-multishop/src/main/java/com/yami/shop/groupbuy/multishop/controller/GroupSkuController.java 71 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-multishop/src/main/java/com/yami/shop/groupbuy/multishop/controller/GroupTeamController.java 58 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-platform/pom.xml 29 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-platform/src/main/java/com/yami/shop/groupbuy/platform/config/SwaggerConfiguration.java 34 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-platform/src/main/java/com/yami/shop/groupbuy/platform/controller/GroupActivityController.java 143 ●●●●● patch | view | raw | blame | history
yami-shop-groupbuy/yami-shop-groupbuy-platform/src/main/java/com/yami/shop/groupbuy/platform/task/GroupBuyTask.java 69 ●●●●● patch | view | raw | blame | history
yami-shop-distribution/pom.xml
New file
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>yami-shop</artifactId>
        <groupId>com.yami.shop</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>yami-shop-distribution</artifactId>
    <description>商城分销模块</description>
    <packaging>pom</packaging>
    <modules>
        <module>yami-shop-distribution-api</module>
        <module>yami-shop-distribution-common</module>
        <module>yami-shop-distribution-multishop</module>
        <module>yami-shop-distribution-platform</module>
    </modules>
</project>
yami-shop-distribution/yami-shop-distribution-api/pom.xml
New file
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.yami.shop</groupId>
        <artifactId>yami-shop-distribution</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>yami-shop-distribution-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <modelVersion>4.0.0</modelVersion>
    <description>商城分销模块后台管理部分</description>
    <dependencies>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-distribution-common</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-security-api</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
    </dependencies>
</project>
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/config/SwaggerConfiguration.java
New file
@@ -0,0 +1,34 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.config;
import lombok.AllArgsConstructor;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * @author yami
 */
@Configuration("distributionSwaggerConfiguration")
@AllArgsConstructor
public class SwaggerConfiguration {
    @Bean
    public GroupedOpenApi distributionRestApi() {
        return GroupedOpenApi.builder()
                .group("分销接口")
                .packagesToScan("com.yami.shop.distribution.api.controller")
                .pathsToMatch("/**")
                .build();
    }
}
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionBasicController.java
New file
@@ -0,0 +1,40 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.controller;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.distribution.common.vo.DistributionConfigVO;
import com.yami.shop.service.SysConfigService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * @author lgh on 2019/04/01.
 */
@RestController
@RequestMapping("/p/distribution/distributionBasicSet")
@Tag(name = "分销基本设置")
public class DistributionBasicController {
    @Autowired
    private SysConfigService sysConfigService;
    @GetMapping("/canDistribution")
    @Operation(summary = "分销开关是否开启" , description = "获取分销开关是否开启,0关闭 1开启")
    public ServerResponseEntity<Integer> info(){
        DistributionConfigVO distributionConfigVO = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_CONFIG, DistributionConfigVO.class);
        return ServerResponseEntity.success(distributionConfigVO.getDistributionSwitch());
    }
}
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionBindUserController.java
New file
@@ -0,0 +1,89 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.dto.BindUserInfoDto;
import com.yami.shop.distribution.common.service.DistributionBindUserService;
import com.yami.shop.security.api.util.SecurityUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
 * @author yami
 */
@RestController
@RequestMapping("/p/distribution")
@Tag(name = "分销员绑定用户")
@Slf4j
public class DistributionBindUserController {
    @Autowired
    private DistributionBindUserService distributionBindUserService;
    @PostMapping("/bindUser")
    @Operation(summary = "绑定用户" , description = "根据分销员卡号绑定用户")
    @Parameters({
            @Parameter(name = "cardNo", description = "卡号" , required = true)
    })
    public ServerResponseEntity<Void> bindUser(@RequestBody String cardNo) {
        // 没有扫码绑定功能,先注释掉
//        String userId = SecurityUtils.getUser().getUserId();
//
//        log.info("绑定用户cardNo:{}",cardNo);
//
//        if (StrUtil.isBlank(cardNo)) {
//            log.error("获取推广员信息失败");
//            return ServerResponseEntity.success();
//        }
//
//        DistributionUser sharerUser = distributionUserService.getByCardNo(cardNo);
//
//        if (sharerUser == null) {
//            log.error("获取推广员信息失败");
//            return ServerResponseEntity.success();
//        }
//        if (sharerUser.getState() != 1) {
//            log.error("推广员状态异常");
//            return ServerResponseEntity.success();
//        }
//        Long shopId = sharerUser.getShopId();
//
//        DistributionRecruitConfigVO distributionConfigVO = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_RECRUIT_CONFIG, DistributionRecruitConfigVO.class);
//        if (distributionConfigVO.getState() == 0) {
//            log.error("推广计划已关闭");
//            return ServerResponseEntity.success();
//        }
//
//
//        ServerResponse<DistributionUser> serverResponse = distributionBindUserService.bindDistribution(sharerUser, userId, 0);
//        if (!serverResponse.isSuccess()) {
//            log.error(serverResponse.getMsg());
//        }
        return ServerResponseEntity.success();
    }
    @GetMapping("/bindUserList")
    @Operation(summary = "绑定用户列表" , description = "获取分销员所绑定的用户列表")
    public ServerResponseEntity<IPage<BindUserInfoDto>> bindUserList(PageParam pageParam) {
        Long shopId = Constant.PLATFORM_SHOP_ID;
        String userId = SecurityUtils.getUser().getUserId();
        return ServerResponseEntity.success(distributionBindUserService.bindUserList(pageParam,shopId,userId));
    }
}
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionMsgController.java
New file
@@ -0,0 +1,56 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.dto.DistributionMsgDto;
import com.yami.shop.distribution.common.model.DistributionMsg;
import com.yami.shop.distribution.common.service.DistributionMsgService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 * @author yami
 */
@RestController
@RequestMapping("/p/distribution/msg")
@Tag(name = "分销公告接口")
public class DistributionMsgController {
    @Autowired
    private DistributionMsgService distributionMsgService;
    @GetMapping("/info")
    @Operation(summary = "获取公告详情" , description = "根据公告id获取")
    @Parameter(name = "msgId", description = "公告id" , required = true)
    public ServerResponseEntity<DistributionMsgDto> info(Long msgId){
        return ServerResponseEntity.success(distributionMsgService.getDistributionMsgDtoByMsgId(msgId));
    }
    @GetMapping("/page")
    @Operation(summary = "公告列表")
    @Parameters({
            @Parameter(name = "isTop", description = "是否置顶" )
    })
    public ServerResponseEntity<IPage<DistributionMsgDto>> page(PageParam<DistributionMsg> page,
                                                          @RequestParam(value = "isTop", required = false) Integer isTop) {
        return ServerResponseEntity.success(distributionMsgService.getDistributionMsgDtoShopId(page,isTop));
    }
}
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionProdController.java
New file
@@ -0,0 +1,79 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.dto.DistributionProdDto;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.service.DistributionProdService;
import com.yami.shop.distribution.common.service.DistributionUserService;
import com.yami.shop.security.api.util.SecurityUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 * @author yami
 */
@RestController
@RequestMapping("/p/distribution/prod")
@Tag(name = "分销商品接口")
public class DistributionProdController {
    @Autowired
    private DistributionProdService distributionProdService;
    @Autowired
    private DistributionUserService distributionUserService;
    @GetMapping("/page")
    @Operation(summary = "分页查看分销商品" , description = "根据店铺和分销员id获取")
    @Parameters({
            @Parameter(name = "shopId", description = "店铺id" ),
            @Parameter(name = "prodName", description = "商品名" ),
            @Parameter(name = "sort", description = "排序(1时间排序 2销量排序 3价格排序) 默认1" ),
            @Parameter(name = "orderBy", description = "排序(0升序 1降序) 默认1" ),
    })
    public ServerResponseEntity<IPage<DistributionProdDto>> page(@RequestParam(value = "shopId", required = false, defaultValue = "0") Long shopId,
                                                           @RequestParam(value = "prodName") String prodName,
                                                           @RequestParam(value = "sort", defaultValue = "1") Integer sort,
                                                           @RequestParam(value = "orderBy", defaultValue = "1") Integer orderBy,
                                                           PageParam<DistributionProdDto> page) {
        String userId = SecurityUtils.getUser().getUserId();
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(userId, shopId);
        page.setRecords(distributionProdService.distributionProdDtoPage(page, prodName, sort, orderBy, distributionUser));
        return ServerResponseEntity.success(page);
    }
    @GetMapping("/isDistributionProd")
    @Operation(summary = "根据商品id查看该商品是否为分销商品" , description = "根据商品id获取")
    @Parameter(name = "prodId", description = "商品id" , required = true)
    public ServerResponseEntity<Boolean> isDistributionProd(Long prodId) {
        return ServerResponseEntity.success(distributionProdService.getDistributionProdPoByProdId(prodId) != null);
    }
    @GetMapping("/isStateByProdId")
    @Operation(summary = "根据商品id与状态查看该商品是处于该状态" , description = "根据商品id与状态查看该商品是处于该状态")
    @Parameters({
            @Parameter(name = "prodId", description = "商品id" , required = true),
            @Parameter(name = "state", description = "分销商品状态" , required = true)
    })
    public ServerResponseEntity<Boolean> isStateByProdId(@RequestParam(value = "prodId") Long prodId,
                                                   @RequestParam(value = "state") Integer state) {
        return ServerResponseEntity.success(distributionProdService.isStateByProdId(prodId, state));
    }
}
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionQrCodeController.java
New file
@@ -0,0 +1,131 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.controller;
import cn.hutool.json.JSONObject;
import com.yami.shop.bean.app.dto.ResourcesInfoDto;
import com.yami.shop.bean.enums.QRCodeType;
import com.yami.shop.bean.model.QrcodeTicket;
import com.yami.shop.common.bean.Domain;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.IdUtil;
import com.yami.shop.config.ShopConfig;
import com.yami.shop.config.WxConfig;
import com.yami.shop.service.AttachFileService;
import com.yami.shop.service.QrcodeTicketService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.Date;
import java.util.Objects;
/**
 * @author LGH
 */
@Slf4j
@RestController
@RequestMapping("/p/distribution/qrCode")
@Tag(name = "生成二维码接口")
public class DistributionQrCodeController {
    @Autowired
    private QrcodeTicketService qrcodeTicketService;
    @Autowired
    private WxConfig wxConfig;
    @Autowired
    private IdUtil idUtil;
    @Autowired
    private AttachFileService attachFileService;
    @Autowired
    private ShopConfig shopConfig;
    @GetMapping("/invitation")
    @Operation(summary = "分销员邀请二维码" , description = "分销员的邀请二维码带有cardNo")
    @Parameters({
            @Parameter(name = "scene", description = "二维码携带的参数" , required = true),
            @Parameter(name = "page", description = "获取二维码后跳转的页面" , required = true)
    })
    public ResponseEntity<FileSystemResource> qrCodeCreate(String page,String scene) throws WxErrorException {
        File file = wxConfig.getWxMaService().getQrcodeService().createWxaCodeUnlimit(scene, page);
        return ResponseEntity.ok().contentLength(file.length()).contentType(MediaType.IMAGE_PNG).body(new FileSystemResource(file));
    }
    @GetMapping("/invitationPath")
    @Operation(summary = "分销员邀请二维码" , description = "分销员的邀请二维码带有cardNo")
    @Parameters({
            @Parameter(name = "content", description = "要保存的内容" , required = true),
            @Parameter(name = "type", description = "类型:1. 小程序团购商品 2.小程序分销商品二维码" , required = true)
    })
    public ServerResponseEntity<ResourcesInfoDto> qrCodeCreatePath(String content, Integer type) throws WxErrorException {
        String page;
        if(Objects.equals(type, QRCodeType.GROUP.value()) || Objects.equals(type, QRCodeType.DISTRIBUTION.value())) {
            page = "pages/prod/prod";
        }else if(Objects.equals(type, 3))  {
            page = "pages/snapUpDetail/snapUpDetail";
        } else {
            // 无法获取页面信息
            throw new YamiShopBindException("yami.unable.get.page");
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("type", type);
        jsonObject.set("content", content);
        String ticket = idUtil.nextShortId();
        QrcodeTicket qrcodeTicket = new QrcodeTicket();
        qrcodeTicket.setContent(jsonObject.toString());
        qrcodeTicket.setCreateTime(new Date());
        qrcodeTicket.setType(type);
        qrcodeTicket.setTicket(ticket);
        qrcodeTicket.setTicketUrl(page);
        qrcodeTicketService.save(qrcodeTicket);
        File file = wxConfig.getWxMaService().getQrcodeService().createWxaCodeUnlimit(ticket, page);
        ResourcesInfoDto resourcesInfoDto = null;
        //新的 byte 数组输出流,缓冲区容量1024byte
        try (FileInputStream fis = new FileInputStream(file);
             ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);){
            //缓存
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            //改变为byte[]
            byte[] data = bos.toByteArray();
            //
            String fileName = attachFileService.uploadFile(data,file.getName());
            Domain domain = shopConfig.getDomain();
            String resourcesUrl = domain.getResourcesDomainName();
            resourcesInfoDto = new ResourcesInfoDto();
            resourcesInfoDto.setResourcesUrl(resourcesUrl);
            resourcesInfoDto.setFilePath(fileName);
            return ServerResponseEntity.success(resourcesInfoDto);
        } catch (Exception e) {
            log.error("获取分销员邀请二维码错误:", e);
        }
        return ServerResponseEntity.success();
    }
}
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionRecruitSetController.java
New file
@@ -0,0 +1,49 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.controller;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.distribution.common.dto.DistributionRecruitSetDto;
import com.yami.shop.distribution.common.vo.DistributionRecruitConfigVO;
import com.yami.shop.service.SysConfigService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Objects;
/**
 * @author yami
 */
@RestController
@RequestMapping("/p/distribution/recruit")
@Tag(name = "分销推广接口")
public class DistributionRecruitSetController {
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private MapperFacade mapperFacade;
    @GetMapping("/info")
    @Operation(summary = "根据店铺id获取")
    public ServerResponseEntity<DistributionRecruitSetDto> info(){
        DistributionRecruitConfigVO distributionRecruitConfigVO = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_RECRUIT_CONFIG, DistributionRecruitConfigVO.class);
        if (Objects.equals(0,distributionRecruitConfigVO.getState())) {
            distributionRecruitConfigVO.setContent("");
        }
        return ServerResponseEntity.success(mapperFacade.map(distributionRecruitConfigVO, DistributionRecruitSetDto.class));
    }
}
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionRegisterController.java
New file
@@ -0,0 +1,249 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.distribution.UserShoppingDataDto;
import com.yami.shop.bean.model.User;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.IdUtil;
import com.yami.shop.common.util.Json;
import com.yami.shop.dao.OrderMapper;
import com.yami.shop.distribution.api.param.DistributionUserParam;
import com.yami.shop.distribution.common.constants.DistributionUserStateEnum;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.service.DistributionUserService;
import com.yami.shop.distribution.common.vo.DistributionConfigVO;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.SysConfigService;
import com.yami.shop.service.UserService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * @author yami
 */
@Slf4j
@RestController
@RequestMapping("/p/distribution/register")
@Tag(name = "分销员注册接口")
public class DistributionRegisterController {
    @Autowired
    private DistributionUserService distributionUserService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private IdUtil idUtil;
    @Autowired
    private UserService userService;
    @GetMapping("/condition")
    @Operation(summary = "成为分销员所需要填写的信息")
    public ServerResponseEntity<DistributionConfigVO> getDistributionAuditingInfoVO() {
        DistributionConfigVO distributionConfigVO = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_CONFIG, DistributionConfigVO.class);
//        DistributionAuditingInfoVO distributionAuditingInfoVO = new DistributionAuditingInfoVO();
//        distributionAuditingInfoVO.setIdentityCardNumber(distributionConfigVO.getIdentityCardNumber());
//        distributionAuditingInfoVO.setRealName(distributionConfigVO.getRealName());
//        distributionAuditingInfoVO.setIdentityCardPic(distributionConfigVO.getIdentityCardPic());
        return ServerResponseEntity.success(distributionConfigVO);
    }
    @PostMapping("/addDistributionUser")
    @Operation(summary = "申请成为分销员" , description = "申请成为分销员,返回分销员状态 0 待审核 1 正常")
    public ServerResponseEntity<Integer> addDistributionUser(@Valid @RequestBody DistributionUserParam distributionUserParam) {
        log.debug(Json.toJsonString(distributionUserParam));
        Long shopId = Constant.PLATFORM_SHOP_ID;
        // 店铺分销员审核设置
        DistributionConfigVO distributionConfigVO = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_CONFIG, DistributionConfigVO.class);
        // 判断传入的资料是否齐全
        if (distributionConfigVO == null) {
            // 分销设置异常
            throw new YamiShopBindException("yami.distribution.set.exception");
        }
        if (distributionConfigVO.getIdentityCardNumber()) {
            if (!StrUtil.isNotBlank(distributionUserParam.getIdentityCardNumber())) {
                // 申请填写信息不全,需要身份证号
                throw new YamiShopBindException("yami.distribution.info.cardno");
            }
        }
        if (distributionConfigVO.getIdentityCardPic()) {
            if (!StrUtil.isNotBlank(distributionUserParam.getIdentityCardPicBack()) || !StrUtil.isNotBlank(distributionUserParam.getIdentityCardPicFront()) || !StrUtil.isNotBlank(distributionUserParam.getIdentityCardPicHold())) {
                // 申请填写信息不全,需要身份证照片
                throw new YamiShopBindException("yami.distribution.info.pic");
            }
        }
        if (distributionConfigVO.getRealName()) {
            if (!StrUtil.isNotBlank(distributionUserParam.getRealName())) {
                // 申请填写信息不全,需要真实姓名
                throw new YamiShopBindException("yami.distribution.info.name");
            }
        }
        String userId = SecurityUtils.getUser().getUserId();
        User user = userService.getUserByUserId(userId);
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(userId, shopId);
        checkUserInfo(distributionUserParam, distributionUser);
        distributionUser = new DistributionUser();
        distributionUser.setUserId(userId);
        distributionUser.setShopId(shopId);
        // 设置分享人信息
        setSharer(distributionUserParam, shopId, userId, distributionUser);
        if (distributionConfigVO.getAutoCheck() == 1) {
            autoCheck(shopId, distributionConfigVO, userId, distributionUser);
        } else {
            // 待审核
            distributionUser.setState(0);
        }
        //设置信息
        distributionUser.setUserMobile(distributionUserParam.getUserMobile());
        distributionUser.setRealName(distributionUserParam.getRealName());
        distributionUser.setIdentityCardNumber(distributionUserParam.getIdentityCardNumber());
        distributionUser.setIdentityCardPicFront(distributionUserParam.getIdentityCardPicFront());
        distributionUser.setIdentityCardPicHold(distributionUserParam.getIdentityCardPicHold());
        distributionUser.setIdentityCardPicBack(distributionUserParam.getIdentityCardPicBack());
        // level从1开始
        distributionUser.setLevel(1);
        //设置用户信息字段
        distributionUser.setNickName(user.getNickName());
        distributionUser.setPic(user.getPic());
        // 设置用户卡号
        distributionUser.setCardNo(idUtil.nextShortId());
        distributionUserService.registerDistributionUser(distributionUser);
        // 清除缓存
        distributionUserService.removeCacheByUserIdAndShopId(distributionUser.getUserId(), distributionUser.getShopId());
        distributionUserService.removeCacheByCardNo(distributionUser.getCardNo());
        return ServerResponseEntity.success(distributionUser.getState());
    }
    private void setSharer(DistributionUserParam distributionUserParam, Long shopId, String userId, DistributionUser distributionUser) {
        if (StrUtil.isNotBlank(distributionUserParam.getSharerCardNo())) {
            DistributionUser parentUser = distributionUserService.getByCardNo(distributionUserParam.getSharerCardNo());
            if (parentUser == null) {
                // 无法获取邀请人信息
                throw new YamiShopBindException("yami.distribution.get.examine");
            }
            if (!Objects.equals(parentUser.getShopId(), shopId)) {
                // 邀请人店铺信息有误
                throw new YamiShopBindException("yami.distribution.shop.error");
            }
            if (Objects.equals(parentUser.getUserId(), userId)) {
                // 自己无法邀请自己
                throw new YamiShopBindException("yami.distribution.user.error");
            }
            if (!Objects.equals(parentUser.getState(), DistributionUserStateEnum.PER_BAN.getValue())
                    && !Objects.equals(parentUser.getState(), DistributionUserStateEnum.BAN.getValue())) {
                //上级不能是暂时封禁或永久封禁状态
                //设置上级id
                distributionUser.setParentId(parentUser.getDistributionUserId());
                //设置上级ids
                if (parentUser.getParentId() == null) {
                    distributionUser.setParentIds(StringUtils.join(StrUtil.COMMA, parentUser.getDistributionUserId(), StrUtil.COMMA));
                } else {
                    distributionUser.setParentIds(StringUtils.join(parentUser.getParentIds(), parentUser.getDistributionUserId(), StrUtil.COMMA));
                }
                distributionUser.setGrade(parentUser.getGrade() + 1);
            }
        } else {
            distributionUser.setGrade(0);
        }
    }
    private void checkUserInfo(DistributionUserParam distributionUserParam, DistributionUser distributionUser) {
        if (distributionUser != null) {
            if (distributionUser.getState() == DistributionUserStateEnum.WAIT_AUDIT.getValue()) {
                // 你已经提交过审核了,请耐心等待
                throw new YamiShopBindException("yami.distribution.submit.examine");
            } else if (distributionUser.getState() == DistributionUserStateEnum.PER_BAN.getValue()) {
                // 该账户已被永久封禁
                throw new YamiShopBindException("yami.distribution.ban.examine");
            } else if (distributionUser.getState() == DistributionUserStateEnum.BAN.getValue()) {
//                // 已暂时封禁不可申请,请联系管理员
                throw new YamiShopBindException("yami.distribution.clear.examine");
            } else if (distributionUser.getState() == DistributionUserStateEnum.NORMAL.getValue()) {
                // 你的审核已经通过,无需再次审核
                throw new YamiShopBindException("yami.distribution.success.examine");
            }
        }
        List<DistributionUser> distributionUsersDb = distributionUserService.getDistributionUserByIdCardNumberAndUserMobile(distributionUserParam.getIdentityCardNumber(), distributionUserParam.getUserMobile());
        for (DistributionUser distributionUserDb : distributionUsersDb) {
            if (StrUtil.isNotBlank(distributionUserParam.getIdentityCardNumber()) && StrUtil.equals(distributionUserDb.getIdentityCardNumber(), distributionUserParam.getIdentityCardNumber())) {
                //该身份证号码已存在
                throw new YamiShopBindException("yami.id.number.already.exists");
            } else if (Objects.equals(distributionUserDb.getUserMobile(), distributionUserParam.getUserMobile())) {
                //该手机号码已存在
                throw new YamiShopBindException("yami.phone.number.already.exists");
            }
        }
        DistributionUser one = distributionUserService.getOne(new LambdaQueryWrapper<DistributionUser>().eq(DistributionUser::getUserMobile, distributionUserParam.getUserMobile())
                .and(item -> item.eq(DistributionUser::getState, DistributionUserStateEnum.BAN.getValue())
                        .or().eq(DistributionUser::getState, DistributionUserStateEnum.PER_BAN.getValue())));
        if (Objects.nonNull(one)){
            //该手机号码已存在
            throw new YamiShopBindException("yami.phone.number.already.exists");
        }
    }
    private void autoCheck(Long shopId, DistributionConfigVO distributionAuditingSet, String userId, DistributionUser distributionUser) {
        //判断是否需要购买置指定商品
        if (CollectionUtil.isNotEmpty(distributionAuditingSet.getProdIdList())) {
            boolean has = false;
            for (Long prodId : distributionAuditingSet.getProdIdList()) {
                // 判断有没有没有购买过指定商品
                if (orderMapper.hasBuySuccessProd(prodId, distributionUser.getUserId()) > 0) {
                    has = true;
                    break;
                }
            }
            if (!has) {
                // 不符合申请条件,请联系客服进行申请
                throw new YamiShopBindException("yami.distribution.user.Unqualified");
            }
        }
        UserShoppingDataDto userShoppingDataDto = orderMapper.calculateUserInShopData(shopId, userId);
        //判断是否需要消费金额条件
        if (distributionAuditingSet.getExpenseAmount() != null) {
            if (userShoppingDataDto.getSumOfConsumption() == null) {
                userShoppingDataDto.setSumOfConsumption(0.0);
            }
            if (userShoppingDataDto.getSumOfConsumption() < distributionAuditingSet.getExpenseAmount()) {
                // 消费金额不符合要求
                throw new YamiShopBindException("yami.distribution.fee.error");
            }
        }
        //判断是否需要达到消费笔数条件
        if (distributionAuditingSet.getExpenseNumber() != null) {
            if (userShoppingDataDto.getExpenseNumber() < distributionAuditingSet.getExpenseNumber()) {
                // 消费笔数不符合要求
                throw new YamiShopBindException("yami.distribution.fee.num");
            }
        }
        distributionUser.setState(1);
        distributionUser.setBindTime(new Date());
    }
}
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionUserController.java
New file
@@ -0,0 +1,117 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.dto.AchievementDataDto;
import com.yami.shop.distribution.common.dto.DistributionOrderDto;
import com.yami.shop.distribution.common.dto.DistributionUserDto;
import com.yami.shop.distribution.common.dto.DistributionUserSimpleDto;
import com.yami.shop.distribution.common.model.DistributionMsg;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.service.DistributionUserIncomeService;
import com.yami.shop.distribution.common.service.DistributionUserService;
import com.yami.shop.distribution.common.vo.DistributionRecruitConfigVO;
import com.yami.shop.distribution.common.vo.DistributionUserInfoVO;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.SysConfigService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import lombok.AllArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Objects;
/**
 * @author yami
 */
@RestController
@RequestMapping("/p/distribution/user")
@Tag(name = "分销员接口")
@AllArgsConstructor
public class DistributionUserController {
    private final DistributionUserService distributionUserService;
    private final DistributionUserIncomeService distributionUserIncomeService;
    private final SysConfigService sysConfigService;
    private final MapperFacade mapperFacade;
    @GetMapping("/info")
    @Operation(summary = "查看分销中心信息")
    @Parameter(name = "shopId", description = "店铺id" )
    public ServerResponseEntity<AchievementDataDto> info(@RequestParam(value = "shopId", required = false, defaultValue = "0") Long shopId) {
//        Long shopId = 0L;
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(SecurityUtils.getUser().getUserId(), shopId);
        if (Objects.isNull(distributionUser)) {
            // 您还不是销售员
            throw new YamiShopBindException("yami.distribution.user.no.distributor");
        }
        return ServerResponseEntity.success(distributionUserService.getAchievementDataDtoById(distributionUser.getDistributionUserId()));
    }
    @GetMapping("/distributionUserOrders")
    @Operation(summary = "分页查看分销员佣金明细" , description = "传入分销员id")
    public ServerResponseEntity<IPage<DistributionOrderDto>> getDistributionOrderDtosByDistributionUserId(PageParam<DistributionOrderDto> page) {
        Long shopId = Constant.PLATFORM_SHOP_ID;
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(SecurityUtils.getUser().getUserId(), shopId);
        return ServerResponseEntity.success(distributionUserIncomeService.getDistributionOrderDtoByDistributionUserId(page, distributionUser.getDistributionUserId()));
    }
    @GetMapping("/distributionUserInfo")
    @Operation(summary = "分销员信息")
    public ServerResponseEntity<DistributionUserDto> isDistributionUser() {
        Long shopId = Constant.PLATFORM_SHOP_ID;
        // 推广开关
        DistributionRecruitConfigVO distributionConfigVO = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_RECRUIT_CONFIG, DistributionRecruitConfigVO.class);
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(SecurityUtils.getUser().getUserId(), shopId);
        DistributionUserDto distributionUserDto = mapperFacade.map(distributionUser, DistributionUserDto.class);
        if (distributionUserDto == null) {
            distributionUserDto = new DistributionUserDto();
            distributionUserDto.setRecruitState(distributionConfigVO.getState());
            return ServerResponseEntity.success(distributionUserDto);
        }
        distributionUserDto.setRecruitState(distributionConfigVO.getState());
        return ServerResponseEntity.success(distributionUserDto);
    }
    @GetMapping("/subordinate")
    @Operation(summary = "查看下级")
    public ServerResponseEntity<IPage<DistributionUserSimpleDto>> subordinatePage(PageParam<DistributionMsg> page) {
        Long shopId = Constant.PLATFORM_SHOP_ID;
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(SecurityUtils.getUser().getUserId(), shopId);
        return ServerResponseEntity.success(distributionUserService.getDistributionUserSimpleDtoByParentUserIdPage(page, distributionUser.getDistributionUserId()));
    }
    @GetMapping("/subordinateUser")
    @Operation(summary = "获取好友接口")
    @Parameters({
            @Parameter(name = "userType", description = "类型 1 我的用户, 2 我的好友" )
    })
    public ServerResponseEntity<List<DistributionUserInfoVO>> subordinateUserPage(@RequestParam(value = "userType") Integer userType){
        Long shopId = Constant.PLATFORM_SHOP_ID;
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(SecurityUtils.getUser().getUserId(), shopId);
        List<DistributionUserInfoVO> myFriends = distributionUserService.getDistributionMyFriend(distributionUser, userType);
        return ServerResponseEntity.success(myFriends);
    }
}
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionUserIncomeController.java
New file
@@ -0,0 +1,94 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.constants.DistributionUserStateEnum;
import com.yami.shop.distribution.common.dto.DistributionUserIncomeDto;
import com.yami.shop.distribution.common.dto.StatisticsDisUserIncomeDto;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.model.DistributionUserIncome;
import com.yami.shop.distribution.common.service.DistributionUserIncomeService;
import com.yami.shop.distribution.common.service.DistributionUserService;
import com.yami.shop.distribution.common.vo.DistributionOrdersVO;
import com.yami.shop.security.api.util.SecurityUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Objects;
/**
 * @author yami
 */
@Tag(name = "分销员收入接口")
@RestController
@RequestMapping("/p/distribution/income")
public class DistributionUserIncomeController {
    @Autowired
    private DistributionUserIncomeService distributionUserIncomeService;
    @Autowired
    private DistributionUserService distributionUserService;
    @GetMapping("/statistics")
    @Operation(summary = "统计分销员今日、本月的收益")
    public ServerResponseEntity<StatisticsDisUserIncomeDto> statisticsDistributionUserIncome() {
        Long shopId = Constant.PLATFORM_SHOP_ID;
        String userId = SecurityUtils.getUser().getUserId();
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(userId, shopId);
        if (Objects.isNull(distributionUser)) {
            // 您还不是本店的分销员
            throw new YamiShopBindException("yami.distribution.user.no.shop");
        }
        return ServerResponseEntity.success(distributionUserIncomeService.statisticsDistributionUserIncome(distributionUser.getDistributionUserId()));
    }
    @GetMapping("/page")
    @Operation(summary = "分页获取收益列表")
    public ServerResponseEntity<IPage<DistributionUserIncomeDto>> getDistributionUserIncomePage(PageParam<DistributionUserIncome> page) {
        Long shopId = Constant.PLATFORM_SHOP_ID;
        String userId = SecurityUtils.getUser().getUserId();
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(userId, shopId);
        if (Objects.isNull(distributionUser)) {
            // 您还不是本店的分销员
            throw new YamiShopBindException("yami.distribution.user.no.shop");
        }
        IPage<DistributionUserIncomeDto> distributionUserIncomeDto = distributionUserIncomeService.getDistributionUserIncomePage(page, distributionUser.getDistributionUserId());
        return ServerResponseEntity.success(distributionUserIncomeDto);
    }
    @GetMapping("/myPromotionOrder")
    @Operation(summary = "我的推广订单" , description = "通过状态获取我的推广订单(0:待支付 1:待结算 2:已结算 -1:订单失效)")
    @Parameter(name = "state", description = "状态" )
    public ServerResponseEntity<IPage<DistributionOrdersVO>> getMyPromotionOrderByState(PageParam<DistributionOrdersVO> page,
                                                                                        @RequestParam(value = "state", required = false) Integer state) {
        Long shopId = Constant.PLATFORM_SHOP_ID;
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(SecurityUtils.getUser().getUserId(), shopId);
        if (Objects.isNull(distributionUser)) {
            // 您还不是本店的分销员
            throw new YamiShopBindException("yami.distribution.user.no.shop");
        }
        if (!Objects.equals(distributionUser.getState(), DistributionUserStateEnum.NORMAL.getValue())) {
            // 您的分销身份异常,请联系管理员
            throw new YamiShopBindException("yami.distribution.user.no.distributor1");
        }
        IPage<DistributionOrdersVO> result = distributionUserIncomeService.getMyPromotionOrderByState(page, distributionUser.getDistributionUserId(), state);
        return ServerResponseEntity.success(result);
    }
}
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionUserWalletController.java
New file
@@ -0,0 +1,74 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.dto.DistributionUserWalletBillDto;
import com.yami.shop.distribution.common.dto.DistributionUserWalletDto;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.service.DistributionUserService;
import com.yami.shop.distribution.common.service.DistributionUserWalletBillService;
import com.yami.shop.distribution.common.service.DistributionUserWalletService;
import com.yami.shop.security.api.util.SecurityUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Objects;
/**
 * @author yami
 */
@RestController
@RequestMapping("/p/distribution/wallet")
@Tag(name = "分销钱包接口")
public class DistributionUserWalletController {
    @Autowired
    private DistributionUserWalletService distributionUserWalletService;
    @Autowired
    private DistributionUserService distributionUserService;
    @Autowired
    private DistributionUserWalletBillService distributionUserWalletBillService;
    @GetMapping("/info")
    @Operation(summary = "查看分销员钱包数据")
    public ServerResponseEntity<DistributionUserWalletDto> getDistributionUserWalletDtoByDistributionUserId() {
        Long shopId = Constant.PLATFORM_SHOP_ID;
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(SecurityUtils.getUser().getUserId(), shopId);
        if (Objects.isNull(distributionUser)) {
            // 您还不是销售员
            throw new YamiShopBindException("yami.distribution.user.no.distributor");
        }
        return ServerResponseEntity.success(distributionUserWalletService.getDistributionUserWalletDtoByDistributionUserId(distributionUser.getDistributionUserId()));
    }
    @GetMapping("/page")
    @Operation(summary = "查看分销员钱包流水记录")
    @Parameters({
            @Parameter(name = "orderBy", description = "时间排序(0升序 1降序) 默认1" )
    })
    public ServerResponseEntity<IPage<DistributionUserWalletBillDto>> getDistributionUserWalletBillDtoPage(PageParam<DistributionUserWalletBillDto> page,
                                                                                                     @RequestParam(value = "orderBy", defaultValue = "1") Integer orderBy) {
        Long shopId = Constant.PLATFORM_SHOP_ID;
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(SecurityUtils.getUser().getUserId(), shopId);
        return ServerResponseEntity.success(distributionUserWalletBillService
                .getDistributionUserWalletBillDtoPage(page, distributionUser.getDistributionUserId(), orderBy));
    }
}
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/controller/DistributionWithdrawCashController.java
New file
@@ -0,0 +1,142 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.api.param.DistributionWithdrawCashSaceParam;
import com.yami.shop.distribution.common.constants.DistributionUserStateEnum;
import com.yami.shop.distribution.common.dto.DistributionWithdrawCashDto;
import com.yami.shop.distribution.common.dto.DistributionWithdrawCashSetDto;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import com.yami.shop.distribution.common.service.DistributionUserService;
import com.yami.shop.distribution.common.service.DistributionUserWalletService;
import com.yami.shop.distribution.common.service.DistributionWithdrawCashService;
import com.yami.shop.distribution.common.vo.DistributionConfigVO;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.security.common.enums.SocialType;
import com.yami.shop.security.common.model.AppConnect;
import com.yami.shop.security.common.service.AppConnectService;
import com.yami.shop.service.SysConfigService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;
/**
 * @author yami
 */
@RestController
@RequestMapping("/p/distribution/withdrawCash")
@Tag(name = "分销员提现接口")
public class DistributionWithdrawCashController {
    @Autowired
    private DistributionWithdrawCashService distributionWithdrawCashService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private DistributionUserService distributionUserService;
    @Autowired
    private MapperFacade mapperFacade;
    @Autowired
    private DistributionUserWalletService distributionUserWalletService;
    @Autowired
    private AppConnectService appConnectService;
    @GetMapping("/info")
    @Operation(summary = "获取提现设置信息")
    public ServerResponseEntity<DistributionWithdrawCashSetDto> setInfo() {
        DistributionConfigVO distributionConfigVO = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_CONFIG, DistributionConfigVO.class);
        return ServerResponseEntity.success(mapperFacade.map(distributionConfigVO, DistributionWithdrawCashSetDto.class));
    }
    @GetMapping("/page")
    @Operation(summary = "分页查看提现记录")
    public ServerResponseEntity<IPage<DistributionWithdrawCashDto>> page(PageParam<DistributionWithdrawCashDto> page) {
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(SecurityUtils.getUser().getUserId(), Constant.PLATFORM_SHOP_ID);
        if (Objects.isNull(distributionUser)) {
            // 您还不是分销员
            throw new YamiShopBindException("yami.distribution.user.no.distributor");
        }
        return ServerResponseEntity.success(distributionWithdrawCashService.distributionWithdrawCashDtoPageByUserId(page, distributionUser.getDistributionUserId()));
    }
    @PostMapping("/apply")
    @Operation(summary = "用户发起提现申请" , description = "填入提现参数")
    public ServerResponseEntity<Void> apply(@Valid @RequestBody DistributionWithdrawCashSaceParam distributionWithdrawCashSaceParam) {
        String userId = SecurityUtils.getUser().getUserId();
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(userId, Constant.PLATFORM_SHOP_ID);
        if (Objects.isNull(distributionUser)) {
            // 您还不是分销员
            throw new YamiShopBindException("yami.distribution.user.no.distributor");
        }
        if (!Objects.equals(distributionUser.getState(), DistributionUserStateEnum.NORMAL.getValue())){
            // 您的分销身份异常,请联系管理员
            throw new YamiShopBindException("yami.distribution.user.no.distributor1");
        }
        AppConnect appConnect = appConnectService.getOne(new LambdaQueryWrapper<AppConnect>()
                .eq(AppConnect::getUserId, distributionUser.getUserId())
                .eq(AppConnect::getAppId, SocialType.MA.value()));
        if(Objects.isNull(appConnect)){
            throw new YamiShopBindException("yami.distribution.user.withdrawals");
        }
        //发起提现
        distributionWithdrawCashService.apply(distributionWithdrawCashSaceParam.getAmount(), distributionUser, appConnect);
        return ServerResponseEntity.success();
    }
    @GetMapping("/isWithdrawCash")
    @Operation(summary = "当前是否可以提现")
    public ServerResponseEntity<Boolean> isWithdrawCash() {
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(SecurityUtils.getUser().getUserId(), Constant.PLATFORM_SHOP_ID);
        Long distributionUserId = distributionUser.getDistributionUserId();
        //获取店铺提现设置
        DistributionConfigVO distributionWithdrawCashSet = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_CONFIG, DistributionConfigVO.class);
        //获取店铺设置的提现频率算出时间区间
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - distributionWithdrawCashSet.getFrequency());
        //获取玩家最近的提现次数
        //判断是否能够提现
        if (distributionWithdrawCashService.getCountByRangeTimeAndDistributionUserId(new RangeTimeParam(calendar.getTime(), new Date()), distributionUserId) >= distributionWithdrawCashSet.getNumber()) {
            // 提现次数为x天x次
            String info = I18nMessage.getMessage("yami.distribution.cash.num");
            String num = I18nMessage.getMessage("yami.constant.num");
            String day = I18nMessage.getMessage("yami.day");
            throw new YamiShopBindException(info + distributionWithdrawCashSet.getFrequency() + day + distributionWithdrawCashSet.getNumber() + num);
        }
        return ServerResponseEntity.success(true);
    }
    @GetMapping("/totalWithdrawCash")
    @Operation(summary = "查看用户总提现金额")
    public ServerResponseEntity<Double> getUserTotalWithdrawCash() {
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(SecurityUtils.getUser().getUserId(), Constant.PLATFORM_SHOP_ID);
        if (Objects.isNull(distributionUser)) {
            // 您还不是分销员
            throw new YamiShopBindException("yami.distribution.user.no.distributor");
        }
        Long distributionUserId = distributionUser.getDistributionUserId();
        Long walletId = distributionUserWalletService.getWalletIdByDistributionUserId(distributionUserId);
        Double totalWithdrawCash = distributionWithdrawCashService.getUserTotalWithdrawCash(walletId);
        return ServerResponseEntity.success(totalWithdrawCash);
    }
}
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/linstener/UpdateDistributionUserListener.java
New file
@@ -0,0 +1,50 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.linstener;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.app.param.UserInfoParam;
import com.yami.shop.bean.event.UpdateDistributionUserEvent;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.service.DistributionUserService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.Objects;
/**
 * 企业支付事件监听
 * @author lhd
 */
@Component("updateDistributionUserListener")
@AllArgsConstructor
public class UpdateDistributionUserListener {
    private final DistributionUserService distributionUserService;
    @EventListener(UpdateDistributionUserEvent.class)
    public void updateDistributionUserEventHandle(UpdateDistributionUserEvent event) {
        UserInfoParam userInfoParam = event.getUserInfoParam();
        DistributionUser distributionUser = distributionUserService.getOne(new LambdaQueryWrapper<DistributionUser>().eq(DistributionUser::getUserId, event.getUserId()));
        if(Objects.isNull(distributionUser)){
            return;
        }
        distributionUser.setNickName(StrUtil.isBlank(userInfoParam.getNickName())? distributionUser.getNickName():userInfoParam.getNickName());
        distributionUser.setPic(StrUtil.isBlank(userInfoParam.getAvatarUrl())?distributionUser.getPic() :userInfoParam.getAvatarUrl());
        distributionUserService.updateById(distributionUser);
        distributionUserService.removeCacheByUserIdAndShopId(distributionUser.getUserId(),distributionUser.getShopId());
    }
}
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/param/DistributionUserParam.java
New file
@@ -0,0 +1,45 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.param;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
 * @author yami
 */
@Data
public class DistributionUserParam {
    @Schema(description = "手机号码" ,required=true)
    @NotNull(message = "手机号不能为空")
    private String userMobile;
    @Schema(description = "真实姓名" )
    @Size(max = 50, message = "真实姓名长度应该小于{max}")
    private String realName;
    @Schema(description = "身份证号" )
    private String  identityCardNumber;
    @Schema(description = "身份证正面" )
    private String identityCardPicFront;
    @Schema(description = "身份证背面" )
    private String identityCardPicBack;
    @Schema(description = "手持身份证照片" )
    private String identityCardPicHold;
    @Schema(description = "分享者" )
    private String sharerCardNo;
}
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/param/DistributionWithdrawCashParam.java
New file
@@ -0,0 +1,37 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.param;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 提现参数
 * @author yami
 */
@Data
public class DistributionWithdrawCashParam {
    @Schema(description = "店铺id" ,required=true)
    @NotNull(message = "店铺id不能为空")
    private Long shopId;
    @Schema(description = "提现金额" ,required=true)
    @NotNull(message = "提现金额不能为空")
    private Double amount;
//    @Schema(description = "支付手续费" ,required=true)
//    private Double fee;
}
yami-shop-distribution/yami-shop-distribution-api/src/main/java/com/yami/shop/distribution/api/param/DistributionWithdrawCashSaceParam.java
New file
@@ -0,0 +1,28 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.api.param;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
/**
 * @author yami
 */
@Data
public class DistributionWithdrawCashSaceParam {
    @Schema(description = "提现金额" , required = true)
    @NotNull(message = "{yami.distribution.cash.param1}")
    @Min(value = 1, message = "{yami.distribution.cash.param2}")
    private Double amount;
}
yami-shop-distribution/yami-shop-distribution-common/pom.xml
New file
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.yami.shop</groupId>
        <artifactId>yami-shop-distribution</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>yami-shop-distribution-common</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-security-common</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
    </dependencies>
</project>
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/BasicSetDistributionSwitchEnum.java
New file
@@ -0,0 +1,41 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.constants;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
 * 基本设置分销开关枚举
 * @author yami
 */
@Getter
@AllArgsConstructor
public enum BasicSetDistributionSwitchEnum {
    /**
     * 关闭
     */
    DISABLE(0, "关闭"),
    /**
     * 启动
     */
    ENABLE(1, "启动"),
    /**
     * 违规下线
     */
    OFFLINE(2, "平台禁用"),
    /**
     * 等待审核
     */
    WAIT_AUDIT(3, "等待审核");
    private int value;
    private String desc;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/BindEnum.java
New file
@@ -0,0 +1,32 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.constants;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
 * 基本设置分销开关枚举
 * @author yami
 */
@Getter
@AllArgsConstructor
public enum BindEnum {
    /**
     * 扫码
     */
    SCAN_CODE(0),
    /**
     * 下单
     */
    PLACE_ORDER(1);
    private int value;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DUserType.java
New file
@@ -0,0 +1,24 @@
package com.yami.shop.distribution.common.constants;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
 * @author
 */
@Getter
@AllArgsConstructor
public enum DUserType {
    /**
     * 用户
     */
    MY_USER(1, "我的用户"),
    /**
     * 好友
     */
    MY_FRIEND(2,"我的好友");
    private final Integer value;
    private final String type;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DistributionAudit.java
New file
@@ -0,0 +1,35 @@
package com.yami.shop.distribution.common.constants;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum DistributionAudit {
    /**
     * 提现方式
     */
    Withdrawals_ZERO(0,"无需审核直接发放"),
    Withdrawals_ONE(1,"审核后系统发放"),
    TWithdrawals_TWO(2,"审核后人工发放"),
    /**
     * 收入提示
     */
    INCOME_ZERO(0,"正常"),
    INCOME_ONE(1,"分销佣金大于或者等于订单项实付金额"),
    INCOME_TWO(2,"订单项售后成功"),
    INCOME_THREE(3, "订单无效:无效原因:分销佣金小于0.01"),
    /**
     * 用户分销员绑定状态
     */
    BIND_SYMBOL_ONE(-1,"失效"),
    BIND_ZERO(0, "预绑定"),
    BIND_ONE(1,"生效");
    private Integer value;
    private String info;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DistributionBindAttributionEnum.java
New file
@@ -0,0 +1,37 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.constants;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
 * 业绩归属
 *
 * @Author lth
 * @Date 2021/5/13 20:10
 */
@Getter
@AllArgsConstructor
public enum DistributionBindAttributionEnum {
    /**
     * 允许绑定,关系优先
     */
    ALLOW_BINDING(0, "允许绑定,关系优先"),
    /**
     * 不绑定 分享人优先
     */
    NOT_BOUND(1, "不绑定 分享人优先"),
    ;
    private int value;
    private String desc;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DistributionProdStateEnum.java
New file
@@ -0,0 +1,45 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.constants;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
 * 优惠券状态
 * @author yami
 */
@Getter
@AllArgsConstructor
public enum DistributionProdStateEnum {
    /**
     * 商家下架
     */
    PUT_OFF(0, "商家下架"),
    /**
     * 商家上架
     */
    PUT_ON(1, "商家上架"),
    /**
     * 违规下架
     */
    OFFLINE(2, "违规下架"),
    /**
     * 等待审核
     */
    WAIT_AUDIT(3, "等待审核"),
    ;
    private int value;
    private String desc;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DistributionUserIncomeStateEnum.java
New file
@@ -0,0 +1,44 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.constants;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
 * 分销收入状态
 * @author yami
 */
@Getter
@AllArgsConstructor
public enum DistributionUserIncomeStateEnum {
    /**
     * 待支付
     */
    UNPAY(0, "待支付"),
    /**
     * 待结算
     */
    UNCOMMISSION(1, "待结算"),
    /**
     * 已结算
     */
    COMMISSION(2, "已结算"),
    /**
     * 已失效
     */
    INVALID(-1, "已失效"),
    ;
    private int value;
    private String desc;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DistributionUserIncomeTypeEnum.java
New file
@@ -0,0 +1,47 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.constants;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
 * 分销收入类型
 * @author yami
 */
@Getter
@AllArgsConstructor
public enum DistributionUserIncomeTypeEnum {
    /**
     * 其他奖励
     */
    OTHER(0, "其他"),
    /**
     * 直推奖励
     */
    AWARD_ONE(1, "直推奖励"),
    /**
     * 间推奖励
     */
    AWARD_TWO(2, "间推奖励"),
    /**
     * 邀请奖励
     */
    INVITATION(3, "邀请奖励"),
    /**
     * 平台修改
     */
    PLATFORM(4,"平台修改");
    private int value;
    private String desc;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DistributionUserStateEnum.java
New file
@@ -0,0 +1,46 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.constants;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
 * @author chendt
 * @date 2021/6/7 16:45
 */
@Getter
@AllArgsConstructor
public enum DistributionUserStateEnum {
    /**
     * 永久封禁
     */
    PER_BAN(-1, "永久封禁"),
    /**
     * 暂时封禁
     */
    BAN(2, "暂时封禁"),
    /**
     * 待审核状态
     */
    WAIT_AUDIT(0,"待审核状态"),
    /**
     * 正常
     */
    NORMAL(1, "正常"),
    /**
     * 审核未通过
     */
    FAIL_AUDIT(3,"审核未通过");
    private int value;
    private String desc;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/constants/DistributionWithdrawCashStateEnum.java
New file
@@ -0,0 +1,41 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.constants;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
 *  分销提现状态
 * @author yami
 */
@Getter
@AllArgsConstructor
public enum DistributionWithdrawCashStateEnum {
    /**
     * 提现中
     */
    APPLY(0, "提现中"),
    /**
     * 提现成功
     */
    CASH_SUCCESS(1, "提现成功"),
    /**
     * 提现失败
     */
    CASH_REJECT(2,"提现失败"),
    /**
     * 提现失败
     */
    CASH_FAIL(-1, "提现失败");
    private int value;
    private String desc;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionAuditingMapper.java
New file
@@ -0,0 +1,37 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.distribution.common.dto.DistributionAuditingDto;
import com.yami.shop.distribution.common.model.DistributionAuditing;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import org.apache.ibatis.annotations.Param;
/**
 * @author yami
 */
public interface DistributionAuditingMapper extends BaseMapper<DistributionAuditing> {
    /**
     * 获取分销员审核信息
     * @param page 分页信息
     * @param distributionAuditing 审核信息
     * @param rangeTimeParam 申请时间
     * @param startExpenseNumber 订单数量
     * @param endExpenseNumber 订单数量
     * @param startPayAmount 支付金额范围
     * @param endPayAmount 支付金额范围
     * @param mobile 手机号
     * @return 分销员审核信息
     */
    Page<DistributionAuditingDto> distributionAuditingPage(Page page, @Param("distributionAuditing") DistributionAuditing distributionAuditing, @Param("rangeTimeParam") RangeTimeParam rangeTimeParam, @Param("startExpenseNumber") Integer startExpenseNumber, @Param("endExpenseNumber")Integer endExpenseNumber, @Param("startPayAmount") Double startPayAmount, @Param("endPayAmount") Double endPayAmount, @Param("mobile") String mobile);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionMsgMapper.java
New file
@@ -0,0 +1,45 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.distribution.common.dto.DistributionMsgDto;
import com.yami.shop.distribution.common.model.DistributionMsg;
import org.apache.ibatis.annotations.Param;
/**
 * @author yami
 */
public interface DistributionMsgMapper extends BaseMapper<DistributionMsg> {
    /**
     * 查询分销通知
     * @param page 分页信息
     * @param distributionMsg 查询参数
     * @return 分销通知列表
     */
    IPage<DistributionMsg> getDistributionMsgsAndSysUserPage(Page page, @Param("distributionMsg") DistributionMsg distributionMsg);
    /**
     * 查询分销通知
     * @param page 分页信息
     * @param isTop 是否置顶
     * @return 分销通知列表
     */
    IPage<DistributionMsgDto> getDistributionMsgDtoByShopId(Page page, @Param("isTop") Integer isTop);
    /**
     * 获取分销通知详情
     * @param msgId 消息id
     * @return 分销通知详情
     */
    DistributionMsgDto getDistributionMsgDtoByMsgId(@Param("msgId") Long msgId);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionProdBindMapper.java
New file
@@ -0,0 +1,30 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.distribution.common.model.DistributionProdBind;
import org.apache.ibatis.annotations.Param;
/**
 * 分销商品绑定表
 *
 * @author xwc
 * @date 2019-04-22 10:01:44
 */
public interface DistributionProdBindMapper extends BaseMapper<DistributionProdBind> {
    /**
     * 根据分销员id修改状态(将商品分享记录设为失效)
     * @param distributionUserId 分销员id
     * @param state 状态
     */
    void updateStateByDistributionUserId(@Param("distributionUserId") Long distributionUserId,@Param("state") Integer state);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionProdMapper.java
New file
@@ -0,0 +1,81 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.model.DistributionProd;
import com.yami.shop.distribution.common.model.DistributionProdLog;
import com.yami.shop.distribution.common.po.DistributionProdPO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * @author yami
 */
public interface DistributionProdMapper extends BaseMapper<DistributionProd> {
    /**
     * 查询分销商品列表
     * @param page 分页参数
     * @param distributionProd 分销商品
     * @param prodName 商品名称
     * @param dbLang 语言
     * @return 分销商品列表
     */
    IPage<DistributionProd> distributionProdsPage(Page page, @Param("distributionProd") DistributionProd distributionProd, @Param("prodName") String prodName, @Param("dbLang") Integer dbLang);
    /**
     * 查询分销商品列表
     * @param page 分页参数
     * @param prodName 商品名称
     * @param sort 排序规则
     * @param orderBy 正序 / 倒序
     * @param dbLang 语言
     * @return 分销商品 分页
     */
    IPage<DistributionProdPO> distributionProdPoPage(Page page, @Param("prodName") String prodName,
                                                     @Param("sort") Integer sort, @Param("orderBy") Integer orderBy, @Param("dbLang") Integer dbLang);
    /**
     * 获取分销商品详情
     * @param prodId 商品id
     * @return 分销商品详情
     */
    DistributionProdPO getDistributionProdPoByProdId(@Param("prodId") Long prodId);
    /**
     * 更新分销商品状态
     * @param distributionProdId 分销商品id
     * @param state 状态
     * @return 是否更新成功
     */
    int updateState(@Param("distributionProdId") Long distributionProdId, @Param("state") int state);
    /**
     * 分销商品记录
     * @param page 分页参数
     * @param distributionProdLog 记录参数
     * @param dblang 语言
     * @return 分销商品记录
     */
    IPage<DistributionProdLog> getDistributionProdLogPage(@Param("page") PageParam<DistributionProdLog> page, @Param("distributionProdLog") DistributionProdLog distributionProdLog, @Param("dblang") Integer dblang);
    /**
     * 获取订单项中的分销商品信息
     * @param orderItems 订单项信息
     * @return 分销商品信息
     */
    List<DistributionProd> listByOrderItems(@Param("orderItems") List<OrderItem> orderItems);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionUserBanMapper.java
New file
@@ -0,0 +1,31 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.distribution.common.model.DistributionUserBan;
import org.apache.ibatis.annotations.Param;
/**
 * @author yami
 */
public interface DistributionUserBanMapper extends BaseMapper<DistributionUserBan> {
    /**
     * 分销员封禁列表
     * @param page 分页参数
     * @param shopId 店铺id
     * @param userMobile 手机号
     * @param distributionUserBan 查询参数
     * @return 封禁列表
     */
    IPage<DistributionUserBan> distributionUserBanPage(Page page, @Param("shopId") Long shopId, @Param("userMobile") String userMobile, @Param("distributionUserBan") DistributionUserBan distributionUserBan);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionUserBindMapper.java
New file
@@ -0,0 +1,96 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.distribution.common.dto.BindUserInfoDto;
import com.yami.shop.distribution.common.model.DistributionUserBind;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * @author yami
 */
public interface DistributionUserBindMapper extends BaseMapper<DistributionUserBind> {
    /**
     * 分销员和用户绑定关系列表
     * @param page 分页参数
     * @param distributionUserBind 绑定信息
     * @param bindTime 绑定时间
     * @param invalidTime 失效时间
     * @param userName 用户昵称
     * @param parentName 分销员昵称
     * @param cUserMobile 用户号码
     * @param dUserMobile 分销员号码
     * @return 分销员和用户绑定关系列表
     */
    IPage<DistributionUserBind> distributionMsgsAndUserPage(Page page, @Param("distributionUserBind") DistributionUserBind distributionUserBind,
                                                            @Param("bindTime") RangeTimeParam bindTime, @Param("invalidTime") RangeTimeParam invalidTime,
                                                            @Param("userName") String userName, @Param("parentName") String parentName,
                                                            @Param("cUserMobile") String cUserMobile, @Param("dUserMobile") String dUserMobile,
                                                            @Param("sort") Integer sort, @Param("orderBy") Integer orderBy);
    /**
     * 根据用户id和店铺Id获取绑定人id
     * @param shopId 店铺Id
     * @param userId 用户id
     * @param state 分销员绑定状态
     * @return 绑定的分销员id
     */
    Long getParentDistributionIdByShopIdAndUserId(@Param("shopId") Long shopId, @Param("userId") String userId, @Param("state") Integer state);
    /**
     * 根据客户id 店铺id 状态获取最新的一条记录
     * @param shopId 店铺Id
     * @param userId 用户id
     * @param state 分销员绑定状态
     * @return 最新的一条绑定记录
     */
    DistributionUserBind getNewDistributionUserBindByUserIdAndShopIdAndState(@Param("shopId") Long shopId, @Param("userId") String userId, @Param("state") Integer state);
    /**
     * 通过绑定的分销员id 更新 分销员绑定状态
     * @param distributionUserId 绑定的分销员id
     * @param state 分销员绑定状态
     */
    void updateStateAndReasonByDistributionUserId(@Param("distributionUserId") Long distributionUserId, @Param("state") Integer state);
    /**
     * 通过绑定的分销员userId 更新 分销员绑定状态
     * @param userId 绑定的分销员userId
     * @param state 分销员绑定状态
     */
    void updateStateAndReasonByUserId(@Param("userId") String userId, @Param("state") Integer state);
    /**
     * 获取绑定的用户信息
     * @param page 分页参数
     * @param shopId 店铺id
     * @param userId 用户id
     * @return 绑定的用户信息
     */
    IPage<BindUserInfoDto> bindUserList(Page page, @Param("shopId") Long shopId, @Param("userId") String userId);
    /**
     * 查询出所有的暂时封禁但已经被抢的用户
     * @param distributionUserBindList 绑定信息
     * @return 没有被抢的用户id列表
     */
    List<String> selectClearUserByDistributionUserId(@Param("distributionUserBindList") List<DistributionUserBind> distributionUserBindList);
    /**
     * 将没有被抢的,失效的绑定用户设为正常
     * @param distributionUserBinds 绑定用户列表
     */
    void recoveryRelationsByUserId(@Param("distributionUserBinds") List<DistributionUserBind> distributionUserBinds);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionUserGroupMapper.java
New file
@@ -0,0 +1,37 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.distribution.common.model.DistributionUserGroup;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * @author yami
 */
public interface DistributionUserGroupMapper extends BaseMapper<DistributionUserGroup> {
    /**
     * 分销员分组信息
     * @param page 分页参数
     * @param distributionUserGroup 查询参数
     * @return 分销员分组信息
     */
    IPage<DistributionUserGroup> distributionUserGroupsAndSysUserPage(Page page, @Param("distributionUserGroup") DistributionUserGroup distributionUserGroup);
    /**
     * 批量删除分组信息
     * @param ids ids
     */
    void deleteByIds(@Param("ids") List<Long> ids);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionUserIncomeMapper.java
New file
@@ -0,0 +1,156 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.dto.DistributionOrderDto;
import com.yami.shop.distribution.common.dto.DistributionUserIncomeDto;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.model.DistributionUserIncome;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import com.yami.shop.distribution.common.vo.DistributionOrdersVO;
import com.yami.shop.distribution.common.vo.DistributionUserInfoVO;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
 * @author yami
 */
public interface DistributionUserIncomeMapper extends BaseMapper<DistributionUserIncome> {
    /**
     * 获取分销员的收入记录
     * @param page 分页参数
     * @param shopId 店铺id
     * @param rangeTimeParam 时间范围
     * @param userMobile 手机号
     * @param orderNumber 订单号
     * @param state 收入状态
     * @param distributionUserIncome 分销员收入信息
     * @return 分销员的收入记录
     */
    IPage<DistributionUserIncome> incomeAndDistributionUserPage(Page page, @Param("shopId") Long shopId, @Param("rangeTimeParam") RangeTimeParam rangeTimeParam,
                                                                @Param("userMobile") String userMobile, @Param("orderNumber") String orderNumber,
                                                                @Param("state") Integer state,@Param("distributionUserIncome") DistributionUserIncome distributionUserIncome);
    /**
     * 分销员推广订单信息
     * @param page 分页参数
     * @param distributionUserId 分销员id
     * @return 分销员推广订单信息
     */
    IPage<DistributionOrderDto> getDistributionOrderDtoByDistributionUserId(Page page, @Param("distributionUserId") Long distributionUserId);
    /**
     * 根据订单号更新收入状态
     * @param state 状态
     * @param orderNumber 订单号
     */
    void updateStateByOrderNumber(@Param("state") Integer state, @Param("orderNumber") String orderNumber);
    /**
     * 根据分销员id更新收入状态
     * @param distributionUserId 分销员id
     * @param state 收入状态
     */
    void updateStateByDistributionUserId(@Param("distributionUserId") Long distributionUserId, @Param("state") Integer state);
    /**
     * 通过订单项、订单编号修改订单状态
     *
     * @param state 收入状态
     * @param orderNumber 订单号
     * @param orderItemId 订单项id
     */
    void updateStateByOrderNumberAndOrderItem(@Param("orderNumber") String orderNumber, @Param("orderItemId") Long orderItemId, @Param("state") int state);
    /**
     * 统计分销员某时间段收入
     * @param distributionUserId 分销员id
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 收入金额
     */
    Double statisticsDisUserIncome(@Param("distributionUserId") Long distributionUserId, @Param("startTime") Date startTime, @Param("endTime") Date endTime);
    /**
     * 查询分销员收入记录
     * @param page 分页参数
     * @param distributionUserId 分销员id
     * @return 收入记录
     */
    IPage<DistributionUserIncomeDto> getDistributionUserIncomePage(@Param("page") PageParam<DistributionUserIncome> page, @Param("distributionUserId") Long distributionUserId);
    /**
     * 通过状态获取我的推广订单(0:待支付 1:待结算 2:已结算 -1:订单失效)
     *
     * @param page 分页参数
     * @param distributionUserId 分销员id
     * @param state 收入状态 0:待支付 1:待结算 2:已结算 -1:订单失效
     * @param dbLang 语言
     * @return 我的推广订单
     */
    IPage<DistributionOrdersVO> getMyPromotionOrderByState(@Param("page") PageParam<DistributionOrdersVO> page, @Param("distributionUserId") Long distributionUserId, @Param("state") Integer state, @Param("dbLang") Integer dbLang);
    /**
     * 未结算的收益记录
     * @param orderNumbers 符合结算条件的订单列表
     * @return 收益记录
     */
    List<DistributionUserIncome> listWaitCommissionSettlement(@Param("orderNumbers") List<String> orderNumbers);
    /**
     * 批量更新收入记录
     * @param distributionUserIncomeList 收入记录列表
     * @param state 收入状态 0:待支付 1:待结算 2:已结算 -1:订单失效
     * @param reson
     * @return 是否更新成功
     */
    int updateBatchState(@Param("distributionUserIncomeList") List<DistributionUserIncome> distributionUserIncomeList, @Param("state") Integer state, @Param("reson")Integer reson);
    /**
     * 根据分销员id和订单流水号统计佣金和订单数量
     * @param userIds
     * @param orderNumbers
     * @param type  收益类型 收入类型(1一代奖励、2二代奖励 3邀请奖励 等 )
     * @param distributionUser
     * @return
     */
    List<DistributionUserInfoVO> selectIncomeInfo(@Param("userIds") List<String> userIds, @Param("orderNumbers")List<String> orderNumbers,
                                                  @Param("type")Integer type, @Param("distributionUser")DistributionUser distributionUser);
    /**
     * 根据订单号和分销员id修改收入状态
     * @param orderNumber
     * @param distributionUserId
     * @param state
     * @param type
     */
    void updateDistributionUserIncomesBy(@Param("list")List<String> orderNumber, @Param("id")Long distributionUserId, @Param("state")Integer state, @Param("type")Integer type);
    /**
     * 获取我的好友信息
     * @param distributionUser 当前用户
     * @param friends 该用户的好友
     * @param type 收益类型
     * @return
     */
    List<DistributionUserInfoVO> getFriendInfo(@Param("distributionUser")DistributionUser distributionUser,
                                               @Param("friends")List<DistributionUser> friends, @Param("type")Integer type);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionUserMapper.java
New file
@@ -0,0 +1,131 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.distribution.common.dto.AchievementDataDto;
import com.yami.shop.distribution.common.dto.DistributionUserAchievementDataDto;
import com.yami.shop.distribution.common.dto.DistributionUserSimpleDto;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * @author yami
 */
public interface DistributionUserMapper extends BaseMapper<DistributionUser> {
//    String getParentIdsByDistributionUserId(@Param("distributionUserId") Long distributionUserId);
    /**
     * 分销员业绩数据
     * @param id 分销员id
     * @return 分销员业绩数据
     */
    AchievementDataDto getAchievementDataDtoById(Long id);
    /**
     * 查询分销员列表
     * @param page 分页参数
     * @param distributionUser 查询参数
     * @param rangeTimeParam 分销员上级绑定时间
     * @param mobile 手机号
     * @param parentMobile 上级手机号
     * @param sortChange 排序规则
     * @return 分销员列表
     */
    IPage<DistributionUser> distributionUserPage(Page page, @Param("distributionUser") DistributionUser distributionUser
            , @Param("rangeTimeParam") RangeTimeParam rangeTimeParam, @Param("mobile") String mobile
            , @Param("parentMobile") String parentMobile, @Param("sortChange") Integer sortChange, @Param("state")Integer state);
    /**
     * 查询分销员列表
     * @param page 分页参数
     * @param distributionUser 查询参数
     * @param userMobile 手机号
     * @return 分销员列表
     */
    IPage<DistributionUser> getDistributionUserAchievementPage(Page page, @Param("distributionUser") DistributionUser distributionUser, @Param("userMobile") String userMobile);
    /**
     * 获取分销员与等级条件匹配的数据
     * @param distributionUserId 分销员id
     * @return 分销员与等级条件匹配的数据
     */
    DistributionUserAchievementDataDto getLevelDistributionUserAchievementDataByDistributionUserId(@Param("distributionUserId") Long distributionUserId);
//    Long getParentDistributionUserIdByDistributionUserId(@Param("distributionUserId") Long distributionUserId);
//    String getUserIdByDistributionUserId(@Param("distributionUserId") Long distributionUserId);
    /**
     * 分页获取精简版分销员数据
     * @param page 分页参数
     * @param parentDistributionUserId 上级分销员id
     * @return 精简版分销员分页数据
     */
    IPage<DistributionUserSimpleDto> getDistributionUserSimpleDtoByParentUserIdPage(Page page, @Param("parentDistributionUserId") Long parentDistributionUserId);
    /**
     * 修改分销员等级
     * @param distributionUserId 分销员id
     * @param level 等级
     */
    void updateLevel(@Param("distributionUserId") Long distributionUserId, @Param("level") Integer level);
    /**
     * 将已到达分销员的上限等级的替换掉 替换等级
     * @param shopId 店铺id
     * @param maxLevel 最大等级
     */
    void replaceLevel(@Param("shopId") Long shopId, @Param("maxLevel") int maxLevel);
    /**
     * 获取分销员列表
     * @param identityCardNumber 分销员身份证信息
     * @param userMobile 手机号
     * @return 分销员列表
     */
    List<DistributionUser> getDistributionUserByIdCardNumberAndUserMobile(@Param("identityCardNumber") String identityCardNumber, @Param("userMobile") String userMobile);
    /**
     * 获取大于等级的分销员用户id
     * @param shopId 店铺id
     * @param level 等级
     * @return 大于等级的分销员用户id
     */
    List<String> listByMaxLevel(@Param("shopId") Long shopId, @Param("maxLevel") int level);
    /**
     * 修改分销员状态
     * @param distributionUser 修改信息
     */
    void updateStatusById(@Param("distributionUser") DistributionUser distributionUser);
    /**
     * 根据分销员id清除他的下级关系
     * @param distributionUserId 被永久封禁的分销员id
     */
    void updateParentIdById(@Param("distributionUserId")Long distributionUserId);
//     int getLevelIdByDistributionUserId(Long distributionUserId);
    /**
     * 根据分销员推广号获取有效的分销订单orderNumber
     * @param cardNo
     * @return
     */
    List<String> selectDistributionOrderId(String cardNo);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionUserWalletBillMapper.java
New file
@@ -0,0 +1,52 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.distribution.common.dto.DistributionUserWalletBillDto;
import com.yami.shop.distribution.common.model.DistributionUserWalletBill;
import org.apache.ibatis.annotations.Param;
/**
 * 分销员钱包流水
 *
 * @author xwc
 * @date 2019-04-29 16:39:13
 */
public interface DistributionUserWalletBillMapper extends BaseMapper<DistributionUserWalletBill> {
    /**
     * 获取分销员钱包流水记录
     * @param page 分页参数
     * @param userMobile 手机号
     * @return 分销员钱包流水记录
     */
    Page<DistributionUserWalletBill> getDistributionUserWalletBillAndUserPage(Page page,@Param("userMobile") String userMobile);
    /**
     * 获取分销员钱包流水记录
     * @param page 分页参数
     * @param distributionUserId 分销员用户id
     * @param orderBy 排序方式
     * @return 分销员钱包流水记录
     */
    Page<DistributionUserWalletBillDto> getDistributionUserWalletBillDtoPage(Page page, @Param("distributionUserId") Long distributionUserId,@Param("orderBy") Integer orderBy);
    /**
     * 根据钱包id获取已提现金额
     * @param walletId
     * @return
     */
    Double getHaveWithdrawalSum(@Param("walletId") Long walletId);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionUserWalletMapper.java
New file
@@ -0,0 +1,72 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.distribution.common.dto.DistributionUserWalletDto;
import com.yami.shop.distribution.common.model.DistributionUserWallet;
import org.apache.ibatis.annotations.Param;
/**
 * @author yami
 */
public interface DistributionUserWalletMapper extends BaseMapper<DistributionUserWallet> {
    /**
     * 根据分销员id获取钱包id
     *
     * @param distributionUserId 分销员id
     * @return 钱包id
     */
    Long getWalletIdByDistributionUserId(@Param("distributionUserId") Long distributionUserId);
    /**
     * 返回钱包对象和用户vo分页
     *
     * @param page       分页参数
     * @param userMobile 手机号
     * @return 钱包对象和用户vo
     */
    Page<DistributionUserWallet> getDistributionUserWalletAndDistributionUserVoPage(Page page, @Param("userMobile") String userMobile);
    /**
     * 获取分销员钱包信息
     *
     * @param distributionUserId 分销员id
     * @return 分销员钱包信息
     */
    DistributionUserWalletDto getDistributionUserWalletDtoByDistributionUserId(@Param("distributionUserId") Long distributionUserId);
    /**
     * 根据分销员id修改钱包状态
     *
     * @param distributionUserId 分销员id
     * @param state              钱包状态
     */
    void updateStateByDistributionUserId(@Param("distributionUserId") Long distributionUserId, @Param("state") Integer state);
    /**
     * 永久封禁时根据分销员id更改金额为0
     *
     * @param distributionUserId 分销员id
     */
    void updateAmountByDistributionUserId(@Param("distributionUserId") Long distributionUserId);
    /**
     * 更新可提现金额
     *
     * @param distributionUserId
     * @param settledAmount
     */
    void updateSettledAmount(@Param("distributionUserId") Long distributionUserId, @Param("settledAmount") Double settledAmount);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dao/DistributionWithdrawCashMapper.java
New file
@@ -0,0 +1,63 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.distribution.common.dto.DistributionWithdrawCashDto;
import com.yami.shop.distribution.common.model.DistributionWithdrawCash;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import org.apache.ibatis.annotations.Param;
/**
 * @author yami
 */
public interface DistributionWithdrawCashMapper extends BaseMapper<DistributionWithdrawCash> {
    /**
     * 分页获取分销员提现申请记录
     * @param page 分页参数
     * @param shopId 店铺id
     * @param rangeTimeParam 申请时间
     * @param userMobile 手机号
     * @param distributionWithdrawCash 查询参数
     * @return 分销员提现申请记录
     */
    IPage<DistributionWithdrawCash> distributionWithdrawCashsPage(Page page, @Param("shopId") Long shopId, @Param("rangeTimeParam") RangeTimeParam rangeTimeParam, @Param("userMobile") String userMobile, @Param("distributionWithdrawCash") DistributionWithdrawCash distributionWithdrawCash);
    /**
     * 分页获取分销员提现申请记录
     * @param page 分页参数
     * @param distributionUserId 分销员id
     * @return 分销员提现申请记录
     */
    IPage<DistributionWithdrawCashDto> distributionWithdrawCashDtoPageByUserId(Page page, @Param("distributionUserId") Long distributionUserId);
    /**
     * 根据时间区间获取用户的提现次数
     * @param rangeTimeParam 时间范围
     * @param distributionuserId 分销员id
     * @return 分销员提现申请记录数量
     */
    Integer getCountByRangeTimeAndDistributionUserId(@Param("rangeTimeParam") RangeTimeParam rangeTimeParam, @Param("distributionuserId") Long distributionuserId);
    /**
     * 查看分销员总提现金额
     * @param walletId 钱包id
     * @return 总提现金额
     */
    Double getUserTotalWithdrawCash(@Param("walletId") Long walletId);
    /**
     * 永久封禁时,根据用户id更新其提现中的记录为拒绝提现
     * @param distributionUserId 用户id
     */
    void updateUserByDistributionUserId(@Param("distributionUserId") Long distributionUserId);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/AchievementDataDto.java
New file
@@ -0,0 +1,43 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * 分销员业绩数据
 * @author yami
 */
@Data
public class AchievementDataDto {
    /**
     * 积累绑定客户数
     */
    @Schema(description = "积累绑定客户数" )
    private Integer boundCustomers;
    /**
     * 积累邀请分销员数
     */
    @Schema(description = "积累邀请分销员数" )
    private Integer invitedVeeker;
    /**
     * 积累推广订单数
     */
    @Schema(description = "积累订单数" )
    private Integer orderCount;
    @Schema(description = "分销员钱包" )
    private DistributionUserWalletDto distributionUserWallet;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/BindUserInfoDto.java
New file
@@ -0,0 +1,48 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
/**
 * @author yami
 */
@Data
public class BindUserInfoDto  {
    @Schema(description = "0 失效 1生效" )
    private Integer state;
    @Schema(description = "0 超过有效期 1 管理员更改 2抢客" )
    private Integer invalidReason;
    @Schema(description = "变动时间" )
    private Date updateTime;
    @Schema(description = "绑定时间" )
    private Date bindTime;
    @Schema(description = "失效时间" )
    private Date invalidTime;
    @Schema(description = "用户昵称" )
    private String nickName;
    @Schema(description = "用户手机号" )
    private String userMobile;
    @Schema(description = "用户头像" )
    private String pic;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionAuditingDto.java
New file
@@ -0,0 +1,148 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.yami.shop.common.serializer.json.ImgJsonSerializer;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
 * @author yami
 */
@Data
public class DistributionAuditingDto {
    /**
     * 分销员申请表
     */
    private Long auditingId;
    /**
     * 店铺Id
     */
    private Long shopId;
    /**
     * 邀请人id
     */
    private Long parentDistributionUserId;
    /**
     * 申请人id
     */
    private Long distributionUserId;
    /**
     * 申请时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date auditingTime;
    /**
     * 不通过原因
     */
    private Integer reason;
    /**
     * 审核状态:0 未审核 1已通过 -1未通过
     */
    private Integer state;
    /**
     * 操作时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    /**
     * 操作人
     */
    private Long modifier;
    /**
     * 备注
     */
    private String remarks;
    //销售员信息
    /**
     * 用户id
     */
    private String userId;
    /**
     * 用户昵称
     */
    private String nickName;
    /**
     * 手机号码
     */
    private String userMobile;
    /**
     * 真实姓名
     */
    private String realName;
    /**
     * 身份证号
     */
    private String identityCardNumber;
    /**
     * 身份证正面
     */
    @JsonSerialize(using = ImgJsonSerializer.class)
    private String identityCardPicFront;
    /**
     * 身份证背面
     */
    @JsonSerialize(using = ImgJsonSerializer.class)
    private String identityCardPicBack;
    /**
     * 手持身份证照片
     */
    @JsonSerialize(using = ImgJsonSerializer.class)
    private String identityCardPicHold;
    // 总消费
    /**
     * 用户消费笔数
     */
    private Double expenseNumber;
    /**
     * 用户消费金额
     */
    private Double sumOfConsumption;
    /**
     * 邀请人信息
     */
    private String parentNickName;
    private String parentUserMobile;
    /**
     * 操作人信息
     */
    private String sysUserId;
    private String sysUsername;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionConfigDTO.java
New file
@@ -0,0 +1,86 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.math.BigDecimal;
import java.util.List;
/**
 * @author lhd
 * @date 2021-09-06 14:20:02
 */
@Data
@Schema(description = "分销配置")
public class DistributionConfigDTO {
    @Schema(description = "分销开关: 0:关闭 1:开启" )
    private Integer distributionSwitch;
    @Schema(description = "客户绑定设置-业绩归属 :  0:允许绑定,关系优先 1:不绑定 分享人优先" )
    private Integer attribution;
    /**
     * 申请条件配置-------------------------------------------------------------
     */
    @Schema(description = "0:人工判定 1:系统判定" )
    private Integer autoCheck;
    @Schema(description = "购买指定商品,确认收货任意一件商品后计入" )
    private List<Long> prodIdList;
    @Schema(description = "消费金额大于等于expenseAmount元,实付金额+积分抵扣+余额抵扣总金额,收货后计入" )
    @DecimalMax(value = "92233720368547758", message = "最大不能超过" + 92233720368547758L)
    private BigDecimal expenseAmount;
    @Schema(description = "消费笔数大于等于expenseNumber次,下单次数,收货后计入" )
    private Integer expenseNumber;
    @Schema(description = "是否需要真实姓名 true 需要 false不需要" )
    private Boolean realName;
    @Schema(description = "是否需要身份证号码 true 需要 false不需要" )
    private Boolean identityCardPic;
    @Schema(description = "是否需要身份证照片 true 需要 false不需要" )
    private Boolean identityCardNumber;
    @Schema(description = "提现发放方式: 0.无需审核直接发放,1.审核后系统发放,2.审核后人工发放" )
    private Integer withdrawal;
    /**
     * 提现申请配置-------------------------------------------------------------
     */
    @Schema(description = "提现频率(天)" )
    private Integer frequency;
    @Schema(description = "单笔提现最高(元)" )
    @Max(value = 20000, message = "单笔提现最高不能超过2W")
    private BigDecimal amountMax;
    @Schema(description = "单笔提现最低 (元)" )
    @Max(value = 19999, message = "单笔提现最低不能超过19999元")
    @Min(value = 1, message = "单笔提现最低不能低于1元")
    private BigDecimal amountMin;
    @Schema(description = "打款说明" )
    private String paymentExplain;
    @Schema(description = "提现次数" )
    @Min(value = 0, message = "提现次数不能小于0")
    private Integer number;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionLevelDto.java
New file
@@ -0,0 +1,40 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import com.yami.shop.distribution.common.vo.DistributionLevelConditionDataVO;
import com.yami.shop.distribution.common.vo.DistributionLevelConditionsSwitchVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * @author yami
 */
@Data
@Schema(description = "分销员等级对象")
public class DistributionLevelDto {
    @Schema(description = "等级id" )
    private Long levelId;
    @Schema(description = "等级名称" )
    private String name;
    @Schema(description = "等级级别" )
    private Integer level;
    @Schema(description = "等级所需条件" )
    private DistributionLevelConditionDataVO distributionLevelConditionDataVO;
    @Schema(description = "等级所需条件开关" )
    private DistributionLevelConditionsSwitchVO levelSetConditionsSwitch;
    @Schema(description = "用户是否在当前等级" )
    private Boolean isCurrentLevel;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionMsgDto.java
New file
@@ -0,0 +1,80 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.yami.shop.common.serializer.json.ImgJsonSerializer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
 * @author yami
 */
@Data
@Schema(description = "分销公告接口")
public class DistributionMsgDto {
    /**
     * 公告表
     */
    @TableId
    private Long msgId;
    /**
     * 公告级别(0 系统通知 1商家通知 2团队通知)
     */
    @Schema(description = "通知级别(0 系统通知 1商家通知 2团队通知)" )
    private Integer level;
    /**
     * 公告标题
     */
    @Schema(description = "通知标题" )
    private String msgTitle;
    /**
     * 发布时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Schema(description = "发布时间" )
    private Date startTime;
    /**
     * 是否置顶(0 不置顶 1 置顶)
     */
    @Schema(description = "是否置顶(0 不置顶 1 置顶)" )
    private Integer isTop;
    /**
     * 通知内容
     */
    @Schema(description = "通知内容" )
    private String content;
    /**
     * 通知封面图
     */
    @JsonSerialize(using = ImgJsonSerializer.class)
    @Schema(description = "通知封面图" )
    private String pic;
    /**
     * 通知类型(0:紧急通知, 1:活动通知,2:一般通知)
     */
    @Schema(description = "通知类型(0:紧急通知, 1:活动通知,2:一般通知)" )
    private Integer msgType;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionOrderDto.java
New file
@@ -0,0 +1,44 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
/**
 * @author yami
 */
@Data
@Schema(description = "分销员推广订单对象")
public class DistributionOrderDto {
    @Schema(description = "佣金数额" )
    private Double incomeAmount;
    @Schema(description = "佣金状态(0待支付,1用户未收货待结算,2收货已结算 -1订单失效)" )
    private Integer state;
    @Schema(description = "建单时间" ,required=true)
    private Date createTime;
    @Schema(description = "商品图片" ,required=true)
    private String pic;
    @Schema(description = "商品名称" ,required=true)
    private String prodName;
    @Schema(description = "商品id" ,required=true)
    private String prodId;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionOrderItemDto.java
New file
@@ -0,0 +1,39 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.yami.shop.common.serializer.json.ImgJsonSerializer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * @author yami
 */
@Data
@Schema(description = "分销订单项")
public class DistributionOrderItemDto {
    @Schema(description = "商品名称" )
    private String prodName;
    @Schema(description = "商品价格" )
    private Double price;
    @Schema(description = "商品图片" )
    @JsonSerialize(using = ImgJsonSerializer.class)
    private String pic;
    @Schema(description = "商品数量" )
    private Integer prodCount;
    @Schema(description = "规格名称" )
    private String skuName;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionProdDto.java
New file
@@ -0,0 +1,44 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.yami.shop.common.serializer.json.ImgJsonSerializer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * @author yami
 */
@Data
public class DistributionProdDto {
    @Schema(description = "商品名称" ,required=true)
    private String prodName;
    @Schema(description = "商品ID" ,required=true)
    private Long prodId;
    @Schema(description = "商品主图" ,required=true)
    @JsonSerialize(using = ImgJsonSerializer.class)
    private String pic;
    @Schema(description = "商品价格" ,required=true)
    private Double price;
    @Schema(description = "奖励数额(元/百分比)" ,required=true)
    private Double awardNumber;
    @Schema(description = "上级奖励数额(元/百分比)" )
    private Double  parentAwardNumber;
    @Schema(description = "奖励比例(0 按比例 1 按固定数值)" ,required=true)
    private Integer awardProportion;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionRecruitConfigDTO.java
New file
@@ -0,0 +1,41 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
 * @author lhd
 * @date 2021-09-06 14:20:02
 */
@Data
@Schema(description = "分销招募推广配置")
public class DistributionRecruitConfigDTO {
    @Schema(description = "推广图" )
    private String pic;
    @Schema(description = "推广标题" )
    @NotBlank(message = "推广标题不能为空")
    private String title;
    @Schema(description = "推广内容" )
    @NotBlank(message = "推广内容不能为空")
    private String content;
    @Schema(description = "推广链接" )
    private String url;
    @Schema(description = "推广开关: 状态(0下线 1上线)" )
    private Integer state;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionRecruitSetDto.java
New file
@@ -0,0 +1,36 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.yami.shop.common.serializer.json.ImgJsonSerializer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * @author yami
 */
@Data
@Schema(description = "分校推广数据")
public class DistributionRecruitSetDto {
    @Schema(description = "推广图" )
    @JsonSerialize(using = ImgJsonSerializer.class)
    private String pic;
    @Schema(description = "标题" )
    private String title;
    @Schema(description = "推广内容" )
    private String content;
    @Schema(description = "状态(0下线 1上线)" )
    private Integer state;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionSettlementDto.java
New file
@@ -0,0 +1,36 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import lombok.Data;
/**
 * 后台结算页面数据
 * @author yami
 */
@Data
public class DistributionSettlementDto {
    /**
     * 订单号
     */
    private String orderNumber;
    /**
     * 订单状态 -1 已取消 0:待付款 1:待发货 2:待收货 3:已完成
     */
    private Integer status;
    /**
     * 订单总佣金
     */
    private Double sumAmount;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserAchievementDataDto.java
New file
@@ -0,0 +1,77 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import com.yami.shop.distribution.common.vo.DistributionUserIncomeVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * 分销员数据
 * @author yami
 */
@Data
public class DistributionUserAchievementDataDto {
    /**
     * 积累绑定客户数
     */
    @Schema(description = "积累绑定客户数" )
    private Integer boundCustomers;
    /**
     * 积累邀请分销员数
     */
    private Integer invitedVeeker;
    /**
     * 积累支付单数
     */
    private Integer payNumber;
    /**
     * 积累成功成交单数
     */
    private Integer successOrderNumber;
    /**
     * 积累成功成交金额
     */
    private Integer successTradingVolume;
    /**
     * 积累推广订单数
     */
    private Integer orderNumber;
    /**
     * 用户消费笔数
     */
    private Double expenseNumber;
    /**
     * 用户消费金额
     */
    private Double sumOfConsumption;
//    /**
//     * 积累充值金额
//     */
//    private Double rechargeAmount ;
    /**
     * 分销员收益明细
     */
    @Schema(description = "收益明细" )
    private DistributionUserIncomeVO distributionUserIncome;
    @Schema(description = "分销员钱包" )
    private DistributionUserWalletDto distributionUserWallet;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserDto.java
New file
@@ -0,0 +1,53 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.yami.shop.common.serializer.json.ImgJsonSerializer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * @author yami
 */
@Data
public class DistributionUserDto {
    @Schema(description = "分销员id" )
    private Long distributionUserId;
    @Schema(description = "分销员昵称" )
    private String  nickName;
    @Schema(description = "分销员卡号" )
    private String cardNo;
    @Schema(description = "分销员手机号" )
    private String userMobile;
    @Schema(description = "头像" )
    @JsonSerialize(using = ImgJsonSerializer.class)
    private String pic;
    @Schema(description = "分销员状态 (-1永久封禁 0 待审核 1 正常 2 暂时封禁 3审核失败)" )
    private Integer state;
    @Schema(description = "分销员等级" )
    private Integer level;
    @Schema(description = "分销员等级名称" )
    private String levelName;
    @Schema(description = "推广状态(0下线 1上线)" )
    private Integer recruitState;
//
//    @Schema(description = "分销员各项数据" )
//    private AchievementDataDto distributionUserAchievementData;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserIncomeDto.java
New file
@@ -0,0 +1,36 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
 * @author yami
 */
@Data
@Schema(description = "分销员收入数据")
public class DistributionUserIncomeDto {
    @Schema(description = "收入类型(0其他、1直推奖励、2间推奖励、3邀请奖励、4平台修改 )" )
    private Integer incomeType;
    @Schema(description = "佣金数额" )
    private Double incomeAmount;
    @Schema(description = "更新时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    @Schema(description = "佣金状态(0:待支付、1:待结算、2:已结算、-1:订单失效)" )
    private Integer state;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserIncomeOrderDto.java
New file
@@ -0,0 +1,44 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
 * @author yami
 */
@Data
@Schema(description = "分销员推广订单对象")
public class DistributionUserIncomeOrderDto {
    @Schema(description = "订单编号" )
    private String orderNumber;
    @Schema(description = "收入金额" )
    private Double incomeAmount;
    @Schema(description = "商品数量" )
    private String productNums;
    @Schema(description = "商品名称" )
    private String prodName;
    @Schema(description = "实际支付" )
    private Double actualTotal;
    @Schema(description = "订单状态(0:待支付 1:待结算 2:已结算 -1:订单失效)" )
    private Integer state;
    @Schema(description = "分销订单项列表" )
    private List<DistributionOrderItemDto> orderItemDtoList;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserOrderItemDTO.java
New file
@@ -0,0 +1,19 @@
package com.yami.shop.distribution.common.dto;
import com.yami.shop.bean.model.Order;
import lombok.Data;
import java.util.List;
/**
 * 分销员和他的用户所有订单项
 * @author
 */
@Data
public class DistributionUserOrderItemDTO {
    private Long distributionUserId;
    private List<Order> orders;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserSimpleDto.java
New file
@@ -0,0 +1,39 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
/**
 * @author yami
 */
@Data
@Schema(description = "精简版分销员数据")
public class DistributionUserSimpleDto {
    @Schema(description = "分销员昵称" )
    private Long distributionUserId;
    @Schema(description = "分销员昵称" )
    private String nickName;
    @Schema(description = "真实姓名" )
    private String realName;
    @Schema(description = "头像" )
    private String pic;
    @Schema(description = "绑定时间" )
    @JsonFormat(pattern = "yyyy/MM/dd")
    private Date bindTime;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserWalletBillDto.java
New file
@@ -0,0 +1,53 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
/**
 * @author yami
 */
@Data
@Schema(description = "钱包流水记录")
public class DistributionUserWalletBillDto {
    /**
     * 待结算金额变更数额
     */
    @Schema(description = "待结算金额变更数额" )
    private Double unsettledAmount;
    /**
     * 可提现金额变更数额
     */
    @Schema(description = "可提现金额变更数额" )
    private Double settledAmount;
    /**
     * 失效金额变更数额
     */
    @Schema(description = "失效金额变更数额" )
    private Double invalidAmount;
    /**
     * 积累收益变更数额
     */
    @Schema(description = "积累收益变更数额" )
    private Double addupAmount;
    /**
     * 创建时间
     */
    @Schema(description = "创建时间" )
    private Date createTime;
    /**
     * 备注
     */
    @Schema(description = "备注" )
    private String remarks;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionUserWalletDto.java
New file
@@ -0,0 +1,47 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * @author yami
 */
@Data
@Schema(description = "分销员钱包数据")
public class DistributionUserWalletDto {
    /**
     * 待结算金额
     */
    @Schema(description = "待结算金额" )
    private Double unsettledAmount;
    /**
     * 可提现金额
     */
    @Schema(description = "可提现金额" )
    private Double settledAmount;
    /**
     * 已失效金额
     */
    @Schema(description = "已失效金额" )
    private Double invalidAmount;
    /**
     * 积累收益
     */
    @Schema(description = "积累收益(包含已经提现的佣金和可提现佣金)" )
    private Double addupAmount;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionWithdrawCashDto.java
New file
@@ -0,0 +1,83 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
 * @author yami
 */
@Data
@Schema(description = "提现数据")
public class DistributionWithdrawCashDto {
    /**
     * 提现记录id
     */
    @Schema(description = "提现记录id" )
    private Long withdrawCashId;
    /**
     * 金额
     */
    @Schema(description = "提现金额" )
    private Double amount;
    /**
     * 手续费
     */
    @Schema(description = "手续费" )
    private Double fee;
    /**
     * 类型(0 手动提现 1自动提现)
     */
    @Schema(description = "类型(0线下打款 1线上打款)" )
    private Integer type;
    /**
     * 资金流向(0 微信红包 1企业付款到微信零钱)
     */
    @Schema(description = "0 微信红包 1企业付款到微信零钱" )
    private Integer moneyFlow;
    /**
     * 流水号
     */
    @Schema(description = "流水号" )
    private String merchantOrderId;
    /**
     * 提现状态(0:申请中 1:提现成功 2:拒绝提现 -1:提现失败)
     */
    @Schema(description = "提现状态(0:申请中 1:提现成功 2:拒绝提现 -1:提现失败)" )
    private Integer state;
    /**
     * 创建时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Schema(description = "创建时间" )
    private Date createTime;
    /**
     * 更新时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Schema(description = "更新时间" )
    private Date updateTime;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/DistributionWithdrawCashSetDto.java
New file
@@ -0,0 +1,56 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * @author yami
 */
@Schema(description = "商家提现设置")
@Data
public class DistributionWithdrawCashSetDto {
    /**
     * 提现频率(天)
     */
    @Schema(description = "提现频率(天)" )
    private Integer frequency;
    /**
     * 提现次数
     */
    @Schema(description = "提现次数(N天N次)" )
    private Integer number;
    /**
     * 单笔提现最高
     */
    @Schema(description = "单笔提现最高" )
    private Double amountMax;
    /**
     * 单笔提现最低
     */
    @Schema(description = "单笔提现最低" )
    private Double amountMin;
    /**
     * 打款说明
     */
    @Schema(description = "打款说明" )
    private String paymentExplain;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/dto/StatisticsDisUserIncomeDto.java
New file
@@ -0,0 +1,26 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * @author yami
 */
@Data
public class StatisticsDisUserIncomeDto {
    @Schema(description = "今日收益" )
    private Double todayAmount;
    @Schema(description = "本月收益" )
    private Double monthAmount;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/listener/CategoryDistributionListener.java
New file
@@ -0,0 +1,34 @@
package com.yami.shop.distribution.common.listener;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.event.CategoryWordEvent;
import com.yami.shop.distribution.common.constants.DistributionProdStateEnum;
import com.yami.shop.distribution.common.model.DistributionProd;
import com.yami.shop.distribution.common.service.DistributionProdService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.List;
@Component("CategoryDistributionListener")
@Slf4j
@AllArgsConstructor
public class CategoryDistributionListener {
    private final DistributionProdService distributionProdService;
    @EventListener(CategoryWordEvent.class)
    public void categoryListener(CategoryWordEvent event){
        List<Long> prodIds = event.getProdIdList();
        // 失效分销活动
        if(CollUtil.isNotEmpty(prodIds)){
            distributionProdService.update(Wrappers.lambdaUpdate(DistributionProd.class)
                    .set(DistributionProd::getState, DistributionProdStateEnum.PUT_OFF.getValue())
                    .in(DistributionProd::getProdId, prodIds)
                    .eq(DistributionProd::getState, DistributionProdStateEnum.PUT_ON.getValue())
            );
        }
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/listener/OpenShopInitListener.java
New file
@@ -0,0 +1,50 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.listener;
import com.yami.shop.bean.event.OpenShopInitEvent;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
/**
 * 开店初始化事件
 * @author yami
 */
@Slf4j
@Component("distributionOpenShopInitListener")
@AllArgsConstructor
public class OpenShopInitListener {
//    private final DistributionBasicSetService distributionBasicSetService;
    @EventListener(OpenShopInitEvent.class)
    public void openShopInitDistributionSetEvent(OpenShopInitEvent event) {
//        ShopDetail shopDetail = event.getShopDetail();
//        // 添加设置
//        DistributionBasicSet distributionBasicSet = new DistributionBasicSet();
//        // 分销互购
//        distributionBasicSet.setParallelDeal(0);
//        // 分销自购
//        distributionBasicSet.setOwnBuyAward(0);
//        // 会员价购买
//        distributionBasicSet.setVipBuyAward(0);
//        // 分销总开关
//        distributionBasicSet.setDistributionSwitch(1);
//
//        // 0表示为系统设置
//        distributionBasicSet.setModifierId(0L);
//        distributionBasicSet.setUpdateTime(new Date());
//        distributionBasicSet.setShopId(shopDetail.getShopId());
//        distributionBasicSet.setShopName(shopDetail.getShopName());
//        distributionBasicSetService.save(distributionBasicSet);
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/listener/OrderSettlementListener.java
New file
@@ -0,0 +1,55 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.listener;
import com.yami.shop.bean.enums.OrderType;
import com.yami.shop.bean.event.OrderSettlementEvent;
import com.yami.shop.bean.order.ConfirmOrderOrder;
import com.yami.shop.distribution.common.service.DistributionUserIncomeService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
 * 订单结算的事件
 * @author yami
 */
@Slf4j
@Component("orderSettlementDistributionListener")
@AllArgsConstructor
public class OrderSettlementListener {
    private final DistributionUserIncomeService distributionUserIncomeService;
    @EventListener(OrderSettlementEvent.class)
    @Order(ConfirmOrderOrder.DEFAULT)
    public void distributionSettlementOrderEvent(OrderSettlementEvent event) {
        List<String> orderNumbers = new ArrayList<>();
        for (com.yami.shop.bean.model.Order order : event.getOrder()) {
            //如果是积分订单无需操作
            if (Objects.equals(order.getOrderType(), OrderType.SCORE.value())) {
                continue;
            }
            orderNumbers.add(order.getOrderNumber());
        }
        if(CollectionUtils.isNotEmpty(orderNumbers)) {
            distributionUserIncomeService.commissionSettlementHandle(orderNumbers);
        }
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/listener/PaySuccessOrderListener.java
New file
@@ -0,0 +1,583 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.listener;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yami.shop.bean.event.PaySuccessOrderEvent;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.order.PaySuccessOrderOrder;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.Arith;
import com.yami.shop.distribution.common.constants.DistributionAudit;
import com.yami.shop.distribution.common.constants.DistributionUserIncomeStateEnum;
import com.yami.shop.distribution.common.constants.DistributionUserStateEnum;
import com.yami.shop.distribution.common.dao.DistributionUserBindMapper;
import com.yami.shop.distribution.common.model.*;
import com.yami.shop.distribution.common.po.DistributionProdPO;
import com.yami.shop.distribution.common.service.*;
import com.yami.shop.distribution.common.vo.DistributionAwardDataVO;
import com.yami.shop.distribution.common.vo.DistributionConfigVO;
import com.yami.shop.service.OrderItemService;
import com.yami.shop.service.OrderService;
import com.yami.shop.service.SysConfigService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
/**
 * 支付成功事件
 * @author yami
 */
@Slf4j
@Component("distributionPaySuccessOrderListener")
@AllArgsConstructor
public class PaySuccessOrderListener {
    private final DistributionUserIncomeService distributionUserIncomeService;
    private final SysConfigService sysConfigService;
    private final DistributionBindUserService distributionBindUserService;
    private final DistributionUserService distributionUserService;
    private final DistributionProdService distributionProdService;
    private final DistributionUserWalletService distributionUserWalletService;
    private final DistributionUserWalletBillService distributionUserWalletBillService;
    private final OrderItemService orderItemService;
    private final OrderService orderService;
    private final DistributionUserBindMapper distributionUserBindMapper;
    @EventListener(PaySuccessOrderEvent.class)
    @org.springframework.core.annotation.Order(PaySuccessOrderOrder.DISTRIBUTION)
    public void distributionPaySuccessOrderEvent(PaySuccessOrderEvent event) {
        if(Objects.equals(event.getOrders().get(0).getShopId(),Constant.PLATFORM_SHOP_ID)){
            return;
        }
        // 店铺分销基础设置
        DistributionConfigVO distributionConfigVO = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_CONFIG, DistributionConfigVO.class);
        // 没有开启分销
        if (distributionConfigVO == null || distributionConfigVO.getDistributionSwitch() == 0) {
            log.debug("平台没有开启分销,跳过分销的流程");
            return;
        }
        // 设置为分销的订单项
        List<OrderItem> distributionOrderItems = new ArrayList<>();
        List<Order> orders = event.getOrders();
        // 不绑定,分享人优先
        if (distributionConfigVO.getAttribution() == 1){
            log.info("过滤没有推广卡号的订单项");
            orders.forEach( item -> {
                List<OrderItem> orderItems = item.getOrderItems();
                orderItems.removeIf(orderItem -> StringUtils.isEmpty(orderItem.getDistributionCardNo()));
                item.setOrderItems(orderItems);
            });
        }
        //过滤封禁分销员推广的分销订单
        if (filtrationOrders(orders, distributionConfigVO)){
            return;
        }
        // 获取所有商品分销状态为1的分销商品
        List<DistributionProd> distributionProds = distributionProdService.listByOrderItems(event.getAllOrderItems());
        List<Long> prodIds = distributionProds.stream().map(DistributionProd::getProdId).collect(Collectors.toList());
        // 所有的订单项
        for (Order order : orders) {
            // 所有的订单项
            List<OrderItem> orderItems = order.getOrderItems();
            boolean isFirstGetBindUser = true;
            DistributionUser oldDistributionUser = null;
            for (OrderItem orderItem : orderItems) {
                // 如果没有状态正常的分销商品则不能进行分销
                if(!prodIds.contains(orderItem.getProdId())){
                    continue;
                }
                // 如果该订单项有分销信息,则将该订单项放入distributionOrderItems中
                if (StrUtil.isNotBlank(orderItem.getDistributionCardNo()) && this.checkSelfShare(orderItem, distributionConfigVO)) {
                    distributionOrderItems.add(orderItem);
                    //处理用户绑定和一二级佣金的
                    doDistribution(oldDistributionUser,orderItem, distributionConfigVO);
                    continue;
                }
                // 初始化用户的旧绑定分销员
                if (isFirstGetBindUser) {
                    isFirstGetBindUser = false;
                    // 查询该用户以前绑定的分享人
                    DistributionUserBind distributionUserBind = distributionUserBindMapper.selectOne(new LambdaQueryWrapper<DistributionUserBind>()
                            .eq(DistributionUserBind::getShopId, Constant.PLATFORM_SHOP_ID)
                            .eq(DistributionUserBind::getState, 1)
                            .eq(DistributionUserBind::getUserId, order.getUserId())
                    );
                    // 该用户以前有绑定分享人
                    if (distributionUserBind != null) {
                        // 查询以前的绑定的用户信息-并赋值
                        oldDistributionUser = distributionUserService.getById(distributionUserBind.getDistributionUserId());
                    }
                }
                if (oldDistributionUser == null) {
                    continue;
                }
                if (!Objects.equals(oldDistributionUser.getState(), 1)) {
                    continue;
                }
                // 设置分销员卡号-用户直接购买商品时,前端没传分销员卡号,需要手动插入
                orderItem.setDistributionCardNo(oldDistributionUser.getCardNo());
                // 将订单项添加到分销项中
                distributionOrderItems.add(orderItem);
                doDistribution(oldDistributionUser,orderItem, distributionConfigVO);
            }
        }
        // 更新分销订单项
        updateOrderItems(distributionOrderItems, orders);
    }
    /**
     * 过滤分销员封禁后推广的分销商品
     * @param orders
     */
    public boolean filtrationOrders(List<Order> orders, DistributionConfigVO distributionConfigVO){
        // 获取分销员卡号
        String carNo = null;
        for (Order order : orders) {
            for (OrderItem orderItem : order.getOrderItems()) {
                if (StringUtils.isNotBlank(orderItem.getDistributionCardNo())){
                    carNo = orderItem.getDistributionCardNo();
                    break;
                }
            }
        }
        // 分享人优先,需要是扫码分销的订单才进行分销
        if (distributionConfigVO.getAttribution() == 1 && StrUtil.isBlank(carNo)) {
            return true;
        }
        // 关系链优先不用传卡号,不需要校验分销员封禁(已绑定的分销员在封禁时会解绑)
        if (StrUtil.isBlank(carNo)) {
            return false;
        }
        DistributionUser distributionUser = distributionUserService.getOne(new LambdaQueryWrapper<DistributionUser>().eq(DistributionUser::getCardNo, carNo));
        if (!Objects.equals(distributionUser.getState(), DistributionUserStateEnum.NORMAL.getValue())) {
            log.info("过滤分销员封禁后推广的分销商品");
            return true;
        }
        return false;
    }
    private void updateOrderItems(List<OrderItem> distributionOrderItems, List<Order> orders) {
        if (CollectionUtils.isNotEmpty(distributionOrderItems)) {
            // 更新订单的分销金额,及订单项的分销金额
            Map<String, List<OrderItem>> orderItemMap = distributionOrderItems.stream().collect(Collectors.groupingBy(OrderItem::getOrderNumber));
            for (String orderNumber : orderItemMap.keySet()) {
                List<OrderItem> orderItems = orderItemMap.get(orderNumber);
                double distributionAmount = 0.0;
                for (OrderItem orderItem : orderItems) {
                    distributionAmount = Arith.add(distributionAmount,Objects.isNull(orderItem.getDistributionAmount())? 0.0:orderItem.getDistributionAmount());
                    distributionAmount = Arith.add(distributionAmount,Objects.isNull(orderItem.getDistributionParentAmount())? 0.0:orderItem.getDistributionParentAmount());
                }
                // 分销金额放进去order里面
                for (Order order : orders) {
                    if(StrUtil.equals(orderNumber,order.getOrderNumber())){
                        order.setDistributionAmount(distributionAmount);
                    }
                }
                orderService.update(new LambdaUpdateWrapper<Order>().set(Order::getDistributionAmount,distributionAmount)
                        .eq(Order::getOrderNumber,orderNumber));
            }
            orderItemService.updateBatchById(distributionOrderItems);
        }
    }
    /**
     * 进行分销操作
     * @param oldShareUser 用户已绑定的分销员
     * @param orderItem 订单项
     * @param distributionConfigVO 分销配置
     */
    private void doDistribution(DistributionUser oldShareUser, OrderItem orderItem, DistributionConfigVO distributionConfigVO){
        DistributionUser shareUser;
        DistributionUser bindUser;
        if (oldShareUser != null && Objects.equals(orderItem.getDistributionCardNo(), oldShareUser.getCardNo())){
            shareUser = oldShareUser;
            bindUser = oldShareUser;
        } else {
            shareUser = distributionUserService.getByCardNo(orderItem.getDistributionCardNo());
            // 判断是否可以进行分销操作
            if(checkAmountOver(shareUser, orderItem)){
                return;
            }
            // 自推不进行绑定
            if(Objects.equals(orderItem.getUserId(), shareUser.getUserId())){
                return;
            }
            // 绑定绑定销售员信息
            ServerResponseEntity serverResponse = distributionBindUserService.bindDistribution(shareUser, orderItem.getUserId(), 1);
            if (serverResponse.isFail()) {
                log.info("绑定销售员信息失败,跳过分销流程,订单号:{}, 订单项Id:{}",orderItem.getOrderNumber(),orderItem.getOrderItemId());
            }
            // 绑定的用户
            bindUser = (DistributionUser) serverResponse.getData();
        }
//        // 没有开启分销员自购,也就是自己推广自己的东西没有收益
//        if (Objects.equals(shareUser.getUserId(), orderItem.getUserId()) && !Objects.equals(basicSet.getOwnBuyAward(), 1)) {
//            log.info("没有开启分销员自购,推广人不能自己哟");
//            // 推广人不能自己哟
//            return;
//        } else {
//            // 看看自己是不是分销员,如果没有开启分销员互购,自己是分销员推广人也没有收益
//            DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(orderItem.getUserId(), shareUser.getShopId());
//            // 下单的用户以前申请过分销员,但现在又不是了,所以就将分销员信息置空
//            if (distributionUser != null && !Objects.equals(distributionUser.getState(), 1)) {
//                distributionUser = null;
//            }
//
//            // 没有开启互购
//            if (!Objects.equals(basicSet.getParallelDeal(), 1) && distributionUser != null
//                    && !Objects.equals(distributionUser.getDistributionUserId(), shareUser.getDistributionUserId())) {
//                log.info("店铺没有开启互购,购买用户也已成为该店铺的推广员,无法被推广");
//                // 您已成为该店铺的推广员,无法被推广
//                return;
//            }
//        }
        //推广人若为永久封禁
        if (Objects.equals(shareUser.getState(),DistributionUserStateEnum.PER_BAN.getValue()) || Objects.equals(shareUser.getState(), DistributionUserStateEnum.BAN.getValue())){
            log.info("推广员已被暂时封禁或永久封禁");
            return;
        }
        // 添加收入流水记录并将收入添加到待结算金额到钱包中
        createIncomeByOrderItem(distributionConfigVO, shareUser, bindUser, orderItem);
    }
    /**
     * 创建订单项收入记录添加待结算金额到钱包中
     */
    private void createIncomeByOrderItem(DistributionConfigVO distributionConfigVO, DistributionUser shareUser, DistributionUser bindUser, OrderItem orderItem) {
        //判断是否会产生分销业绩
        if (Objects.isNull(bindUser) && Objects.isNull(shareUser)) {
            log.error("没有分享人,没有关系人,不产生业绩");
            return;
        }
        //获取该分销商品的设置数据
        DistributionProdPO distributionProdPo = distributionProdService.getDistributionProdPoByProdId(orderItem.getProdId());
        // 这件商品原本是分销商品被加入了购物车,后来又不是了
        if (distributionProdPo == null) {
            return;
        } else {
            distributionProdPo.setShopId(orderItem.getShopId());
            // 计算佣金,用实付金额计算
            distributionProdPo.setPrice(orderItem.getActualTotal());
        }
        //定义一个最终的业绩归属人变量
        DistributionUser finalDistributionUser;
        //判断是分享人优先还是关系链优先 0 允许绑定,关系优先,1,不绑定 分享人优先
        if (distributionConfigVO.getAttribution() == 0) {
            //关系链优先
            log.info("关系链优先,关系人获得业绩");
            finalDistributionUser = bindUser;
        } else {
            //分享人优先
            log.info("分享人优先,分享人获得业绩");
            finalDistributionUser = shareUser;
        }
        // 关系链优先时,用户扫了别的分销员二维码,
        // 前端传的分销员卡号不是该用户绑定分销员的卡号,所以要重新插入下
        orderItem.setDistributionCardNo(finalDistributionUser.getCardNo());
        if (finalDistributionUser == null) {
            log.info("没有找到业绩归属者");
            return;
        }
        // 判断是否可以进行分销操作
        if(checkAmountOver(finalDistributionUser, orderItem)){
            return;
        }
        DistributionUserIncome distributionUserIncome = new DistributionUserIncome();
        distributionUserIncome.setOrderNumber(orderItem.getOrderNumber());
        distributionUserIncome.setOrderItemId(orderItem.getOrderItemId());
        distributionUserIncome.setCreateTime(new Date());
        distributionUserIncome.setUpdateTime(new Date());
        //计算佣金金额
        DistributionAwardDataVO distributionAwardDataVO = distributionProdService.getAwardDataVO(distributionProdPo, finalDistributionUser.getDistributionUserId(),orderItem);
        //创建插入业绩记录对象
            // 直推奖励
        insertAwardNumber(orderItem, finalDistributionUser, distributionAwardDataVO, distributionUserIncome);
        //不使用默认奖励
        if (Objects.equals(distributionProdPo.getDefaultReward(),0)){
            //是否开启了上级奖励(0 关闭 1开启)
            if (!Objects.equals(distributionProdPo.getParentAwardSet(), 1)) {
                log.info("没有开启上级奖励");
                return;
            }
        }
        //获取上级id
        if (Objects.isNull(finalDistributionUser.getParentId()) && Objects.equals(distributionConfigVO.getAttribution(),0)) {
            log.info("无法获取推广员的上级id");
            return;
        }
        if(distributionAwardDataVO.getParentAwardNumber() == 0) {
            log.info("订单编号-{},商品id-{}:二级分销金额为0,不进行二级分销的操作", orderItem.getOrderNumber(), orderItem.getProdId());
            return;
        }
        // 需要失效记录注释
    /*    double totalAwardNumber = Arith.add(distributionAwardDataVO.getAwardNumber() ,distributionAwardDataVO.getParentAwardNumber());
        if(totalAwardNumber >= orderItem.getActualTotal()) {
            log.info("订单编号-{},商品id-{}:总分销金额大于等于实付金额,不进行二级分销的操作", orderItem.getOrderNumber(), orderItem.getProdId());
            return;
        }*/
        log.info("进入上级奖励流程");
        // 间推奖励
        insertParentAwardNumber(distributionConfigVO, orderItem, finalDistributionUser, bindUser, distributionAwardDataVO, distributionUserIncome);
    }
    /**
     * 检查分销金额是否超出订单项金额
     * @param finalDistributionUser
     * @param orderItem
     * @return
     */
    private boolean checkAmountOver(DistributionUser finalDistributionUser, OrderItem orderItem) {
        //获取该分销商品的设置数据
        DistributionProdPO distributionProdPo = distributionProdService.getDistributionProdPoByProdId(orderItem.getProdId());
        // 这件商品原本是分销商品被加入了购物车,后来又不是了
        if (distributionProdPo == null) {
            return true;
        } else {
            distributionProdPo.setShopId(orderItem.getShopId());
            // 计算佣金,用实付金额计算
            distributionProdPo.setPrice(orderItem.getActualTotal());
        }
        // 如果是没开启上级奖励,则上级比例为0
        if(Objects.equals(distributionProdPo.getParentAwardSet(),0)){
            distributionProdPo.setParentAwardNumbers(0.0);
        }
        return false;
    }
    /**
     *  实付金额小于佣金,修改收入订单为失效
     * @param orderItem
     * @param distributionAwardDataVO
     * @param distributionUserIncome
     * @param type 1直推 2间推
     */
    private void setDistributionIncome(OrderItem orderItem, DistributionAwardDataVO distributionAwardDataVO, DistributionUserIncome distributionUserIncome, int type){
        if (type == 1){
            if (distributionAwardDataVO.getAwardNumber()  >= orderItem.getActualTotal()) {
                log.info("直推 分销金额比实付金额要大,分销佣金收入记录改为失效订单");
                distributionUserIncome.setState(DistributionUserIncomeStateEnum.INVALID.getValue());
                distributionUserIncome.setReson(DistributionAudit.INCOME_ONE.getValue());
                return;
            }
        }else if (type == 2){
            if ((distributionAwardDataVO.getAwardNumber() + distributionAwardDataVO.getParentAwardNumber())  >= orderItem.getActualTotal()) {
                log.info("间推 分销金额比实付金额要大,分销佣金收入记录改为失效订单");
                distributionUserIncome.setState(DistributionUserIncomeStateEnum.INVALID.getValue());
                distributionUserIncome.setReson(DistributionAudit.INCOME_ONE.getValue());
                return;
            }
        }
        double incomeAmount = Arith.roundByBanker(distributionUserIncome.getIncomeAmount(), 2);
        // 分销佣金小于0.01
        if (incomeAmount < Constant.MIN_PRODUCT_AMOUNT) {
            if (Objects.nonNull(distributionUserIncome.getReson())){
                return;
            }
            distributionUserIncome.setIncomeAmount(Constant.ZERO_DOUBLE);
            distributionUserIncome.setReson(DistributionAudit.INCOME_THREE.getValue());
            distributionUserIncome.setState(DistributionUserIncomeStateEnum.INVALID.getValue());
            return;
        }
        // 如果系统设置为交易完毕后结算,则记录为结算状态,否则为未结算状态
        distributionUserIncome.setState(1);
    }
    private void insertAwardNumber(OrderItem orderItem, DistributionUser finalDistributionUser, DistributionAwardDataVO distributionAwardDataVO, DistributionUserIncome distributionUserIncome) {
        // 查询该推广员钱包信息
        DistributionUserWallet distributionUserWallet = distributionUserWalletService.getOne(new LambdaQueryWrapper<DistributionUserWallet>().eq(DistributionUserWallet::getDistributionUserId, finalDistributionUser.getDistributionUserId()));
        distributionUserIncome.setDistributionUserId(finalDistributionUser.getDistributionUserId());
        distributionUserIncome.setWalletId(distributionUserWallet.getWalletId());
        distributionUserIncome.setIncomeAmount(distributionAwardDataVO.getAwardNumber());
        // 若佣金大于实付金额改收入改为失效订单
        setDistributionIncome(orderItem, distributionAwardDataVO, distributionUserIncome, 1);
        // 收入类型为一级奖励
        distributionUserIncome.setIncomeType(1);
        distributionUserIncomeService.save(distributionUserIncome);
        // 订单项添加分佣奖励
        orderItem.setDistributionAmount(distributionUserIncome.getIncomeAmount());
        if (distributionUserIncome.getState().equals(DistributionUserIncomeStateEnum.UNCOMMISSION.getValue())){
            // 给钱包增加待结算金额
            distributionUserWallet.setUnsettledAmount(Arith.add(distributionUserWallet.getUnsettledAmount(), distributionAwardDataVO.getAwardNumber()));
            distributionUserWalletBillService.save(new DistributionUserWalletBill(distributionUserWallet, "客户支付获取待结算金额","Customer payment to obtain the amount to be settled", distributionAwardDataVO.getAwardNumber(), 0.0, 0.0, 0.0, 0));
        }else {
            log.info("增加失效佣金");
            // 给钱包增加待失效金额
            distributionUserWallet.setInvalidAmount(Arith.add(distributionUserWallet.getInvalidAmount(), distributionUserIncome.getIncomeAmount()));
            if (distributionUserIncome.getIncomeAmount() != 0){
                distributionUserWalletBillService.save(new DistributionUserWalletBill(distributionUserWallet, "客户支付小于佣金失效增加金额","The client pays less than the increase in commission lapse", 0.0, 0.0, distributionUserIncome.getIncomeAmount(), 0.0, 0));
            }
            // 佣金失效后,订单中分销金额要清除(如果不清除,失效的分销金额会插入到订单项中,就参与了订单金额的计算)
            orderItem.setDistributionAmount(null);
        }
        //更新钱包
        boolean distributionUserWalletUpdateSuccess = distributionUserWalletService.updateById(distributionUserWallet);
        if (!distributionUserWalletUpdateSuccess) {
            // 更新推广员钱包信息失败
            throw new YamiShopBindException("yami.cannot.distribution.update.wallet");
        }
    }
    private void insertParentAwardNumber(DistributionConfigVO distributionConfigVO,OrderItem orderItem, DistributionUser finalDistributionUser,DistributionUser bindUser,
                                         DistributionAwardDataVO distributionAwardDataVO, DistributionUserIncome distributionUserIncome) {
        //添加二级佣金给上级邀请人
        DistributionUserWallet parentDistributionUserWallet = distributionUserWalletService.getOne(new LambdaQueryWrapper<DistributionUserWallet>().eq(DistributionUserWallet::getDistributionUserId, finalDistributionUser.getParentId()));
        if (Objects.isNull(parentDistributionUserWallet)) {
            log.info("分销员id-{}:没有钱包信息", finalDistributionUser.getParentId());
            return;
        }
        //如果上级不为空,则创建上级奖励业绩记录
        distributionUserIncome.setIncomeId(null);
        distributionUserIncome.setIncomeType(2);
        distributionUserIncome.setDistributionUserId(parentDistributionUserWallet.getDistributionUserId());
        distributionUserIncome.setIncomeAmount(distributionAwardDataVO.getParentAwardNumber());
        distributionUserIncome.setWalletId(parentDistributionUserWallet.getWalletId());
        // 若佣金大于实付金额改收入改为失效订单
        setDistributionIncome(orderItem, distributionAwardDataVO, distributionUserIncome, 2);
        //类型为二级奖励
        distributionUserIncomeService.save(distributionUserIncome);
        if (distributionUserIncome.getState().equals(DistributionUserIncomeStateEnum.UNCOMMISSION.getValue())){
            //给邀请人钱包增加待结算金额
            parentDistributionUserWallet.setUnsettledAmount(Arith.add(parentDistributionUserWallet.getUnsettledAmount(), distributionAwardDataVO.getParentAwardNumber()));
            //增加钱包流水记录
            if(distributionAwardDataVO.getParentAwardNumber() != 0) {
                distributionUserWalletBillService.save(new DistributionUserWalletBill(parentDistributionUserWallet, "间推奖励", "Second-generation rewards",distributionAwardDataVO.getParentAwardNumber(), 0.0, 0.0, 0.0, 0));
            }
            // 订单项添加上级奖励
            orderItem.setDistributionParentAmount(distributionUserIncome.getIncomeAmount());
        }else {
            log.info("增加失效佣金");
            //给邀请人钱包增加失效金额
            parentDistributionUserWallet.setInvalidAmount(Arith.add(parentDistributionUserWallet.getInvalidAmount(), distributionUserIncome.getIncomeAmount()));
            //增加钱包流水记录
            if(distributionAwardDataVO.getParentAwardNumber() != 0) {
                distributionUserWalletBillService.save(new DistributionUserWalletBill(parentDistributionUserWallet, "间推奖励失效", "Intermittent bonuses are void", 0.0, 0.0, distributionUserIncome.getIncomeAmount(),0.0, 0));
            }
            //佣金失效后,订单中分销金额要清除(如果不清除,失效的分销金额会插入到订单项中,就参与了订单金额的计算)
            orderItem.setDistributionParentAmount(null);
        }
        //更新邀请人钱包
        boolean parentDistributionUserWalletUpdateSuccess = distributionUserWalletService.updateById(parentDistributionUserWallet);
        if (!parentDistributionUserWalletUpdateSuccess) {
            // 更新推广员钱包信息失败
            throw new YamiShopBindException("yami.cannot.distribution.update.wallet");
        }
    }
    /**
     * 当该商品是用户分享时,检查是否能给该用户产生收益
     * @param orderItem 订单项
     * @param distributionConfigVO 分销绑定条件设置
     * @return true: 可以,false:不可以
     */
    private boolean checkSelfShare(OrderItem orderItem, DistributionConfigVO distributionConfigVO) {
        if (Objects.isNull(orderItem)) {
            return true;
        }
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(orderItem.getUserId(), Constant.PLATFORM_SHOP_ID);
        if (Objects.isNull(distributionUser)) {
            // 用户不是分销员
            return true;
        }
        if (StrUtil.isBlank(orderItem.getDistributionCardNo()) || !Objects.equals(distributionUser.getCardNo(), orderItem.getDistributionCardNo())) {
            // 订单没有分销信息或者分销信息不是当前用户的链接
            return true;
        }
        if (Objects.equals(distributionConfigVO.getAttribution(),1)) {
            //不绑定,分享人优先
            return true;
        }
        // 查询该用户绑定的分享人
        DistributionUserBind distributionUserBind = distributionUserBindMapper.selectOne(new LambdaQueryWrapper<DistributionUserBind>()
                .eq(DistributionUserBind::getShopId, Constant.PLATFORM_SHOP_ID)
                .eq(DistributionUserBind::getState, 1)
                .eq(DistributionUserBind::getUserId, orderItem.getUserId())
        );
//        if (Objects.nonNull(distributionUserBind)) {
//            // 判断是否处于保存期内
//            Calendar calendar = Calendar.getInstance();
//            calendar.setTime(distributionUserBind.getBindTime());
//            calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + distributionBindSet.getProtectDay());
//            if (calendar.getTime().after(new Date())) {
//                // 用户处于保护期内,无法通过自己分享的链接产生个人收益
//                isSelfIncome = false;
//            }
//            return false;
//        }
        return Objects.isNull(distributionUserBind);
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/listener/ProdChangeListener.java
New file
@@ -0,0 +1,117 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.listener;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yami.shop.bean.enums.ProdStatusEnums;
import com.yami.shop.bean.event.ProdChangeEvent;
import com.yami.shop.bean.event.ProdChangeStatusEvent;
import com.yami.shop.bean.model.Product;
import com.yami.shop.bean.order.GeneralActivitiesOrder;
import com.yami.shop.distribution.common.constants.DistributionProdStateEnum;
import com.yami.shop.distribution.common.model.DistributionProd;
import com.yami.shop.distribution.common.service.DistributionProdService;
import com.yami.shop.service.SysConfigService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Objects;
/**
 * @author yami
 */
@Slf4j
@Component("distributionProdChangeListener")
@AllArgsConstructor
public class ProdChangeListener {
    private final SysConfigService sysConfigService;
    private final DistributionProdService distributionProdService;
    @EventListener(ProdChangeEvent.class)
    public void prodChangeEvent(ProdChangeEvent event) {
        // 删除的商品的时候,好像不需要删除分销的设置
        // 因为删除了商品,有购买过依旧可以判断这个商品用户是否购买过
        // 暂时不执行下满的代码
        // 删除商品时,处理分销设置
//        handleDistributionAfterDeleteProd(event);
    }
    /**
     * 同步商品状态到分销商品中
     */
    @EventListener(ProdChangeStatusEvent.class)
    @Order(GeneralActivitiesOrder.DISTRIBUTION)
    public void distributionProdChangeStatusListener(ProdChangeStatusEvent event) {
        Product product = event.getProduct();
        Integer status = event.getStatus();
        // 平台下架,商家下架再同步过去
        if (Objects.equals(status, ProdStatusEnums.PLATFORM_OFFLINE.getValue()) && Objects.equals(status, ProdStatusEnums.SHOP_OFFLINE.getValue())) {
            return;
        }
        // 同步商品状态到分销商品
        Long prodId = product.getProdId();
        DistributionProd distributionProd = distributionProdService.getOne(new LambdaUpdateWrapper<DistributionProd>().eq(DistributionProd::getProdId, prodId));
        if (Objects.isNull(distributionProd) || Objects.equals(distributionProd.getState(), ProdStatusEnums.PLATFORM_OFFLINE.getValue())) {
            return;
        }
        if (Objects.equals(status, ProdStatusEnums.PLATFORM_OFFLINE.getValue())) {
            status = DistributionProdStateEnum.PUT_OFF.getValue();
        }
        distributionProdService.updateState(distributionProd.getDistributionProdId(),status);
        // 清理一下缓存
        distributionProdService.removeDistributionProdPoCacheByProdId(prodId);
    }
//    /**  删除商品时,处理分销设置 */
//    private void handleDistributionAfterDeleteProd(ProdChangeEvent event) {
//        Product product = event.getProduct();
//        Long prodId = product.getProdId();
//        if (Objects.isNull(prodId)) {
//            return;
//        }
//        // 店铺分销员审核设置
//        DistributionConfigVO distributionConfigVO = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_CONFIG, DistributionConfigVO.class);
//        DistributionAuditingSet distributionAuditingSet = distributionAuditingSetService.getByShopId();
//        DistributionAuditingConditionsVO auditingConditions = distributionConfigVO.getAuditingConditions();
//        List<Long> prodIds = auditingConditions.getProdList();
//        if (Objects.isNull(prodIds)) {
//            return;
//        }
//        if (!prodIds.contains(prodId)) {
//            return;
//        }
//        // 删除的商品在 分销设置->申请条件设置->申请条件->购买指定商品的列表中
//        // 删除商品时也删除掉这个列表中的商品
//        prodIds.remove(prodId);
//        auditingConditions.setProdList(prodIds);
//        auditingConditions.setProductDtoList(null);
//        distributionAuditingSet.setAuditingConditions(auditingConditions);
//        distributionAuditingSet.setAuditingConditionsJson(Json.toJsonString(distributionAuditingSet.getAuditingConditions()));
//        if (Objects.isNull(distributionAuditingSet.getAuditingConditionsJson())) {
//            return;
//        }
//        boolean update = distributionAuditingSetService.update(new LambdaUpdateWrapper<DistributionAuditingSet>()
//                .set(DistributionAuditingSet::getAuditingConditionsJson, distributionAuditingSet.getAuditingConditionsJson())
//                .set(DistributionAuditingSet::getUpdateTime, new Date())
//                .eq(DistributionAuditingSet::getAuditingSetId, distributionAuditingSet.getAuditingSetId()));
//        if (update) {
//            distributionAuditingSetService.removeCacheByShopId(Constant.PLATFORM_SHOP_ID);
//        }
//        String okStr = update ? "成功" : "失败";
//        Log.info("删除商品prodId = " + prodId + "时,同时也去除在分销设置中的商品prodId = "+ prodId + " ,更新" + okStr);
//    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/listener/ShopChangeStatusListener.java
New file
@@ -0,0 +1,52 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.listener;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.enums.ShopStatus;
import com.yami.shop.bean.event.ShopChangeStatusEvent;
import com.yami.shop.distribution.common.constants.DistributionProdStateEnum;
import com.yami.shop.distribution.common.model.DistributionProd;
import com.yami.shop.distribution.common.service.DistributionProdService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.Objects;
/**
 * 店铺改变状态监听
 *
 * @Author lth
 * @Date 2021/11/22 17:18
 */
@Component("distributionShopChangeStatusListener")
@AllArgsConstructor
public class ShopChangeStatusListener {
    private final DistributionProdService distributionProdService;
    @EventListener(ShopChangeStatusEvent.class)
    public void distributionShopChangeStatusListener(ShopChangeStatusEvent event) {
        Long shopId = event.getShopId();
        ShopStatus shopStatus = event.getShopStatus();
        if (Objects.isNull(shopId) || Objects.isNull(shopStatus)) {
            return;
        }
        if (Objects.equals(shopStatus, ShopStatus.OFFLINE)) {
            // 店铺下线时,把上架状态的分销商品置为下架
            distributionProdService.update(Wrappers.lambdaUpdate(DistributionProd.class)
                    .set(DistributionProd::getState, DistributionProdStateEnum.PUT_OFF.getValue())
                    .eq(DistributionProd::getShopId, shopId)
                    .eq(DistributionProd::getState, DistributionProdStateEnum.PUT_ON.getValue())
            );
        }
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionAuditing.java
New file
@@ -0,0 +1,76 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yami.shop.bean.vo.SysUserVO;
import com.yami.shop.distribution.common.vo.DistributionUserVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
 * @author yami
 */
@Data
@TableName( "tz_distribution_auditing")
public class DistributionAuditing implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId
    @Schema(description = "分销员申请表id" )
    private Long auditingId;
    @Schema(description = "店铺Id" )
    private Long shopId;
    @Schema(description = "邀请人id" )
    private Long parentDistributionUserId;
    @Schema(description = "申请人id" )
    private Long distributionUserId;
    @Schema(description = "申请时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date auditingTime;
    @Schema(description = "不通过原因" )
    private Integer reason;
    @Schema(description = "审核状态:0 未审核 1已通过 -1未通过" )
    private Integer state;
    @Schema(description = "操作时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    @Schema(description = "操作人" )
    private Long modifier;
    @Schema(description = "备注" )
    private String remarks;
    @Schema(description = "关联邀请人" )
    @TableField(exist = false)
    private DistributionUserVO parentDistributionUser;
    @Schema(description = "关联用户" )
    @TableField(exist = false)
    private DistributionUser distributionUser;
    @Schema(description = "关联操作人" )
    @TableField(exist = false)
    private SysUserVO sysUser;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionMsg.java
New file
@@ -0,0 +1,75 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yami.shop.bean.vo.SysUserVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
 * @author yami
 */
@Data
@TableName( "tz_distribution_msg")
public class DistributionMsg {
    @TableId
    @Schema(description = "通知表id" )
    private Long msgId;
    @Schema(description = "通知级别(0 系统通知 1商家通知 2团队通知)" )
    private Integer level;
    @Schema(description = "通知标题" )
    private String msgTitle;
    @Schema(description = "店铺id" )
    private Long shopId;
    @Schema(description = "指定上线时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date startTime;
    @Schema(description = "指定下线时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date endTime;
    @Schema(description = "是否置顶(0 不置顶 1 置顶)" )
    private Integer isTop;
    @Schema(description = "公告内容" )
    private String content;
    @Schema(description = "公告封面图" )
    private String pic;
    @Schema(description = "通知类型(0:紧急通知, 1:活动通知,2:一般通知)" )
    private Integer msgType;
    @Schema(description = "通知状态(0 下线 1上线)" )
    private Integer state;
    @Schema(description = "修改时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    @Schema(description = "修改人" )
    private Long modifier;
    @Schema(description = "关联管理员" )
    @TableField(exist = false)
    private SysUserVO sysUser;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionProd.java
New file
@@ -0,0 +1,73 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yami.shop.bean.model.Product;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
 * @author yami
 */
@Data
@TableName( "tz_distribution_prod")
public class DistributionProd {
    @TableId
    @Schema(description = "分销商品表id" )
    private Long distributionProdId;
    @Schema(description = "店铺id" )
    private Long shopId;
    @Schema(description = "商品id" )
    private Long prodId;
    @Schema(description = "奖励id" )
    private Long awardId;
    @Schema(description = "状态(0:商家下架 1:商家上架 2:违规下架 3:平台审核)" )
    private Integer state;
    @Schema(description = "修改时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    @Schema(description = "操作人id" )
    private Long modifier;
    @Schema(description = "是否使用默认奖励(0 不使用 1使用)" )
    private Integer defaultReward;
    @Schema(description = "关联商品" )
    @TableField(exist = false)
    private Product product;
    @Schema(description = "奖励比例(0 按比例 1 按固定数值)" )
    private Integer awardProportion;
    @Schema(description = "奖励数额设置(0 固定奖励,1 根据等级奖励)" )
    private Integer awardNumberSet;
    @Schema(description = "奖励数额(json)" )
    private String awardNumbers;
    @Schema(description = "上级奖励数额(json)" )
    private String parentAwardNumbers;
    @Schema(description = "上级奖励设置(0 关闭 1开启)" )
    private Integer parentAwardSet;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionProdBind.java
New file
@@ -0,0 +1,50 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.model;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
/**
 * @author xwc
 * @date 2019-04-22 10:01:44
 */
@Data
@TableName("tz_distribution_prod_bind")
@EqualsAndHashCode
@Schema(description = "分销商品绑定表")
public class DistributionProdBind implements Serializable{
    private static final long serialVersionUID = 1L;
    @TableId
    @Schema(description = "用户商品绑定表" )
    private Long id;
    @Schema(description = "分销员id" )
    private Long distributionUserId;
    @Schema(description = "用户id" )
    private String userId;
    @Schema(description = "绑定时间" )
    private Date bindTime;
    @Schema(description = "商品id" )
    private Long prodId;
    @Schema(description = "状态(0失效 1生效)" )
    private Integer state;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionProdLog.java
New file
@@ -0,0 +1,64 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
/**
 * @author yami
 */
@Data
@Schema(description = "分销记录表")
public class DistributionProdLog {
    @Schema(description = "分销记录表Id" )
    private Long incomeId;
    @Schema(description = "佣金数额" )
    private Double incomeAmount;
    @Schema(description = "佣金状态(0:待支付、1:待结算、2:已结算、-1:订单失效)" )
    private Integer state;
    @Schema(description = "佣金类型 1直推 2间推" )
    private Integer incomeType;
    @Schema(description = "商品名称" )
    private String prodName;
    @Schema(description = "商品主图" )
    private String pic;
    @Schema(description = "店铺Id" )
    private Long shopId;
    @Schema(description = "店铺名称" )
    private String shopName;
    @Schema(description = "分销员昵称" )
    private String nickName;
    @Schema(description = "分销员手机号" )
    private String userMobile;
    @Schema(description = "下单时间" )
    private Date placeTime;
    @Schema(description = "订单号" )
    private String orderNumber;
    @Schema(description = "失效原因:" )
    private Integer reson;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionUser.java
New file
@@ -0,0 +1,119 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.model;
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.databind.annotation.JsonSerialize;
import com.yami.shop.common.serializer.json.ImgJsonSerializer;
import com.yami.shop.distribution.common.dto.DistributionUserAchievementDataDto;
import com.yami.shop.distribution.common.vo.DistributionUserVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
 * @author yami
 */
@Data
@TableName("tz_distribution_user")
public class DistributionUser implements Serializable {
    @Schema(description = "促销员表id" )
    @TableId(type = IdType.AUTO)
    private Long distributionUserId;
    @Schema(description = "店铺id" )
    private Long shopId;
    @Schema(description = "卡号" )
    private String cardNo;
    @Schema(description = "用户id" )
    private String userId;
    @Schema(description = "上级id" )
    private Long parentId;
    @Schema(description = "上级促销员ids (如:1,2,3)最上级处于最前面的位置" )
    private String parentIds;
    @Schema(description = "层级(0顶级)" )
    private Integer grade;
    @Schema(description = "关联等级id" )
    private Integer level;
    @Schema(description = "分组id" )
    private Long groupId;
    @Schema(description = "状态(-1永久封禁 0 待审核 1 正常 2 暂时封禁 3 审核未通过,需要重新申请)" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date bindTime;
    @Schema(description = "状态(-1永久封禁 0 待审核 1 正常 2 暂时封禁 3 审核未通过,需要重新申请)" )
    private Integer state;
    @Schema(description = "用户昵称" )
    private String nickName;
    @Schema(description = "手机号码" )
    private String userMobile;
    @Schema(description = "真实姓名" )
    private String realName;
    @Schema(description = "身份证号" )
    private String identityCardNumber;
    @Schema(description = "改变成永久封禁或者暂时封禁时的状态记录" )
    private Integer stateRecord;
    @Schema(description = "身份证正面" )
    @JsonSerialize(using = ImgJsonSerializer.class)
    private String identityCardPicFront;
    @Schema(description = "身份证背面" )
    @JsonSerialize(using = ImgJsonSerializer.class)
    private String identityCardPicBack;
    @Schema(description = "手持身份证照片" )
    @JsonSerialize(using = ImgJsonSerializer.class)
    private String identityCardPicHold;
    @Schema(description = "头像" )
    private String pic;
    @Schema(description = "上级分销员" )
    @TableField(exist = false)
    private DistributionUserVO parentDistributionUser;
    @Schema(description = "分销员收入记录" )
    @TableField(exist = false)
    private DistributionUserIncome distributionUserIncome;
    @Schema(description = "分销员各项数据" )
    @TableField(exist = false)
    private DistributionUserAchievementDataDto distributionUserAchievementDataDto;
    @Schema(description ="排序字段" +
            "分销管理-分销员管理: 0无 1加入时间 2累计客户 3累计邀请 4累计收益" +
            "分销管理-业绩统计: 0无 1一代佣金 2二代佣金 3邀请奖励 4待结算金额 5可提现金额 6已失效金额")
    @TableField(exist = false)
    private Integer sortParam = 0;
    @Schema(description = "排序类型 0无 1 正序 2倒序" )
    @TableField(exist = false)
    private Integer sortType = 0;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionUserBan.java
New file
@@ -0,0 +1,67 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yami.shop.bean.vo.SysUserVO;
import com.yami.shop.distribution.common.vo.DistributionUserVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
 * @author yami
 */
@Data
@TableName( "tz_distribution_user_ban")
public class DistributionUserBan {
    @TableId
    @Schema(description = "封禁id" )
    private Long banId;
    @Schema(description = "分销员id" )
    private Long distributionUserId;
    @Schema(description = "封禁原因(0 失去联系 1恶意刷单 2其他)" )
    private Integer banReason;
    @Schema(description = "备注" )
    private String remarks;
    @Schema(description = "操作时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    @Schema(description = "操作人" )
    private Long modifier;
    @Schema(description = "状态(0 正常 1暂时封禁 -1永久封禁)" )
    private Integer state;
    @Schema(description = "操作人" )
    @TableField(exist = false)
    private SysUserVO sysUser;
    @Schema(description = "关联分销员" )
    @TableField(exist = false)
    private DistributionUserVO distributionUser;
    @Schema(description = "排序字段 分销员-封禁记录:0无 1操作时间" )
    @TableField(exist = false)
    private Integer sortParam = 0;
    @Schema(description = "排序类型 0无 1 正序 2倒序" )
    @TableField(exist = false)
    private Integer sortType = 0;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionUserBind.java
New file
@@ -0,0 +1,69 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yami.shop.bean.vo.UserVO;
import com.yami.shop.distribution.common.vo.DistributionUserVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
 * @author yami
 */
@Data
@TableName( "tz_distribution_user_bind")
public class DistributionUserBind implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId
    @Schema(description = "用户关系表id" )
    private Long bindId;
    @Schema(description = "分销员id" )
    private Long distributionUserId;
    @Schema(description = "店铺id" )
    private Long shopId;
    @Schema(description = "用户id" )
    private String userId;
    @Schema(description = "当前绑定关系(-1失效 0 预绑定 1生效)" )
    private Integer state;
    @Schema(description = "失效原因(0 超过有效期 1 管理员更改 3.暂时封禁)" )
    private Integer invalidReason;
    @Schema(description = "变动时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    @Schema(description = "绑定时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date bindTime;
    @Schema(description = "失效时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date invalidTime;
    @Schema(description = "关联用户" )
    @TableField(exist = false)
    private UserVO user;
    @Schema(description = "关联分销员" )
    @TableField(exist = false)
    private DistributionUserVO distributionUser;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionUserGroup.java
New file
@@ -0,0 +1,48 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yami.shop.bean.vo.SysUserVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
 * @author yami
 */
@Data
@TableName( "tz_distribution_user_group")
public class DistributionUserGroup {
    @TableId
    @Schema(description = "分组表id" )
    private Long groupId;
    @Schema(description = "分组名" )
    private String groupName;
    @Schema(description = "修改时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    @Schema(description = "操作人id" )
    private Long modifier;
    @Schema(description = "店铺id" )
    private Long shopId;
    @Schema(description = "操作人" )
    @TableField(exist = false)
    private SysUserVO sysUser;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionUserIncome.java
New file
@@ -0,0 +1,95 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.vo.SysUserVO;
import com.yami.shop.distribution.common.vo.DistributionUserVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
 * @author yami
 */
@Data
@TableName( "tz_distribution_user_income")
public class DistributionUserIncome implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId
    @Schema(description = "收入记录id" )
    private Long incomeId;
    @Schema(description = "钱包id" )
    private Long walletId;
    @Schema(description = "收入类型(0其他、1直推奖励、2间推奖励、3邀请奖励、4平台修改)" )
    private Integer incomeType;
    @Schema(description = "佣金状态(0:待支付、1:待结算、2:已结算、-1:订单失效)" )
    private Integer state;
    @Schema(description = "佣金数额" )
    private Double incomeAmount;
    @Schema(description = "关联订单项号" )
    private Long orderItemId;
    @Schema(description = "商户订单号" )
    private String merchantOrderId;
    @Schema(description = "分销员id" )
    private Long distributionUserId;
    @Schema(description = "订单号" )
    private String orderNumber;
    @Schema(description = "创建时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @Schema(description = "更新时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    @Schema(description = "失效原因(0正常,1佣金为0订单失效,2订单项退款)" )
    private Integer reson;
    @Schema(description = "关联分销员" )
    @TableField(exist = false)
    private DistributionUserVO distributionUser;
    @Schema(description = "关联订单" )
    @TableField(exist = false)
    private Order order;
    @Schema(description = "关联操作人" )
    @TableField(exist = false)
    private SysUserVO sysUserVO;
    @Schema(description = "订单项" )
    @TableField(exist = false)
    private OrderItem orderItem;
    @Schema(description = "排序字段:分销业绩-推广效果:0无 1佣金 2创建时间 3更新时间" )
    @TableField(exist = false)
    private Integer sortParam = 0;
    @Schema(description = "排序类型 0无 1 正序 2倒序" )
    @TableField(exist = false)
    private Integer sortType = 0;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionUserWallet.java
New file
@@ -0,0 +1,60 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import com.yami.shop.distribution.common.vo.DistributionUserVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * @author yami
 */
@Data
@TableName( "tz_distribution_user_wallet")
public class DistributionUserWallet {
    @TableId
    @Schema(description = "分销员钱包id" )
    private Long walletId;
    @Schema(description = "分销员id" )
    private Long distributionUserId;
    @Schema(description = "待结算金额(用户付款后 增加该金额,结算时减少该金额,取消订单或退货减少该金额)" )
    private Double unsettledAmount;
    @Schema(description = "可提现金额(用户收货后或者维权期过后增加该金额,提现减少该金额)" )
    private Double settledAmount;
    @Schema(description = "积累收益(用户收货后或者维权期过后增加该金额,提现不减少该金额)" )
    private Double addupAmount;
    @Schema(description = "失效金额(用户取消订单或退货增加该金额)" )
    private Double invalidAmount;
    @Version
    @Schema(description = "乐观锁" )
    private Integer version;
    @Schema(description = "钱包状态( 0未生效(分销审核未通过) 1正常)" )
    private Integer state;
    @Schema(description = "关联分销员" )
    @TableField(exist = false)
    private DistributionUserVO distributionUser;
    @Schema(description = "可提现的改变金额" )
    @TableField(exist = false)
    private Double changeAmount;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionUserWalletBill.java
New file
@@ -0,0 +1,122 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yami.shop.bean.vo.SysUserVO;
import com.yami.shop.distribution.common.vo.DistributionUserVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
/**
 * 分销员钱包流水
 *
 * @author xwc
 * @date 2019-04-29 16:39:13
 */
@Data
@TableName("tz_distribution_user_wallet_bill")
@EqualsAndHashCode
public class DistributionUserWalletBill implements Serializable{
    private static final long serialVersionUID = 1L;
    public DistributionUserWalletBill(){
    }
    /**
     *
     * @param distributionUserWallet 变更后的钱包对象
     * @param remarks
     */
    public DistributionUserWalletBill(DistributionUserWallet distributionUserWallet,
                                      String remarks,
                                      String remarksEn,
                                      Double unsettledAmount,
                                      Double settledAmount,
                                      Double invalidAmount,
                                      Double addupAmount,
                                      Integer type){
        this.remarks=remarks;
        this.remarksEn =remarksEn;
        this.unsettledAmount=unsettledAmount;
        this.settledAmount=settledAmount;
        this.invalidAmount=invalidAmount;
        this.addupAmount=addupAmount;
        this.type=type;
        this.createTime=new Date();
        this.walletId=distributionUserWallet.getWalletId();
        this.unsettledAmountAfter=distributionUserWallet.getUnsettledAmount();
        this.settledAmountAfter=distributionUserWallet.getSettledAmount();
        this.invalidAmountAfter=distributionUserWallet.getInvalidAmount();
        this.addupAmountAfter=distributionUserWallet.getAddupAmount();
    }
    @TableId
    @Schema(description = "钱包流水记录id" )
    private Long id;
    @Schema(description = "钱包id" )
    private Long walletId;
    @Schema(description = "待结算金额变更数额" )
    private Double unsettledAmount;
    @Schema(description = "可提现金额变更数额" )
    private Double settledAmount;
    @Schema(description = "失效金额变更数额" )
    private Double invalidAmount;
    @Schema(description = "积累收益变更数额" )
    private Double addupAmount;
    @Schema(description = "创建时间" )
    private Date createTime;
    @Schema(description = "备注" )
    private String remarks;
    @Schema(description = "英文备注" )
    private String remarksEn;
    @Schema(description = "变更后待结算金额" )
    private Double unsettledAmountAfter;
    @Schema(description = "变更后可提现金额" )
    private Double settledAmountAfter;
    @Schema(description = "变更后失效金额" )
    private Double invalidAmountAfter;
    @Schema(description = "变更后积累收益" )
    private Double addupAmountAfter;
    @Schema(description = "类型(0 系统修改 1人工修改)" )
    private Integer type;
    @Schema(description = "操作人id(空为系统)" )
    private Long modifier;
    @Schema(description = "关联分销员" )
    @TableField(exist=false)
    private DistributionUserVO distributionUser;
    @Schema(description = "关联操作人" )
    @TableField(exist=false)
    private SysUserVO sysUser;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/model/DistributionWithdrawCash.java
New file
@@ -0,0 +1,80 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import com.yami.shop.distribution.common.vo.DistributionUserVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
 * @author yami
 */
@Data
@TableName( "tz_distribution_withdraw_cash")
public class DistributionWithdrawCash {
    @TableId
    @Schema(description = "提现记录id" )
    private Long withdrawCashId;
    @Schema(description = "钱包id" )
    private Long walletId;
    @Schema(description = "金额" )
    private Double amount;
    @Schema(description = "手续费" )
    private Double fee;
    @Schema(description = "类型(0 手动提现 1自动提现)" )
    private Integer type;
    @Schema(description = "资金流向(1企业付款到微信零钱)" )
    private Integer moneyFlow;
    @Schema(description = "流水号" )
    private String merchantOrderId;
    @Version
    @Schema(description = "乐观锁" )
    private Integer version;
    @Schema(description = "创建时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @Schema(description = "更新时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    @Schema(description = "提现状态(0:申请中 1:提现成功 2:拒绝提现 -1:提现失败)" )
    private Integer state;
    @Schema(description = "第三方登录userId" )
    private String bizUserId;
    @Schema(description = "关联分销员" )
    @TableField(exist = false)
    private DistributionUserVO distributionUser;
    @Schema(description = "排序字段 分销钱包-提现记录:0无 1金额 2手续费 3提现时间 4更新时间" )
    @TableField(exist = false)
    private Integer sortParam = 0;
    @Schema(description = "排序类型 0无 1 正序 2倒序" )
    @TableField(exist = false)
    private Integer sortType = 0;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/param/AuditWithdrawCashParam.java
New file
@@ -0,0 +1,34 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.param;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 分销提现审核参数
 * @author yami
 */
@Data
public class AuditWithdrawCashParam {
    /**
     * 提现记录id
     */
    @Schema(description = "提现记录id" )
    @NotNull(message = "提现记录Id不能为空")
    private Long withdrawCashId;
    @Schema(description = "状态" )
    @NotNull(message = "状态不能为空")
    private Integer state;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/param/RangeTimeParam.java
New file
@@ -0,0 +1,54 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.param;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
 * 时间范围参数
 * @author yami
 */
@Data
public class RangeTimeParam {
    public RangeTimeParam(){}
    public RangeTimeParam(Date startTime, Date endTime){
        this.startTime=startTime;
        this.endTime=endTime;
    }
    /**
     * 起始时间
     */
    @Schema(description = "起始时间" ,required=true)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date startTime;
    /**
     * 结束时间
     */
    @Schema(description = "结束时间" ,required=true)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date endTime;
    @Override
    public String toString() {
        return "RangeTimeParam{" +
                "startTime=" + startTime.toString() +
                ", endTime=" + endTime.toString() +
                '}';
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/param/UpdateDistributionUserParam.java
New file
@@ -0,0 +1,33 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.param;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * 更新分销员状态的状态参数
 * @author yami
 */
@Data
public class UpdateDistributionUserParam {
    @Schema(description = "分销员id" )
    private Long distributionUserId;
    @Schema(description = "状态(-1永久封禁 0待审核状态 1正常 2暂时封禁 3 审核未通过)" )
    private Integer state;
    @Schema(description = "封禁原因(0 失去联系 1恶意刷单 2其他)" )
    private Integer banReason;
    @Schema(description = "备注" )
    private String remarks;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/po/DistributionProdPO.java
New file
@@ -0,0 +1,79 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.po;
import lombok.Data;
import java.io.Serializable;
/**
 * @author yami
 */
@Data
public class DistributionProdPO  implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 店铺id
     */
    private  Long shopId;
    /**
     *
     * 商品id
     */
    private Long prodId;
    /**
     * 商品名字
     */
    private String prodName;
    /**
     * 商品主图
     */
    private String pic;
    /**
     * 商品价格
     */
    private Double price;
    /**
     * 是否使用默认奖励(0 不使用 1使用)
     */
    private Integer defaultReward;
    /**
     * 奖励比例(0 按比例 1 按固定数值)
     */
    private Integer awardProportion;
    /**
     * 奖励数额设置(0 固定奖励,1 根据等级奖励)
     */
    private Integer awardNumberSet;
    /**
     * 奖励数额(Double)
     */
    private Double awardNumbers;
    /**
     * 上级奖励数额
     */
    private Double parentAwardNumbers;
    /**
     * 上级奖励设置(0 关闭 1开启)
     */
    private Integer parentAwardSet;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionAuditingService.java
New file
@@ -0,0 +1,43 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.distribution.common.dto.DistributionAuditingDto;
import com.yami.shop.distribution.common.model.DistributionAuditing;
import com.yami.shop.distribution.common.param.RangeTimeParam;
/**
 *
 * @author lgh on 2019/04/01.
 */
public interface DistributionAuditingService extends IService<DistributionAuditing> {
      /**
       * 获取分销员审核信息
       * @param page 分页信息
       * @param distributionAuditing 审核信息
       * @param rangeTimeParam 申请时间
       * @param startExpenseNumber 订单数量
       * @param endExpenseNumber 订单数量
       * @param startPayAmount 支付金额范围
       * @param endPayAmount 支付金额范围
       * @param mobile 手机号
       * @return 分销员审核信息
       */
      Page<DistributionAuditingDto> distributionAuditingPage(Page page, DistributionAuditing distributionAuditing, RangeTimeParam rangeTimeParam, Integer startExpenseNumber, Integer endExpenseNumber, Double startPayAmount, Double endPayAmount, String mobile);
      /**
       * 分销员审核操作
       * @param distributionAuditing 审核信息
       */
      void examine(DistributionAuditing distributionAuditing);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionBindUserService.java
New file
@@ -0,0 +1,49 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.distribution.common.dto.BindUserInfoDto;
import com.yami.shop.distribution.common.model.DistributionUser;
/**
 * @author yami
 */
public interface DistributionBindUserService {
    /**
     * 根据分享人的卡号,判断该用户是否能与该分享人进行绑定
     * @param shareUser 分享人
     * @param userId
     * @param type 0 扫码 1 下单
     * @return
     */
    ServerResponseEntity bindDistribution(DistributionUser shareUser, String userId, int type);
    /**
     * 获取绑定用户的列表
     * @param page 分页信息
     * @param shopId 店铺id
     * @param userId 用户id
     * @return 绑定用户的列表
     */
    IPage<BindUserInfoDto> bindUserList(Page page, Long shopId, String userId);
    /**
     * 邀请好友成为分销员绑定用户关系
     * @param shareDistributionId 邀请分销员id
     * @param distributionId    审核通过分销员id
     */
    void bindUser(Long shareDistributionId, Long distributionId);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionMsgService.java
New file
@@ -0,0 +1,47 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.distribution.common.dto.DistributionMsgDto;
import com.yami.shop.distribution.common.model.DistributionMsg;
/**
 *
 * @author lgh on 2019/04/03.
 */
public interface DistributionMsgService extends IService<DistributionMsg> {
    /**
     * 根据id获取dto
     * @param msgId 消息id
     * @return
     */
    DistributionMsgDto getDistributionMsgDtoByMsgId(Long msgId);
    /**
     * 查询分销通知
     * @param page 分页信息
     * @param distributionMsg 查询参数
     * @return 分销通知列表
     */
    IPage<DistributionMsg> getDistributionMsgsAndSysUserPage(Page page, DistributionMsg distributionMsg);
    /**
     *
     * 根据分销员id 分页获取相应的公告
     * @param page 分页信息
     * @param isTop 是否置顶
     * @return 分页获取相应的公告
     */
    IPage<DistributionMsgDto> getDistributionMsgDtoShopId(Page page,Integer isTop);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionProdBindService.java
New file
@@ -0,0 +1,24 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.distribution.common.model.DistributionProdBind;
/**
 * 分销商品绑定表
 *
 * @author xwc
 * @date 2019-04-22 10:01:44
 */
public interface DistributionProdBindService extends IService<DistributionProdBind> {
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionProdService.java
New file
@@ -0,0 +1,129 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.param.OfflineHandleEventAuditParam;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.dto.DistributionProdDto;
import com.yami.shop.distribution.common.model.DistributionProd;
import com.yami.shop.distribution.common.model.DistributionProdLog;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.po.DistributionProdPO;
import com.yami.shop.distribution.common.vo.DistributionAwardDataVO;
import java.util.List;
/**
 * @author lgh on 2019/04/01.
 */
public interface DistributionProdService extends IService<DistributionProd> {
    /**
     * 查询分销商品列表
     * @param page 分页参数
     * @param distributionProd 分销商品
     * @param prodName 商品名称
     * @return 分销商品列表
     */
    IPage<DistributionProd> distributionProdsPage(Page page, DistributionProd distributionProd, String prodName);
    /**
     * 根据获得商品id获得po对象
     *
     * @param prodId 商品id
     * @return 分销商品详情
     */
    DistributionProdPO getDistributionProdPoByProdId(Long prodId);
    /**
     * 移除分销商品缓存
     * @param prodId 商品id
     */
    void removeDistributionProdPoCacheByProdId(Long prodId);
    /**
     * 根据分销员id获得分销商品 分页
     * @param page  分页参数
     * @param prodName 商品名称
     * @param sort 排序
     * @param orderBy 正序 / 倒序
     * @param distributionUser 分销员信息
     * @return 分销商品 分页
     */
    List<DistributionProdDto> distributionProdDtoPage(Page<DistributionProdDto> page, String prodName, Integer sort, Integer orderBy, DistributionUser distributionUser);
    /**
     * 计算佣金金额
     *
     * @param distributionProdPo 分销商品
     * @param distributionUserId 分销员
     * @param orderItem 订单项
     * @return 佣金金额
     */
    DistributionAwardDataVO getAwardDataVO(DistributionProdPO distributionProdPo, Long distributionUserId, OrderItem orderItem);
    /**
     * 下线分销商品
     * @param distributionProd 分销商品
     * @param offlineReason 下线原因
     * @param sysUserId 操作人
     */
    void offline(DistributionProd distributionProd, String offlineReason, Long sysUserId);
    /**
     * 审核活动商品
     * @param offlineHandleEventAuditParam 审核信息
     * @param sysUserId 操作人
     */
    void auditDistributionProd(OfflineHandleEventAuditParam offlineHandleEventAuditParam, Long sysUserId);
    /**
     * 提交审核
     * @param eventId 事件id
     * @param distributionProdId 分销商品id
     * @param reapplyReason 申请原因
     */
    void auditApply(Long eventId, Long distributionProdId, String reapplyReason);
    /**
     * 获取分销商品记录
     * @param page 分页参数
     * @param distributionProdLog 分销商品记录查询参数
     * @return 分销商品记录
     */
    IPage<DistributionProdLog> getDistributionProdLogPage(PageParam<DistributionProdLog> page, DistributionProdLog distributionProdLog);
    /**
     * 获取订单项中的分销商品信息
     * @param orderItems 订单项信息
     * @return 分销商品信息
     */
    List<DistributionProd> listByOrderItems(List<OrderItem> orderItems);
    /**
     * 根据商品id与状态查看该商品是处于该状态
     * @param prodId 商品id
     * @param state 状态
     * @return
     */
    Boolean isStateByProdId(Long prodId, Integer state);
    /**
     * 修改分销商品中的状态
     * @param distributionProdId 商品分销id
     * @param status 状态
     * @return 修改行数
     */
    int updateState(Long distributionProdId, Integer status);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionUserBanService.java
New file
@@ -0,0 +1,33 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.distribution.common.model.DistributionUserBan;
/**
 *
 * @author lgh on 2019/04/01.
 */
public interface DistributionUserBanService extends IService<DistributionUserBan> {
    /**
     * 分销员封禁列表
     * @param page 分页参数
     * @param shopId 店铺id
     * @param userMobile 手机号
     * @param distributionUserBan 查询参数
     * @return 封禁列表
     */
    IPage<DistributionUserBan> distributionUserBanPage(Page page, Long shopId, String userMobile, DistributionUserBan distributionUserBan);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionUserBindService.java
New file
@@ -0,0 +1,36 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.distribution.common.model.DistributionUserBind;
import com.yami.shop.distribution.common.param.RangeTimeParam;
/**
 *
 * @author lgh on 2019/04/01.
 */
public interface DistributionUserBindService extends IService<DistributionUserBind> {
    /**
     * 分销员和用户绑定关系列表
     * @param page 分页参数
     * @param distributionUserBind 绑定信息
     * @param bindTime 绑定时间
     * @param invalidTime 失效时间
     * @param userName 用户昵称
     * @param parentName 分销员昵称
     * @param sort 排序字段
     * @param orderBy 排序方式
     * @return 分销员和用户绑定关系列表
     */
    IPage<DistributionUserBind> distributionMsgsAndUserPage(Page page, DistributionUserBind distributionUserBind, RangeTimeParam bindTime, RangeTimeParam invalidTime, String userName, String  parentName, String cUserMobile, String dUserMobile, Integer sort, Integer orderBy);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionUserGroupService.java
New file
@@ -0,0 +1,32 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.distribution.common.model.DistributionUserGroup;
/**
 *
 * @author lgh on 2019/04/01.
 */
public interface DistributionUserGroupService extends IService<DistributionUserGroup> {
    /**
     * 分销员分组信息
     * @param page 分页参数
     * @param distributionUserGroup 查询参数
     * @return 分销员分组信息
     */
    IPage<DistributionUserGroup> distributionUserGroupsAndSysUserPage(Page page, DistributionUserGroup distributionUserGroup);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionUserIncomeService.java
New file
@@ -0,0 +1,89 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.dto.DistributionOrderDto;
import com.yami.shop.distribution.common.dto.DistributionUserIncomeDto;
import com.yami.shop.distribution.common.dto.StatisticsDisUserIncomeDto;
import com.yami.shop.distribution.common.model.DistributionUserIncome;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import com.yami.shop.distribution.common.vo.DistributionOrdersVO;
import java.util.List;
/**
 * @author lgh on 2019/04/01.
 */
public interface DistributionUserIncomeService extends IService<DistributionUserIncome> {
    /**
     * 获取分销员的收入记录
     * @param page 分页参数
     * @param shopId 店铺id
     * @param rangeTimeParam 时间范围
     * @param userMobile 手机号
     * @param orderNumber 订单号
     * @param state 收入状态
     * @param distributionUserIncome 分销员收入信息
     * @return 分销员的收入记录
     */
    IPage<DistributionUserIncome> incomeAndDistributionUserPage(Page page, Long shopId, RangeTimeParam rangeTimeParam, String userMobile, String orderNumber, Integer state,DistributionUserIncome distributionUserIncome);
    /**
     * 分销员推广订单信息
     * @param page 分页参数
     * @param distributionUserId 分销员id
     * @return 分销员推广订单信息
     */
    IPage<DistributionOrderDto> getDistributionOrderDtoByDistributionUserId(Page page, Long distributionUserId);
    /**
     * 统计分销员当日收入
     * @param distributionUserId 分销员id
     * @return 收入金额
     */
    StatisticsDisUserIncomeDto statisticsDistributionUserIncome(Long distributionUserId);
    /**
     * 查询分销员收入记录
     * @param page 分页参数
     * @param distributionUserId 分销员id
     * @return 收入记录
     */
    IPage<DistributionUserIncomeDto> getDistributionUserIncomePage(PageParam<DistributionUserIncome> page, Long distributionUserId);
    /**
     * 通过状态获取我的推广订单(0:待支付 1:待结算 2:已结算 -1:订单失效)
     *
     * @param page 分页参数
     * @param distributionUserId 分销员id
     * @param state 收入状态 0:待支付 1:待结算 2:已结算 -1:订单失效
     * @return 我的推广订单
     */
    IPage<DistributionOrdersVO> getMyPromotionOrderByState(PageParam<DistributionOrdersVO> page, Long distributionUserId, Integer state);
    /**
     * 分销员佣金结算处理
     * @param orderNumbers 最后结算时间
     */
    void commissionSettlementHandle(List<String> orderNumbers);
    /**
     * 批量更新分销收入记录
     * @param distributionUserIncomeList
     * @return
     */
     int updateBatchState(List<DistributionUserIncome> distributionUserIncomeList);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionUserService.java
New file
@@ -0,0 +1,135 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.distribution.common.dto.AchievementDataDto;
import com.yami.shop.distribution.common.dto.DistributionUserAchievementDataDto;
import com.yami.shop.distribution.common.dto.DistributionUserSimpleDto;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import com.yami.shop.distribution.common.param.UpdateDistributionUserParam;
import com.yami.shop.distribution.common.vo.DistributionUserInfoVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 *
 * @author lgh on 2019/04/01.
 */
public interface DistributionUserService extends IService<DistributionUser> {
    /**
     * 获取分销员用户信息
     * @param userId 用户id
     * @param shopId 店铺id
     * @return 分销员用户信息
     */
    DistributionUser getByUserIdAndShopId(String userId,Long shopId);
    /**
     * 移除分销员用户信息缓存
     * @param userId 用户id
     * @param shopId 店铺id
     */
    void removeCacheByUserIdAndShopId(String userId,Long shopId);
    /**
     * 分销员业绩数据
     * @param id 分销员id
     * @return 分销员业绩数据
     */
    AchievementDataDto getAchievementDataDtoById(Long id);
    /**
     * 获取分销员与等级条件匹配的数据
     * @param distributionUserId 分销员id
     * @return 分销员与等级条件匹配的数据
     */
    DistributionUserAchievementDataDto getDistributionUserLevelAchievementDataByDistributionUserId(@Param("distributionUserId") Long distributionUserId);
    /**
     * 查询分销员列表
     * @param page 分页参数
     * @param distributionUser 查询参数
     * @param rangeTimeParam 分销员上级绑定时间
     * @param mobile 手机号
     * @param parentMobile 上级手机号
     * @param sortChange 排序规则
     * @return 分销员列表
     */
    IPage<DistributionUser> distributionUserPage(Page page, DistributionUser distributionUser, RangeTimeParam rangeTimeParam
            , String mobile, String parentMobile, Integer sortChange, Integer state);
    /**
     * 封禁分销员
     * @param param 更新分销员状态的状态参数
     * @param modifier 操作人
     */
    void updateSelectiveAndInsertDistributionUserBan(UpdateDistributionUserParam param, Long modifier);
    /**
     * 查询分销员列表
     * @param page 分页参数
     * @param distributionUser 查询参数
     * @param userMobile 手机号
     * @return 分销员列表
     */
    IPage<DistributionUser> getDistributionUserAchievementPage(Page page,DistributionUser distributionUser,String userMobile);
    /**
     * 申请注册成为分销员
     * @param distributionUser 分销员信息
     */
    void registerDistributionUser(DistributionUser distributionUser);
    /**
     * 分页获取精简版分销员数据
     * @param page 分页参数
     * @param parentDistributionUserId 上级分销员id
     * @return 精简版分销员分页数据
     */
    IPage<DistributionUserSimpleDto> getDistributionUserSimpleDtoByParentUserIdPage(Page page, Long parentDistributionUserId);
    /**
     * 根据分销员卡号获取分销员信息
     * @param cardNo 卡号
     * @return 分销员信息
     */
    DistributionUser getByCardNo(String cardNo);
    /**
     * 移除根据分销员卡号获取分销员信息的缓存
     * @param cardNo 卡号
     */
    void removeCacheByCardNo(String cardNo);
    /**
     * 获取分销员列表
     * @param identityCardNumber 分销员身份证信息
     * @param userMobile 手机号
     * @return 分销员列表
     */
    List<DistributionUser> getDistributionUserByIdCardNumberAndUserMobile(String identityCardNumber, String userMobile);
    /**
     * 获取好友列表
     * @param user 分销员信息
     * @param userType
     * @return
     */
    List<DistributionUserInfoVO> getDistributionMyFriend(DistributionUser user, Integer userType);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionUserWalletBillService.java
New file
@@ -0,0 +1,43 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.distribution.common.dto.DistributionUserWalletBillDto;
import com.yami.shop.distribution.common.model.DistributionUserWalletBill;
/**
 * 分销员钱包流水
 *
 * @author xwc
 * @date 2019-04-29 16:39:13
 */
public interface DistributionUserWalletBillService extends IService<DistributionUserWalletBill> {
    /**
     * 获取分销员钱包流水记录
     * @param page 分页参数
     * @param userMobile 手机号
     * @return 分销员钱包流水记录
     */
    Page<DistributionUserWalletBill> getDistributionUserWalletBillAndUserPage(Page page,String userMobile);
    /**
     * 获取分销员钱包流水记录
     * @param page 分页参数
     * @param distributionUserId 分销员用户id
     * @param orderBy 排序方式
     * @return 分销员钱包流水记录
     */
    Page<DistributionUserWalletBillDto> getDistributionUserWalletBillDtoPage(Page page, Long distributionUserId,Integer orderBy);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionUserWalletService.java
New file
@@ -0,0 +1,55 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.distribution.common.dto.DistributionUserWalletDto;
import com.yami.shop.distribution.common.model.DistributionUserWallet;
import org.apache.ibatis.annotations.Param;
/**
 *
 * @author lgh on 2019/04/01.
 */
public interface DistributionUserWalletService extends IService<DistributionUserWallet> {
    /**
     * 根据分销员id获取钱包id
     * @param distributionUserId 分销员id
     * @return 钱包id
     */
    Long getWalletIdByDistributionUserId(@Param("distributionUserId")Long distributionUserId);
    /**
     *  返回钱包对象和用户vo分页
     * @param page 分页参数
     * @param userMobile 手机号
     * @return 钱包对象和用户vo
     */
    Page<DistributionUserWallet> getDistributionUserWalletAndDistributionUserVoPage(Page page, @Param("userMobile")String userMobile);
    /**
     * 人工修改钱包 并且添加一条钱包流水记录
     * @param distributionUserWallet 钱包信息
     * @param modifier 操作人id
     */
    void updateDistributionUserWallet(DistributionUserWallet distributionUserWallet,Long modifier);
    /**
     * 获取分销员钱包信息
     * @param distributionUserId 分销员id
     * @return 分销员钱包信息
     */
    DistributionUserWalletDto getDistributionUserWalletDtoByDistributionUserId(Long distributionUserId);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/DistributionWithdrawCashService.java
New file
@@ -0,0 +1,79 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.distribution.common.dto.DistributionWithdrawCashDto;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.model.DistributionWithdrawCash;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import com.yami.shop.security.common.model.AppConnect;
/**
 * @author lgh on 2019/04/01.
 */
public interface DistributionWithdrawCashService extends IService<DistributionWithdrawCash> {
    /**
     * 分页获取分销员提现申请记录
     * @param page 分页参数
     * @param shopId 店铺id
     * @param rangeTimeParam 申请时间
     * @param userMobile 手机号
     * @param distributionWithdrawCash 查询参数
     * @return 分销员提现申请记录
     */
    IPage<DistributionWithdrawCash> distributionWithdrawCashsPage(Page page, Long shopId, RangeTimeParam rangeTimeParam, String userMobile, DistributionWithdrawCash distributionWithdrawCash);
    /**
     * 分页获取分销员提现申请记录
     * @param page 分页参数
     * @param distributionUserId 分销员id
     * @return 分销员提现申请记录
     */
    IPage<DistributionWithdrawCashDto> distributionWithdrawCashDtoPageByUserId(Page page, Long distributionUserId);
    /**
     * 发起提现申请
     * @param amount 申请金额
     * @param distributionUser 分销员信息
     * @param appConnect 第三方登录信息(微信企业付款到零钱可能会用到)
     */
    void apply(Double amount, DistributionUser distributionUser, AppConnect appConnect);
    /**
     * 根据时间区间获取用户的提现次数
     *
     * @param rangeTimeParam 时间范围
     * @param distributionUserId 分销员id
     * @return 获取用户的提现次数
     */
    Integer getCountByRangeTimeAndDistributionUserId(RangeTimeParam rangeTimeParam, Long distributionUserId);
    /**
     * 查看分销员总提现金额
     * @param walletId 钱包id
     * @return 总提现金额
     */
    Double getUserTotalWithdrawCash(Long walletId);
    /**
     * 添加企业支付记录
     * @param distributionWithdrawCash  提现记录
     * @param userId     提现用户id
     * @param openId     提现用户openId
     * @param status     提现状态
     */
    void enterprisePay(DistributionWithdrawCash distributionWithdrawCash, String userId, String openId, Integer status);
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionAuditingServiceImpl.java
New file
@@ -0,0 +1,128 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.common.util.PrincipalUtil;
import com.yami.shop.distribution.common.constants.DistributionUserStateEnum;
import com.yami.shop.distribution.common.dao.DistributionAuditingMapper;
import com.yami.shop.distribution.common.dao.DistributionUserBindMapper;
import com.yami.shop.distribution.common.dao.DistributionUserMapper;
import com.yami.shop.distribution.common.dto.DistributionAuditingDto;
import com.yami.shop.distribution.common.model.DistributionAuditing;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.model.DistributionUserBind;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import com.yami.shop.distribution.common.service.DistributionAuditingService;
import com.yami.shop.distribution.common.service.DistributionBindUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
 * @author lgh on 2019/04/01.
 */
@Service
@RequiredArgsConstructor
public class DistributionAuditingServiceImpl extends ServiceImpl<DistributionAuditingMapper, DistributionAuditing> implements DistributionAuditingService {
    @Value("${yami.expose.operation.auth:}")
    private Boolean permission;
    private final DistributionAuditingMapper distributionAuditingMapper;
    private final DistributionUserMapper distributionUserMapper;
    private final DistributionUserBindMapper distributionUserBindMapper;
    private final DistributionBindUserService distributionBindUserService;
    @Override
    public Page<DistributionAuditingDto> distributionAuditingPage(Page page, DistributionAuditing distributionAuditing, RangeTimeParam rangeTimeParam, Integer startExpenseNumber, Integer endExpenseNumber, Double startPayAmount, Double endPayAmount, String mobile) {
        Page<DistributionAuditingDto> auditingPage = distributionAuditingMapper.distributionAuditingPage(page, distributionAuditing, rangeTimeParam, startExpenseNumber, endExpenseNumber, startPayAmount, endPayAmount, mobile);
        if (BooleanUtil.isFalse(permission)){
            for (DistributionAuditingDto record : auditingPage.getRecords()) {
                if(StrUtil.isNotBlank(record.getUserMobile())) {
                    record.setUserMobile(PhoneUtil.hideBetween(record.getUserMobile()).toString());
                }
                if (PrincipalUtil.isMobile(record.getNickName())) {
                    record.setNickName(PhoneUtil.hideBetween(record.getNickName()).toString());
                }
                Long parent = record.getParentDistributionUserId();
                if (Objects.nonNull(parent)) {
                    if(StrUtil.isNotBlank(record.getParentUserMobile())) {
                        record.setParentUserMobile(PhoneUtil.hideBetween(record.getParentUserMobile()).toString());
                    }
                    if (PrincipalUtil.isMobile(record.getParentNickName())) {
                        record.setParentNickName(PhoneUtil.hideBetween(record.getParentNickName()).toString());
                    }
                }
            }
        }
        return auditingPage;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void examine(DistributionAuditing distributionAuditing) {
        DistributionUser distributionUser = new DistributionUser();
        distributionUser.setDistributionUserId(distributionAuditing.getDistributionUserId());
        distributionUser.setBindTime(new Date());
        distributionUser.setStateRecord(null);
        //判断是否通过
        if (distributionAuditing.getState() == 1) {
            DistributionUser distributionUserDb = distributionUserMapper.selectById(distributionAuditing.getDistributionUserId());
            // 如果之前是暂时封禁状态,现在改成正常状态,恢复以前的没有被抢的绑定用户。
            if (Objects.nonNull(distributionUserDb.getStateRecord()) && distributionUserDb.getStateRecord() == DistributionUserStateEnum.BAN.getValue()) {
                List<DistributionUserBind> userBindList = distributionUserBindMapper.selectList(new LambdaQueryWrapper<DistributionUserBind>()
                        .eq(DistributionUserBind::getDistributionUserId, distributionAuditing.getDistributionUserId())
                        .eq(DistributionUserBind::getState, -1)
                        .eq(DistributionUserBind::getInvalidReason, 3));
                if(CollectionUtil.isNotEmpty(userBindList)) {
                    // 查询出所有暂时封禁但已经被抢的用户
                    List<String> userIds = distributionUserBindMapper.selectClearUserByDistributionUserId(userBindList);
                    if(CollectionUtil.isNotEmpty(userIds)) {
                        userBindList = userBindList.stream().filter(userBind -> !userIds.contains(userBind.getUserId())).collect(Collectors.toList());
                    }
                    if(CollectionUtil.isNotEmpty(userBindList)) {
                        // 将没有被抢的,失效的绑定用户设为正常。
                        distributionUserBindMapper.recoveryRelationsByUserId(userBindList);
                    }
                }
            }
            distributionUser.setLevel(distributionUserDb.getLevel());
            if (distributionUserDb.getState() == DistributionUserStateEnum.FAIL_AUDIT.getValue() ||
                    distributionUserDb.getState() == DistributionUserStateEnum.WAIT_AUDIT.getValue()){
                //通过审核,修改分销员状态
                distributionUser.setState(1);
                // 邀请人绑定申请分销员
                distributionBindUserService.bindUser(distributionAuditing.getParentDistributionUserId(), distributionAuditing.getDistributionUserId());
            }
        } else if (distributionAuditing.getState() == -1) {
            //未通过审核,修改分销员状态
            distributionUser.setState(3);
            distributionUser.setLevel(1);
        }
        distributionUserMapper.updateStatusById(distributionUser);
        distributionAuditingMapper.updateById(distributionAuditing);
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionBindUserServiceImpl.java
New file
@@ -0,0 +1,157 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.distribution.common.constants.DistributionUserStateEnum;
import com.yami.shop.distribution.common.dao.DistributionUserBindMapper;
import com.yami.shop.distribution.common.dto.BindUserInfoDto;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.model.DistributionUserBind;
import com.yami.shop.distribution.common.service.DistributionBindUserService;
import com.yami.shop.distribution.common.service.DistributionUserService;
import com.yami.shop.distribution.common.vo.DistributionConfigVO;
import com.yami.shop.service.SysConfigService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.Objects;
/**
 * @author yami
 */
@Slf4j
@Service
@AllArgsConstructor
public class DistributionBindUserServiceImpl implements DistributionBindUserService {
    private final DistributionUserService distributionUserService;
    private final SysConfigService sysConfigService;
    private final DistributionUserBindMapper distributionUserBindMapper;
    @Override
    public ServerResponseEntity bindDistribution(DistributionUser shareUser, String userId, int type) {
        //分享员信息
        if (shareUser == null) {
            // 获取推广员信息失败
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.distribution.get.fail"));
        }
        if (shareUser.getState() != 1) {
            log.info("推广员状态异常");
            // 推广员状态异常
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.distribution.status.error"));
        }
        DistributionConfigVO distributionConfigVO = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_CONFIG, DistributionConfigVO.class);
        // 查询该用户以前绑定的分享人
        DistributionUserBind distributionUserBind = distributionUserBindMapper.selectOne(new LambdaQueryWrapper<DistributionUserBind>()
                .eq(DistributionUserBind::getShopId, Constant.PLATFORM_SHOP_ID)
                .eq(DistributionUserBind::getState, 1)
                .eq(DistributionUserBind::getUserId, userId)
        );
        // 没有绑定分享人,或分享人已被冻结,可以与该用户进行绑定
        if (distributionUserBind == null) {
            bindUser(userId, shareUser);
            return ServerResponseEntity.success(shareUser);
        }
        // 如果现在的分享人就是以前的分享人
        if (Objects.equals(distributionUserBind.getDistributionUserId(),shareUser.getDistributionUserId())) {
            // 如果绑定人相同 延长绑定时间
            updateBindTime(distributionUserBind.getBindId());
            return ServerResponseEntity.success(shareUser);
        }
        // 查询以前的绑定的用户信息
        DistributionUser oldDistributionUser = distributionUserService.getById(distributionUserBind.getDistributionUserId());
        // 不绑定,分享人优先
        if (Objects.equals(distributionConfigVO.getAttribution(), 1)) {
            unBindUser(distributionUserBind.getBindId());
            bindUser(userId, shareUser);
            return ServerResponseEntity.success(shareUser);
        }
        log.info("用户在保护期内,绑定失败");
        // 用户在保护期内,绑定失败
        return ServerResponseEntity.fail("200", I18nMessage.getMessage("yami.distribution.user.protection.period"), oldDistributionUser);
    }
    @Override
    public IPage<BindUserInfoDto> bindUserList(Page page, Long shopId, String userId) {
        return distributionUserBindMapper.bindUserList(page,shopId,userId);
    }
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void bindUser(Long shareDistributionId, Long distributionId) {
        if (shareDistributionId == null){
            log.info("没有分销员邀请,不改变绑定关系");
            return;
        }
        DistributionUser shareUser = distributionUserService.getById(shareDistributionId);
        DistributionUser user = distributionUserService.getById(distributionId);
        DistributionUserBind distributionUserBind = distributionUserBindMapper.selectOne(new LambdaQueryWrapper<DistributionUserBind>().eq(DistributionUserBind::getUserId, user.getUserId())
                .and(i -> i.eq(DistributionUserBind::getState, DistributionUserStateEnum.NORMAL.getValue())));
        if (distributionUserBind != null && StringUtils.isNotBlank(distributionUserBind.getUserId())){
            log.info("修改用户原有绑定关系");
            // 有绑定记录修改绑定状态
            distributionUserBind.setInvalidTime(new Date());
            distributionUserBind.setUpdateTime(new Date());
            distributionUserBind.setInvalidReason(1);
            distributionUserBind.setState(-1);
            distributionUserBindMapper.updateById(distributionUserBind);
        }
        bindUser(user.getUserId(), shareUser);
    }
    private void bindUser(String userId, DistributionUser sharerUser) {
        DistributionUserBind distributionUserBind = new DistributionUserBind();
        distributionUserBind.setBindTime(new Date());
        distributionUserBind.setUserId(userId);
        distributionUserBind.setState(1);
        distributionUserBind.setShopId(sharerUser.getShopId());
        distributionUserBind.setUpdateTime(new Date());
        distributionUserBind.setDistributionUserId(sharerUser.getDistributionUserId());
        distributionUserBindMapper.insert(distributionUserBind);
    }
    private void updateBindTime(Long bindId) {
        DistributionUserBind distributionUserBind = new DistributionUserBind();
        distributionUserBind.setBindId(bindId);
        distributionUserBind.setUpdateTime(new Date());
        distributionUserBindMapper.updateById(distributionUserBind);
    }
    private void unBindUser(Long bindId) {
        Date date = new Date();
        DistributionUserBind distributionUserBind = new DistributionUserBind();
        distributionUserBind.setBindId(bindId);
        distributionUserBind.setUpdateTime(date);
        distributionUserBind.setInvalidReason(2);
        distributionUserBind.setState(-1);
        distributionUserBind.setInvalidTime(date);
        distributionUserBindMapper.updateById(distributionUserBind);
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionMsgServiceImpl.java
New file
@@ -0,0 +1,47 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.distribution.common.dao.DistributionMsgMapper;
import com.yami.shop.distribution.common.dto.DistributionMsgDto;
import com.yami.shop.distribution.common.model.DistributionMsg;
import com.yami.shop.distribution.common.service.DistributionMsgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 *
 * @author lgh on 2019/04/03.
 */
@Service
public class DistributionMsgServiceImpl extends ServiceImpl<DistributionMsgMapper, DistributionMsg> implements DistributionMsgService {
    @Autowired
    private DistributionMsgMapper distributionMsgMapper;
    @Override
    public DistributionMsgDto getDistributionMsgDtoByMsgId(Long msgId) {
        return distributionMsgMapper.getDistributionMsgDtoByMsgId(msgId);
    }
    @Override
    public IPage<DistributionMsg> getDistributionMsgsAndSysUserPage(Page page, DistributionMsg distributionMsg) {
        return distributionMsgMapper.getDistributionMsgsAndSysUserPage(page,distributionMsg);
    }
    @Override
    public IPage<DistributionMsgDto> getDistributionMsgDtoShopId(Page page,Integer isTop) {
        return distributionMsgMapper.getDistributionMsgDtoByShopId(page,isTop);
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionProdBindServiceImpl.java
New file
@@ -0,0 +1,34 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.distribution.common.dao.DistributionProdBindMapper;
import com.yami.shop.distribution.common.model.DistributionProdBind;
import com.yami.shop.distribution.common.service.DistributionProdBindService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * 分销商品绑定表
 *
 * @author xwc
 * @date 2019-04-22 10:01:44
 */
@Service
public class DistributionProdBindServiceImpl extends ServiceImpl<DistributionProdBindMapper, DistributionProdBind> implements DistributionProdBindService {
    @Autowired
   private  DistributionProdBindMapper distributionProdBindMapper;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionProdServiceImpl.java
New file
@@ -0,0 +1,231 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service.impl;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.enums.OfflineHandleEventStatus;
import com.yami.shop.bean.enums.OfflineHandleEventType;
import com.yami.shop.bean.model.OfflineHandleEvent;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.param.OfflineHandleEventAuditParam;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.common.util.PrincipalUtil;
import com.yami.shop.distribution.common.constants.DistributionProdStateEnum;
import com.yami.shop.distribution.common.dao.DistributionProdMapper;
import com.yami.shop.distribution.common.dao.DistributionUserMapper;
import com.yami.shop.distribution.common.dto.DistributionProdDto;
import com.yami.shop.distribution.common.model.DistributionProd;
import com.yami.shop.distribution.common.model.DistributionProdLog;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.po.DistributionProdPO;
import com.yami.shop.distribution.common.service.DistributionProdService;
import com.yami.shop.distribution.common.vo.DistributionAwardDataVO;
import com.yami.shop.service.OfflineHandleEventService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * @author lgh on 2019/04/01.
 */
@Service
@RequiredArgsConstructor
public class DistributionProdServiceImpl extends ServiceImpl<DistributionProdMapper, DistributionProd> implements DistributionProdService {
    @Value("${yami.expose.operation.auth:}")
    private Boolean permission;
    private final DistributionProdMapper distributionProdMapper;
    private final DistributionUserMapper distributionUserMapper;
    private final OfflineHandleEventService offlineHandleEventService;
    @Override
    public IPage<DistributionProd> distributionProdsPage(Page page, DistributionProd distributionProd, String prodName) {
        return distributionProdMapper.distributionProdsPage(page, distributionProd, prodName, I18nMessage.getDbLang());
    }
    @Override
    public List<DistributionProdDto> distributionProdDtoPage(Page<DistributionProdDto> page, String prodName, Integer sort, Integer orderBy, DistributionUser distributionUser) {
        IPage<DistributionProdPO> distributionProdPoPage = distributionProdMapper.distributionProdPoPage(page, prodName, sort, orderBy,I18nMessage.getDbLang());
        // 获取商品的分佣金额,或分佣奖励
        List<DistributionProdDto> distributionProdDtoList = new ArrayList<>();
        for (DistributionProdPO distributionProdPo : distributionProdPoPage.getRecords()) {
            //po转dto
            DistributionProdDto distributionProdDto = new DistributionProdDto();
            distributionProdDto.setProdId(distributionProdPo.getProdId());
            distributionProdDto.setProdName(distributionProdPo.getProdName());
            distributionProdDto.setPic(distributionProdPo.getPic());
            distributionProdDto.setPrice(distributionProdPo.getPrice());
            distributionProdDto.setAwardProportion(distributionProdPo.getAwardProportion());
            distributionProdDto.setAwardNumber(distributionProdPo.getAwardNumbers());
            distributionProdDto.setParentAwardNumber(distributionProdPo.getParentAwardNumbers());
            //添加到集合中
            distributionProdDtoList.add(distributionProdDto);
        }
        return distributionProdDtoList;
    }
    /**
     * 根据分销商品设置、分享人id,计算奖励数据
     *
     * @param distributionProdPo
     * @param distributionUserId
     * @param orderItem
     * @return
     */
    @Override
    public DistributionAwardDataVO getAwardDataVO(DistributionProdPO distributionProdPo, Long distributionUserId, OrderItem orderItem) {
        DistributionAwardDataVO distributionAwardDataVO = new DistributionAwardDataVO();
        distributionAwardDataVO.setAwardNumber(distributionProdPo.getAwardNumbers());
        distributionAwardDataVO.setParentAwardNumber(distributionProdPo.getParentAwardNumbers());
        distributionAwardDataVO.setAwardProportion(distributionProdPo.getAwardProportion());
        if (Objects.nonNull(distributionAwardDataVO.getAwardProportion())) {
            //如果计算为按比例计算,则转化为具体金额
            if(Objects.equals(distributionAwardDataVO.getAwardProportion(), 0)) {
                distributionAwardDataVO.setAwardProportion(0);
                //根据商品价格,计算得到的佣金
                distributionAwardDataVO.setAwardNumber(Arith.div(Arith.mul(distributionProdPo.getPrice(),distributionAwardDataVO.getAwardNumber()),100, 2));
                distributionAwardDataVO.setParentAwardNumber(Arith.div(Arith.mul(distributionProdPo.getPrice(),distributionAwardDataVO.getParentAwardNumber()), 100, 2));
            } else {
                distributionAwardDataVO.setAwardNumber(Arith.roundByBanker(Arith.mul(distributionAwardDataVO.getAwardNumber(),orderItem.getProdCount()),2));
                distributionAwardDataVO.setParentAwardNumber(Arith.roundByBanker(Arith.mul(distributionAwardDataVO.getParentAwardNumber(),orderItem.getProdCount()),2));
            }
        }
        return distributionAwardDataVO;
    }
    @Override
    @Cacheable(cacheNames = "DistributionProdPO", key = "#prodId")
    public DistributionProdPO getDistributionProdPoByProdId(Long prodId) {
        return distributionProdMapper.getDistributionProdPoByProdId(prodId);
    }
    @Override
    @CacheEvict(cacheNames = "DistributionProdPO", key = "#prodId")
    public void removeDistributionProdPoCacheByProdId(Long prodId) {
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void offline(DistributionProd distributionProd, String offlineReason, Long sysUserId) {
        List<Integer> statusIds = new ArrayList<>();
        statusIds.add(OfflineHandleEventStatus.OFFLINE_BY_PLATFORM.getValue());
        statusIds.add(OfflineHandleEventStatus.APPLY_BY_SHOP.getValue());
        int count = offlineHandleEventService.count(new LambdaQueryWrapper<OfflineHandleEvent>()
                .eq(OfflineHandleEvent::getHandleType, OfflineHandleEventType.DISTRIBUTION_PROD.getValue())
                .eq(OfflineHandleEvent::getHandleId, distributionProd.getDistributionProdId())
                .in(OfflineHandleEvent::getStatus, statusIds));
        if(count > 0){
            throw new YamiShopBindException("yami.platform.prod.offline.check");
        }
        // 添加下线处理记录
        Date now = new Date();
        OfflineHandleEvent offlineHandleEvent = new OfflineHandleEvent();
        offlineHandleEvent.setShopId(distributionProd.getShopId());
        offlineHandleEvent.setHandleId(distributionProd.getDistributionProdId());
        offlineHandleEvent.setHandleType(OfflineHandleEventType.DISTRIBUTION_PROD.getValue());
        offlineHandleEvent.setCreateTime(now);
        offlineHandleEvent.setOfflineReason(offlineReason);
        offlineHandleEvent.setHandlerId(sysUserId);
        offlineHandleEvent.setStatus(OfflineHandleEventStatus.OFFLINE_BY_PLATFORM.getValue());
        offlineHandleEvent.setUpdateTime(now);
        offlineHandleEventService.save(offlineHandleEvent);
        // 更新活动状态为下线
        if (distributionProdMapper.updateState(distributionProd.getDistributionProdId(), DistributionProdStateEnum.OFFLINE.getValue()) < 0) {
            // 更新活动商品失败
            throw new YamiShopBindException("yami.activity.prod.update.error");
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditDistributionProd(OfflineHandleEventAuditParam offlineHandleEventAuditParam, Long sysUserId) {
        // 审核通过
        if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.AGREE_BY_PLATFORM.getValue())) {
            // 更新活动状态
            distributionProdMapper.updateState(offlineHandleEventAuditParam.getHandleId(), DistributionProdStateEnum.PUT_OFF.getValue());
        }
        // 审核不通过
        else if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.DISAGREE_BY_PLATFORM.getValue())) {
            distributionProdMapper.updateState(offlineHandleEventAuditParam.getHandleId(), DistributionProdStateEnum.OFFLINE.getValue());
        }
        offlineHandleEventService.auditOfflineEvent(offlineHandleEventAuditParam, sysUserId);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditApply(Long eventId, Long distributionProdId, String reapplyReason) {
        // 更新活动为待审核状态
        distributionProdMapper.updateState(distributionProdId, DistributionProdStateEnum.WAIT_AUDIT.getValue());
        // 更新事件状态
        offlineHandleEventService.updateToApply(eventId, reapplyReason);
    }
    @Override
    public IPage<DistributionProdLog> getDistributionProdLogPage(PageParam<DistributionProdLog> page, DistributionProdLog distributionProdLog) {
        IPage<DistributionProdLog> logPage = distributionProdMapper.getDistributionProdLogPage(page, distributionProdLog, I18nMessage.getDbLang());
        if (BooleanUtil.isFalse(permission)) {
            for (DistributionProdLog record : logPage.getRecords()) {
                if(StrUtil.isNotBlank(record.getUserMobile())) {
                    record.setUserMobile(PhoneUtil.hideBetween(record.getUserMobile()).toString());
                }
                if (PrincipalUtil.isMobile(record.getNickName())) {
                    record.setNickName(PhoneUtil.hideBetween(record.getNickName()).toString());
                }
            }
        }
        return logPage;
    }
    @Override
    public List<DistributionProd> listByOrderItems(List<OrderItem> orderItems) {
        return distributionProdMapper.listByOrderItems(orderItems);
    }
    @Override
    public Boolean isStateByProdId(Long prodId, Integer state) {
        DistributionProd distributionProd = distributionProdMapper.selectOne(new LambdaQueryWrapper<DistributionProd>().eq(DistributionProd::getProdId, prodId).eq(DistributionProd::getState, state));
        return Objects.nonNull(distributionProd);
    }
    @Override
    public int updateState(Long distributionProdId, Integer status) {
        return distributionProdMapper.updateState(distributionProdId,status);
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionUserBanServiceImpl.java
New file
@@ -0,0 +1,57 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service.impl;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.PhoneUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.common.util.PrincipalUtil;
import com.yami.shop.distribution.common.dao.DistributionUserBanMapper;
import com.yami.shop.distribution.common.model.DistributionUserBan;
import com.yami.shop.distribution.common.service.DistributionUserBanService;
import com.yami.shop.distribution.common.vo.DistributionUserVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
 *
 * @author lgh on 2019/04/01.
 */
@Service
@RequiredArgsConstructor
public class DistributionUserBanServiceImpl extends ServiceImpl<DistributionUserBanMapper, DistributionUserBan> implements DistributionUserBanService {
    @Value("${yami.expose.operation.auth:}")
    private Boolean permission;
    private final DistributionUserBanMapper distributionUserBanMapper;
    @Override
    public IPage<DistributionUserBan> distributionUserBanPage(Page page, Long shopId, String userMobile, DistributionUserBan distributionUserBan) {
        if (distributionUserBan.getSortParam() == 0 ){
            distributionUserBan.setSortParam(1);
            distributionUserBan.setSortType(2);
        }
        IPage<DistributionUserBan> userBanPage = distributionUserBanMapper.distributionUserBanPage(page, shopId, userMobile, distributionUserBan);
        if (BooleanUtil.isFalse(permission)) {
            for (DistributionUserBan record : userBanPage.getRecords()) {
                DistributionUserVO distributionUser = record.getDistributionUser();
                distributionUser.setUserMobile(PhoneUtil.hideBetween(distributionUser.getUserMobile()).toString());
                if (PrincipalUtil.isMobile(distributionUser.getNickName())) {
                    distributionUser.setNickName(PhoneUtil.hideBetween(distributionUser.getNickName()).toString());
                }
            }
        }
        return userBanPage;
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionUserBindServiceImpl.java
New file
@@ -0,0 +1,68 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service.impl;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.vo.UserVO;
import com.yami.shop.common.util.PrincipalUtil;
import com.yami.shop.distribution.common.dao.DistributionUserBindMapper;
import com.yami.shop.distribution.common.model.DistributionUserBind;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import com.yami.shop.distribution.common.service.DistributionUserBindService;
import com.yami.shop.distribution.common.vo.DistributionUserVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Objects;
/**
 * @author lgh on 2019/04/01.
 */
@Service
@RequiredArgsConstructor
public class DistributionUserBindServiceImpl extends ServiceImpl<DistributionUserBindMapper, DistributionUserBind> implements DistributionUserBindService {
    @Value("${yami.expose.operation.auth:}")
    private Boolean permission;
    private final DistributionUserBindMapper distributionUserBindMapper;
    @Override
    public IPage<DistributionUserBind> distributionMsgsAndUserPage(Page page, DistributionUserBind distributionUserBind, RangeTimeParam bindTime, RangeTimeParam invalidTime, String userName, String parentName, String cUserMobile, String dUserMobile, Integer sort, Integer orderBy) {
        IPage<DistributionUserBind> bindPage = distributionUserBindMapper.distributionMsgsAndUserPage(page, distributionUserBind, bindTime, invalidTime, userName, parentName, cUserMobile, dUserMobile, sort, orderBy);
        if (BooleanUtil.isFalse(permission)) {
            for (DistributionUserBind record : bindPage.getRecords()) {
                DistributionUserVO distributionUser = record.getDistributionUser();
                if (Objects.nonNull(distributionUser)) {
                    if(StrUtil.isNotBlank(distributionUser.getUserMobile())){
                        distributionUser.setUserMobile(PhoneUtil.hideBetween(distributionUser.getUserMobile()).toString());
                    }
                    if (PrincipalUtil.isMobile(distributionUser.getNickName())) {
                        distributionUser.setNickName(PhoneUtil.hideBetween(distributionUser.getNickName()).toString());
                    }
                }
                UserVO user = record.getUser();
                if (Objects.nonNull(user)) {
                    user.setUserMobile(user.getUserMobile() != null ? PhoneUtil.hideBetween(user.getUserMobile()).toString() : null);
                    if (PrincipalUtil.isMobile(user.getNickName())) {
                        user.setNickName(PhoneUtil.hideBetween(user.getNickName()).toString());
                    }
                }
            }
        }
        return bindPage;
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionUserGroupServiceImpl.java
New file
@@ -0,0 +1,36 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.distribution.common.dao.DistributionUserGroupMapper;
import com.yami.shop.distribution.common.model.DistributionUserGroup;
import com.yami.shop.distribution.common.service.DistributionUserGroupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 *
 * @author lgh on 2019/04/01.
 */
@Service
public class DistributionUserGroupServiceImpl extends ServiceImpl<DistributionUserGroupMapper, DistributionUserGroup> implements DistributionUserGroupService {
    @Autowired
    private DistributionUserGroupMapper distributionUserGroupMapper;
    @Override
    public IPage<DistributionUserGroup> distributionUserGroupsAndSysUserPage(Page page, DistributionUserGroup distributionUserGroup) {
        return distributionUserGroupMapper.distributionUserGroupsAndSysUserPage(page,distributionUserGroup);
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionUserIncomeServiceImpl.java
New file
@@ -0,0 +1,221 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.PhoneUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.common.util.PrincipalUtil;
import com.yami.shop.distribution.common.constants.DistributionUserIncomeStateEnum;
import com.yami.shop.distribution.common.constants.DistributionUserIncomeTypeEnum;
import com.yami.shop.distribution.common.dao.DistributionUserIncomeMapper;
import com.yami.shop.distribution.common.dao.DistributionUserWalletMapper;
import com.yami.shop.distribution.common.dto.DistributionOrderDto;
import com.yami.shop.distribution.common.dto.DistributionUserIncomeDto;
import com.yami.shop.distribution.common.dto.StatisticsDisUserIncomeDto;
import com.yami.shop.distribution.common.model.DistributionUserIncome;
import com.yami.shop.distribution.common.model.DistributionUserWallet;
import com.yami.shop.distribution.common.model.DistributionUserWalletBill;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import com.yami.shop.distribution.common.service.DistributionUserIncomeService;
import com.yami.shop.distribution.common.service.DistributionUserWalletBillService;
import com.yami.shop.distribution.common.vo.DistributionOrdersVO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * @author lgh on 2019/04/01.
 */
@Service
@RequiredArgsConstructor
public class DistributionUserIncomeServiceImpl extends ServiceImpl<DistributionUserIncomeMapper, DistributionUserIncome> implements DistributionUserIncomeService {
    @Value("${yami.expose.operation.auth:}")
    private Boolean permission;
    private final DistributionUserIncomeMapper distributionUserIncomeMapper;
    private final DistributionUserWalletMapper distributionUserWalletMapper;
    private final DistributionUserWalletBillService distributionUserWalletBillService;
    @Override
    public IPage<DistributionUserIncome> incomeAndDistributionUserPage(Page page, Long shopId, RangeTimeParam rangeTimeParam, String userMobile, String orderNumber, Integer state,DistributionUserIncome distributionUserIncome) {
        IPage<DistributionUserIncome> userPage = distributionUserIncomeMapper.incomeAndDistributionUserPage(page, shopId, rangeTimeParam, userMobile, orderNumber, state, distributionUserIncome);
        if (BooleanUtil.isFalse(permission)) {
            for (DistributionUserIncome record : userPage.getRecords()) {
                record.getDistributionUser().setUserMobile(PhoneUtil.hideBetween(record.getDistributionUser().getUserMobile()).toString());
                if (PrincipalUtil.isMobile(record.getDistributionUser().getNickName())) {
                    record.getDistributionUser().setNickName(PhoneUtil.hideBetween(record.getDistributionUser().getNickName()).toString());
                }
            }
        }
        return userPage;
    }
    @Override
    public IPage<DistributionOrderDto> getDistributionOrderDtoByDistributionUserId(Page page, Long distributionUserId) {
        return distributionUserIncomeMapper.getDistributionOrderDtoByDistributionUserId(page, distributionUserId);
    }
    @Override
    public StatisticsDisUserIncomeDto statisticsDistributionUserIncome(Long distributionUserId) {
        StatisticsDisUserIncomeDto statisticsDisUserIncomeDto = new StatisticsDisUserIncomeDto();
        Date now = new Date();
        double todayAmount = distributionUserIncomeMapper.statisticsDisUserIncome(distributionUserId, DateUtil.beginOfDay(now), DateUtil.endOfDay(now));
        double monthAmount = distributionUserIncomeMapper.statisticsDisUserIncome(distributionUserId, DateUtil.beginOfMonth(now), DateUtil.endOfMonth(now));
        statisticsDisUserIncomeDto.setTodayAmount(todayAmount);
        statisticsDisUserIncomeDto.setMonthAmount(monthAmount);
        return statisticsDisUserIncomeDto;
    }
    @Override
    public IPage<DistributionUserIncomeDto> getDistributionUserIncomePage(PageParam<DistributionUserIncome> page, Long distributionUserId) {
        return distributionUserIncomeMapper.getDistributionUserIncomePage(page, distributionUserId);
    }
    @Override
    public IPage<DistributionOrdersVO> getMyPromotionOrderByState(PageParam<DistributionOrdersVO> page, Long distributionUserId, Integer state) {
        return distributionUserIncomeMapper.getMyPromotionOrderByState(page, distributionUserId, state, I18nMessage.getDbLang());
    }
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void commissionSettlementHandle1(Date date) {
//        // 查询需要处理的支付收入记录,15天前确认收货的订单
//        List<DistributionUserIncome> distributionUserIncomeList = distributionUserIncomeMapper.listWaitCommissionSettlement(date);
//        List<DistributionUserIncome> updateBatchDistributionUserIncomeList = new ArrayList<>();
//        List<DistributionUserWalletBill> saveBatchDistributionWalletBillList = new ArrayList<>();
//
//        for (DistributionUserIncome distributionUserIncome : distributionUserIncomeList) {
//            // 减少用户的待结算佣金,添加已结算金额
//            DistributionUserWallet distributionUserWallet = distributionUserWalletMapper.selectById(distributionUserIncome.getWalletId());
//            if (distributionUserWallet == null) {
//                // 未找到分销员信息
//                throw new YamiShopBindException("yami.distribution.exist.error");
//            }
//
//            // 添加分销钱包日志
//            distributionUserWallet.setSettledAmount(Arith.add(distributionUserWallet.getSettledAmount(), distributionUserIncome.getIncomeAmount()));
//            distributionUserWallet.setUnsettledAmount(Arith.sub(distributionUserWallet.getUnsettledAmount(), distributionUserIncome.getIncomeAmount()));
//            distributionUserWallet.setAddupAmount(Arith.add(distributionUserWallet.getAddupAmount(), distributionUserIncome.getIncomeAmount()));
//            distributionUserWalletMapper.updateById(distributionUserWallet);
//
//            // 更新收入状态
//            updateBatchDistributionUserIncomeList.add(distributionUserIncome);
//
//            // 添加钱包变动日志
//            if (Objects.equals(DistributionUserIncomeTypeEnum.AWARD_ONE.getValue(), distributionUserIncome.getIncomeType())) {
//                saveBatchDistributionWalletBillList.add(new DistributionUserWalletBill(distributionUserWallet, "直推奖励","Direct push reward", -distributionUserIncome.getIncomeAmount(), distributionUserIncome.getIncomeAmount(), 0.0, distributionUserIncome.getIncomeAmount(), 0));
//            } else if (Objects.equals(DistributionUserIncomeTypeEnum.AWARD_TWO.getValue(), distributionUserIncome.getIncomeType())) {
//                saveBatchDistributionWalletBillList.add(new DistributionUserWalletBill(distributionUserWallet, "间推奖励","Indirect reward", -distributionUserIncome.getIncomeAmount(), distributionUserIncome.getIncomeAmount(), 0.0, distributionUserIncome.getIncomeAmount(), 0));
//            } else {
//                saveBatchDistributionWalletBillList.add(new DistributionUserWalletBill(distributionUserWallet, "邀请奖励","Invitation reward", -distributionUserIncome.getIncomeAmount(), distributionUserIncome.getIncomeAmount(), 0.0, distributionUserIncome.getIncomeAmount(), 0));
//            }
//        }
//        // 批量更新分销收入状态
//        if (CollectionUtils.isNotEmpty(updateBatchDistributionUserIncomeList)) {
//            if (distributionUserIncomeMapper.updateBatchState(updateBatchDistributionUserIncomeList, DistributionUserIncomeStateEnum.COMMISSION.getValue()) <= 0) {
//                // 批量更新分销收入状态失败
//                throw new YamiShopBindException("yami.distribution.batch.update.income");
//            }
//        }
//
//        // 批量添加钱包变动日志
//        if (CollectionUtils.isNotEmpty(saveBatchDistributionWalletBillList)) {
//            distributionUserWalletBillService.saveBatch(saveBatchDistributionWalletBillList);
//        }
//    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void commissionSettlementHandle(List<String> orderNumbers) {
        // 查询需要处理的支付收入记录,15天前确认收货的订单
        List<DistributionUserIncome> distributionUserIncomeList = distributionUserIncomeMapper.listWaitCommissionSettlement(orderNumbers);
        List<DistributionUserIncome> updateBatchDistributionUserIncomeList = new ArrayList<>();
        List<DistributionUserWalletBill> saveBatchDistributionWalletBillList = new ArrayList<>();
        for (DistributionUserIncome distributionUserIncome : distributionUserIncomeList) {
            // 减少用户的待结算佣金,添加已结算金额
            DistributionUserWallet distributionUserWallet = distributionUserWalletMapper.selectById(distributionUserIncome.getWalletId());
            if (distributionUserWallet == null) {
                // 未找到分销员信息
                throw new YamiShopBindException("yami.distribution.exist.error");
            }
            // 添加分销钱包日志
            distributionUserWallet.setSettledAmount(Arith.add(distributionUserWallet.getSettledAmount(), distributionUserIncome.getIncomeAmount()));
            distributionUserWallet.setUnsettledAmount(Arith.sub(distributionUserWallet.getUnsettledAmount(), distributionUserIncome.getIncomeAmount()));
            distributionUserWallet.setAddupAmount(Arith.add(distributionUserWallet.getAddupAmount(), distributionUserIncome.getIncomeAmount()));
            distributionUserWalletMapper.updateById(distributionUserWallet);
            // 更新收入状态
            updateBatchDistributionUserIncomeList.add(distributionUserIncome);
            // 添加钱包变动日志
            if (Objects.equals(DistributionUserIncomeTypeEnum.AWARD_ONE.getValue(), distributionUserIncome.getIncomeType())) {
                saveBatchDistributionWalletBillList.add(new DistributionUserWalletBill(distributionUserWallet, "直推奖励","Direct push reward", -distributionUserIncome.getIncomeAmount(), distributionUserIncome.getIncomeAmount(), 0.0, distributionUserIncome.getIncomeAmount(), 0));
            } else if (Objects.equals(DistributionUserIncomeTypeEnum.AWARD_TWO.getValue(), distributionUserIncome.getIncomeType())) {
                saveBatchDistributionWalletBillList.add(new DistributionUserWalletBill(distributionUserWallet, "间推奖励","Indirect reward", -distributionUserIncome.getIncomeAmount(), distributionUserIncome.getIncomeAmount(), 0.0, distributionUserIncome.getIncomeAmount(), 0));
            } else {
                saveBatchDistributionWalletBillList.add(new DistributionUserWalletBill(distributionUserWallet, "邀请奖励","Invitation reward", -distributionUserIncome.getIncomeAmount(), distributionUserIncome.getIncomeAmount(), 0.0, distributionUserIncome.getIncomeAmount(), 0));
            }
        }
        // 批量更新分销收入状态
        if (CollectionUtils.isNotEmpty(updateBatchDistributionUserIncomeList)) {
//            if (distributionUserIncomeMapper.updateBatchState(updateBatchDistributionUserIncomeList, DistributionUserIncomeStateEnum.COMMISSION.getValue(), DistributionAudit.INCOME_ZERO.getValue()) <= 0) {
//                // 批量更新分销收入状态失败
//                throw new YamiShopBindException("yami.distribution.batch.update.income");
////            }
            updateBatchDistributionUserIncomeList.forEach( item -> {
                item.setState(DistributionUserIncomeStateEnum.COMMISSION.getValue());
            });
            if (updateBatchState(updateBatchDistributionUserIncomeList) <= 0){
                throw new YamiShopBindException("yami.distribution.batch.update.income");
            }
        }
        // 批量添加钱包变动日志
        if (CollectionUtils.isNotEmpty(saveBatchDistributionWalletBillList)) {
            distributionUserWalletBillService.saveBatch(saveBatchDistributionWalletBillList);
        }
    }
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int updateBatchState(List<DistributionUserIncome> distributionUserIncomeList){
        int i = 0;
        for (DistributionUserIncome entity :
                distributionUserIncomeList) {
            int b = distributionUserIncomeMapper.updateById(entity);
            if (b > 0){
                i++;
            }
        }
        return i;
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionUserServiceImpl.java
New file
@@ -0,0 +1,360 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.common.util.PrincipalUtil;
import com.yami.shop.distribution.common.constants.*;
import com.yami.shop.distribution.common.dao.*;
import com.yami.shop.distribution.common.dto.AchievementDataDto;
import com.yami.shop.distribution.common.dto.DistributionUserAchievementDataDto;
import com.yami.shop.distribution.common.dto.DistributionUserSimpleDto;
import com.yami.shop.distribution.common.model.*;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import com.yami.shop.distribution.common.param.UpdateDistributionUserParam;
import com.yami.shop.distribution.common.service.DistributionUserService;
import com.yami.shop.distribution.common.service.DistributionUserWalletBillService;
import com.yami.shop.distribution.common.service.DistributionUserWalletService;
import com.yami.shop.distribution.common.vo.DistributionUserInfoVO;
import com.yami.shop.distribution.common.vo.DistributionUserVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
 * @author lgh on 2019/04/01.
 */
@Service
@RequiredArgsConstructor
public class DistributionUserServiceImpl extends ServiceImpl<DistributionUserMapper, DistributionUser> implements DistributionUserService {
    @Value("${yami.expose.operation.auth:}")
    private Boolean permission;
    private final DistributionUserMapper distributionUserMapper;
    private final DistributionUserBanMapper distributionUserBanMapper;
    private final DistributionUserBindMapper distributionUserBindMapper;
    private final DistributionAuditingMapper distributionAuditingMapper;
    private final DistributionUserWalletService distributionUserWalletService;
    private final DistributionProdBindMapper distributionProdBindMapper;
    private final DistributionUserIncomeMapper distributionUserIncomeMapper;
    private final DistributionUserWalletMapper distributionUserWalletMapper;
    private final DistributionWithdrawCashMapper distributionWithdrawCashMapper;
    private final DistributionUserWalletBillService distributionUserWalletBillService;
    @Override
    @Cacheable(cacheNames = "distribution_user", key = "#shopId + ':' + #userId")
    public DistributionUser getByUserIdAndShopId(String userId, Long shopId) {
        return distributionUserMapper.selectOne(new LambdaQueryWrapper<DistributionUser>().eq(DistributionUser::getUserId, userId).eq(DistributionUser::getShopId, shopId));
    }
    @Override
    @CacheEvict(cacheNames = "distribution_user", key = "#shopId + ':' + #userId")
    public void removeCacheByUserIdAndShopId(String userId, Long shopId) {
    }
    @Override
    public AchievementDataDto getAchievementDataDtoById(Long id) {
        return distributionUserMapper.getAchievementDataDtoById(id);
    }
    @Override
    public DistributionUserAchievementDataDto getDistributionUserLevelAchievementDataByDistributionUserId(Long distributionUserId) {
        return distributionUserMapper.getLevelDistributionUserAchievementDataByDistributionUserId(distributionUserId);
    }
    @Override
    public IPage<DistributionUser> distributionUserPage(Page page, DistributionUser distributionUser, RangeTimeParam rangeTimeParam
            , String mobile, String parentMobile, Integer sortChange, Integer state) {
        IPage<DistributionUser> userPage = distributionUserMapper.distributionUserPage(page, distributionUser, rangeTimeParam, mobile, parentMobile, sortChange, state);
        if (BooleanUtil.isFalse(permission)) {
            for (DistributionUser record : userPage.getRecords()) {
                if (StrUtil.isNotBlank(record.getUserMobile())) {
                    record.setUserMobile(PhoneUtil.hideBetween(record.getUserMobile()).toString());
                }
                if (PrincipalUtil.isMobile(record.getNickName())) {
                    record.setNickName(PhoneUtil.hideBetween(record.getNickName()).toString());
                }
                DistributionUserVO parent = record.getParentDistributionUser();
                if (Objects.nonNull(parent)) {
                    parent.setUserMobile(PhoneUtil.hideBetween(parent.getUserMobile()).toString());
                    if (PrincipalUtil.isMobile(parent.getNickName())) {
                        parent.setNickName(PhoneUtil.hideBetween(parent.getNickName()).toString());
                    }
                }
            }
        }
        return userPage;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSelectiveAndInsertDistributionUserBan(UpdateDistributionUserParam param, Long modifier) {
        //创建ban对象,插入数据后修改分销员状态
        DistributionUserBan distributionUserBan = new DistributionUserBan();
        distributionUserBan.setDistributionUserId(param.getDistributionUserId());
        distributionUserBan.setRemarks(param.getRemarks());
        distributionUserBan.setBanReason(param.getBanReason());
        distributionUserBan.setState(param.getState());
        distributionUserBan.setModifier(modifier);
        distributionUserBan.setUpdateTime(new Date());
        distributionUserBanMapper.insert(distributionUserBan);
        DistributionUser distributionUserDb = getById(param.getDistributionUserId());
        // 如果之前是暂时封禁[2]状态,现在改成正常状态[1],恢复以前的没有被抢的绑定用户。
        if (distributionUserDb.getState() == DistributionUserStateEnum.BAN.getValue() && param.getState() == DistributionUserStateEnum.NORMAL.getValue()) {
            List<DistributionUserBind> userBindList = distributionUserBindMapper.selectList(new LambdaQueryWrapper<DistributionUserBind>()
                    .eq(DistributionUserBind::getDistributionUserId, param.getDistributionUserId())
                    .eq(DistributionUserBind::getState, -1)
                    .eq(DistributionUserBind::getInvalidReason, 3));
            if (CollectionUtil.isNotEmpty(userBindList)) {
                // 查询出所有暂时封禁但已经被抢的用户
                List<String> userIds = distributionUserBindMapper.selectClearUserByDistributionUserId(userBindList);
                if (CollectionUtil.isNotEmpty(userIds)) {
                    userBindList = userBindList.stream().filter(userBind -> !userIds.contains(userBind.getUserId())).collect(Collectors.toList());
                }
                if (CollectionUtil.isNotEmpty(userBindList)) {
                    // 将没有被抢的,失效的绑定用户设为正常。
                    distributionUserBindMapper.recoveryRelationsByUserId(userBindList);
                }
            }
        }
        // 更新分销员状态
        DistributionUser distributionUser = new DistributionUser();
        distributionUser.setDistributionUserId(param.getDistributionUserId());
        distributionUser.setState(param.getState());
        distributionUser.setBindTime(distributionUserDb.getBindTime());
        distributionUser.setLevel(distributionUserDb.getLevel());
        //如果是暂时封禁[2]或永久封禁[-1]
        if (param.getState() == DistributionUserStateEnum.BAN.getValue() || param.getState() == DistributionUserStateEnum.PER_BAN.getValue()) {
            distributionUser.setStateRecord(param.getState());
            //将绑定的用户设为失效
            distributionUserBindMapper.updateStateAndReasonByDistributionUserId(param.getDistributionUserId(), -1);
            DistributionUser distributionUser1 = distributionUserMapper.selectById(param.getDistributionUserId());
            distributionUserBindMapper.updateStateAndReasonByUserId(distributionUser1.getUserId(), -1);
            //将商品分享记录设为失效
            distributionProdBindMapper.updateStateByDistributionUserId(param.getDistributionUserId(), -1);
            //判断是否为永久封禁
            if (param.getState() == DistributionUserStateEnum.PER_BAN.getValue()) {
                //将正在处理中的佣金订单冻结
                updateStateByDistributionUserId(param.getDistributionUserId());
                //将tz_distribution_user_wallet累计收益改为0
                updateAmountByDistributionUserId(param.getDistributionUserId());
                //将tz_distribution_user上级id清空[清空该被永久封禁的分销员的下级关系]
                distributionUserMapper.updateParentIdById(param.getDistributionUserId());
                //提现记录为申请中的变为拒绝提现
                distributionWithdrawCashMapper.updateUserByDistributionUserId(param.getDistributionUserId());
                //等级恢复为1
                distributionUser.setLevel(1);
            }
        }
        // 如果恢复成正常状态就不需要记录之前的状态了
        if (param.getState() == DistributionUserStateEnum.NORMAL.getValue()) {
            distributionUser.setStateRecord(null);
        }
        distributionUserMapper.updateStatusById(distributionUser);
    }
    /**
     * 永久封禁后冻结所有收入订单和上级间推收入
     *
     * @param id
     */
//    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    void updateStateByDistributionUserId(Long id) {
        distributionUserIncomeMapper.updateStateByDistributionUserId(id, -1);
        DistributionUser distributionUser = distributionUserMapper.selectById(id);
        if (distributionUser.getParentId() == null) {
            log.debug("没有上级分销员");
            return;
        }
        List<DistributionUserIncome> distributionUserIncomes = distributionUserIncomeMapper.selectList(new LambdaQueryWrapper<DistributionUserIncome>().eq(DistributionUserIncome::getDistributionUserId, id));
        List<String> collect = distributionUserIncomes.stream().map(DistributionUserIncome::getOrderNumber).collect(Collectors.toList());
        distributionUserIncomeMapper.updateDistributionUserIncomesBy(collect, distributionUser.getParentId(), DistributionUserIncomeStateEnum.INVALID.getValue(), DistributionUserIncomeTypeEnum.AWARD_TWO.getValue());
    }
    /**
     * 永久封禁收益清零,插入一条流水记录
     * @param id 分销员id
     */
//    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    void updateAmountByDistributionUserId(Long id) {
        DistributionUserWallet distributionUserWallet = distributionUserWalletMapper.selectOne(new LambdaQueryWrapper<DistributionUserWallet>().eq(DistributionUserWallet::getDistributionUserId, id));
//        插入一条流水记录  unsettled_amount = 0,settled_amount = 0,invalid_amount = 0,addup_amount = 0
        Double amount = 0d;
        DistributionUserWalletBill bill = new DistributionUserWalletBill();
        bill.setAddupAmount(amount);
        bill.setUnsettledAmount(amount);
        bill.setSettledAmount(amount);
        bill.setInvalidAmount(amount);
        bill.setRemarks("分销员被永久封禁,清空收益");
        bill.setRemarksEn("Distributors are permanently banned, emptying up earnings");
        bill.setCreateTime(new Date());
        bill.setType(0);
        bill.setWalletId(distributionUserWallet.getWalletId());
        distributionUserWalletBillService.save(bill);
        //将tz_distribution_user_wallet累计收益改为0
        distributionUserWalletMapper.updateAmountByDistributionUserId(id);
    }
    @Override
    public IPage<DistributionUser> getDistributionUserAchievementPage(Page page, DistributionUser distributionUser, String userMobile) {
        IPage<DistributionUser> userPage = distributionUserMapper.getDistributionUserAchievementPage(page, distributionUser, userMobile);
        if (BooleanUtil.isFalse(permission)) {
            for (DistributionUser record : userPage.getRecords()) {
                if (StrUtil.isNotBlank(record.getUserMobile())) {
                    record.setUserMobile(PhoneUtil.hideBetween(record.getUserMobile()).toString());
                }
                if (PrincipalUtil.isMobile(record.getNickName())) {
                    record.setNickName(PhoneUtil.hideBetween(record.getNickName()).toString());
                }
            }
        }
        return userPage;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void registerDistributionUser(DistributionUser distributionUser) {
        DistributionUser dbDistributionUser = getByUserIdAndShopId(distributionUser.getUserId(), distributionUser.getShopId());
        // 返回自增id
        Long distributionUserId;
        if (dbDistributionUser == null) {
            //存入分销员数据库
            distributionUserMapper.insert(distributionUser);
            distributionUserId = distributionUser.getDistributionUserId();
            //为这个分销员创建一个钱包
            DistributionUserWallet distributionUserWallet = new DistributionUserWallet();
            distributionUserWallet.setAddupAmount(0.0);
            distributionUserWallet.setSettledAmount(0.0);
            distributionUserWallet.setInvalidAmount(0.0);
            distributionUserWallet.setVersion(0);
            distributionUserWallet.setDistributionUserId(distributionUserId);
            distributionUserWallet.setUnsettledAmount(0.0);
            distributionUserWalletService.save(distributionUserWallet);
        } else {
            dbDistributionUser.setState(0);
            distributionUser.setDistributionUserId(dbDistributionUser.getDistributionUserId());
            distributionUserMapper.updateById(distributionUser);
            distributionUserId = dbDistributionUser.getDistributionUserId();
        }
        //创建申请记录该用户是否为本店分销员
        DistributionAuditing distributionAuditing = new DistributionAuditing();
        distributionAuditing.setAuditingTime(new Date());
        distributionAuditing.setShopId(distributionUser.getShopId());
        distributionAuditing.setDistributionUserId(distributionUserId);
        distributionAuditing.setParentDistributionUserId(distributionUser.getParentId());
        //符合条件,自动通过
        if (Objects.equals(distributionUser.getState(), DistributionUserStateEnum.NORMAL.getValue())) {
            distributionAuditing.setRemarks("系统判断自动通过审核");
            distributionAuditing.setState(1);
        } else {
            distributionAuditing.setState(0);
        }
        if (dbDistributionUser == null) {
            //存入申请记录
            distributionAuditingMapper.insert(distributionAuditing);
        } else {
            DistributionAuditing dbAuditing = distributionAuditingMapper.selectOne(new LambdaQueryWrapper<DistributionAuditing>().eq(DistributionAuditing::getDistributionUserId, distributionUserId));
            distributionAuditing.setAuditingId(dbAuditing.getAuditingId());
            distributionAuditingMapper.updateById(distributionAuditing);
        }
    }
    @Override
    public IPage<DistributionUserSimpleDto> getDistributionUserSimpleDtoByParentUserIdPage(Page page, Long parentDistributionUserId) {
        return distributionUserMapper.getDistributionUserSimpleDtoByParentUserIdPage(page, parentDistributionUserId);
    }
    @Override
    @Cacheable(cacheNames = "distribution_user_by_card_no", key = "#cardNo")
    public DistributionUser getByCardNo(String cardNo) {
        return distributionUserMapper.selectOne(new LambdaQueryWrapper<DistributionUser>().eq(DistributionUser::getCardNo, cardNo));
    }
    @Override
    @CacheEvict(cacheNames = "distribution_user_by_card_no", key = "#cardNo")
    public void removeCacheByCardNo(String cardNo) {
    }
    @Override
    public List<DistributionUser> getDistributionUserByIdCardNumberAndUserMobile(String identityCardNumber, String userMobile) {
        return distributionUserMapper.getDistributionUserByIdCardNumberAndUserMobile(identityCardNumber, userMobile);
    }
    @Override
    public List<DistributionUserInfoVO> getDistributionMyFriend(DistributionUser user, Integer userType) {
        if (userType.equals(DUserType.MY_FRIEND.getValue())) {
            // 获取二级佣金 == 我的好友推广的订单我的间接佣金
            List<DistributionUser> distributionUsers = distributionUserMapper.selectList(new LambdaQueryWrapper<DistributionUser>()
                    .eq(DistributionUser::getParentId, user.getDistributionUserId())
                    .eq(DistributionUser::getState, 1));
            if (CollUtil.isEmpty(distributionUsers)) {
                return new ArrayList<>();
            }
            return distributionUserIncomeMapper.getFriendInfo(user, distributionUsers, DistributionUserIncomeTypeEnum.AWARD_TWO.getValue());
        } else {
            //所有分销订单
            List<String> orderNumbers = distributionUserMapper.selectDistributionOrderId(user.getCardNo());
            if (CollUtil.isEmpty(orderNumbers)) {
                return new ArrayList<>();
            }
            List<DistributionUserBind> distributionUserBinds = distributionUserBindMapper.selectList(new LambdaQueryWrapper<DistributionUserBind>()
                    .eq(DistributionUserBind::getDistributionUserId, user.getDistributionUserId())
                    .eq(DistributionUserBind::getState, DistributionAudit.BIND_ONE.getValue()));
            List<String> userIds = distributionUserBinds.stream().map(DistributionUserBind::getUserId).collect(Collectors.toList());
            if (CollUtil.isEmpty(userIds)) {
                return new ArrayList<>();
            }
            return distributionUserIncomeMapper.selectIncomeInfo(userIds, orderNumbers, DistributionUserIncomeTypeEnum.AWARD_ONE.getValue(), user);
        }
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionUserWalletBillServiceImpl.java
New file
@@ -0,0 +1,71 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service.impl;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.PhoneUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.util.PrincipalUtil;
import com.yami.shop.distribution.common.dao.DistributionUserWalletBillMapper;
import com.yami.shop.distribution.common.dto.DistributionUserWalletBillDto;
import com.yami.shop.distribution.common.model.DistributionUserWalletBill;
import com.yami.shop.distribution.common.service.DistributionUserWalletBillService;
import com.yami.shop.distribution.common.vo.DistributionUserVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * 分销员钱包流水
 * @author xwc
 * @date 2019-04-29 16:39:13
 */
@Service
@RequiredArgsConstructor
public class DistributionUserWalletBillServiceImpl extends ServiceImpl<DistributionUserWalletBillMapper, DistributionUserWalletBill> implements DistributionUserWalletBillService {
    @Value("${yami.expose.operation.auth:}")
    private Boolean permission;
    private final DistributionUserWalletBillMapper distributionUserWalletBillMapper;
    @Override
    public Page<DistributionUserWalletBill> getDistributionUserWalletBillAndUserPage(Page page,String userMobile) {
        Page<DistributionUserWalletBill> billPage = distributionUserWalletBillMapper.getDistributionUserWalletBillAndUserPage(page, userMobile);
        List<DistributionUserWalletBill> billPageRecords = billPage.getRecords();
        if (BooleanUtil.isFalse(permission)) {
            for (DistributionUserWalletBill billPageRecord : billPageRecords) {
                DistributionUserVO distributionUser = billPageRecord.getDistributionUser();
                distributionUser.setUserMobile(PhoneUtil.hideBetween(distributionUser.getUserMobile()).toString());
                if (PrincipalUtil.isMobile(distributionUser.getNickName())) {
                    distributionUser.setNickName(PhoneUtil.hideBetween(distributionUser.getNickName()).toString());
                }
            }
        }
        if (I18nMessage.getLang() == 1) {
            for (DistributionUserWalletBill billPageRecord : billPageRecords) {
                if (billPageRecord.getRemarksEn() != null){
                    billPageRecord.setRemarks(billPageRecord.getRemarksEn());
                }
            }
        }
        return billPage;
    }
    @Override
    public Page<DistributionUserWalletBillDto> getDistributionUserWalletBillDtoPage(Page page, Long distributionUserId,Integer orderBy) {
        return distributionUserWalletBillMapper.getDistributionUserWalletBillDtoPage(page,distributionUserId,orderBy);
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionUserWalletServiceImpl.java
New file
@@ -0,0 +1,146 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service.impl;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.PhoneUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.PrincipalUtil;
import com.yami.shop.distribution.common.constants.DistributionUserIncomeTypeEnum;
import com.yami.shop.distribution.common.dao.DistributionUserWalletBillMapper;
import com.yami.shop.distribution.common.dao.DistributionUserWalletMapper;
import com.yami.shop.distribution.common.dto.DistributionUserWalletDto;
import com.yami.shop.distribution.common.model.DistributionUserIncome;
import com.yami.shop.distribution.common.model.DistributionUserWallet;
import com.yami.shop.distribution.common.model.DistributionUserWalletBill;
import com.yami.shop.distribution.common.service.DistributionUserIncomeService;
import com.yami.shop.distribution.common.service.DistributionUserWalletService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
/**
 * @author lgh on 2019/04/01.
 */
@Service
@RequiredArgsConstructor
public class DistributionUserWalletServiceImpl extends ServiceImpl<DistributionUserWalletMapper, DistributionUserWallet> implements DistributionUserWalletService {
    @Value("${yami.expose.operation.auth:}")
    private Boolean permission;
    @Autowired
    private DistributionUserWalletMapper distributionUserWalletMapper;
    @Autowired
    private DistributionUserWalletBillMapper distributionUserWalletBillMapper;
    @Autowired
    private DistributionUserIncomeService distributionUserIncomeService;
    @Override
    public Long getWalletIdByDistributionUserId(Long distributionUserId) {
        return distributionUserWalletMapper.getWalletIdByDistributionUserId(distributionUserId);
    }
    @Override
    public Page<DistributionUserWallet> getDistributionUserWalletAndDistributionUserVoPage(Page page, String userMobile) {
        Page<DistributionUserWallet> walletPage = distributionUserWalletMapper.getDistributionUserWalletAndDistributionUserVoPage(page, userMobile);
        if (BooleanUtil.isFalse(permission)) {
            for (DistributionUserWallet record : walletPage.getRecords()) {
                record.getDistributionUser().setUserMobile(PhoneUtil.hideBetween(record.getDistributionUser().getUserMobile()).toString());
                if (PrincipalUtil.isMobile(record.getDistributionUser().getNickName())) {
                    record.getDistributionUser().setNickName(PhoneUtil.hideBetween(record.getDistributionUser().getNickName()).toString());
                }
            }
        }
        //计算累计收益
        for (DistributionUserWallet record : walletPage.getRecords()) {
            Double haveWithdrawalSum = distributionUserWalletBillMapper.getHaveWithdrawalSum(record.getWalletId());
            record.setAddupAmount(haveWithdrawalSum+record.getSettledAmount());
        }
//        List<DistributionUserWallet> records = walletPage.getRecords();
//        for (int i = 0; i < records.size(); i++) {
//            Double haveWithdrawalSum = distributionUserWalletBillMapper.getHaveWithdrawalSum(records.get(i).getWalletId());
//            records.get(i).setAddupAmount(haveWithdrawalSum+records.get(i).getSettledAmount());
//        }
//        walletPage.setRecords(records);
        return walletPage;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDistributionUserWallet(DistributionUserWallet distributionUserWallet, Long modifier) {
        //获取到变动前的钱包
        DistributionUserWallet oldDistributionUserWallet = distributionUserWalletMapper.selectById(distributionUserWallet.getWalletId());
        //变动数额
        Double settledAmount = distributionUserWallet.getChangeAmount();
        // 可提现金额不能小于0
        if (Arith.add(oldDistributionUserWallet.getSettledAmount(), settledAmount) < 0) {
            throw new YamiShopBindException("yami.prod.common.invalid");
        }
        // 可提现金额没有变动,不需要继续执行
        if (settledAmount == 0) {
            return;
        }
        // 待结算金额和失效金额不能更改-如果平台减少用户待结算金额,且订单待结算的金额大于用户的结算金额, 在系统结算订单后用户待结算金额会小于0 (结算时: 订单待结算金额 - 用户待结算金额 = 用户剩余待结算金额)
        distributionUserWallet.setUnsettledAmount(null);
        distributionUserWallet.setInvalidAmount(null);
        double addupAmount = 0;
        // 提现金额增加时,积累收益也要对应增加
        if (settledAmount > 0) {
            addupAmount = settledAmount;
            distributionUserWallet.setAddupAmount(Arith.add(addupAmount, oldDistributionUserWallet.getAddupAmount()));
        }
        // 根据变化的金额,重新计算要钱包的变动金额
        //修改钱包-只变动提现金额和积累收益
        distributionUserWalletMapper.updateSettledAmount(distributionUserWallet.getDistributionUserId(), settledAmount);
        //增加钱包流水记录
        DistributionUserWalletBill distributionUserWalletBill = new DistributionUserWalletBill(distributionUserWallet, "人工修改", "Manual modification", 0D, settledAmount, 0D, addupAmount, 1);
        distributionUserWalletBill.setModifier(modifier);
        // 可提现金额发生变动时,增加或减少用户收益明细
        saveDistributionUserIncome(oldDistributionUserWallet, settledAmount);
        distributionUserWalletBillMapper.insert(distributionUserWalletBill);
    }
    private void saveDistributionUserIncome(DistributionUserWallet oldDistributionUserWallet, Double addupAmount) {
        DistributionUserIncome distributionUserIncome = new DistributionUserIncome();
        distributionUserIncome.setWalletId(oldDistributionUserWallet.getWalletId());
        distributionUserIncome.setIncomeType(DistributionUserIncomeTypeEnum.PLATFORM.getValue());
        distributionUserIncome.setIncomeAmount(addupAmount);
        distributionUserIncome.setDistributionUserId(oldDistributionUserWallet.getDistributionUserId());
        distributionUserIncome.setCreateTime(new Date());
        distributionUserIncome.setUpdateTime(new Date());
        distributionUserIncomeService.save(distributionUserIncome);
    }
    @Override
    public DistributionUserWalletDto getDistributionUserWalletDtoByDistributionUserId(Long distributionUserId) {
        return distributionUserWalletMapper.getDistributionUserWalletDtoByDistributionUserId(distributionUserId);
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/service/impl/DistributionWithdrawCashServiceImpl.java
New file
@@ -0,0 +1,235 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.service.impl;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.PhoneUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.enums.EnterpriseApplyType;
import com.yami.shop.bean.enums.EnterprisePayStatus;
import com.yami.shop.bean.model.EnterprisePay;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.PrincipalUtil;
import com.yami.shop.dao.EnterprisePayMapper;
import com.yami.shop.distribution.common.constants.DistributionAudit;
import com.yami.shop.distribution.common.constants.DistributionWithdrawCashStateEnum;
import com.yami.shop.distribution.common.dao.DistributionUserWalletBillMapper;
import com.yami.shop.distribution.common.dao.DistributionUserWalletMapper;
import com.yami.shop.distribution.common.dao.DistributionWithdrawCashMapper;
import com.yami.shop.distribution.common.dto.DistributionWithdrawCashDto;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.model.DistributionUserWallet;
import com.yami.shop.distribution.common.model.DistributionUserWalletBill;
import com.yami.shop.distribution.common.model.DistributionWithdrawCash;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import com.yami.shop.distribution.common.service.DistributionWithdrawCashService;
import com.yami.shop.distribution.common.vo.DistributionConfigVO;
import com.yami.shop.security.common.model.AppConnect;
import com.yami.shop.service.SysConfigService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;
/**
 * @author lgh on 2019/04/01.
 */
@Service
@RequiredArgsConstructor
public class DistributionWithdrawCashServiceImpl extends ServiceImpl<DistributionWithdrawCashMapper, DistributionWithdrawCash> implements DistributionWithdrawCashService {
    @Value("${yami.expose.operation.auth:}")
    private Boolean permission;
    private final DistributionWithdrawCashMapper distributionWithdrawCashMapper;
    private final SysConfigService sysConfigService;
    private final DistributionUserWalletMapper distributionUserWalletMapper;
    private final DistributionUserWalletBillMapper distributionUserWalletBillMapper;
    private final Snowflake snowflake;
    private final EnterprisePayMapper enterprisePayMapper;
    @Override
    public IPage<DistributionWithdrawCash> distributionWithdrawCashsPage(Page page, Long shopId, RangeTimeParam rangeTimeParam, String userMobile, DistributionWithdrawCash distributionWithdrawCash) {
        IPage<DistributionWithdrawCash> cashsPage = distributionWithdrawCashMapper.distributionWithdrawCashsPage(page, shopId, rangeTimeParam, userMobile, distributionWithdrawCash);
        if (BooleanUtil.isFalse(permission)) {
            for (DistributionWithdrawCash record : cashsPage.getRecords()) {
                record.getDistributionUser().setUserMobile(PhoneUtil.hideBetween(record.getDistributionUser().getUserMobile()).toString());
                if (PrincipalUtil.isMobile(record.getDistributionUser().getNickName())) {
                    record.getDistributionUser().setNickName(PhoneUtil.hideBetween(record.getDistributionUser().getNickName()).toString());
                }
            }
        }
        return cashsPage;
    }
    @Override
    public IPage<DistributionWithdrawCashDto> distributionWithdrawCashDtoPageByUserId(Page page, Long distributionUserId) {
        return distributionWithdrawCashMapper.distributionWithdrawCashDtoPageByUserId(page, distributionUserId);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void apply(Double amount, DistributionUser distributionUser, AppConnect appConnect) {
        //获取用户的钱包数据
        DistributionUserWallet distributionUserWallet = distributionUserWalletMapper.selectOne(new LambdaQueryWrapper<DistributionUserWallet>()
                .eq(DistributionUserWallet::getDistributionUserId, distributionUser.getDistributionUserId()));
        //获取店铺提现设置
        DistributionConfigVO distributionConfigVO = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_CONFIG, DistributionConfigVO.class);
        //结算提现金额是否超出限制
        if (amount > distributionConfigVO.getAmountMax()) {
            // 提现金额大于最大提现金额
            throw new YamiShopBindException("yami.distribution.fee.than.error");
        }
        if (amount < distributionConfigVO.getAmountMin()) {
            // 提现金额小于最小提现金额
            throw new YamiShopBindException("yami.distribution.fee.less.error");
        }
        //获取店铺设置的提现频率算出时间区间
        Calendar calendar = Calendar.getInstance();
        int monthDay = 30;
        if(distributionConfigVO.getFrequency() == monthDay){
            //每月的第一天
            calendar.set(Calendar.DAY_OF_MONTH, 1);
        } else {
            calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - distributionConfigVO.getFrequency());
        }
        //将小时至0
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        //将分钟至0
        calendar.set(Calendar.MINUTE, 0);
        //将秒至0
        calendar.set(Calendar.SECOND,0);
        //将毫秒至0
        calendar.set(Calendar.MILLISECOND, 0);
        RangeTimeParam rangeTimeParam = new RangeTimeParam(calendar.getTime(), new Date());
        //获取用户最近的提现次数,判断是否能够提现
        if (distributionWithdrawCashMapper.getCountByRangeTimeAndDistributionUserId(rangeTimeParam, distributionUser.getDistributionUserId()) >= distributionConfigVO.getNumber()) {
            // 提现次数为
            String message = I18nMessage.getMessage("yami.distribution.cash.num");
            String day = I18nMessage.getMessage("yami.day");
            String num = I18nMessage.getMessage("yami.constant.num");
            if (distributionConfigVO.getFrequency() == monthDay){
                String month = I18nMessage.getMessage("yami.distribution.cash.month");
                throw new YamiShopBindException(message + month + distributionConfigVO.getNumber() + num);
            } else {
                throw new YamiShopBindException(message + distributionConfigVO.getFrequency() + day + distributionConfigVO.getNumber() + num);
            }
        }
        //判断提现金额 是否大于钱包金额
        if (distributionUserWallet.getSettledAmount() < amount) {
            // 提现失败,余额不足
            throw new YamiShopBindException("yami.distribution.balance.not.enough");
        }
        //扣除可提现余额
        distributionUserWallet.setSettledAmount(Arith.sub(distributionUserWallet.getSettledAmount(), amount));
        //插入一条提现记录
        Date now = new Date();
        DistributionWithdrawCash distributionWithdrawCash = new DistributionWithdrawCash();
        distributionWithdrawCash.setBizUserId(appConnect.getBizUserId());
        distributionWithdrawCash.setCreateTime(now);
        distributionWithdrawCash.setWalletId(distributionUserWallet.getWalletId());
        distributionWithdrawCash.setAmount(amount);
        distributionWithdrawCash.setMerchantOrderId(String.valueOf(snowflake.nextId()));
        distributionWithdrawCash.setVersion(0);
        distributionWithdrawCash.setUpdateTime(now);
        // 暂时没有手续费
        distributionWithdrawCash.setFee(0.0);
        // 判断人工审核后线下打款
        if (distributionConfigVO.getWithdrawal().equals(DistributionAudit.TWithdrawals_TWO.getValue())){
            //设置为手动提现
            distributionWithdrawCash.setType(0);
            distributionWithdrawCash.setMoneyFlow(0);
        }else{
            distributionWithdrawCash.setType(1);
            distributionWithdrawCash.setMoneyFlow(1);
        }
        distributionWithdrawCash.setState(DistributionWithdrawCashStateEnum.APPLY.getValue());
        if (distributionConfigVO.getWithdrawal().equals(DistributionAudit.Withdrawals_ZERO.getValue())){
            distributionWithdrawCash.setState(DistributionWithdrawCashStateEnum.CASH_SUCCESS.getValue());
        }
        // 存入提现记录
        distributionWithdrawCashMapper.insert(distributionWithdrawCash);
        // 增加钱包流水记录
        distributionUserWalletBillMapper.insert(new DistributionUserWalletBill(distributionUserWallet, "用户提现","User withdrawals", 0.0, -amount, 0.0, 0.0, 0));
        // 修改钱包
        distributionUserWalletMapper.updateById(distributionUserWallet);
        // 判断人工审核后线下打款
        if (distributionConfigVO.getWithdrawal().equals(DistributionAudit.TWithdrawals_TWO.getValue())){
            return;
        }
     /*   if (appConnect == null) {
            // 未找到此用户信息
            throw new YamiShopBindException("yami.user.no.exist");
        }*/
        // 判断用户是否有openId没有提示绑定微信小程序
        if (Objects.isNull(appConnect) || StringUtils.isBlank(appConnect.getBizUserId()) || StringUtils.isBlank(appConnect.getUserId())){
            throw new YamiShopBindException("yami.distribution.user.withdrawals");
        }
        if (distributionConfigVO.getWithdrawal().equals(DistributionAudit.Withdrawals_ZERO.getValue())){
            enterprisePay(distributionWithdrawCash, appConnect.getUserId(), appConnect.getBizUserId(), EnterprisePayStatus.APPLY.getValue());
        }
    }
    @Override
    public void enterprisePay(DistributionWithdrawCash distributionWithdrawCash, String userId, String openId, Integer status){
        // 添加企业支付记录
        EnterprisePay enterprisePay = new EnterprisePay();
        enterprisePay.setStatus(status);
        enterprisePay.setType(EnterpriseApplyType.DISTRIBUTION_WITHDRAW.value());
        enterprisePay.setBizId(distributionWithdrawCash.getWithdrawCashId());
        enterprisePay.setUserId(userId);
        enterprisePay.setOpenId(openId);
        enterprisePay.setVersion(0);
        enterprisePay.setEntPayOrderNo(snowflake.nextId());
        enterprisePay.setUpdateTime(new Date());
        enterprisePay.setCreateTime(new Date());
        enterprisePay.setAmount(distributionWithdrawCash.getAmount());
        enterprisePayMapper.insert(enterprisePay);
    }
    @Override
    public Integer getCountByRangeTimeAndDistributionUserId(RangeTimeParam rangeTimeParam, Long distributionUserId) {
        return distributionWithdrawCashMapper.getCountByRangeTimeAndDistributionUserId(rangeTimeParam, distributionUserId);
    }
    @Override
    public Double getUserTotalWithdrawCash(Long walletId) {
        return distributionWithdrawCashMapper.getUserTotalWithdrawCash(walletId);
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionAmountAndWalletVO.java
New file
@@ -0,0 +1,40 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.vo;
import lombok.Data;
/**
 * 钱包和佣金数据(用于分销结算)
 * @author yami
 */
@Data
public class DistributionAmountAndWalletVO {
    /**
     * 分销员钱包
     */
    Long distributionUserWalletId;
    /**
     * 上级分销员钱包
     */
    Long parentDistributionUserWalletId;
    /**
     * 佣金
     */
    Double amount;
    /**
     * 上级佣金
     */
    Double parentAmount;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionAuditingConditionsVO.java
New file
@@ -0,0 +1,58 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.yami.shop.bean.model.Product;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
 * 成为分销员的条件设置数据
 * @author yami
 */
@Data
public class DistributionAuditingConditionsVO implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 是否需要关注公众号
     */
    private Boolean isFocus;
    /**
     * 用户id列表
     */
    private List<Long> userList;
    /**
     * 商品id列
     */
    private List<Long> prodList;
    /**
     * 消费笔数大于等于
     */
    private Double expenseNumber;
    /**
     * 消费金额大于等于
     */
    private Double expenseAmount;
    /**
     * 商品列表
     */
    @TableField(exist = false)
    private List<Product> productDtoList;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionAuditingInfoVO.java
New file
@@ -0,0 +1,42 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
/**
 * 申请成为分销员所需填写资料
 * @author yami
 */
@Data
public class DistributionAuditingInfoVO implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 真实姓名
     */
    @Schema(description = "真实姓名" )
    private Boolean realName;
    /**
     * 身份证号
     */
    @Schema(description = "身份证号" )
    private Boolean identityCardNumber;
    /**
     * 身份证照片
     */
    @Schema(description = "身份证照片" )
    private Boolean identityCardPic;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionAwardDataVO.java
New file
@@ -0,0 +1,36 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.vo;
import lombok.Data;
/**
 * 奖励数据
 * @author yami
 */
@Data
public class DistributionAwardDataVO {
    /**
     * 奖励数额(元)
     */
    private Double awardNumber;
    /**
     * 上级奖励数额(元)
     */
    private Double parentAwardNumber;
    /**
     * 奖励比例(0 按比例 1 按固定数值)
     */
    private Integer awardProportion;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionBindSceneVO.java
New file
@@ -0,0 +1,38 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.vo;
import lombok.Data;
import java.io.Serializable;
/**
 * 分销绑定场景json对象
 * @author yami
 */
@Data
public class DistributionBindSceneVO implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 关注公众号
     */
    private Boolean follow;
    /**
     * 下单
     */
    private Boolean buy;
    /**
     * 扫码直接绑定
     */
    private Boolean sweepCode;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionBindSetRobVO.java
New file
@@ -0,0 +1,33 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.vo;
import lombok.Data;
import java.io.Serializable;
/**
 * 抢客方式
 * @author yami
 */
@Data
public class DistributionBindSetRobVO implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 下单
     */
    private Boolean buy;
    /**
     * 扫码
     */
    private Boolean sweepCode;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionConfigVO.java
New file
@@ -0,0 +1,76 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.vo;
import com.yami.shop.bean.model.Product;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
 * @author lhd
 * @date 2021-09-06 14:19:49
 */
@Data
public class DistributionConfigVO {
    @Schema(description = "分销开关: 0:关闭 1:开启" )
    private Integer distributionSwitch;
    @Schema(description = "客户绑定设置-业绩归属 :  0:允许绑定,关系优先 1:不绑定 分享人优先" )
    private Integer attribution;
// 申请条件配置-------------------------------------------------------------
    @Schema(description = "申请条件-条件审核判定: 0:人工判定 1:系统判定" )
    private Integer autoCheck;
    @Schema(description = "申请条件-条件审核判定:购买指定商品,确认收货任意一件商品后计入" )
    private List<Long> prodIdList;
    @Schema(description = "商品列表" )
    private List<Product> productVOList;
    @Schema(description = "申请条件-条件审核判定:消费金额大于等于expenseAmount元,实付金额+积分抵扣+余额抵扣总金额,收货后计入(单位: 元)" )
    private Double expenseAmount;
    @Schema(description = "申请条件-条件审核判定:消费笔数大于等于expenseNumber次,下单次数,收货后计入" )
    private Integer expenseNumber;
    @Schema(description = "申请条件-申请所需信息:是否需要真实姓名 true 需要 false不需要" )
    private Boolean realName;
    @Schema(description = "申请条件-申请所需信息:是否需要身份证号码 true 需要 false不需要" )
    private Boolean identityCardPic;
    @Schema(description = "申请条件-申请所需信息:是否需要身份证照片 true 需要 false不需要" )
    private Boolean identityCardNumber;
    @Schema(description = "提现发放方式: 0.无需审核直接发放,1.审核后系统发放,2.审核后人工发放" )
    private Integer withdrawal;
// 提现申请配置-------------------------------------------------------------
    @Schema(description = "提现频率(天)" )
    private Integer frequency;
    @Schema(description = "单笔提现最高(元)" )
    private Double amountMax;
    @Schema(description = "单笔提现最低 (元)" )
    private Double amountMin;
    @Schema(description = "打款说明" )
    private String paymentExplain;
    @Schema(description = "提现次数" )
    private Integer number;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionLevelConditionDataVO.java
New file
@@ -0,0 +1,94 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
 * 等级升级所需条件
 * @author yami
 */
@Data
public class DistributionLevelConditionDataVO implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 绑定客户数
     */
    @Schema(description = "绑定客户数" )
    private Integer boundCustomers;
    /**
     * 邀请分销员数
     */
    @Schema(description = "邀请分销员数" )
    private Integer invitedVeeker;
    /**
     * 支付单数
     */
    @Schema(description = "支付单数" )
    private Integer payNumber;
    /**
     * 积累收益
     */
    @Schema(description = "积累收益" )
    private Double addupAmount;
    /**
     * 成交单数
     */
    @Schema(description = "成交单数" )
    private Integer successOrderNumber;
    /**
     * 成交金额
     */
    @Schema(description = "成交金额" )
    private Double successTradingVolume;
    /**
     * 消费金额
     */
    @Schema(description = "消费金额" )
    private Double sumOfConsumption;
    /**
     * 购买指定商品
     */
    @Schema(description = "购买指定商品" )
    private List<CommodityItemData> commodity;
    @Data
    public static class CommodityItemData {
        /**
         * 商品id
         */
        private Long prodId;
        /**
         * 商品名称
         */
        private String prodName;
        /**
         * 商品图片
         */
        private String pic;
    }
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionLevelConditionsSwitchVO.java
New file
@@ -0,0 +1,77 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
/**
 * 升级所需条件开关设置
 * @author yami
 */
@Data
public class DistributionLevelConditionsSwitchVO implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 绑定客户数
     */
    @Schema(description = "绑定客户数" )
    private Boolean boundCustomers;
    /**
     * 邀请分销员数
     */
    @Schema(description = "邀请分销员数" )
    private Boolean invitedVeeker;
    /**
     * 支付单数
     */
    @Schema(description = "支付单数" )
    private Boolean payNumber ;
    /**
     * 积累收益
     */
    @Schema(description = "积累收益" )
    private Boolean addupAmount ;
    /**
     * 成功成交单数
     */
    @Schema(description = "成功成交单数" )
    private Boolean successOrderNumber ;
    /**
     * 成功成交金额
     */
    @Schema(description = "成功成交金额" )
    private Boolean successTradingVolume ;
    /**
     * 消费金额
     */
    @Schema(description = "消费金额" )
    private Boolean sumOfConsumption ;
//    /**
//     * 充值金额
//     */
//    @Schema(description = "充值金额" )
//    private Boolean rechargeAmount ;
    /**
     * 购买指定商品
     */
    @Schema(description = "购买指定商品" )
    private Boolean commodity ;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionLevelVO.java
New file
@@ -0,0 +1,31 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.vo;
import lombok.Data;
import java.io.Serializable;
/**
 * @author yami
 */
@Data
public class DistributionLevelVO implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 等级id
     */
    private Long levelId;
    /**
     * 等级名称
     */
    private String name;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionOrdersVO.java
New file
@@ -0,0 +1,55 @@
package com.yami.shop.distribution.common.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
 * @author
 */
@Data
@Schema(description = "我的分销订单项信息")
public class DistributionOrdersVO implements Serializable {
    private static final long serialVersionUID = 6222259729061826852L;
    @Schema(description = "订单流水号" )
    private String orderNumber;
    @Schema(description = "总金额" )
    private Double total;
    @Schema(description = "订单商品总数" )
    private Integer prodCount;
    @Schema(description = "图片" )
    private String pic;
    @Schema(description = "售价" )
    private Double price;
    @Schema(description = "商品名称" )
    private String prodName;
    @Schema(description = "sku名称" )
    private String skuName;
    @Schema(description = "分销佣金" )
    private Double distributionAmount;
    @Schema(description = "订单是否有效 1 未结算,2 已结算" )
    private Integer state;
    @Schema(description = "更新时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    private Long orderItemId;
    @Schema(description = "失效原因(0正常,1.分销佣金大于或者等于订单项实付金额,2.订单项售后成功)" )
    private Integer reson;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionRecruitConfigVO.java
New file
@@ -0,0 +1,37 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * @author lhd
 * @date 2021-09-06 14:20:02
 */
@Data
public class DistributionRecruitConfigVO {
    @Schema(description = "推广封面" )
    private String pic;
    @Schema(description = "推广标题" )
    private String title;
    @Schema(description = "推广内容" )
    private String content;
    /**
     * 状态(0下线 1上线)
     */
    @Schema(description = "状态 0关 1开" )
    private Integer state;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionUserIncomeVO.java
New file
@@ -0,0 +1,38 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.vo;
import lombok.Data;
import java.io.Serializable;
/**
 * @author yami
 */
@Data
public class DistributionUserIncomeVO implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 积累一代佣金
     */
    private Double aGenerationCommission;
    /**
     * 积累二代佣金
     */
    private Double  secondGenerationCommission;
    /**
     * 积累邀请奖励
     */
    private Double invitationRewards;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionUserInfoVO.java
New file
@@ -0,0 +1,44 @@
package com.yami.shop.distribution.common.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
 * 我的用户信息
 * @author LanHai
 */
@Schema(description = "分销员推广用户信息")
@Data
public class DistributionUserInfoVO implements Serializable {
    private static final long serialVersionUID = 1L;
    @Schema(description = "用户id" )
    private String userId;
    @Schema(description = "分销员id" )
    private Long distributionUserId;
    @Schema(description = "用户昵称" )
    private String nickName;
    @Schema(description = "头像" )
    private String pic;
    @Schema(description = "贡献收益" )
    private Double money;
    @Schema(description = "成交订单数" )
    private Integer orderNumber;
    @Schema(description = "用户状态 状态(-1永久封禁 0待审核状态 1正常 2暂时封禁 3 审核未通过)" )
    private Integer state;
    @Schema(description = "加入时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date bindTime;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/java/com/yami/shop/distribution/common/vo/DistributionUserVO.java
New file
@@ -0,0 +1,44 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.common.vo;
import lombok.Data;
import java.io.Serializable;
/**
 * @author yami
 */
@Data
public class DistributionUserVO implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 分销员id
     */
    private Long distributionUserId;
    /**
     * 用户昵称
     */
    private String nickName;
    /**
     * 分销员手机
     */
    private String userMobile;
    /**
     * 分销员等级信息
     */
    private DistributionLevelVO distributionLevel;
}
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionAuditingMapper.xml
New file
@@ -0,0 +1,124 @@
<?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.yami.shop.distribution.common.dao.DistributionAuditingMapper">
  <resultMap id="BaseResultMap" type="com.yami.shop.distribution.common.model.DistributionAuditing">
    <id column="auditing_id" jdbcType="BIGINT" property="auditingId" />
    <result column="shop_id" jdbcType="BIGINT" property="shopId" />
    <result column="parent_distribution_user_id" jdbcType="BIGINT" property="parentDistributionUserId" />
    <result column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId" />
    <result column="auditing_time" jdbcType="TIMESTAMP" property="auditingTime" />
    <result column="state" jdbcType="TINYINT" property="state" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    <result column="modifier" jdbcType="VARCHAR" property="modifier" />
    <result column="remarks" jdbcType="VARCHAR" property="remarks" />
    <result column="reason" jdbcType="TINYINT" property="reason" />
  </resultMap>
  <!--审核管理-->
  <resultMap id="DistributionAuditing_DistributionUser_SysUser" type="com.yami.shop.distribution.common.model.DistributionAuditing">
    <id column="auditing_id" jdbcType="BIGINT" property="auditingId" />
    <result column="shop_id" jdbcType="BIGINT" property="shopId" />
    <result column="parent_distribution_user_id" jdbcType="BIGINT" property="parentDistributionUserId" />
    <result column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId" />
    <result column="auditing_time" jdbcType="TIMESTAMP" property="auditingTime" />
    <result column="state" jdbcType="TINYINT" property="state" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    <result column="modifier" jdbcType="VARCHAR" property="modifier" />
    <result column="remarks" jdbcType="VARCHAR" property="remarks" />
    <result column="reason" jdbcType="TINYINT" property="reason" />
    <association property="distributionUser" javaType="com.yami.shop.distribution.common.model.DistributionUser">
      <id column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId" />
      <result column="nick_name" jdbcType="VARCHAR" property="nickName" />
      <result column="user_mobile" jdbcType="VARCHAR" property="userMobile" />
      <result column="real_name" jdbcType="VARCHAR" property="realName" />
      <result column="identity_card_number" jdbcType="VARCHAR" property="identityCardNumber" />
      <result column="identity_card_pic_front" jdbcType="VARCHAR" property="identityCardPicFront" />
      <result column="identity_card_pic_back" jdbcType="VARCHAR" property="identityCardPicBack" />
      <result column="identity_card_pic_hold" jdbcType="VARCHAR" property="identityCardPicHold" />
      <association property="distributionUserAchievementDataDto"  javaType="com.yami.shop.distribution.common.dto.DistributionUserAchievementDataDto">
        <association property="userShoppingDataDto" javaType="com.yami.shop.bean.distribution.UserShoppingDataDto">
          <result property="sumOfConsumption" jdbcType="DECIMAL" column="sum_of_consumption"/>
          <result property="expenseNumber" jdbcType="INTEGER" column="expense_number"/>
        </association>
      </association>
    </association>
    <association property="parentDistributionUser" javaType="com.yami.shop.distribution.common.vo.DistributionUserVO">
      <id column="parent_distribution_user_id" jdbcType="BIGINT" property="distributionUserId" />
      <result column="parent_nick_name" jdbcType="VARCHAR" property="nickName" />
      <result column="parent_user_mobile" jdbcType="VARCHAR" property="userMobile" />
    </association>
    <association property="sysUser" javaType="com.yami.shop.bean.vo.SysUserVO">
      <id column="sys_user_id" jdbcType="BIGINT" property="userId" />
      <result column="sys_username" jdbcType="VARCHAR" property="username" />
    </association>
  </resultMap>
    <!--审核管理 -->
    <select id="distributionAuditingPage" resultType="com.yami.shop.distribution.common.dto.DistributionAuditingDto">
      select a.*,
             su.user_id as sys_user_id,
             su.username as sys_username
      from
      (
        select
        da.*,
        -- 申请信息
        du.user_mobile,
        du.Identity_card_number,
        du.real_name,
        du.Identity_card_pic_front,
        du.Identity_card_pic_back,
        du.Identity_card_pic_hold,
        du.user_id,
        du.nick_name,
        -- 总消费
        sum( os.pay_amount) as sum_of_consumption,
        -- 消费单数
        count(os.settlement_id) as expense_number,
        -- 邀请人信息
        parent_du.nick_name as parent_nick_name,
        parent_du.user_mobile as parent_user_mobile
        from
        tz_distribution_auditing da
        -- 获取申请人的信息
        left join tz_distribution_user du on du.distribution_user_id = da.distribution_user_id
        -- 获取邀请人信息
        LEFT JOIN tz_distribution_user parent_du ON parent_du.distribution_user_id = da.parent_distribution_user_id
        -- 找到申请人消费记录
        left join tz_order_settlement os on os.user_id=du.user_id and os.pay_status=1 and os.pay_amount &gt; 0
        <where>
          <if test="distributionAuditing!= null and distributionAuditing.state != null">
            and da.state=#{distributionAuditing.state}
          </if>
          <if test="mobile!= null and mobile != ''">
            and du.user_mobile like concat('%',#{mobile},'%')
          </if>
          <if test="rangeTimeParam.startTime!= null ">
            and da.auditing_time &gt;=#{rangeTimeParam.startTime}
          </if>
          <if test="rangeTimeParam.endTime!= null ">
            and da.auditing_time &lt;=#{rangeTimeParam.endTime}
          </if>
          <if test="startPayAmount!= null ">
            and pay_amount &gt;=#{startPayAmount}
          </if>
          <if test="endPayAmount!= null ">
            and pay_amount &lt;=#{endPayAmount}
          </if>
        </where>
        GROUP BY da.auditing_id
        having 1=1
        <if test="startExpenseNumber!= null ">
          and COUNT(os.settlement_id)&gt;=#{startExpenseNumber}
        </if>
        <if test="endExpenseNumber!= null ">
          and COUNT(os.settlement_id)&lt;=#{endExpenseNumber}
        </if>
        order by da.auditing_time desc
    ) a
    -- 找到操作人
    left join tz_sys_user su on a.modifier=su.user_id and a.state != 0
    </select>
</mapper>
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionMsgMapper.xml
New file
@@ -0,0 +1,100 @@
<?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.yami.shop.distribution.common.dao.DistributionMsgMapper">
  <resultMap id="BaseResultMap" type="com.yami.shop.distribution.common.model.DistributionMsg">
    <id column="msg_id" jdbcType="BIGINT" property="msgId" />
    <result column="level" jdbcType="TINYINT" property="level" />
    <result column="msg_title" jdbcType="VARCHAR" property="msgTitle" />
    <result column="shop_id" jdbcType="BIGINT" property="shopId" />
    <result column="start_time" jdbcType="TIMESTAMP" property="startTime" />
    <result column="end_time" jdbcType="TIMESTAMP" property="endTime" />
    <result column="is_top" jdbcType="TINYINT" property="isTop" />
    <result column="content" jdbcType="VARCHAR" property="content" />
    <result column="pic" jdbcType="VARCHAR" property="pic" />
    <result column="msg_type" jdbcType="TINYINT" property="msgType" />
    <result column="state" jdbcType="TINYINT" property="state" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    <result column="modifier" jdbcType="BIGINT" property="modifier" />
  </resultMap>
  <resultMap id="getDistributionMsgsAndSysUserMap" type="com.yami.shop.distribution.common.model.DistributionMsg">
    <id column="msg_id" jdbcType="BIGINT" property="msgId" />
    <result column="level" jdbcType="TINYINT" property="level" />
    <result column="msg_title" jdbcType="VARCHAR" property="msgTitle" />
    <result column="shop_id" jdbcType="BIGINT" property="shopId" />
    <result column="start_time" jdbcType="TIMESTAMP" property="startTime" />
    <result column="end_time" jdbcType="TIMESTAMP" property="endTime" />
    <result column="is_top" jdbcType="TINYINT" property="isTop" />
    <result column="content" jdbcType="VARCHAR" property="content" />
    <result column="pic" jdbcType="VARCHAR" property="pic" />
    <result column="msg_type" jdbcType="TINYINT" property="msgType" />
    <result column="state" jdbcType="TINYINT" property="state" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    <result column="modifier" jdbcType="BIGINT" property="modifier" />
    <association property="sysUser" javaType="com.yami.shop.bean.vo.SysUserVO">
      <id column="user_id" jdbcType="BIGINT" property="userId" />
      <result column="username" jdbcType="VARCHAR" property="username" />
    </association>
  </resultMap>
  <select id="getDistributionMsgsAndSysUserPage" resultMap="getDistributionMsgsAndSysUserMap">
    select
    msg.*,
    su.user_id,su.username
    from
    tz_distribution_msg msg
    left join tz_sys_user su on msg.modifier=su.user_id
    <where>
      <if test="distributionMsg.msgTitle!= null and distributionMsg.msgTitle!='' ">
        and trim(replace(msg_title,' ','')) like trim(replace(concat('%',#{distributionMsg.msgTitle},'%'),' ',''))
      </if>
      <if test="distributionMsg.state !=null">
        and state =#{distributionMsg.state}
      </if>
      <if test="distributionMsg.startTime !=null">
        and start_time &gt;=#{distributionMsg.startTime}
      </if>
      <if test="distributionMsg.endTime !=null">
        and end_time &lt;=#{distributionMsg.endTime}
      </if>
    </where>
  </select>
  <sql id="DistributionMsgDto">
    msg_id,
    level,
    msg_title,
    start_time,
    is_top,
    content,
    pic,
    msg_type
  </sql>
  <select id="getDistributionMsgDtoByMsgId" resultType="com.yami.shop.distribution.common.dto.DistributionMsgDto">
    select
    <include refid="DistributionMsgDto"/>
    from tz_distribution_msg
    where
    msg_id = #{msgId}
  </select>
  <select id="getDistributionMsgDtoByShopId" resultType="com.yami.shop.distribution.common.dto.DistributionMsgDto">
    select
    msg_id,
    level,
    msg_title,
    start_time,
    is_top,
    pic,
    msg_type
    from tz_distribution_msg
    where
    start_time &lt; now()
    and end_time &gt; now()
    <if test="isTop != null">
      and is_top=#{isTop}
    </if>
    order by is_top desc,start_time DESC
  </select>
</mapper>
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionProdBindMapper.xml
New file
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yami.shop.distribution.common.dao.DistributionProdBindMapper">
    <resultMap id="distributionProdBindMap" type="com.yami.shop.distribution.common.model.DistributionProdBind">
         <id property="id" column="id"/>
        <result property="distributionUserId" column="distribution_user_id"/>
        <result property="userId" column="user_id"/>
        <result property="bindTime" column="bind_time"/>
        <result property="prodId" column="prod_id"/>
        <result property="state" column="state"/>
    </resultMap>
    <!--根据分销员id修改状态-->
    <update id="updateStateByDistributionUserId">
        update tz_distribution_prod_bind
        set state = #{state}
        where
        distribution_user_id = #{distributionUserId}
    </update>
</mapper>
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionProdMapper.xml
New file
@@ -0,0 +1,216 @@
<?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.yami.shop.distribution.common.dao.DistributionProdMapper">
  <resultMap id="BaseResultMap" type="com.yami.shop.distribution.common.model.DistributionProd">
    <id column="distribution_prod_id" jdbcType="BIGINT" property="distributionProdId" />
    <result column="shop_id" jdbcType="BIGINT" property="shopId" />
    <result column="prod_id" jdbcType="BIGINT" property="prodId" />
    <result column="award_id" jdbcType="DOUBLE" property="awardId" />
    <result column="state" jdbcType="TINYINT" property="state" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    <result column="modifier" jdbcType="VARCHAR" property="modifier" />
    <result column="default_reward" jdbcType="TINYINT" property="defaultReward" />
  </resultMap>
  <resultMap id="DistributionProd_ProdCut_DistributionAward" type="com.yami.shop.distribution.common.model.DistributionProd">
    <id column="distribution_prod_id" jdbcType="BIGINT" property="distributionProdId" />
    <result column="shop_id" jdbcType="BIGINT" property="shopId" />
    <result column="prod_id" jdbcType="BIGINT" property="prodId" />
    <result column="state" jdbcType="TINYINT" property="state" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    <result column="modifier" jdbcType="VARCHAR" property="modifier" />
    <result column="default_reward" jdbcType="TINYINT" property="defaultReward" />
    <result column="award_proportion" jdbcType="TINYINT" property="awardProportion" />
    <result column="award_number_set" jdbcType="TINYINT" property="awardNumberSet" />
    <result column="award_numbers" jdbcType="VARCHAR" property="awardNumbers" />
    <result column="parent_award_numbers" jdbcType="VARCHAR" property="parentAwardNumbers" />
    <result column="parent_award_set" jdbcType="TINYINT" property="parentAwardSet" />
    <association javaType="com.yami.shop.bean.model.Product" property="product">
      <id column="prod_id" jdbcType="BIGINT" property="prodId" />
      <result column="prod_name" jdbcType="VARCHAR" property="prodName" />
      <result column="pic" jdbcType="VARCHAR" property="pic" />
      <result column="shop_name" property="shopName"/>
    </association>
  </resultMap>
    <select id="distributionProdsPage" resultMap="DistributionProd_ProdCut_DistributionAward">
        select
            p.prod_id,ifnull(pl.prod_name,p.prod_name) as prod_name,p.pic,tsd.shop_name,
            dp.distribution_prod_id,
            dp.shop_id,
            dp.award_id,
            dp.state,
            dp.update_time,
            dp.modifier,
            dp.default_reward,
            dp.award_proportion,
            dp.award_number_set,
            dp.award_numbers,
            dp.parent_award_numbers,
            dp.parent_award_set
        from
        tz_distribution_prod dp
        join tz_prod p on p.prod_id=dp.prod_id and p.`status` != -1
        JOIN tz_shop_detail tsd ON p.shop_id = tsd.shop_id
        LEFT JOIN tz_prod_lang pl on pl.prod_id = p.prod_id and pl.lang =#{dbLang}
        <where>
          <if test="distributionProd.shopId != null ">
           and  dp.shop_id=#{distributionProd.shopId}
          </if>
          <if test="distributionProd.state != null ">
            and  dp.state=#{distributionProd.state}
          </if>
          <if test="prodName!= null and prodName!='' ">
            and trim(replace(p.prod_name,' ','')) like trim(replace(concat('%',#{prodName},'%'),' ',''))
          </if>
        </where>
        ORDER BY dp.update_time DESC
    </select>
    <!--分销商品接口-->
    <resultMap id="DistributionProdPO" type="com.yami.shop.distribution.common.po.DistributionProdPO">
        <result column="shop_id" property="shopId"/>
        <result column="prod_name" property="prodName"/>
        <result column="prod_id" property="prodId"/>
        <result column="pic" property="pic"/>
        <result column="price" property="price"/>
        <result column="award_proportion" jdbcType="TINYINT" property="awardProportion" />
        <result column="award_number_set" jdbcType="TINYINT" property="awardNumberSet" />
        <result column="award_numbers" jdbcType="VARCHAR" property="awardNumbers" />
        <result column="parent_award_numbers" jdbcType="VARCHAR" property="parentAwardNumbers" />
        <result column="parent_award_set" jdbcType="TINYINT" property="parentAwardSet" />
    </resultMap>
    <select id="distributionProdPoPage" resultMap="DistributionProdPO">
            select
                ifnull(pl.prod_name,p.prod_name) as prod_name,
                p.pic,
                p.price,
                dp.default_reward,
                dp.prod_id,
                dp.shop_id,
                dp.award_proportion,
                dp.award_number_set,
                dp.award_numbers,
                dp.award_id,
                dp.parent_award_numbers,
                dp.parent_award_set
            from
            tz_distribution_prod dp
            join tz_prod p on p.prod_id=dp.prod_id
            join tz_shop_detail sd on dp.shop_id = sd.shop_id
            LEFT JOIN tz_prod_lang pl on pl.prod_id = p.prod_id and pl.lang =#{dbLang}
            <if test="sort == 2">
                LEFT JOIN tz_prod_extension pe ON pe.prod_id=p.prod_id
            </if>
            <where>
                dp.state = 1 and p.`status` = 1 and sd.shop_status = 1
                <if test="prodName != null and prodName!=''">
                    and p.prod_name like concat('%',#{prodName} ,'%')
                </if>
                <if test="sort == 1">
                    order by p.putaway_time
                </if>
                <if test="sort == 2">
                    order by pe.sold_num
                </if>
                <if test="sort == 3">
                    order by p.price
                </if>
                <if test="orderBy == 0">
                    asc
                </if>
                <if test="orderBy == 1">
                    desc
                </if>
            </where>
    </select>
    <select id="getDistributionProdPoByProdId" resultMap="DistributionProdPO">
        select
            dp.default_reward,
            dp.prod_id,
            dp.shop_id,
            dp.award_proportion,
            dp.award_number_set,
            dp.award_numbers,
            dp.award_id,
            dp.parent_award_numbers,
            dp.parent_award_set
        from
        tz_distribution_prod dp
        where dp.prod_id=#{prodId}
    </select>
    <select id="listByOrderItems" resultType="com.yami.shop.distribution.common.model.DistributionProd">
        select
            dp.default_reward,
            dp.prod_id,
            dp.shop_id,
            dp.award_proportion,
            dp.award_number_set,
            dp.award_numbers,
            dp.award_id,
            dp.parent_award_numbers,
            dp.parent_award_set
        from
        tz_distribution_prod dp
        where dp.state = 1 and dp.prod_id in (
        <foreach collection="orderItems" separator="," item="orderItem">
          #{orderItem.prodId}
        </foreach>
        )
    </select>
    <update id="updateState">
        UPDATE tz_distribution_prod dp SET dp.`state` = #{state} WHERE dp.`distribution_prod_id`= #{distributionProdId}
    </update>
    <select id="getDistributionProdLogPage"
            resultType="com.yami.shop.distribution.common.model.DistributionProdLog">
        SELECT res.*,IFNULL(toil.`prod_name`,res.prod_name_temp) AS prod_name FROM (
        SELECT dui.income_id,dui.income_amount,dui.create_time,dui.order_number,dui.state,
                dui.income_type, oi.prod_name as prod_name_temp,
               oi.pic,oi.shop_id,du.nick_name,du.user_mobile,dui.order_item_id,o.create_time as place_time,
                dui.reson
          <if test="distributionProdLog.shopId == null">
              ,sd.shop_name
          </if>
        FROM  tz_distribution_user_income dui
        JOIN tz_order_item oi ON dui.order_item_id = oi.order_item_id
        JOIN tz_order o ON o.order_number = oi.order_number
        JOIN tz_distribution_user du ON du.distribution_user_id = dui.distribution_user_id
        <if test="distributionProdLog.shopId == null">
            JOIN tz_shop_detail sd ON sd.shop_id = oi.shop_id
        </if>
        WHERE dui.income_type IN (1,2)
        <if test="distributionProdLog.shopId != null">
            AND oi.shop_id = #{distributionProdLog.shopId}
        </if>
        <if test="distributionProdLog.orderNumber != null">
            and trim(replace(oi.order_number,' ','')) like trim(replace(concat('%',#{distributionProdLog.orderNumber},'%'),' ',''))
        </if>
        <if test="distributionProdLog.state != null">
            AND dui.state = #{distributionProdLog.state}
        </if>
        <if test="distributionProdLog.prodName != null and distributionProdLog.prodName != ''">
            and trim(replace(oi.prod_name,' ','')) like trim(replace(concat('%',#{distributionProdLog.prodName},'%'),' ',''))
        </if>
        <if test="distributionProdLog.shopName != null and distributionProdLog.shopName != ''">
            and trim(replace(sd.shop_name,' ','')) like trim(replace(concat('%',#{distributionProdLog.shopName},'%'),' ',''))
        </if>
        <if test="distributionProdLog.nickName != null and distributionProdLog.nickName != ''">
            and trim(replace(du.nick_name,' ','')) like trim(replace(concat('%',#{distributionProdLog.nickName},'%'),' ',''))
        </if>
        <if test="distributionProdLog.userMobile != null and distributionProdLog.userMobile != ''">
            AND du.user_mobile LIKE CONCAT('%',#{distributionProdLog.userMobile},'%')
        </if>
        ) res LEFT JOIN `tz_order_item_lang` AS toil ON res.order_item_id=toil.`order_item_id` AND toil.`lang`=#{dblang}
        ORDER BY res.create_time DESC, res.order_number
    </select>
</mapper>
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionUserBanMapper.xml
New file
@@ -0,0 +1,78 @@
<?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.yami.shop.distribution.common.dao.DistributionUserBanMapper">
  <resultMap id="BaseResultMap" type="com.yami.shop.distribution.common.model.DistributionUserBan">
    <id column="ban_id" jdbcType="BIGINT" property="banId" />
    <result column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId" />
    <result column="ban_reason" jdbcType="TINYINT" property="banReason" />
    <result column="remarks" jdbcType="VARCHAR" property="remarks" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    <result column="modifier" jdbcType="VARCHAR" property="modifier" />
    <result column="state" jdbcType="TINYINT" property="state" />
  </resultMap>
  <resultMap id="DistributionUserBan_DistributionUser_SysUser" type="com.yami.shop.distribution.common.model.DistributionUserBan">
    <id column="ban_id" jdbcType="BIGINT" property="banId" />
    <result column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId" />
    <result column="ban_reason" jdbcType="TINYINT" property="banReason" />
    <result column="remarks" jdbcType="VARCHAR" property="remarks" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    <result column="modifier" jdbcType="VARCHAR" property="modifier" />
    <result column="state" jdbcType="TINYINT" property="state" />
    <association property="distributionUser" javaType="com.yami.shop.distribution.common.vo.DistributionUserVO">
      <id column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId" />
        <result column="nick_name" jdbcType="VARCHAR" property="nickName" />
        <result column="user_mobile" jdbcType="VARCHAR" property="userMobile" />
    </association>
    <association property="sysUser" javaType="com.yami.shop.bean.vo.SysUserVO">
      <id column="sys_user_id" jdbcType="BIGINT" property="userId" />
      <result column="username" jdbcType="VARCHAR" property="username" />
    </association>
  </resultMap>
  <select id="distributionUserBanPage" resultMap="DistributionUserBan_DistributionUser_SysUser">
    select
    dub.*,
    du.nick_name,du.user_mobile,
    su.username,su.user_id as sys_user_id
    from
    tz_distribution_user_ban dub
    left join tz_distribution_user du on du.distribution_user_id=dub.distribution_user_id
    left join tz_sys_user su on su.user_id=dub.modifier
    <where>
      <if test="shopId!=null ">
        and du.shop_id=#{shopId}
      </if>
      <if test="userMobile!=null and userMobile!=''">
        and du.user_mobile like concat('%',#{userMobile},'%')
      </if>
      <if test="distributionUserBan.state!=null">
        and dub.state =#{distributionUserBan.state}
      </if>
      <if test="distributionUserBan.banReason!=null">
        and ban_reason =#{distributionUserBan.banReason}
      </if>
    </where>
    GROUP BY dub.ban_id
    <if test="distributionUserBan.sortParam != 0 and distributionUserBan.sortType != 0">
      ORDER BY
      <choose>
        <when test="distributionUserBan.sortParam == 1">
          dub.update_time
        </when>
        <otherwise>
          dub.ban_id
        </otherwise>
      </choose>
      <choose>
        <when test="distributionUserBan.sortType == 1">
          ASC
        </when>
        <when test="distributionUserBan.sortType == 2">
          DESC
        </when>
      </choose>
    </if>
  </select>
</mapper>
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionUserBindMapper.xml
New file
@@ -0,0 +1,156 @@
<?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.yami.shop.distribution.common.dao.DistributionUserBindMapper">
  <resultMap id="BaseResultMap" type="com.yami.shop.distribution.common.model.DistributionUserBind">
    <result column="bind_id" jdbcType="BIGINT" property="bindId" />
    <result column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId" />
    <result column="shop_id" jdbcType="BIGINT" property="shopId" />
    <result column="user_id" jdbcType="VARCHAR" property="userId" />
    <result column="state" jdbcType="TINYINT" property="state" />
    <result column="invalid_reason" jdbcType="TINYINT" property="invalidReason" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    <result column="bind_time" jdbcType="TIMESTAMP" property="bindTime" />
    <result column="invalid_time" jdbcType="TIMESTAMP" property="invalidTime" />
  </resultMap>
  <resultMap id="DistributionUserBind_User_User_DistributionUser"  type="com.yami.shop.distribution.common.model.DistributionUserBind">
    <result column="bind_id" jdbcType="BIGINT" property="bindId" />
    <result column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId" />
    <result column="shop_id" jdbcType="BIGINT" property="shopId" />
    <result column="user_id" jdbcType="VARCHAR" property="userId" />
    <result column="state" jdbcType="TINYINT" property="state" />
    <result column="invalid_reason" jdbcType="TINYINT" property="invalidReason" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    <result column="bind_time" jdbcType="TIMESTAMP" property="bindTime" />
    <result column="invalid_time" jdbcType="TIMESTAMP" property="invalidTime" />
    <association property="user" javaType="com.yami.shop.bean.vo.UserVO">
      <id column="user_id" jdbcType="VARCHAR" property="userId" />
      <result column="nick_name" jdbcType="VARCHAR" property="nickName" />
      <result column="u_user_mobile" jdbcType="BIGINT" property="userMobile" />
    </association>
    <association property="distributionUser" javaType="com.yami.shop.distribution.common.vo.DistributionUserVO">
      <result column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId" />
      <result column="parent_nick_name" jdbcType="VARCHAR" property="nickName" />
      <result column="parent_user_mobile" jdbcType="VARCHAR" property="userMobile" />
    </association>
  </resultMap>
  <select id="distributionMsgsAndUserPage" resultMap="DistributionUserBind_User_User_DistributionUser">
      select dub.*,
      du.nick_name as parent_nick_name,
      du.user_mobile as parent_user_mobile,
      u.nick_name,
      u.user_mobile as u_user_mobile
      from
      tz_distribution_user_bind dub
      left join tz_distribution_user du on du.distribution_user_id=dub.distribution_user_id
      left join tz_user u on dub.user_id=u.user_id
     <where>
       <if test="userName!= null and userName!='' ">
         and trim(replace(u.nick_name,' ','')) like trim(replace(concat('%',#{userName},'%'),' ',''))
       </if>
       <if test="parentName!= null and parentName!='' ">
         and trim(replace(du.nick_name,' ','')) like trim(replace(concat('%',#{parentName},'%'),' ',''))
       </if>
       <if test="distributionUserBind.state!= null ">
          and dub.state=#{distributionUserBind.state}
       </if>
       <if test="bindTime != null  and bindTime.startTime!= null ">
         and dub.bind_time &gt;= #{bindTime.startTime}
       </if>
       <if test="bindTime != null  and bindTime.endTime!= null ">
         and dub.bind_time &lt;= #{bindTime.endTime}
       </if>
       <if test="invalidTime != null  and invalidTime.startTime!= null ">
         and dub.invalid_time &gt;= #{invalidTime.startTime}
       </if>
       <if test="invalidTime != null  and invalidTime.endTime!= null ">
         and dub.invalid_time &lt;= #{invalidTime.endTime}
       </if>
       <if test="cUserMobile != null ">
         and trim(replace(u.user_mobile,' ','')) like trim(replace(concat('%',#{cUserMobile},'%'),' ',''))
       </if>
       <if test="dUserMobile != null ">
         and trim(replace(du.user_mobile,' ','')) like trim(replace(concat('%',#{dUserMobile},'%'),' ',''))
       </if>
     </where>
      <if test="sort == 1">
          order by dub.bind_time
      </if>
      <if test="sort == 2">
          order by dub.invalid_time
      </if>
      <if test="orderBy == 2">
          asc
      </if>
      <if test="orderBy == 1">
          desc
      </if>
  </select>
  <!--根据用户id和店铺Id获取绑定人id-->
  <select id="getParentDistributionIdByShopIdAndUserId" resultType="long">
    select distribution_user_id from
    tz_distribution_user_bind
    where shop_id=#{shopId}
    and user_id=#{userId}
    and state=#{state}
  </select>
  <!--根据客户id 店铺id 状态获取最新的一条记录-->
  <select id="getNewDistributionUserBindByUserIdAndShopIdAndState" resultMap="BaseResultMap">
        select * from tz_distribution_user_bind
        where shop_id = #{shopId}
        and user_id = #{userId}
        and state = #{state}
        ORDER BY bind_time desc
        limit 0,1
    </select>
    <!--根据分销员id修改绑定状态-->
    <update id="updateStateAndReasonByDistributionUserId">
        update tz_distribution_user_bind
        set state = #{state},invalid_reason = 3,invalid_time = now()
        where
        distribution_user_id = #{distributionUserId} and state = 1
    </update>
    <update id="updateStateAndReasonByUserId">
        update tz_distribution_user_bind
        set state = #{state},invalid_reason = 3,invalid_time = now()
        where
                user_id = #{userId} and state = 1
    </update>
    <select id="bindUserList" resultType="com.yami.shop.distribution.common.dto.BindUserInfoDto">
        select dub.*,
        u.nick_name,
        u.pic
        from
        tz_distribution_user_bind dub
        left join tz_distribution_user du on du.distribution_user_id=dub.distribution_user_id
        left join tz_user u on dub.user_id=u.user_id
        where du.user_id = #{userId}  and dub.state = 1 and du.shop_id = #{shopId} order by dub.bind_time desc
    </select>
    <update id="recoveryRelationsByUserId">
        update tz_distribution_user_bind
        set state = 1,invalid_reason = null,invalid_time = null
        where invalid_reason = 3 and user_id in
        <foreach collection="distributionUserBinds" item="distributionUserBind" separator="," open="(" close=")">
            #{distributionUserBind.userId}
        </foreach>
    </update>
    <select id="selectClearUserByDistributionUserId" resultType="string">
        select user_id from tz_distribution_user_bind
        where state = 1 and user_id in
        <foreach collection="distributionUserBindList" item="distributionUserBind" separator="," open="(" close=")">
            #{distributionUserBind.userId}
        </foreach>
    </select>
</mapper>
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionUserGroupMapper.xml
New file
@@ -0,0 +1,49 @@
<?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.yami.shop.distribution.common.dao.DistributionUserGroupMapper">
  <resultMap id="BaseResultMap" type="com.yami.shop.distribution.common.model.DistributionUserGroup">
    <result column="group_id" jdbcType="BIGINT" property="groupId" />
      <result column="shop_id" jdbcType="BIGINT" property="shopId" />
    <result column="group_name" jdbcType="VARCHAR" property="groupName" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    <result column="modifier" jdbcType="VARCHAR" property="modifier" />
  </resultMap>
  <resultMap id="DistributionUserGroups_SysUser" type="com.yami.shop.distribution.common.model.DistributionUserGroup">
    <result column="group_id" jdbcType="BIGINT" property="groupId" />
      <result column="shop_id" jdbcType="BIGINT" property="shopId" />
    <result column="group_name" jdbcType="VARCHAR" property="groupName" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    <result column="modifier" jdbcType="VARCHAR" property="modifier" />
    <association property="sysUser" javaType="com.yami.shop.bean.vo.SysUserVO">
      <id column="user_id" jdbcType="BIGINT" property="userId" />
      <result column="username" jdbcType="VARCHAR" property="username" />
    </association>
  </resultMap>
  <select id="distributionUserGroupsAndSysUserPage" resultMap="DistributionUserGroups_SysUser">
      select
      dug.*,
      su.user_id,su.username
      from
      tz_distribution_user_group dug
      left join tz_sys_user su on dug.modifier=su.user_id
      <where>
          <if test="distributionUserGroup.shopId!= null ">
              and dug.shop_id=#{distributionUserGroup.shopId}
          </if>
          <if test="distributionUserGroup.groupName!= null and distributionUserGroup.groupName!='' ">
              and group_name LIKE CONCAT('%',#{distributionUserGroup.groupName},'%')
          </if>
      </where>
  </select>
    <delete id="deleteByIds">
        delete from tz_distribution_user_group where group_id in
        <foreach item="id" collection="ids" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
</mapper>
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionUserIncomeMapper.xml
New file
@@ -0,0 +1,310 @@
<?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.yami.shop.distribution.common.dao.DistributionUserIncomeMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.distribution.common.model.DistributionUserIncome">
        <id column="income_id" jdbcType="BIGINT" property="incomeId"/>
        <result column="wallet_id" jdbcType="BIGINT" property="walletId"/>
        <result column="income_type" jdbcType="VARCHAR" property="incomeType"/>
        <result column="state" jdbcType="TINYINT" property="state"/>
        <result column="income_amount" jdbcType="DECIMAL" property="incomeAmount"/>
        <result column="order_item_id" jdbcType="BIGINT" property="orderItemId"/>
        <result column="merchant_order_id" jdbcType="VARCHAR" property="merchantOrderId"/>
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
        <result column="order_number" jdbcType="VARCHAR" property="orderNumber"/>
    </resultMap>
    <!--推广效果-->
    <resultMap id="DistributionUserIncome_DistributionUser"
               type="com.yami.shop.distribution.common.model.DistributionUserIncome">
        <id column="income_id" jdbcType="BIGINT" property="incomeId"/>
        <result column="wallet_id" jdbcType="BIGINT" property="walletId"/>
        <result column="income_type" jdbcType="VARCHAR" property="incomeType"/>
        <result column="state" jdbcType="TINYINT" property="state"/>
        <result column="income_amount" jdbcType="DECIMAL" property="incomeAmount"/>
        <result column="order_item_id" jdbcType="BIGINT" property="orderItemId"/>
        <result column="merchant_order_id" jdbcType="VARCHAR" property="merchantOrderId"/>
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
        <result column="order_number" jdbcType="VARCHAR" property="orderNumber"/>
        <association property="distributionUser" javaType="com.yami.shop.distribution.common.vo.DistributionUserVO">
            <id column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId"/>
            <result column="nick_name" jdbcType="VARCHAR" property="nickName"/>
            <result column="user_mobile" jdbcType="VARCHAR" property="userMobile"/>
        </association>
        <association property="order" javaType="com.yami.shop.bean.model.Order">
            <result column="status" jdbcType="TINYINT" property="status"/>
        </association>
    </resultMap>
    <select id="incomeAndDistributionUserPage" resultMap="DistributionUserIncome_DistributionUser">
        select
        dui.*,
        du.nick_name,du.user_mobile,
        o.`status`
        from
        tz_distribution_user_income dui
        left join tz_distribution_user_wallet duw on duw.wallet_id = dui.wallet_id
        left join tz_distribution_user du on du.distribution_user_id=duw.distribution_user_id
        left join tz_order o on o.order_number = dui.order_number
        <where>
            dui.income_type != 4
            <if test="shopId !=null">
                and du.shop_id=#{shopId}
            </if>
            <if test="rangeTimeParam.startTime !=null">
                and dui.create_time &gt;= #{rangeTimeParam.startTime}
            </if>
            <if test="state !=null">
                and dui.state = #{state}
            </if>
            <if test="rangeTimeParam.endTime !=null">
                and dui.create_time &lt;=#{rangeTimeParam.endTime}
            </if>
            <if test="userMobile!=null and userMobile!=''">
                and du.user_mobile like concat('%',#{userMobile},'%')
            </if>
            <if test="orderNumber != null and orderNumber != ''">
                and dui.order_number like concat('%',#{orderNumber},'%')
            </if>
        </where>
        GROUP BY dui.income_id
        <if test="distributionUserIncome.sortParam != 0 and distributionUserIncome.sortType != 0">
            ORDER BY
            <choose>
                <when test="distributionUserIncome.sortParam == 1">
                    dui.income_amount
                </when>
                <when test="distributionUserIncome.sortParam == 2">
                    dui.create_time
                </when>
                <when test="distributionUserIncome.sortParam == 3">
                    dui.update_time
                </when>
                <otherwise>
                    dui.income_id
                </otherwise>
            </choose>
            <choose>
                <when test="distributionUserIncome.sortType == 1">
                    ASC
                </when>
                <when test="distributionUserIncome.sortType == 2">
                    DESC
                </when>
            </choose>
        </if>
    </select>
    <!--分销推广订单 -->
    <resultMap id="DistributionOrderDtoMap" type="com.yami.shop.distribution.common.dto.DistributionOrderDto">
        <result column="income_amount" property="incomeAmount"/>
        <result column="state" property="state"/>
        <result column="create_time" property="createTime"/>
        <result column="prod_id" property="prodId"/>
        <result column="prod_name" property="prodName"/>
        <result column="pic" property="pic"/>
    </resultMap>
    <select id="getDistributionOrderDtoByDistributionUserId" resultMap="DistributionOrderDtoMap">
            select
            dui.income_amount,
            dui.state,
            dui.create_time,
            o.pic,
            o.prod_id,
            o.prod_name
            from
            tz_distribution_user_income dui
            left join tz_order_item o on o.order_item_id=dui.order_item_id
            where dui.distribution_user_id=#{distributionUserId}
    </select>
    <update id="updateStateByOrderNumber">
        UPDATE tz_distribution_user_income
        SET state = #{state}
        where
        order_number = #{orderNumber}
    </update>
    <resultMap id="DistributionUserWallet" type="com.yami.shop.distribution.common.model.DistributionUserWallet">
        <id column="wallet_id" jdbcType="BIGINT" property="walletId"/>
        <result column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId"/>
        <result column="unsettled_amount" jdbcType="DECIMAL" property="unsettledAmount"/>
        <result column="settled_amount" jdbcType="DECIMAL" property="settledAmount"/>
        <result column="addup_amount" jdbcType="DECIMAL" property="addupAmount"/>
        <result column="version" jdbcType="INTEGER" property="version"/>
    </resultMap>
    <!--<select id="getWalletByOrderNumberAndIncomeType" resultMap="DistributionUserWallet">-->
    <!--select-->
    <!--wallet_id,-->
    <!--distribution_user_id,-->
    <!--unsettled_amount,-->
    <!--settled_amount,-->
    <!--addup_amount,-->
    <!--version-->
    <!--from-->
    <!--tz_distribution_user_wallet-->
    <!--where wallet_id in(-->
    <!--select-->
    <!--any_value(wallet_id)-->
    <!--from-->
    <!--tz_distribution_user_income-->
    <!--where order_number = #{orderNumber}-->
    <!--and-->
    <!--income_type= #{incomeType}-->
    <!--GROUP BY order_number-->
    <!--)-->
    <!--</select>-->
    <!--<select id="getIncomeAmountByOrderNumber" resultType="double">-->
    <!--select-->
    <!--sum(income_amount)-->
    <!--from-->
    <!--tz_distribution_user_income-->
    <!--where-->
    <!--order_number  = #{orderNumber}-->
    <!--</select>-->
    <resultMap id="DistributionAmountAndWalletVO" type="com.yami.shop.distribution.common.vo.DistributionAmountAndWalletVO">
        <result column="wallet_id" jdbcType="BIGINT" property="distributionUserWalletId"/>
        <result column="amount" jdbcType="DECIMAL" property="amount"/>
        <result column="parent_wallet_id" jdbcType="DECIMAL" property="parentDistributionUserWalletId"/>
        <result column="parent_amount" jdbcType="DECIMAL" property="parentAmount"/>
    </resultMap>
    <update id="updateStateByDistributionUserId">
        update tz_distribution_user_income
        set state = #{state}
        where
        distribution_user_id = #{distributionUserId}
    </update>
    <resultMap id="DistributionSettlementDto" type="com.yami.shop.distribution.common.dto.DistributionSettlementDto">
        <result column="order_number" jdbcType="VARCHAR" property="orderNumber"/>
        <result column="status" jdbcType="TINYINT" property="status"/>
        <result column="sum_amount" jdbcType="DECIMAL" property="sumAmount"/>
    </resultMap>
    <update id="updateStateByOrderNumberAndOrderItem">
        UPDATE tz_distribution_user_income
        SET state = #{state}
        WHERE
        order_number = #{orderNumber}
        AND
        order_item_id = #{orderItemId}
    </update>
    <select id="statisticsDisUserIncome" resultType="double">
        SELECT COALESCE(SUM(income_amount),0)
        FROM tz_distribution_user_income dui
        WHERE dui.`distribution_user_id`= #{distributionUserId}  AND dui.`state` =2
        AND dui.`update_time` BETWEEN #{startTime} AND #{endTime}
    </select>
    <select id="getDistributionUserIncomePage" resultType="com.yami.shop.distribution.common.dto.DistributionUserIncomeDto">
        SELECT dui.`income_amount`,dui.`income_type`,dui.`update_time`,dui.state
        FROM tz_distribution_user_income dui
        WHERE dui.income_amount != 0 AND dui.`distribution_user_id` = #{distributionUserId}
        ORDER BY dui.`update_time` DESC
    </select>
    <select id="getMyPromotionOrderByState" resultType="com.yami.shop.distribution.common.vo.DistributionOrdersVO">
        SELECT oi.order_number, oi.actual_total AS total, oi.prod_count, oi.pic, oi.price, ifnull(oil.prod_name, oi.prod_name) as prod_name,
        ifnull(oil.sku_name,oi.sku_name) as sku_name, dui.`update_time`, oi.order_item_id,dui.reson,dui.income_amount as distribution_amount,
        if(dui.reson > 0, -1, dui.state) as state
        FROM
        tz_distribution_user_income dui
        LEFT JOIN tz_order_item oi ON dui.`order_item_id` = oi.`order_item_id`
        LEFT JOIN tz_order_item_lang oil ON  oil.`order_item_id` = oi.`order_item_id` and oil.lang = #{dbLang}
        LEFT JOIN tz_order o ON o.`order_number` = oi.`order_number`
        WHERE dui.`distribution_user_id` = #{distributionUserId} and dui.income_type != 4
        <choose>
            <when test="state != null and state == -1">
                AND dui.reson > 0
            </when>
            <when test="state != null and state != -1">
                AND dui.`state` = #{state}
            </when>
        </choose>
        GROUP BY dui.`income_id`
        ORDER BY dui.`update_time` DESC, dui.`income_id` ASC
    </select>
    <select id="listWaitCommissionSettlement" resultType="com.yami.shop.distribution.common.model.DistributionUserIncome">
        SELECT dui.*,oi.*,o.*, tor.return_money_sts FROM tz_distribution_user_income dui
        JOIN tz_order_item oi ON dui.`order_item_id` = oi.`order_item_id`
        JOIN tz_order  o ON o.`order_number` = dui.`order_number`
            left join tz_order_refund tor on tor.order_item_id = oi.order_item_id
        WHERE dui.`state` = 1 -- 未结算收入
        AND o.`status` = 5  -- 已确认收货
        AND oi.`distribution_card_no` != '' and oi.`distribution_card_no` is not null-- 分销订单项
        AND o.order_number in
        <foreach collection="orderNumbers" item="orderNumber" separator="," open="(" close=")">
            #{orderNumber}
        </foreach>
    </select>
    <update id="updateBatchState">
         UPDATE tz_distribution_user_income dui SET dui.`state` = #{state}, dui.`reson`=#{reson}, dui.`update_time` = NOW()
         WHERE dui.`income_id` IN
         <foreach collection="distributionUserIncomeList" item="distributionUserIncome"  open="(" separator="," close=")">
             #{distributionUserIncome.incomeId}
         </foreach>
     </update>
    <update id="updateDistributionUserIncomesBy">
        update tz_distribution_user_income SET state=#{state}
        WHERE distribution_user_id=#{id}  AND income_type=#{type}
          AND order_number in
            <foreach collection="list" open="(" index="index" item="item" separator="," close=")">
                #{item}
            </foreach>
    </update>
    <select id="selectIncomeInfo" resultType="com.yami.shop.distribution.common.vo.DistributionUserInfoVO">
        SELECT tu.`user_id`, tu.pic, tu.`nick_name`,dui.distribution_user_id,du.state, du.bind_time,
        SUM(IF(dui.`state` = 2, dui.`income_amount`, 0)) AS money,
        COUNT(DISTINCT IF(dui.`state` = 2, dui.`order_number`, NULL)) AS order_number
        FROM tz_distribution_user_income dui
        JOIN tz_user tu ON tu.user_id IN
        <foreach collection="userIds" item="userId" open="(" separator="," close=")">
            #{userId}
        </foreach>
        LEFT JOIN `tz_distribution_user` du ON du.`user_id` = tu.user_id
        LEFT JOIN tz_order_item oi ON  oi.distribution_card_no = #{distributionUser.cardNo}
        WHERE dui.`distribution_user_id` = #{distributionUser.distributionUserId} AND dui.`income_type` = #{type}
        AND dui.`order_number` IN
            <foreach collection="orderNumbers" item="orderNumber" open="(" separator="," close=")">
                #{orderNumber}
            </foreach>
        AND oi.user_id = tu.`user_id` AND oi.`order_number` = dui.`order_number`
        GROUP BY tu.`user_id`
        ORDER BY money DESC
    </select>
    <select id="getFriendInfo" resultType="com.yami.shop.distribution.common.vo.DistributionUserInfoVO">
        SELECT
            tu.`user_id`,
            tu.pic,
            tu.`nick_name`,
            IFNULL(dui.money,0) AS money,
            IFNULL(dui.order_number, 0) AS order_number,
            du.distribution_user_id,
            du.state,
            du.bind_time
        FROM tz_distribution_user AS du
        LEFT JOIN (
            SELECT oi.distribution_card_no card_no,SUM(IFNULL(dui.`income_amount`, 0)) AS money,COUNT(IFNULL(dui.`order_number`, 0)) AS order_number
            FROM tz_distribution_user_income dui
            JOIN tz_order_item oi ON oi.distribution_card_no IN
            <foreach collection="friends" item="friend" open="(" separator="," close=")">
                #{friend.cardNo}
            </foreach>AND dui.order_item_id = oi.order_item_id
            JOIN tz_order o ON oi.order_number = o.order_number AND 1 &lt; o.`status` AND o.`status` &lt; 6
            WHERE dui.`state` = 2 AND dui.`income_type` = #{type} AND dui.distribution_user_id = #{distributionUser.distributionUserId}
            GROUP BY oi.distribution_card_no
        ) dui ON dui.card_no = du.card_no
        JOIN `tz_user` tu ON tu.`user_id` = du.`user_id`
        WHERE du.parent_id = #{distributionUser.distributionUserId} and du.state = 1
        ORDER BY money DESC, du.bind_time
    </select>
</mapper>
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionUserMapper.xml
New file
@@ -0,0 +1,413 @@
<?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.yami.shop.distribution.common.dao.DistributionUserMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.distribution.common.model.DistributionUser">
        <id column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId"/>
        <result column="shop_id" jdbcType="BIGINT" property="shopId"/>
        <result column="card_no" jdbcType="BIGINT" property="cardNo"/>
        <result column="user_id" jdbcType="VARCHAR" property="userId"/>
        <result column="parent_id" jdbcType="BIGINT" property="parentId"/>
        <result column="parent_ids" jdbcType="VARCHAR" property="parentIds"/>
        <result column="grade" jdbcType="INTEGER" property="grade"/>
        <result column="level" jdbcType="INTEGER" property="level"/>
        <result column="group_id" jdbcType="BIGINT" property="groupId"/>
        <result column="bind_time" jdbcType="TIMESTAMP" property="bindTime"/>
        <result column="state" jdbcType="TINYINT" property="state"/>
        <result column="nick_name" jdbcType="VARCHAR" property="nickName"/>
        <result column="user_mobile" jdbcType="VARCHAR" property="userMobile"/>
        <result column="real_name" jdbcType="VARCHAR" property="realName"/>
        <result column="identity_card_number" jdbcType="VARCHAR" property="identityCardNumber"/>
        <result column="identity_card_pic_front" jdbcType="VARCHAR" property="identityCardPicFront"/>
        <result column="identity_card_pic_back" jdbcType="VARCHAR" property="identityCardPicBack"/>
        <result column="identity_card_pic_hold" jdbcType="VARCHAR" property="identityCardPicHold"/>
        <result column="pic" jdbcType="VARCHAR" property="pic"/>
    </resultMap>
    <!--业绩统计-->
    <resultMap id="distributionUser_Achievement" type="com.yami.shop.distribution.common.model.DistributionUser">
        <id column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId"/>
        <result column="nick_name" jdbcType="VARCHAR" property="nickName"/>
        <result column="user_mobile" jdbcType="VARCHAR" property="userMobile"/>
        <result column="state" jdbcType="INTEGER" property="state"/>
        <association property="distributionUserAchievementDataDto"
                     javaType="com.yami.shop.distribution.common.dto.DistributionUserAchievementDataDto">
            <association property="distributionUserIncome"
                         javaType="com.yami.shop.distribution.common.vo.DistributionUserIncomeVO">
                <result property="aGenerationCommission" jdbcType="DECIMAL" column="a_generation_commission"/>
                <result property="secondGenerationCommission" jdbcType="DECIMAL" column="second_generation_commission"/>
                <result property="invitationRewards" jdbcType="DECIMAL" column="invitation_rewards"/>
            </association>
            <association property="distributionUserWallet"
                         javaType="com.yami.shop.distribution.common.dto.DistributionUserWalletDto">
                <result property="addupAmount" jdbcType="DECIMAL" column="addup_amount"/>
                <result property="unsettledAmount" jdbcType="DECIMAL" column="unsettled_amount"/>
                <result property="settledAmount" jdbcType="DECIMAL" column="settled_amount"/>
                <result column="invalid_amount" jdbcType="DECIMAL" property="invalidAmount"/>
            </association>
        </association>
    </resultMap>
    <!--<select id="getParentIdsByDistributionUserId" resultType="string">-->
    <!--select parent_ids from tz_distribution_user where distribution_user_id = #{distributionUserId}-->
    <!--</select>-->
    <select id="getDistributionUserAchievementPage" resultMap="distributionUser_Achievement">
        SELECT
        du.distribution_user_id,
        du.nick_name,
        du.user_mobile,
        du.state,
        any_value(da.addup_amount) as addup_amount,
        any_value(da.settled_amount) as settled_amount,
        any_value(da.unsettled_amount) as unsettled_amount,
        any_value(da.invalid_amount) as invalid_amount,
        sum( CASE WHEN dui.income_type = 1 THEN dui.income_amount ELSE 0 END ) AS a_generation_commission,
        sum( CASE WHEN dui.income_type = 2 THEN dui.income_amount ELSE 0 END ) AS second_generation_commission,
        sum( CASE WHEN dui.income_type = 3 THEN dui.income_amount ELSE 0 END ) AS invitation_rewards
        FROM
        tz_distribution_user du
        LEFT JOIN tz_distribution_user_wallet da ON da.distribution_user_id = du.distribution_user_id
        LEFT JOIN tz_distribution_user_income dui ON dui.wallet_id = da.wallet_id AND dui.state != 0 AND dui.state != -1
        <where>
            du.state IN (-1,1,2)
            <if test="distributionUser.state != null">
                and du.state = #{distributionUser.state}
            </if>
            <if test="distributionUser.shopId!= null">
                and du.shop_id = #{distributionUser.shopId}
            </if>
            <if test="userMobile!= null and userMobile!=''">
                and du.user_mobile like concat('%',#{userMobile},'%')
            </if>
        </where>
        GROUP BY
        du.distribution_user_id
        <if test="distributionUser.sortParam != 0 and distributionUser.sortType != 0">
            ORDER BY
            <choose>
                <when test="distributionUser.sortParam == 1">
                    a_generation_commission
                </when>
                <when test="distributionUser.sortParam == 2">
                    second_generation_commission
                </when>
                <when test="distributionUser.sortParam == 3">
                    invitation_rewards
                </when>
                <when test="distributionUser.sortParam == 4">
                    unsettled_amount
                </when>
                <when test="distributionUser.sortParam == 5">
                    settled_amount
                </when>
                <when test="distributionUser.sortParam == 6">
                    invalid_amount
                </when>
                <otherwise>
                    distribution_user_id
                </otherwise>
            </choose>
            <choose>
                <when test="distributionUser.sortType == 1">
                    ASC
                </when>
                <when test="distributionUser.sortType == 2">
                    DESC
                </when>
            </choose>
        </if>
    </select>
    <!--获取分销员与等级条件匹配的数据-->
    <resultMap id="DistributionUserAchievementData"
               type="com.yami.shop.distribution.common.dto.DistributionUserAchievementDataDto">
        <result property="boundCustomers" jdbcType="INTEGER" column="bound_customers"/>
        <result property="invitedVeeker" jdbcType="INTEGER" column="invited_veeker"/>
        <result property="payNumber" jdbcType="INTEGER" column="pay_number"/>
        <result property="successOrderNumber" jdbcType="INTEGER" column="success_order_number"/>
        <result property="successTradingVolume" jdbcType="DECIMAL" column="success_trading_volume"/>
        <result property="sumOfConsumption" jdbcType="DECIMAL" column="sum_of_consumption"/>
        <association property="distributionUserWallet"
                     javaType="com.yami.shop.distribution.common.dto.DistributionUserWalletDto">
            <result property="addupAmount" jdbcType="DECIMAL" column="addup_amount"/>
        </association>
    </resultMap>
    <!--获取分销员与等级条件匹配的数据-->
    <select id="getLevelDistributionUserAchievementDataByDistributionUserId"
            resultMap="DistributionUserAchievementData">
        select
            -- 积累绑定客户数
            count(distinct dub.user_id)                 as bound_customers,
            -- 积累邀请分销员数
            count(distinct sub_du.distribution_user_id) as invited_veeker,
            -- 积累支付单数
            count(distinct o.order_id)                  as pay_number,
            -- 积累成功成交单数
            count(distinct dui.income_id)               as success_order_number,
            -- 积累成功成交金额
            ifnull(sum(oi.product_total_amount), 0)     as success_trading_volume,
            -- 总消费
            sum(o.actual_total)                         as sum_of_consumption,
            -- 积累收益
            any_value(duw.addup_amount)                 as addup_amount
        from tz_distribution_user du
                 -- 绑定客户信息
                 left join tz_distribution_user_bind dub on dub.distribution_user_id = du.distribution_user_id
            -- 下级信息
                 left join tz_distribution_user sub_du on sub_du.parent_id = du.distribution_user_id
            -- 消费信息
                 left join tz_order o on o.user_id = du.user_id and (o.status = 4 or o.status = 5)
            -- 钱包
                 left join tz_distribution_user_wallet duw on duw.distribution_user_id = du.distribution_user_id
            -- 收益信息(限一级佣金和成功的订单)
                 left join tz_distribution_user_income dui
                           on dui.wallet_id = duw.wallet_id and dui.income_type = 1 and dui.state = 2
            -- 成交的订单项
                 left join tz_order_item oi on oi.order_item_id = dui.order_item_id
        where du.distribution_user_id = #{distributionUserId}
    </select>
    <!--分销员管理页面-->
    <resultMap id="distributionUserPageMap" type="com.yami.shop.distribution.common.model.DistributionUser">
        <id column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId"/>
        <result column="shop_id" jdbcType="BIGINT" property="shopId"/>
        <result column="card_no" jdbcType="BIGINT" property="cardNo"/>
        <result column="user_id" jdbcType="VARCHAR" property="userId"/>
        <result column="parent_id" jdbcType="BIGINT" property="parentId"/>
        <result column="parent_ids" jdbcType="VARCHAR" property="parentIds"/>
        <result column="grade" jdbcType="INTEGER" property="grade"/>
        <result column="level" jdbcType="BIGINT" property="level"/>
        <result column="group_id" jdbcType="BIGINT" property="groupId"/>
        <result column="bind_time" jdbcType="TIMESTAMP" property="bindTime"/>
        <result column="state" jdbcType="TINYINT" property="state"/>
        <result column="nick_name" jdbcType="VARCHAR" property="nickName"/>
        <result column="user_mobile" jdbcType="VARCHAR" property="userMobile"/>
        <result column="real_name" jdbcType="VARCHAR" property="realName"/>
        <result column="identity_card_number" jdbcType="VARCHAR" property="identityCardNumber"/>
        <result column="identity_card_pic_front" jdbcType="VARCHAR" property="identityCardPicFront"/>
        <result column="identity_card_pic_back" jdbcType="VARCHAR" property="identityCardPicBack"/>
        <result column="identity_card_pic_hold" jdbcType="VARCHAR" property="identityCardPicHold"/>
        <!--上级分销员-->
        <association property="parentDistributionUser"
                     javaType="com.yami.shop.distribution.common.vo.DistributionUserVO">
            <result column="parent_nick_name" jdbcType="VARCHAR" property="nickName"/>
            <result column="parent_user_mobile" jdbcType="VARCHAR" property="userMobile"/>
        </association>
        <!--分销员数据-->
        <association property="distributionUserAchievementDataDto"
                     javaType="com.yami.shop.distribution.common.dto.DistributionUserAchievementDataDto">
            <result property="boundCustomers" jdbcType="INTEGER" column="bound_customers"/>
            <result property="invitedVeeker" jdbcType="INTEGER" column="invited_veeker"/>
            <!--分销员钱包-->
            <association property="distributionUserWallet"
                         javaType="com.yami.shop.distribution.common.dto.DistributionUserWalletDto">
                <result property="addupAmount" jdbcType="DECIMAL" column="addup_amount"/>
            </association>
        </association>
    </resultMap>
    <select id="distributionUserPage" resultMap="distributionUserPageMap">
        select
        -- 分销员信息
        du.distribution_user_id,
        du.shop_id,
        du.card_no,
        du.parent_id,
        du.grade,
        du.level,
        du.group_id,
        du.bind_time,
        du.state,
        du.nick_name,
        du.user_mobile,
        du.real_name,
        du.identity_card_number,
        du.identity_card_pic_front,
        du.identity_card_pic_back,
        du.identity_card_pic_hold,
        -- 上级分销员信息
        pdu.user_mobile as parent_user_mobile,
        pdu.nick_name as parent_nick_name,
        -- 积累客户
        ifnull(MAX(dub.bound_customers),0) AS bound_customers,
        -- 积累邀请
        ifnull(count(da.distribution_user_id),0) as invited_veeker,
        -- 积累收益
        any_value(ifnull(duw.addup_amount,0)) as addup_amount
        from tz_distribution_user du
        left join tz_distribution_user_wallet duw on duw.distribution_user_id = du.distribution_user_id
        left join tz_distribution_user pdu on pdu.distribution_user_id=du.parent_id
        LEFT JOIN (
        SELECT dub.distribution_user_id,COUNT(dub.distribution_user_id) AS bound_customers FROM
        tz_distribution_user_bind dub
        WHERE dub.state = 1
        GROUP BY dub.distribution_user_id
        ) AS dub ON dub.distribution_user_id = du.distribution_user_id
        left join tz_distribution_auditing da on da.parent_distribution_user_id=du.distribution_user_id and da.state = 1
        <where>du.state != 0 and du.state != 3
            <if test="state != null">
                and du.state=#{state}
            </if>
            <if test="distributionUser.shopId != null">
                and du.shop_id=#{distributionUser.shopId}
            </if>
            <if test="mobile!= null and mobile != ''">
                and du.user_mobile LIKE concat('%',#{mobile},'%')
            </if>
            <if test="parentMobile!= null and parentMobile != ''">
                and pdu.user_mobile LIKE concat('%',#{parentMobile},'%')
            </if>
            <if test="rangeTimeParam.startTime!= null">
                and du.bind_time &gt;= #{rangeTimeParam.startTime}
            </if>
            <if test="rangeTimeParam.endTime!= null ">
                and du.bind_time &lt;= #{rangeTimeParam.endTime}
            </if>
        </where>
        GROUP BY du.distribution_user_id
        <if test="distributionUser.sortParam != 0 and distributionUser.sortType != 0">
            ORDER BY
            <choose>
                <when test="distributionUser.sortParam == 1">
                    bind_time
                </when>
                <when test="distributionUser.sortParam == 2">
                    bound_customers
                </when>
                <when test="distributionUser.sortParam == 3">
                    invited_veeker
                </when>
                <when test="distributionUser.sortParam == 4">
                    addup_amount
                </when>
                <otherwise>
                    distribution_user_id
                </otherwise>
            </choose>
            <choose>
                <when test="distributionUser.sortType == 1">
                    ASC
                </when>
                <when test="distributionUser.sortType == 2">
                    DESC
                </when>
            </choose>
        </if>
    </select>
    <!--分销中心-->
    <resultMap id="DistributionUserAchievementDataAppDto"
               type="com.yami.shop.distribution.common.dto.AchievementDataDto">
        <result property="boundCustomers" column="bound_customers"/>
        <result property="invitedVeeker" column="invited_veeker"/>
        <result property="orderCount" column="order_number"/>
        <association property="distributionUserWallet"
                     javaType="com.yami.shop.distribution.common.dto.DistributionUserWalletDto">
            <result column="unsettled_amount" jdbcType="DECIMAL" property="unsettledAmount"/>
            <result column="settled_amount" jdbcType="DECIMAL" property="settledAmount"/>
            <result column="addup_amount" jdbcType="DECIMAL" property="addupAmount"/>
            <result column="invalid_amount" jdbcType="DECIMAL" property="invalidAmount"/>
        </association>
    </resultMap>
    <select id="getAchievementDataDtoById" resultMap="DistributionUserAchievementDataAppDto">
        SELECT duw.unsettled_amount,
               duw.settled_amount,
               duw.addup_amount,
               duw.invalid_amount,
               bud.bound_customers,
               pdu.invited_veeker,
               dui.order_number
        FROM tz_distribution_user_wallet duw,
             (SELECT count(distribution_user_id) AS bound_customers
              FROM tz_distribution_user_bind
              WHERE distribution_user_id = #{id}) AS bud,
             (SELECT count(distribution_user_id) AS invited_veeker
              FROM tz_distribution_user
              WHERE parent_id = #{id}) AS pdu,
             (SELECT count(distribution_user_id) AS order_number
              FROM tz_distribution_user_income
              WHERE distribution_user_id = #{id}) AS dui
        where duw.distribution_user_id = #{id}
    </select>
    <!--<select id="getParentDistributionUserIdByDistributionUserId" resultType="long">-->
    <!--select parent_user_id from tz_distribution_user-->
    <!--where distribution_user_id = #{distributionUserId}-->
    <!--</select>-->
    <!--<select id="getUserIdByDistributionUserId" resultType="string">-->
    <!--select user_id from tz_distribution_user-->
    <!--where distribution_user_id = #{distributionUserId}-->
    <!--</select>-->
    <select id="getDistributionUserSimpleDtoByParentUserIdPage"
            resultType="com.yami.shop.distribution.common.dto.DistributionUserSimpleDto">
        select distribution_user_id,
               nick_name,
               pic,
               bind_time,
               real_name
        from tz_distribution_user
        where parent_id = #{parentDistributionUserId}
    </select>
    <update id="updateLevel">
        update
            tz_distribution_user
        set `level` = #{level}
        where distribution_user_id = #{distributionUserId}
    </update>
    <update id="updateStatusById">
        update
        tz_distribution_user
        set
        `state` = #{distributionUser.state},bind_time = #{distributionUser.bindTime},state_record =
        #{distributionUser.stateRecord},
        <if test="distributionUser.level != null">
            `level`= #{distributionUser.level}
        </if>
        where distribution_user_id = #{distributionUser.distributionUserId}
    </update>
    <update id="updateParentIdById">
        update tz_distribution_user
        SET parent_id=NULL,
            parent_ids = replace(parent_ids, concat(',', #{distributionUserId}), ''),
            grade=grade - 1
        WHERE parent_id = #{distributionUserId}
    </update>
    <update id="replaceLevel">
        update tz_distribution_user
        set level = #{maxLevel}
        where shop_id = #{shopId}
          and level &gt; #{maxLevel}
    </update>
    <select id="getDistributionUserByIdCardNumberAndUserMobile"
            resultType="com.yami.shop.distribution.common.model.DistributionUser">
        SELECT identity_card_number, user_mobile
        FROM tz_distribution_user
        WHERE (identity_card_number = #{identityCardNumber}
           OR user_mobile = #{userMobile}) AND state != 3
    </select>
    <select id="listByMaxLevel" resultType="string">
        SELECT user_id
        FROM tz_distribution_user
        WHERE state = 1
          and shop_id = #{shopId}
          and level &gt; #{maxLevel}
    </select>
    <select id="selectDistributionOrderId" resultType="java.lang.String">
        SELECT o.order_number
        FROM tz_distribution_user u
        LEFT JOIN tz_order_item oi ON u.card_no = oi.distribution_card_no
        LEFT JOIN tz_order o ON oi.order_number = o.order_number
        WHERE u.card_no = #{cardNo}
        AND 1 &lt; o.status
        AND u.state = 1
    </select>
</mapper>
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionUserWalletBillMapper.xml
New file
@@ -0,0 +1,99 @@
<?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.yami.shop.distribution.common.dao.DistributionUserWalletBillMapper">
  <resultMap id="distributionUserWalletBillMap" type="com.yami.shop.distribution.common.model.DistributionUserWalletBill">
    <id property="id" column="id"/>
    <result property="walletId" column="wallet_id"/>
    <result property="unsettledAmount" column="unsettled_amount"/>
    <result property="settledAmount" column="settled_amount"/>
    <result property="invalidAmount" column="invalid_amount"/>
    <result property="addupAmount" column="addup_amount"/>
    <result property="createTime" column="create_time"/>
    <result property="remarks" column="remarks"/>
    <result property="remarksEn" column="remarks_en"/>
    <result property="unsettledAmountAfter" column="unsettled_amount_after"/>
    <result property="settledAmountAfter" column="settled_amount_after"/>
    <result property="invalidAmountAfter" column="invalid_amount_after"/>
    <result property="addupAmountAfter" column="addup_amount_after"/>
    <result property="type" column="type"/>
    <result property="modifier" column="modifier"/>
  </resultMap>
  <resultMap id="DistributionUserWalletBill_DistributionUserVO_SysUserVO" type="com.yami.shop.distribution.common.model.DistributionUserWalletBill">
    <id property="id" column="id"/>
    <result property="unsettledAmount" column="unsettled_amount"/>
    <result property="settledAmount" column="settled_amount"/>
    <result property="invalidAmount" column="invalid_amount"/>
    <result property="addupAmount" column="addup_amount"/>
    <result property="createTime" column="create_time"/>
    <result property="remarks" column="remarks"/>
    <result property="remarksEn" column="remarks_en"/>
    <result property="type" column="type"/>
    <association property="distributionUser" javaType="com.yami.shop.distribution.common.vo.DistributionUserVO">
      <id column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId" />
      <result column="nick_name" jdbcType="VARCHAR" property="nickName" />
      <result column="user_mobile" jdbcType="VARCHAR" property="userMobile" />
    </association>
    <association property="sysUser" javaType="com.yami.shop.bean.vo.SysUserVO">
      <id column="user_id" jdbcType="BIGINT" property="userId" />
      <result column="username" jdbcType="VARCHAR" property="username" />
    </association>
  </resultMap>
  <select id="getDistributionUserWalletBillAndUserPage" resultMap="DistributionUserWalletBill_DistributionUserVO_SysUserVO">
      select
      duwb.id,
      duwb.unsettled_amount,
      duwb.settled_amount,
      duwb.invalid_amount,
      duwb.addup_amount,
      duwb.create_time,
      duwb.remarks,
      duwb.remarks_en,
      duwb.type,
      du.distribution_user_id,
      du.nick_name,
      du.user_mobile,
      su.user_id,
      su.username
      from
      tz_distribution_user_wallet_bill duwb
      left join tz_distribution_user_wallet duw on duwb.wallet_id = duw.wallet_id
      left join tz_distribution_user du on du.distribution_user_id = duw.distribution_user_id
      left join tz_sys_user su on su.user_id = duwb.modifier
      <where>
          <if test="userMobile != null and userMobile != ''">
              and du.user_mobile like concat('%',#{userMobile},'%')
          </if>
      </where>
      order by duwb.create_time desc
  </select>
    <select id="getDistributionUserWalletBillDtoPage" resultType="com.yami.shop.distribution.common.dto.DistributionUserWalletBillDto">
        select
        duwb.unsettled_amount,
        duwb.settled_amount,
        duwb.invalid_amount,
        duwb.addup_amount,
        duwb.create_time,
        duwb.remarks,
        duwb.remarks_en
        from
        tz_distribution_user_wallet_bill duwb
        right join tz_distribution_user_wallet duw on duw.wallet_id = duwb.wallet_id
        where
        duw.distribution_user_id = #{distributionUserId}
        order by duwb.create_time
        <if test="orderBy != null and orderBy == 1">
            DESC
        </if>
    </select>
    <select id="getHaveWithdrawalSum" resultType="java.lang.Double">
        SELECT  IFNULL(SUM(- settled_amount),0.00) FROM tz_distribution_user_wallet_bill WHERE settled_amount <![CDATA[ < ]]> 0 AND wallet_id = #{walletId}
    </select>
</mapper>
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionUserWalletMapper.xml
New file
@@ -0,0 +1,94 @@
<?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.yami.shop.distribution.common.dao.DistributionUserWalletMapper">
  <resultMap id="BaseResultMap" type="com.yami.shop.distribution.common.model.DistributionUserWallet">
    <id column="wallet_id" jdbcType="BIGINT" property="walletId" />
    <result column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId" />
    <result column="unsettled_amount" jdbcType="DECIMAL" property="unsettledAmount" />
    <result column="settled_amount" jdbcType="DECIMAL" property="settledAmount" />
    <result column="addup_amount" jdbcType="DECIMAL" property="addupAmount" />
      <result column="invalid_amount" jdbcType="DECIMAL" property="invalidAmount" />
    <result column="version" jdbcType="INTEGER" property="version" />
      <result column="state" jdbcType="INTEGER" property="state" />
  </resultMap>
    <resultMap id="DistributionUserWallet_DistributionUserVO" type="com.yami.shop.distribution.common.model.DistributionUserWallet">
        <id column="wallet_id" jdbcType="BIGINT" property="walletId" />
        <result column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId" />
        <result column="unsettled_amount" jdbcType="DECIMAL" property="unsettledAmount" />
        <result column="settled_amount" jdbcType="DECIMAL" property="settledAmount" />
        <result column="addup_amount" jdbcType="DECIMAL" property="addupAmount" />
        <result column="invalid_amount" jdbcType="DECIMAL" property="invalidAmount" />
        <result column="version" jdbcType="INTEGER" property="version" />
        <result column="state" jdbcType="INTEGER" property="state" />
        <association property="distributionUser" javaType="com.yami.shop.distribution.common.vo.DistributionUserVO">
            <result column="nick_name" jdbcType="VARCHAR" property="nickName" />
            <result column="user_mobile" jdbcType="VARCHAR" property="userMobile" />
        </association>
    </resultMap>
    <select id="getDistributionUserWalletAndDistributionUserVoPage" resultMap="DistributionUserWallet_DistributionUserVO">
        select
        duw.wallet_id,
        duw.distribution_user_id,
        duw.unsettled_amount,
        duw.settled_amount,
        duw.invalid_amount,
        duw.addup_amount,
        duw.version,
        du.state,
        du.nick_name,
        du.user_mobile
        from tz_distribution_user_wallet duw
        left join tz_distribution_user du on du.distribution_user_id = duw.distribution_user_id
        <where>
            du.state != 0 and du.state != 3
            <if test="userMobile !=null and userMobile != ''">
                and du.user_mobile like concat('%',#{userMobile},'%')
            </if>
        </where>
        order by du.distribution_user_id DESC
    </select>
    <select id="getWalletIdByDistributionUserId" resultType="long">
      select
      wallet_id
      from
      tz_distribution_user_wallet
      where distribution_user_id=#{distributionUserId}
    </select>
    <select id="getDistributionUserWalletDtoByDistributionUserId" resultType="com.yami.shop.distribution.common.dto.DistributionUserWalletDto">
        select
        unsettled_amount,
        settled_amount,
        invalid_amount,
        addup_amount
        from
        tz_distribution_user_wallet
        where distribution_user_id = #{distributionUserId}
    </select>
    <!--根据分销员id修改状态-->
    <update id="updateStateByDistributionUserId">
        update tz_distribution_user_wallet
        set state = #{state}
        where
        distribution_user_id = #{distributionUserId}
    </update>
    <update id="updateAmountByDistributionUserId">
        update tz_distribution_user_wallet
        set unsettled_amount = 0,settled_amount = 0,invalid_amount = 0,addup_amount = 0
        where
            distribution_user_id = #{distributionUserId}
    </update>
  <update id="updateSettledAmount">
      update tz_distribution_user_wallet
      set settled_amount = settled_amount + #{settledAmount}
      <if test="settledAmount > 0">
          ,addup_amount = addup_amount + #{settledAmount}
      </if>
      where distribution_user_id = #{distributionUserId}
  </update>
</mapper>
yami-shop-distribution/yami-shop-distribution-common/src/main/resources/mapper/DistributionWithdrawCashMapper.xml
New file
@@ -0,0 +1,165 @@
<?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.yami.shop.distribution.common.dao.DistributionWithdrawCashMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.distribution.common.model.DistributionWithdrawCash">
        <id column="withdraw_cash_id" jdbcType="BIGINT" property="withdrawCashId"/>
        <result column="wallet_id" jdbcType="BIGINT" property="walletId"/>
        <result column="amount" jdbcType="DECIMAL" property="amount"/>
        <result column="fee" jdbcType="DECIMAL" property="fee"/>
        <result column="type" jdbcType="TINYINT" property="type"/>
        <result column="money_flow" jdbcType="TINYINT" property="moneyFlow"/>
        <result column="merchant_order_id" jdbcType="VARCHAR" property="merchantOrderId"/>
        <result column="version" jdbcType="INTEGER" property="version"/>
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
        <result column="state" jdbcType="TINYINT" property="state"/>
    </resultMap>
    <!--提现记录-->
    <resultMap id="DistributionWithdrawCash_User" type="com.yami.shop.distribution.common.model.DistributionWithdrawCash">
        <id column="withdraw_cash_id" jdbcType="BIGINT" property="withdrawCashId"/>
        <result column="wallet_id" jdbcType="BIGINT" property="walletId"/>
        <result column="amount" jdbcType="DECIMAL" property="amount"/>
        <result column="fee" jdbcType="DECIMAL" property="fee"/>
        <result column="type" jdbcType="TINYINT" property="type"/>
        <result column="money_flow" jdbcType="TINYINT" property="moneyFlow"/>
        <result column="merchant_order_id" jdbcType="VARCHAR" property="merchantOrderId"/>
        <result column="version" jdbcType="INTEGER" property="version"/>
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
        <result column="state" jdbcType="TINYINT" property="state"/>
        <result column="biz_user_id" jdbcType="VARCHAR" property="bizUserId"/>
        <association property="distributionUser" javaType="com.yami.shop.distribution.common.vo.DistributionUserVO">
            <id column="distribution_user_id" jdbcType="BIGINT" property="distributionUserId"/>
            <result column="nick_name" jdbcType="VARCHAR" property="nickName"/>
            <result column="user_mobile" jdbcType="VARCHAR" property="userMobile"/>
        </association>
    </resultMap>
    <select id="distributionWithdrawCashsPage" resultMap="DistributionWithdrawCash_User">
        select
        dwc.*,
        du.nick_name,
        du.user_mobile
        from
        tz_distribution_withdraw_cash dwc
        left join tz_distribution_user_wallet duw on duw.wallet_id = dwc.wallet_id
        left join tz_distribution_user du on du.distribution_user_id=duw.distribution_user_id
        <where>
            <if test="shopId !=null">
                and du.shop_id=#{shopId}
            </if>
            <if test="distributionWithdrawCash.merchantOrderId !=null">
                and merchant_order_id = #{distributionWithdrawCash.merchantOrderId}
            </if>
            <if test="distributionWithdrawCash.state != null">
                <if test="distributionWithdrawCash.state &lt; 0 ">
                    and dwc.state in (2,-1)
                </if>
                <if test="distributionWithdrawCash.state &gt;= 0 ">
                    and dwc.state = #{distributionWithdrawCash.state}
                </if>
            </if>
            <if test="rangeTimeParam!=null and  rangeTimeParam.startTime !=null">
                and create_time &gt;=#{rangeTimeParam.startTime}
            </if>
            <if test="rangeTimeParam!=null and  rangeTimeParam.endTime !=null">
                and create_time &lt;=#{rangeTimeParam.endTime}
            </if>
            <if test="userMobile!=null and userMobile!=''">
                and du.user_mobile like concat('%',#{userMobile},'%')
            </if>
        </where>
        GROUP BY dwc.withdraw_cash_id
        <if test="distributionWithdrawCash.sortParam != 0 and distributionWithdrawCash.sortType != 0">
            ORDER BY
            <choose>
                <when test="distributionWithdrawCash.sortParam == 1">
                    dwc.amount
                </when>
                <when test="distributionWithdrawCash.sortParam == 2">
                    dwc.fee
                </when>
                <when test="distributionWithdrawCash.sortParam == 3">
                    create_time
                </when>
                <when test="distributionWithdrawCash.sortParam == 4">
                    dwc.update_time
                </when>
                <otherwise>
                    dwc.withdraw_cash_id
                </otherwise>
            </choose>
            <choose>
                <when test="distributionWithdrawCash.sortType == 1">
                    ASC
                </when>
                <when test="distributionWithdrawCash.sortType == 2">
                    DESC
                </when>
            </choose>
        </if>
    </select>
    <!--分销员提现明细-->
    <resultMap id="distributionWithdrawCashDto" type="com.yami.shop.distribution.common.dto.DistributionWithdrawCashDto">
        <id column="withdraw_cash_id" jdbcType="BIGINT" property="withdrawCashId"/>
        <result column="amount" jdbcType="DECIMAL" property="amount"/>
        <result column="fee" jdbcType="DECIMAL" property="fee"/>
        <result column="type" jdbcType="TINYINT" property="type"/>
        <result column="money_flow" jdbcType="TINYINT" property="moneyFlow"/>
        <result column="merchant_order_id" jdbcType="VARCHAR" property="merchantOrderId"/>
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
        <result column="state" jdbcType="TINYINT" property="state"/>
    </resultMap>
    <select id="distributionWithdrawCashDtoPageByUserId" resultMap="distributionWithdrawCashDto">
        SELECT
            withdraw_cash_id,
            amount,
            fee,
            type,
            money_flow,
            merchant_order_id,
            state,
            create_time,
            update_time
        FROM
            tz_distribution_withdraw_cash
        WHERE
                wallet_id IN ( SELECT wallet_id FROM tz_distribution_user_wallet WHERE distribution_user_id = #{distributionUserId} )
        order by create_time DESC
    </select>
    <select id="getCountByRangeTimeAndDistributionUserId" resultType="integer">
        SELECT
            count(*)
        FROM
            tz_distribution_withdraw_cash
        WHERE
                wallet_id IN ( SELECT wallet_id FROM tz_distribution_user_wallet WHERE distribution_user_id = #{distributionuserId} )
          AND
            create_time &gt;= #{rangeTimeParam.startTime}
          AND
            create_time &lt;= #{rangeTimeParam.endTime}
    </select>
    <select id="getUserTotalWithdrawCash" resultType="double">
        SELECT
            COALESCE(SUM(amount), 0)
        FROM
            tz_distribution_withdraw_cash
        WHERE wallet_id = #{walletId}
    </select>
    <update id="updateUserByDistributionUserId">
        update tz_distribution_withdraw_cash
        set `state` = 2
        where wallet_id in(
            select wallet_id from tz_distribution_user_wallet where distribution_user_id = #{distributionUserId}
            )
        and `state` = 0
    </update>
</mapper>
yami-shop-distribution/yami-shop-distribution-multishop/pom.xml
New file
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.yami.shop</groupId>
        <artifactId>yami-shop-distribution</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>yami-shop-distribution-multishop</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <modelVersion>4.0.0</modelVersion>
    <description>商城分销模块后台管理部分</description>
    <dependencies>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-distribution-common</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-security-multishop</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
    </dependencies>
</project>
yami-shop-distribution/yami-shop-distribution-multishop/src/main/java/com/yami/shop/distribution/multishop/config/SwaggerConfiguration.java
New file
@@ -0,0 +1,35 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.multishop.config;
import lombok.AllArgsConstructor;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * @author yami
 */
@Configuration("distributionSwaggerConfiguration")
@AllArgsConstructor
public class SwaggerConfiguration {
    @Bean
    public GroupedOpenApi distributionRestApi() {
        return GroupedOpenApi.builder()
                .group("分销接口")
                .packagesToScan("com.yami.shop.distribution.multishop.controller")
                .pathsToMatch("/**")
                .build();
    }
}
yami-shop-distribution/yami-shop-distribution-multishop/src/main/java/com/yami/shop/distribution/multishop/controller/DistributionProdController.java
New file
@@ -0,0 +1,376 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.multishop.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.enums.OfflineHandleEventType;
import com.yami.shop.bean.enums.ShopStatus;
import com.yami.shop.bean.model.OfflineHandleEvent;
import com.yami.shop.bean.model.Product;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.bean.model.Sku;
import com.yami.shop.bean.param.OfflineHandleEventAuditParam;
import com.yami.shop.bean.param.ProductParam;
import com.yami.shop.common.enums.StatusEnum;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ResponseEnum;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.constants.DistributionProdStateEnum;
import com.yami.shop.distribution.common.model.DistributionProd;
import com.yami.shop.distribution.common.model.DistributionProdLog;
import com.yami.shop.distribution.common.service.DistributionProdService;
import com.yami.shop.security.multishop.util.SecurityUtils;
import com.yami.shop.service.OfflineHandleEventService;
import com.yami.shop.service.ProductService;
import com.yami.shop.service.ShopDetailService;
import com.yami.shop.service.SkuService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import lombok.AllArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
 * @author lgh on 2019/04/01.
 */
@RestController
@RequestMapping("/distribution/distributionProd")
@AllArgsConstructor
@Tag(name = "商家端分销商品接口")
public class DistributionProdController {
    private final DistributionProdService distributionProdService;
    private final OfflineHandleEventService offlineHandleEventService;
    private final ProductService productService;
    private final SkuService skuService;
    private final ShopDetailService shopDetailService;
    @GetMapping("/count")
    @Operation(summary = "根据商品id计算分销商品数量" , description = "根据商品id获取")
    @Parameter(name = "prodId", description = "商品id" , required = true)
    public ServerResponseEntity<Integer> count(Long prodId) {
        return ServerResponseEntity.success(distributionProdService.count(new LambdaQueryWrapper<DistributionProd>()
                .eq(DistributionProd::getProdId, prodId)));
    }
    @GetMapping("/canDistributionProdPage")
    @Operation(summary = "分页查找可以添加到分销商品的数据")
    public ServerResponseEntity<IPage<Product>> canDistributionProdPage(@ParameterObject ProductParam product, PageParam<Product> page) {
        product.setShopId(SecurityUtils.getShopUser().getShopId());
        product.setLang(I18nMessage.getLang());
        IPage<Product> products = productService.canDistributionProdPage(page, product);
        return ServerResponseEntity.success(products);
    }
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('distribution:distributionProd:page')")
    @Operation(summary = "分页查找分销商品数据")
    @Parameters({
            @Parameter(name = "prodName", description = "商品名称" , required = true),
            @Parameter(name = "state", description = "分销商品状态(0:商家下架 1:商家上架 2:违规下架 3:平台审核)" , required = true)
    })
    public ServerResponseEntity<IPage<DistributionProd>> page(@ParameterObject DistributionProd distributionProd, PageParam<DistributionProd> page,
                                                        String prodName, Integer state) {
        distributionProd.setShopId(SecurityUtils.getShopUser().getShopId());
        distributionProd.setState(state);
        IPage<DistributionProd> list = distributionProdService.distributionProdsPage(page, distributionProd, prodName);
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/info/{id}")
    @Operation(summary = "根据分销商品id查看分销商品数据" , description = "根据分销商品id获取")
    @Parameter(name = "id", description = "分销商品id" , required = true)
    public ServerResponseEntity<DistributionProd> info(@PathVariable("id") Long id) {
        DistributionProd distributionProd = distributionProdService.getById(id);
        return ServerResponseEntity.success(distributionProd);
    }
    @PostMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionProd:save')")
    @Operation(summary = "保存分销商品")
    public ServerResponseEntity<Void> save(@RequestBody @Valid DistributionProd distributionProd) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        distributionProd.setShopId(shopId);
        // 防止重复提交
        int count = distributionProdService.count(new LambdaQueryWrapper<DistributionProd>()
                .eq(DistributionProd::getProdId, distributionProd.getProdId())
                .eq(DistributionProd::getShopId, distributionProd.getShopId()));
        if (count > 0) {
            // 分销商品已经存在
            throw new YamiShopBindException("yami.distribution.prod.exist");
        }
        // 校验数据
        validateDistributionProd(distributionProd, shopId, true);
        setDefaultAwardNumbers(distributionProd);
        distributionProdService.save(distributionProd);
        distributionProdService.removeDistributionProdPoCacheByProdId(distributionProd.getProdId());
        return ServerResponseEntity.success();
    }
    @PutMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionProd:update')")
    @Operation(summary = "修改分销商品")
    public ServerResponseEntity<Void> update(@RequestBody @Valid DistributionProd distributionProd) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        // 校验数据
        validateDistributionProd(distributionProd, shopId, false);
        setDefaultAwardNumbers(distributionProd);
        distributionProdService.updateById(distributionProd);
        distributionProdService.removeDistributionProdPoCacheByProdId(distributionProd.getProdId());
        return ServerResponseEntity.success();
    }
    @DeleteMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionProd:delete')")
    @Operation(summary = "根据分销商品id列表批量删除分销商品")
    @Parameter(name = "ids", description = "分销商品ids" , required = true)
    public ServerResponseEntity<Void> delete(@RequestBody List<Long> ids) {
        distributionProdService.removeByIds(ids);
        return ServerResponseEntity.success();
    }
    private void setDefaultAwardNumbers(@Valid @RequestBody DistributionProd distributionProd) {
        if (StrUtil.isBlank(distributionProd.getParentAwardNumbers())) {
            // 固定奖励
            if (Objects.equals(distributionProd.getAwardNumberSet(), 0)) {
                distributionProd.setParentAwardNumbers("0");
            } else {
                distributionProd.setParentAwardNumbers(null);
            }
        }
        if(Objects.equals(distributionProd.getParentAwardSet(),0)){
            distributionProd.setParentAwardNumbers("0");
        }
        if (StrUtil.isBlank(distributionProd.getAwardNumbers())) {
            distributionProd.setAwardNumbers("0");
            // 固定奖励
            if (Objects.equals(distributionProd.getAwardNumberSet(), 0)) {
                distributionProd.setAwardNumbers("0");
            } else {
                distributionProd.setAwardNumbers(null);
            }
        }
        distributionProd.setUpdateTime(new Date());
    }
    @GetMapping("/getOfflineEventByDistProdId/{distributionProdId}")
    @Operation(summary = "根据分销商品id获取下线信息")
    @Parameter(name = "distributionProdId", description = "分销商品id" , required = true)
    public ServerResponseEntity<OfflineHandleEvent> getOfflineEventByDistProdId(@PathVariable("distributionProdId") Long distributionProdId) {
        OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.DISTRIBUTION_PROD.getValue(), distributionProdId);
        return ServerResponseEntity.success(offlineHandleEvent);
    }
    @PostMapping("/auditApply")
    @PreAuthorize("@pms.hasPermission('distribution:distributionProd:auditApply')")
    @Operation(summary = "违规商品提交审核")
    public ServerResponseEntity<Void> auditApply(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) {
        DistributionProd distributionProd = distributionProdService.getById(offlineHandleEventAuditParam.getHandleId());
        if (distributionProd == null) {
            // 未找到分销商品信息信息
            throw new YamiShopBindException("yami.distribution.prod.exist.error");
        }
        distributionProdService.auditApply(offlineHandleEventAuditParam.getEventId(), offlineHandleEventAuditParam.getHandleId(), offlineHandleEventAuditParam.getReapplyReason());
        return ServerResponseEntity.success();
    }
    @GetMapping("/getDistributionProdLogPage")
    @Operation(summary = "获取分销商品销售记录信息")
    public ServerResponseEntity<IPage<DistributionProdLog>> getDistributionProdLogPage(@ParameterObject DistributionProdLog distributionProdLog,
                                                                                 PageParam<DistributionProdLog> page) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        distributionProdLog.setShopId(shopId);
        IPage<DistributionProdLog> distributionProdLogL = distributionProdService.getDistributionProdLogPage(page, distributionProdLog);
        return ServerResponseEntity.success(distributionProdLogL);
    }
    /**
     * 校验数据
     */
    private void validateDistributionProd(DistributionProd distributionProd, Long shopId, Boolean createOrUpdate) {
        List<Sku> skus = skuService.listByProdId(distributionProd.getProdId(), I18nMessage.getLang());
        if (CollUtil.isEmpty(skus)) {
            // 未找到此商品
            throw new YamiShopBindException("yami.product.not.exist");
        }
        double maxPrice = 0;
        for (Sku sku : skus) {
            if (sku.getPrice() > maxPrice) {
                maxPrice = sku.getPrice();
            }
        }
        Product product = productService.getProductByProdId(distributionProd.getProdId(), I18nMessage.getLang());
        if (CollUtil.isEmpty(skus) || Objects.isNull(product)) {
            // 未找到此商品
            throw new YamiShopBindException("yami.product.not.exist");
        }
        // 检查店铺信息
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId);
        if (Objects.isNull(shopDetail)) {
            throw new YamiShopBindException("找不到店铺信息");
        }
        if (!Objects.equals(shopDetail.getShopStatus(), ShopStatus.STOP.value()) && !Objects.equals(shopDetail.getShopStatus(), ShopStatus.OPEN.value())) {
            // 店铺处于违规下架状态时
            if (createOrUpdate) {
                // 不能新增分销商品
                throw new YamiShopBindException("店铺处于违规下架状态,不能新增分销商品");
            } else {
                if (Objects.equals(distributionProd.getState(), DistributionProdStateEnum.PUT_ON.getValue())) {
                    // 不能把分销商品更新为上架状态
                    throw new YamiShopBindException("店铺处于违规下架状态,不能将分销商品置为上架状态");
                }
            }
        }
        if (!createOrUpdate) {
            if (Objects.equals(distributionProd.getState(), 1) && !Objects.equals(product.getStatus(), StatusEnum.ENABLE.value())) {
                // 商品不处于上线状态,分销商品不能进行上架操作
                throw new YamiShopBindException("yami.product.off.not.enable.disProduct");
            }
            DistributionProd dbDistributionProd = distributionProdService.getById(distributionProd.getDistributionProdId());
            if (Objects.isNull(dbDistributionProd)) {
                // 分销商品已经被删除
                throw new YamiShopBindException("当前分销商品已经被删除");
            }
            if (!Objects.equals(shopId, dbDistributionProd.getShopId())) {
                //没有权限
                throw new YamiShopBindException(ResponseEnum.UNAUTHORIZED);
            }
            if (Objects.equals(dbDistributionProd.getState(), DistributionProdStateEnum.OFFLINE.getValue()) || Objects.equals(dbDistributionProd.getState(), DistributionProdStateEnum.WAIT_AUDIT.getValue())) {
                // 分销商品处于违规下架状态,商家不能直接修改状态
                distributionProd.setState(dbDistributionProd.getState());
            }
        } else {
            // 如果商品不是上架状态,则把分销商品置为下架状态
            distributionProd.setState(Objects.equals(product.getStatus(), StatusEnum.ENABLE.value()) ? distributionProd.getState() : 0);
        }
        // 如果不使用需要校验
        if (distributionProd.getDefaultReward() == 1) {
            return;
        }
        int hundred = 100;
        directPushReward(distributionProd, maxPrice, hundred);
        // 查看是否有开启邀请人奖励
        if (distributionProd.getParentAwardSet() == 0) {
            return;
        }
        interPushBonus(distributionProd, maxPrice, hundred);
    }
    private void interPushBonus(DistributionProd distributionProd, double maxPrice, int hundred) {
        double parentAwardNum = Double.parseDouble(distributionProd.getParentAwardNumbers());
        double awardNum = Double.parseDouble(distributionProd.getAwardNumbers());
        // 按比例
        if (distributionProd.getAwardProportion() == 0) {
            // 奖励数额设置(0 固定奖励,1 根据等级奖励)
            if (distributionProd.getAwardNumberSet() == 0) {
                if (Double.parseDouble(distributionProd.getParentAwardNumbers()) >= hundred) {
                    // 邀请人固定奖励比例设置不能超过100%
                    throw new YamiShopBindException("yami.distribution.prod.parent.award");
                }
                if (Arith.add(parentAwardNum, awardNum) >= hundred) {
                    // 奖励设置不能大于等于商品最高价或者100%
                    throw new YamiShopBindException("yami.distribution.prod.price.check");
                }
            }
            if (distributionProd.getAwardNumberSet() == 1) {
                List<String> awardList = JSONUtil.parseArray(distributionProd.getParentAwardNumbers()).toList(String.class);
                List<Double> list = awardList.stream().map(Double::parseDouble).collect(Collectors.toList());
                if (list.stream().anyMatch(item -> item > hundred)) {
                    // 邀请人等级奖励比例设置不能超过100%
                    throw new YamiShopBindException("yami.distribution.prod.parent.level");
                }
            }
        }
        // 按金额
        if (distributionProd.getAwardProportion() == 1) {
            // 奖励数额设置(0 固定奖励,1 根据等级奖励)
            if (distributionProd.getAwardNumberSet() == 0) {
                if (Double.parseDouble(distributionProd.getParentAwardNumbers()) > maxPrice) {
                    // 邀请人固定奖励不能大于或等于商品的最高价
                    throw new YamiShopBindException("yami.distribution.prod.parentAward.check");
                }
                if (Arith.add(parentAwardNum, awardNum) >= maxPrice) {
                    // 奖励设置不能大于等于商品最高价或者100%
                    throw new YamiShopBindException("yami.distribution.prod.price.check");
                }
            }
            if (distributionProd.getAwardNumberSet() == 1) {
                List<String> awardList = JSONUtil.parseArray(distributionProd.getParentAwardNumbers()).toList(String.class);
                List<Double> list = awardList.stream().map(Double::parseDouble).collect(Collectors.toList());
                if (list.stream().anyMatch(item -> item > maxPrice)) {
                    // 邀请人等级奖励不能大于或等于商品的最高价
                    throw new YamiShopBindException("yami.distribution.prod.parentLevel.check");
                }
            }
        }
    }
    private void directPushReward(DistributionProd distributionProd, double maxPrice, int hundred) {
        // 按比例
        if (distributionProd.getAwardProportion() == 0) {
            // 奖励数额设置(0 固定奖励,1 根据等级奖励)
            if (distributionProd.getAwardNumberSet() == 0) {
                if (Double.parseDouble(distributionProd.getAwardNumbers()) >= hundred) {
                    // 固定奖励比例设置不能超过100%
                    throw new YamiShopBindException("yami.distribution.prod.award");
                }
            }
            if (distributionProd.getAwardNumberSet() == 1) {
                List<String> awardList = JSONUtil.parseArray(distributionProd.getAwardNumbers()).toList(String.class);
                List<Double> list = awardList.stream().map(Double::parseDouble).collect(Collectors.toList());
                if (list.stream().anyMatch(item -> item > hundred)) {
                    // 等级奖励比例设置不能超过100%
                    throw new YamiShopBindException("yami.distribution.prod.level");
                }
            }
        }
        // 按金额
        if (distributionProd.getAwardProportion() == 1) {
            // 奖励数额设置(0 固定奖励,1 根据等级奖励)
            if (distributionProd.getAwardNumberSet() == 0) {
                if (Double.parseDouble(distributionProd.getAwardNumbers()) >= maxPrice) {
                    // 固定奖励设置不能大于等于商品的最高价
                    throw new YamiShopBindException("yami.distribution.prod.award.check");
                }
            }
            if (distributionProd.getAwardNumberSet() == 1) {
                List<String> awardList = JSONUtil.parseArray(distributionProd.getAwardNumbers()).toList(String.class);
                List<Double> list = awardList.stream().map(Double::parseDouble).collect(Collectors.toList());
                if (list.stream().anyMatch(item -> item > maxPrice)) {
                    // 等级奖励设置不能超过商品的最低价
                    throw new YamiShopBindException("yami.distribution.prod.level.check");
                }
            }
        }
    }
}
yami-shop-distribution/yami-shop-distribution-multishop/src/main/java/com/yami/shop/distribution/multishop/listener/OrderRefundListener.java
New file
@@ -0,0 +1,117 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.multishop.listener;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.dto.OrderRefundDto;
import com.yami.shop.bean.event.OrderRefundSuccessEvent;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.Arith;
import com.yami.shop.distribution.common.constants.DistributionAudit;
import com.yami.shop.distribution.common.constants.DistributionUserIncomeStateEnum;
import com.yami.shop.distribution.common.dao.DistributionUserIncomeMapper;
import com.yami.shop.distribution.common.dao.DistributionUserWalletMapper;
import com.yami.shop.distribution.common.model.DistributionUserIncome;
import com.yami.shop.distribution.common.model.DistributionUserWallet;
import com.yami.shop.distribution.common.model.DistributionUserWalletBill;
import com.yami.shop.distribution.common.service.DistributionUserIncomeService;
import com.yami.shop.distribution.common.service.DistributionUserWalletBillService;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 退款订单监听
 * @author yami
 */
@Component("orderRefundListener")
@AllArgsConstructor
public class OrderRefundListener {
    private final DistributionUserIncomeMapper distributionUserIncomeMapper;
    private final DistributionUserWalletMapper distributionUserWalletMapper;
    private final DistributionUserWalletBillService distributionUserWalletBillService;
    private final DistributionUserIncomeService distributionUserIncomeService;
    @EventListener(OrderRefundSuccessEvent.class)
    public void distributionOrderRefundSuccessEvent(OrderRefundSuccessEvent event) {
        OrderRefundDto orderRefundDto = event.getOrderRefundDto();
        if (CollectionUtils.isEmpty(orderRefundDto.getOrderItems())) {
            return;
        }
        // 查看是否有分销订单
        List<OrderItem> distributionOrderItemList = orderRefundDto.getOrderItems().stream().filter(orderItem -> StrUtil.isNotEmpty(orderItem.getDistributionCardNo())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(distributionOrderItemList)) {
            return;
        }
        // 处理分销订单
        List<DistributionUserIncome> updateBatchDistributionUserIncomeList = new ArrayList<>();
        List<DistributionUserWalletBill> saveBatchDistributionWalletBillList = new ArrayList<>();
        // 更新订单收入信息
        for (OrderItem orderItem : distributionOrderItemList) {
            // 减少分销员的待结算金额,添加已失效金额
            List<DistributionUserIncome> distributionUserIncomeList = distributionUserIncomeMapper.selectList(new LambdaQueryWrapper<DistributionUserIncome>().eq(DistributionUserIncome::getOrderItemId, orderItem.getOrderItemId()).eq(DistributionUserIncome::getState, 1));
            for (DistributionUserIncome distributionUserIncome : distributionUserIncomeList) {
                DistributionUserWallet distributionUserWallet = distributionUserWalletMapper.selectById(distributionUserIncome.getWalletId());
                if (distributionUserWallet == null) {
                    // 未找到分销员信息
                    throw new YamiShopBindException("yami.distribution.exist.error");
                }
                // 添加分销钱包日志
                distributionUserWallet.setUnsettledAmount(Arith.sub(distributionUserWallet.getUnsettledAmount(), distributionUserIncome.getIncomeAmount()));
                distributionUserWallet.setInvalidAmount(Arith.add(distributionUserWallet.getInvalidAmount(), distributionUserIncome.getIncomeAmount()));
                distributionUserWalletMapper.updateById(distributionUserWallet);
                // 更新收入状态
                updateBatchDistributionUserIncomeList.add(distributionUserIncome);
                // 添加钱包变动日志
                saveBatchDistributionWalletBillList.add(new DistributionUserWalletBill(distributionUserWallet, "分销订单退款失效奖励","Distribution order refund lapse bonus", -distributionUserIncome.getIncomeAmount(), 0.0, distributionUserIncome.getIncomeAmount(), 0.0, 0));
            }
        }
        // 批量更新分销收入状态
        if (CollectionUtils.isNotEmpty(updateBatchDistributionUserIncomeList)) {
            // 修改失效状态,如果
            updateBatchDistributionUserIncomeList.forEach( item -> {
                item.setState(DistributionUserIncomeStateEnum.INVALID.getValue());
                if (item.getReson().equals(DistributionAudit.INCOME_ZERO.getValue())){
                    item.setReson(DistributionAudit.INCOME_TWO.getValue());
                }
            });
            if (distributionUserIncomeService.updateBatchState(updateBatchDistributionUserIncomeList) < 0){
                // 批量更新分销收入状态失败
                throw new YamiShopBindException("yami.distribution.batch.update.income");
            }
//            if (distributionUserIncomeMapper.updateBatchState(updateBatchDistributionUserIncomeList, DistributionUserIncomeStateEnum.INVALID.getValue(), DistributionAudit.INCOME_TWO.getValue()) <= 0) {
//                // 批量更新分销收入状态失败
//                throw new YamiShopBindException("yami.distribution.batch.update.income");
//            }
        }
        // 批量添加钱包变动日志
        if (CollectionUtils.isNotEmpty(saveBatchDistributionWalletBillList)) {
            distributionUserWalletBillService.saveBatch(saveBatchDistributionWalletBillList);
        }
    }
}
yami-shop-distribution/yami-shop-distribution-platform/pom.xml
New file
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.yami.shop</groupId>
        <artifactId>yami-shop-distribution</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>yami-shop-distribution-platform</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <modelVersion>4.0.0</modelVersion>
    <description>商城分销模块后台管理部分</description>
    <dependencies>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-distribution-common</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-security-platform</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
    </dependencies>
</project>
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/config/SwaggerConfiguration.java
New file
@@ -0,0 +1,34 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.platform.config;
import lombok.AllArgsConstructor;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * @author yami
 */
@Configuration("distributionSwaggerConfiguration")
@AllArgsConstructor
public class SwaggerConfiguration {
    @Bean
    public GroupedOpenApi distributionRestApi() {
        return GroupedOpenApi.builder()
                .group("分销接口")
                .packagesToScan("com.yami.shop.distribution.platform.controller")
                .pathsToMatch("/**")
                .build();
    }
}
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionAuditingController.java
New file
@@ -0,0 +1,88 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.platform.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.dto.DistributionAuditingDto;
import com.yami.shop.distribution.common.model.DistributionAuditing;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import com.yami.shop.distribution.common.service.DistributionAuditingService;
import com.yami.shop.distribution.common.service.DistributionUserService;
import com.yami.shop.security.platform.util.SecurityUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Date;
/**
 * @author lgh on 2019/04/01.
 */
@RestController
@RequestMapping("/distribution/distributionAuditing")
@Tag(name = "平台端分销员审核接口")
public class DistributionAuditingController {
    @Autowired
    private DistributionAuditingService distributionAuditingService;
    @Autowired
    private DistributionUserService distributionUserService;
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('distribution:distributionAuditing:page')")
    @Operation(summary = "分页查看分销员审核信息")
    @Parameters({
            @Parameter(name = "userMobile", description = "分销员手机号码" ),
            @Parameter(name = "startExpenseNumber", description = "最低订单数量" ),
            @Parameter(name = "endExpenseNumber", description = "最高订单数量" ),
            @Parameter(name = "startPayAmount", description = "最低消费金额" ),
            @Parameter(name = "endPayAmount", description = "最高消费金额" )
    })
    public ServerResponseEntity<IPage<DistributionAuditingDto>> page(@ParameterObject DistributionAuditing distributionAuditing, @ParameterObject RangeTimeParam rangeTimeParam,
                                                                     String userMobile, Integer startExpenseNumber, Integer endExpenseNumber,
                                                                     Double startPayAmount, Double endPayAmount, PageParam<DistributionAuditing> page) {
        IPage<DistributionAuditingDto> list = distributionAuditingService.distributionAuditingPage(page, distributionAuditing, rangeTimeParam, startExpenseNumber, endExpenseNumber, startPayAmount, endPayAmount, userMobile);
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/info/{id}")
    @PreAuthorize("@pms.hasPermission('distribution:distributionAuditing:info')")
    @Operation(summary = "根据分销员申请id获取分销员申请信息")
    @Parameter(name = "id", description = "分销员申请信息id" )
    public ServerResponseEntity<DistributionAuditing> info(@PathVariable("id") Long id) {
        DistributionAuditing distributionAuditing = distributionAuditingService.getById(id);
        return ServerResponseEntity.success(distributionAuditing);
    }
    /**
     * 审核
     */
    @PutMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionAuditing:update')")
    @Operation(summary = "审核分销员")
    public ServerResponseEntity<Void> update(@RequestBody @Valid DistributionAuditing distributionAuditing) {
        distributionAuditing.setUpdateTime(new Date());
        distributionAuditing.setModifier(SecurityUtils.getSysUser().getUserId());
        distributionAuditingService.examine(distributionAuditing);
        DistributionUser distributionUser = distributionUserService.getById(distributionAuditing.getDistributionUserId());
        distributionUserService.removeCacheByUserIdAndShopId(distributionUser.getUserId(), distributionAuditing.getShopId());
        distributionUserService.removeCacheByCardNo(distributionUser.getCardNo());
        return ServerResponseEntity.success();
    }
}
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionConfigController.java
New file
@@ -0,0 +1,111 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.platform.controller;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.model.Product;
import com.yami.shop.bean.param.ProductParam;
import com.yami.shop.common.bean.SysConfig;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.Json;
import com.yami.shop.distribution.common.constants.DistributionAudit;
import com.yami.shop.distribution.common.dto.DistributionConfigDTO;
import com.yami.shop.distribution.common.dto.DistributionRecruitConfigDTO;
import com.yami.shop.distribution.common.vo.DistributionConfigVO;
import com.yami.shop.distribution.common.vo.DistributionRecruitConfigVO;
import com.yami.shop.service.ProductService;
import com.yami.shop.service.SysConfigService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import java.util.Objects;
/**
 * @author cl
 * @date 2021-08-06 14:18:03
 */
@RestController
@RequestMapping("/platform/distributionConfig")
@Tag(name = "平台端分销配置接口")
public class DistributionConfigController {
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private ProductService productService;
    @GetMapping("/info")
    @Operation(summary = "获取分销配置信息")
    public ServerResponseEntity<DistributionConfigVO> info() {
        DistributionConfigVO distributionConfigVO = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_CONFIG, DistributionConfigVO.class);
        List<Long> prodIds = distributionConfigVO.getProdIdList();
        if (CollUtil.isEmpty(prodIds)) {
            return ServerResponseEntity.success(distributionConfigVO);
        }
        ProductParam product = new ProductParam();
        product.setProdIds(prodIds);
        List<Product> products = productService.listProdByIdsAndType(product);
        distributionConfigVO.setProductVOList(products);
        return ServerResponseEntity.success(distributionConfigVO);
    }
    @GetMapping("/recruit_info")
    @Operation(summary = "获取分销推广配置信息")
    public ServerResponseEntity<DistributionRecruitConfigVO> recruitInfo() {
        DistributionRecruitConfigVO recruitConfigVO = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_RECRUIT_CONFIG, DistributionRecruitConfigVO.class);
        return ServerResponseEntity.success(recruitConfigVO);
    }
    @PostMapping
    @Operation(summary = "保存分销配置")
    public ServerResponseEntity<Void> save(@RequestBody @Valid DistributionConfigDTO distributionConfigDTO) {
        //提现发放方式: 0.无需审核直接发放,1.审核后系统发放,2.审核后人工发放 默认:审核后系统发放
        if (Objects.isNull(distributionConfigDTO.getWithdrawal())){
            distributionConfigDTO.setWithdrawal(DistributionAudit.TWithdrawals_TWO.getValue());
        }
        SysConfig config = new SysConfig();
        String paramValue = Json.toJsonString(distributionConfigDTO);
        config.setParamKey(Constant.DISTRIBUTION_CONFIG);
        config.setParamValue(paramValue);
        config.setRemark(Constant.DISTRIBUTION_REMARKS);
        if (sysConfigService.count(new LambdaQueryWrapper<SysConfig>()
                .eq(SysConfig::getParamKey, config.getParamKey())) > 0) {
            sysConfigService.updateValueByKey(config.getParamKey(), config.getParamValue());
        } else {
            sysConfigService.save(config);
        }
        sysConfigService.removeSysConfig(config.getParamKey());
        return ServerResponseEntity.success();
    }
    @PostMapping("/recruit")
    @Operation(summary = "保存分销招募推广配置")
    public ServerResponseEntity<Void> saveRecruit(@RequestBody @Valid DistributionRecruitConfigDTO distributionRecruitConfigDTO) {
        SysConfig config = new SysConfig();
        String paramValue = Json.toJsonString(distributionRecruitConfigDTO);
        config.setParamKey(Constant.DISTRIBUTION_RECRUIT_CONFIG);
        config.setParamValue(paramValue);
        config.setRemark(Constant.DISTRIBUTION_RECRUIT_REMARKS);
        if (sysConfigService.count(new LambdaQueryWrapper<SysConfig>()
                .eq(SysConfig::getParamKey, config.getParamKey())) > 0) {
            sysConfigService.updateValueByKey(config.getParamKey(), config.getParamValue());
        } else {
            sysConfigService.save(config);
        }
        sysConfigService.removeSysConfig(config.getParamKey());
        return ServerResponseEntity.success();
    }
}
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionMsgController.java
New file
@@ -0,0 +1,89 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.platform.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.model.DistributionMsg;
import com.yami.shop.distribution.common.service.DistributionMsgService;
import com.yami.shop.security.platform.util.SecurityUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
/**
 * @author lgh on 2019/04/01.
 */
@RestController
@RequestMapping("/distribution/distributionMsg")
@Tag(name = "平台端分销通知接口")
public class DistributionMsgController {
    @Autowired
    private DistributionMsgService distributionMsgService;
    @GetMapping("/page")
    @Operation(summary = "分页获取分销通知列表")
    @PreAuthorize("@pms.hasPermission('distribution:distributionMsg:page')")
    public ServerResponseEntity<IPage<DistributionMsg>> page(@ParameterObject DistributionMsg distributionMsg, PageParam page) {
        IPage<DistributionMsg> list = distributionMsgService.getDistributionMsgsAndSysUserPage(page, distributionMsg);
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/info/{id}")
    @PreAuthorize("@pms.hasPermission('distribution:distributionMsg:info')")
    @Operation(summary = "根据分销通知id查看分销通知信息")
    @Parameter(name = "id", description = "分销通知id" , required = true)
    public ServerResponseEntity<DistributionMsg> info(@PathVariable("id") Long id) {
        DistributionMsg distributionMsg = distributionMsgService.getById(id);
        return ServerResponseEntity.success(distributionMsg);
    }
    @PostMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionMsg:save')")
    @Operation(summary = "保存分销通知信息")
    public ServerResponseEntity<Void> save(@RequestBody @Valid DistributionMsg distributionMsg) {
        distributionMsg.setUpdateTime(new Date());
        distributionMsg.setModifier(SecurityUtils.getSysUser().getUserId());
        distributionMsg.setLevel(1);
        distributionMsg.setShopId(Constant.PLATFORM_SHOP_ID);
        distributionMsgService.save(distributionMsg);
        return ServerResponseEntity.success();
    }
    @PutMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionMsg:update')")
    @Operation(summary = "修改分销通知信息")
    public ServerResponseEntity<Void> update(@RequestBody @Valid DistributionMsg distributionMsg) {
        distributionMsg.setUpdateTime(new Date());
        distributionMsg.setModifier(SecurityUtils.getSysUser().getUserId());
        distributionMsgService.updateById(distributionMsg);
        return ServerResponseEntity.success();
    }
    @DeleteMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionMsg:delete')")
    @Operation(summary = "根据分销通知id列表批量删除分销通知信息")
    @Parameter(name = "ids", description = "分销通知id" , required = true)
    public ServerResponseEntity<Void> delete(@RequestBody List<Long> ids) {
        distributionMsgService.removeByIds(ids);
        return ServerResponseEntity.success();
    }
}
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionProdBindController.java
New file
@@ -0,0 +1,75 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.platform.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.model.DistributionProdBind;
import com.yami.shop.distribution.common.service.DistributionProdBindService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
 * @author xwc
 * @date 2019-04-22 10:01:44
 */
@RestController
@RequestMapping("/distribution/distributionProdBind")
@Tag(name = "平台端分销商品绑定表接口")
public class DistributionProdBindController {
    @Autowired
    private DistributionProdBindService distributionProdBindService;
    @GetMapping("/page")
    @Operation(summary = "分页获取分销商品绑定信息列表")
    public ServerResponseEntity<IPage<DistributionProdBind>> getDistributionProdBindPage(PageParam<DistributionProdBind> page,
                                                                                         @ParameterObject DistributionProdBind distributionProdBind) {
        return ServerResponseEntity.success(distributionProdBindService.page(page, new LambdaQueryWrapper<DistributionProdBind>()));
    }
    @GetMapping("/info/{id}")
    @Operation(summary = "通过id查询分销商品绑定表")
    @Parameter(name = "id", description = "分销商品绑定id" , required = true)
    public ServerResponseEntity<DistributionProdBind> getById(@PathVariable("id") Long id) {
        return ServerResponseEntity.success(distributionProdBindService.getById(id));
    }
    @PostMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionProdBind:save')")
    @Operation(summary = "新增分销商品绑定表")
    public ServerResponseEntity<Boolean> save(@RequestBody @Valid DistributionProdBind distributionProdBind) {
        return ServerResponseEntity.success(distributionProdBindService.save(distributionProdBind));
    }
    @PutMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionProdBind:update')")
    @Operation(summary = "修改分销商品绑定表")
    public ServerResponseEntity<Boolean> updateById(@RequestBody @Valid DistributionProdBind distributionProdBind) {
        return ServerResponseEntity.success(distributionProdBindService.updateById(distributionProdBind));
    }
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('distribution:distributionProdBind:delete')")
    @Operation(summary = "通过id删除分销商品绑定表")
    @Parameter(name = "id", description = "分销商品绑定id" , required = true)
    public ServerResponseEntity<Boolean> removeById(@PathVariable Long id) {
        return ServerResponseEntity.success(distributionProdBindService.removeById(id));
    }
}
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionProdController.java
New file
@@ -0,0 +1,193 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.platform.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.enums.OfflineHandleEventType;
import com.yami.shop.bean.model.OfflineHandleEvent;
import com.yami.shop.bean.param.OfflineHandleEventAuditParam;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.model.DistributionProd;
import com.yami.shop.distribution.common.model.DistributionProdLog;
import com.yami.shop.distribution.common.service.DistributionProdService;
import com.yami.shop.security.platform.model.YamiSysUser;
import com.yami.shop.security.platform.util.SecurityUtils;
import com.yami.shop.service.OfflineHandleEventService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import lombok.AllArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * @author lgh on 2019/04/01.
 */
@RestController
@RequestMapping("/platform/distributionProd")
@AllArgsConstructor
@Tag(name = "平台端分销商品接口")
public class DistributionProdController {
    private final DistributionProdService distributionProdService;
    private final OfflineHandleEventService offlineHandleEventService;
    @GetMapping("/count")
    @PreAuthorize("@pms.hasPermission('platform:distributionProd:info')")
    @Operation(summary = "根据商品id计算分销商品数量" , description = "根据商品id获取")
    @Parameter(name = "prodId", description = "商品id" , required = true)
    public ServerResponseEntity<Integer> count(Long prodId) {
        return ServerResponseEntity.success(distributionProdService.count(new LambdaQueryWrapper<DistributionProd>()
                .eq(DistributionProd::getProdId, prodId)));
    }
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('platform:distributionProd:page')")
    @Operation(summary = "分页查找分销商品数据")
    @Parameters({
            @Parameter(name = "prodName", description = "商品名称" , required = true),
            @Parameter(name = "state", description = "分销商品状态(0:商家下架 1:商家上架 2:违规下架 3:平台审核)" , required = true)
    })
    public ServerResponseEntity<IPage<DistributionProd>> page(@ParameterObject DistributionProd distributionProd, PageParam<DistributionProd> page,
                                                              String prodName, Integer state) {
        distributionProd.setState(state);
        IPage<DistributionProd> list = distributionProdService.distributionProdsPage(page, distributionProd, prodName);
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/info/{id}")
    @PreAuthorize("@pms.hasPermission('platform:distributionProd:info')")
    @Operation(summary = "根据分销商品id查看分销商品数据" , description = "根据分销商品id获取")
    @Parameter(name = "id", description = "分销商品id" , required = true)
    public ServerResponseEntity<DistributionProd> info(@PathVariable("id") Long id) {
        DistributionProd distributionProd = distributionProdService.getById(id);
        return ServerResponseEntity.success(distributionProd);
    }
    @PostMapping
    @PreAuthorize("@pms.hasPermission('platform:distributionProd:save')")
    @Operation(summary = "保存分销商品")
    public ServerResponseEntity<Void> save(@RequestBody @Valid DistributionProd distributionProd) {
        distributionProd.setShopId(Constant.PLATFORM_SHOP_ID);
        distributionProd.setModifier(SecurityUtils.getSysUser().getUserId());
        setDefaultAwardNumbers(distributionProd);
        distributionProdService.save(distributionProd);
        distributionProdService.removeDistributionProdPoCacheByProdId(distributionProd.getProdId());
        return ServerResponseEntity.success();
    }
    @PutMapping
    @PreAuthorize("@pms.hasPermission('platform:distributionProd:update')")
    @Operation(summary = "修改分销商品")
    public ServerResponseEntity<Void> update(@RequestBody @Valid DistributionProd distributionProd) {
        YamiSysUser sysUser = SecurityUtils.getSysUser();
        if (!Objects.equals(distributionProd.getShopId(), Constant.PLATFORM_SHOP_ID)) {
            // 您无权对此活动商品进行操作
            throw new YamiShopBindException("yami.activity.prod.no.auth");
        }
        distributionProd.setModifier(sysUser.getUserId());
        setDefaultAwardNumbers(distributionProd);
        distributionProdService.updateById(distributionProd);
        distributionProdService.removeDistributionProdPoCacheByProdId(distributionProd.getProdId());
        return ServerResponseEntity.success();
    }
    @DeleteMapping
    @PreAuthorize("@pms.hasPermission('platform:distributionProd:delete')")
    @Operation(summary = "根据分销商品id列表批量删除分销商品")
    @Parameter(name = "ids", description = "分销商品ids" , required = true)
    public ServerResponseEntity<Void> delete(@RequestBody List<Long> ids) {
        distributionProdService.removeByIds(ids);
        return ServerResponseEntity.success();
    }
    private void setDefaultAwardNumbers(@Valid @RequestBody DistributionProd distributionProd) {
        distributionProd.setUpdateTime(new Date());
        if (StrUtil.isBlank(distributionProd.getParentAwardNumbers())) {
            // 固定奖励
            if (Objects.equals(distributionProd.getAwardNumberSet(), 0)) {
                distributionProd.setParentAwardNumbers("0");
            } else {
                distributionProd.setParentAwardNumbers(null);
            }
        }
        if (StrUtil.isBlank(distributionProd.getAwardNumbers())) {
            distributionProd.setAwardNumbers("0");
            // 固定奖励
            if (Objects.equals(distributionProd.getAwardNumberSet(), 0)) {
                distributionProd.setAwardNumbers("0");
            } else {
                distributionProd.setAwardNumbers(null);
            }
        }
    }
    @GetMapping("/getOfflineEventByDistProdId/{distributionProdId}")
    @PreAuthorize("@pms.hasPermission('platform:distributionProd:info')")
    @Operation(summary = "根据分销商品id获取下线信息")
    @Parameter(name = "distributionProdId", description = "分销商品id" , required = true)
    public ServerResponseEntity<OfflineHandleEvent> getOfflineEventByDistProdId(@PathVariable("distributionProdId") Long distributionProdId) {
        OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.DISTRIBUTION_PROD.getValue(), distributionProdId);
        return ServerResponseEntity.success(offlineHandleEvent);
    }
    @PostMapping("/offline")
    @PreAuthorize("@pms.hasPermission('platform:distributionProd:update')")
    @Operation(summary = "下线分销商品")
    public ServerResponseEntity<Void> offline(@RequestBody OfflineHandleEvent offlineHandleEvent) {
        Long sysUserId = SecurityUtils.getSysUser().getUserId();
        DistributionProd distributionProd = distributionProdService.getById(offlineHandleEvent.getHandleId());
        if (distributionProd == null) {
            // 未找到该分销商品信息
            throw new YamiShopBindException("yami.distribution.prod.exist.error");
        }
        distributionProdService.offline(distributionProd, offlineHandleEvent.getOfflineReason(), sysUserId);
        return ServerResponseEntity.success();
    }
    @PostMapping("/auditDistributionProd")
    @PreAuthorize("@pms.hasPermission('platform:distributionProd:update')")
    @Operation(summary = "分销商品审核")
    public ServerResponseEntity<Void> auditDistributionProd(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) {
        Long sysUserId = SecurityUtils.getSysUser().getUserId();
        DistributionProd distributionProd = distributionProdService.getById(offlineHandleEventAuditParam.getHandleId());
        if (distributionProd == null) {
            // 未找到该分销商品信息
            throw new YamiShopBindException("yami.distribution.prod.exist.error");
        }
        distributionProdService.auditDistributionProd(offlineHandleEventAuditParam, sysUserId);
        return ServerResponseEntity.success();
    }
    @GetMapping("/getDistributionProdLogPage")
    @Operation(summary = "获取分销商品记录信息")
    public ServerResponseEntity<IPage<DistributionProdLog>> getDistributionProdLogPage(@ParameterObject DistributionProdLog distributionProdLog,
                                                                                 PageParam<DistributionProdLog> page) {
        IPage<DistributionProdLog> distributionProdLogL = distributionProdService.getDistributionProdLogPage(page, distributionProdLog);
        return ServerResponseEntity.success(distributionProdLogL);
    }
}
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionUserBanController.java
New file
@@ -0,0 +1,91 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.platform.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.model.DistributionUserBan;
import com.yami.shop.distribution.common.service.DistributionUserBanService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
 * @author lgh on 2019/04/01.
 */
@RestController
@RequestMapping("/distribution/distributionUserBan")
@Tag(name = "平台端分销员封禁接口")
public class DistributionUserBanController {
    @Autowired
    private DistributionUserBanService distributionUserBanService;
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserBan:page')")
    @Operation(summary = "分页获取分销员封禁信息列表")
    public ServerResponseEntity<IPage<DistributionUserBan>> page(@ParameterObject DistributionUserBan distributionUserBan, PageParam<DistributionUserBan> page) {
        IPage<DistributionUserBan> list = distributionUserBanService.page(page, new LambdaQueryWrapper<DistributionUserBan>());
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/page/anduser")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserBan:page')")
    @Operation(summary = "分页获取分销员封禁列表")
    @Parameter(name = "userMobile", description = "分销员手机号码" , required = true)
    public ServerResponseEntity<IPage<DistributionUserBan>> page(@ParameterObject DistributionUserBan distributionUserBan, String userMobile,
                                                           PageParam<DistributionUserBan> page) {
        IPage<DistributionUserBan> list = distributionUserBanService.distributionUserBanPage(page, Constant.PLATFORM_SHOP_ID, userMobile, distributionUserBan);
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/info/{id}")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserBan:info')")
    @Operation(summary = "根据分销员封禁id获取分销员封禁信息")
    @Parameter(name = "id", description = "分销员封禁id" , required = true)
    public ServerResponseEntity<DistributionUserBan> info(@PathVariable("id") Long id) {
        DistributionUserBan distributionUserBan = distributionUserBanService.getById(id);
        return ServerResponseEntity.success(distributionUserBan);
    }
    @PostMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserBan:save')")
    @Operation(summary = "保存分销员封禁信息")
    public ServerResponseEntity<Void> save(@RequestBody @Valid DistributionUserBan distributionUserBan) {
        distributionUserBanService.save(distributionUserBan);
        return ServerResponseEntity.success();
    }
    @PutMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserBan:update')")
    @Operation(summary = "修改分销员封禁信息")
    public ServerResponseEntity<Void> update(@RequestBody @Valid DistributionUserBan distributionUserBan) {
        distributionUserBanService.updateById(distributionUserBan);
        return ServerResponseEntity.success();
    }
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserBan:delete')")
    @Operation(summary = "根据id删除分销员封禁信息")
    @Parameter(name = "id", description = "分销员封禁id" , required = true)
    public ServerResponseEntity<Void> delete(@PathVariable Long id) {
        distributionUserBanService.removeById(id);
        return ServerResponseEntity.success();
    }
}
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionUserBindController.java
New file
@@ -0,0 +1,91 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.platform.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.model.DistributionUserBind;
import com.yami.shop.distribution.common.service.DistributionUserBindService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
 * @author lgh on 2019/04/01.
 */
@RestController
@RequestMapping("/distribution/distributionUserBind")
@Tag(name = "平台端分销员绑定接口")
public class DistributionUserBindController {
    @Autowired
    private DistributionUserBindService distributionUserBindService;
    /**
     * 分页获取
     */
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserBind:page')")
    @Operation(summary = "分页获取分销员绑定列表")
    @Parameters({
            @Parameter(name = "nickName", description = "分销员昵称" ),
            @Parameter(name = "parentNickName", description = "上级分销员昵称" )
    })
    public ServerResponseEntity<IPage<DistributionUserBind>> page(@ParameterObject DistributionUserBind distributionUserBind, PageParam<DistributionUserBind> page,
                                                                  String nickName, String parentNickName, String cUserMobile, String dUserMobile,
                                                                  @RequestParam(value = "sort", defaultValue = "1") Integer sort,
                                                                  @RequestParam(value = "orderBy", defaultValue = "1") Integer orderBy) {
        IPage<DistributionUserBind> list = distributionUserBindService.distributionMsgsAndUserPage(page, distributionUserBind, null, null, nickName, parentNickName,cUserMobile, dUserMobile, sort, orderBy);
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/info/{id}")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserBind:info')")
    @Operation(summary = "根据id获取分销员绑定信息")
    @Parameter(name = "id", description = "分销员绑定id" )
    public ServerResponseEntity<DistributionUserBind> info(@PathVariable("id") Long id) {
        DistributionUserBind distributionUserBind = distributionUserBindService.getById(id);
        return ServerResponseEntity.success(distributionUserBind);
    }
    @PostMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserBind:save')")
    @Operation(summary = "保存分销员绑定信息")
    public ServerResponseEntity<Void> save(@RequestBody @Valid DistributionUserBind distributionUserBind) {
        distributionUserBindService.save(distributionUserBind);
        return ServerResponseEntity.success();
    }
    @PutMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserBind:update')")
    @Operation(summary = "修改分销员绑定信息")
    public ServerResponseEntity<Void> update(@RequestBody @Valid DistributionUserBind distributionUserBind) {
        distributionUserBindService.updateById(distributionUserBind);
        return ServerResponseEntity.success();
    }
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserBind:delete')")
    @Operation(summary = "根据id删除分销员绑定信息")
    @Parameter(name = "id", description = "分销员绑定id" )
    public ServerResponseEntity<Void> delete(@PathVariable Long id) {
        distributionUserBindService.removeById(id);
        return ServerResponseEntity.success();
    }
}
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionUserController.java
New file
@@ -0,0 +1,149 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.platform.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.dto.DistributionUserAchievementDataDto;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import com.yami.shop.distribution.common.param.UpdateDistributionUserParam;
import com.yami.shop.distribution.common.service.DistributionUserService;
import com.yami.shop.distribution.common.vo.DistributionUserVO;
import com.yami.shop.security.platform.util.SecurityUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import ma.glasnost.orika.MapperFacade;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import java.util.Objects;
/**
 * @author lgh on 2019/04/01.
 */
@RestController
@RequestMapping("/distribution/distributionUser")
@Tag(name = "平台端分销员接口")
public class DistributionUserController {
    @Autowired
    private DistributionUserService distributionUserService;
    @Autowired
    private MapperFacade mapperFacade;
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUser:page')")
    @Operation(summary = "分页查看分销员信息")
    @Parameters({
            @Parameter(name = "userMobile", description = "分销员手机号码" ),
            @Parameter(name = "parentUserMobile", description = "上级分销员手机号码" )
    })
    public ServerResponseEntity<IPage<DistributionUser>> page(@ParameterObject DistributionUser distributionUser, @ParameterObject RangeTimeParam rangeTimeParam,
                                                              String userMobile, String parentUserMobile, Integer state, PageParam<DistributionUser> page) {
        IPage<DistributionUser> list = distributionUserService.distributionUserPage(page, distributionUser, rangeTimeParam, userMobile, parentUserMobile, 0, state);
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/info/achievementData/{id}")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUser:info')")
    @Operation(summary = "获取分销员与等级条件匹配的数据")
    @Parameter(name = "id", description = "分销员id" )
    public ServerResponseEntity<DistributionUserAchievementDataDto> getDistributionUserAchievementData(@PathVariable("id") Long id) {
        return ServerResponseEntity.success(distributionUserService.getDistributionUserLevelAchievementDataByDistributionUserId(id));
    }
    @GetMapping("/info/{id}")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUser:info')")
    @Operation(summary = "获取分销员信息")
    @Parameter(name = "id", description = "分销员id" )
    public ServerResponseEntity<DistributionUser> info(@PathVariable("id") Long id) {
        DistributionUser distributionUser = distributionUserService.getById(id);
        return ServerResponseEntity.success(distributionUser);
    }
    @GetMapping("/page/achievement")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUser:page')")
    @Operation(summary = "获取分销员业绩")
    @Parameter(name = "userMobile", description = "分销员手机号码" )
    public ServerResponseEntity<IPage<DistributionUser>> page(@ParameterObject DistributionUser distributionUser, String userMobile,
                                                        PageParam<DistributionUser> page) {
        distributionUser.setShopId(Constant.PLATFORM_SHOP_ID);
        IPage<DistributionUser> list = distributionUserService.getDistributionUserAchievementPage(page, distributionUser, userMobile);
        return ServerResponseEntity.success(list);
    }
    @PostMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionUser:save')")
    @Operation(summary = "保存分销员信息")
    public ServerResponseEntity<Void> save(@RequestBody @Valid DistributionUser distributionUser) {
        distributionUserService.save(distributionUser);
        return ServerResponseEntity.success();
    }
    @PutMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionUser:update')")
    @Operation(summary = "修改分销员信息")
    public ServerResponseEntity<Void> update(@RequestBody @Valid DistributionUser distributionUser) {
        distributionUserService.updateById(distributionUser);
        return ServerResponseEntity.success();
    }
    @PutMapping("/state")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUser:update')")
    @Operation(summary = "修改分销员状态")
    public ServerResponseEntity<Void> update(@RequestBody UpdateDistributionUserParam param) {
        Integer disState = param.getState();
//        if(disState==1){
//            DistributionUser exitDistributionUser = distributionUserService.getById(param.getDistributionUserId());
//            Integer exitState =exitDistributionUser.getState();
//            if(exitState==1){
//                throw new YamiShopBindException("yami.distribution.has.distributionUser");
//            }
//        }
        distributionUserService.updateSelectiveAndInsertDistributionUserBan(param, SecurityUtils.getSysUser().getUserId());
        DistributionUser dbDistributionUser = distributionUserService.getById(param.getDistributionUserId());
        distributionUserService.removeCacheByUserIdAndShopId(dbDistributionUser.getUserId(), dbDistributionUser.getShopId());
        distributionUserService.removeCacheByCardNo(dbDistributionUser.getCardNo());
        return ServerResponseEntity.success();
    }
    @DeleteMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionUser:delete')")
    @Operation(summary = "根据分销员id批量删除分销员信息")
    @Parameter(name = "ids", description = "分销员id" )
    public ServerResponseEntity<Void> delete(@RequestBody List<Long> ids) {
        distributionUserService.removeByIds(ids);
        return ServerResponseEntity.success();
    }
    @GetMapping("/getInfo/{userId}")
    @Operation(summary = "根据用户id获取分销员信息")
    @Parameter(name = "userId", description = "用户id" )
    public ServerResponseEntity<DistributionUser> getInfo(@PathVariable("userId") String userId) {
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(userId, Constant.PLATFORM_SHOP_ID);
        if (Objects.isNull(distributionUser)) {
            return ServerResponseEntity.success(distributionUser);
        }
        if (Objects.nonNull(distributionUser.getParentId())) {
            DistributionUser parentUser = distributionUserService.getById(distributionUser.getParentId());
            distributionUser.setParentDistributionUser(mapperFacade.map(parentUser, DistributionUserVO.class));
        }
        return ServerResponseEntity.success(distributionUser);
    }
}
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionUserGroupController.java
New file
@@ -0,0 +1,90 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.platform.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.model.DistributionUserGroup;
import com.yami.shop.distribution.common.service.DistributionUserGroupService;
import com.yami.shop.security.platform.util.SecurityUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
/**
 * @author lgh on 2019/04/01.
 */
@RestController
@RequestMapping("/distribution/distributionUserGroup")
@Tag(name = "平台端分销员分组接口")
public class DistributionUserGroupController {
    @Autowired
    private DistributionUserGroupService distributionUserGroupService;
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserGroup:page')")
    @Operation(summary = "分页获取分销员分组信息列表")
    public ServerResponseEntity<IPage<DistributionUserGroup>> page(@ParameterObject DistributionUserGroup distributionUserGroup,
                                                             PageParam<DistributionUserGroup> page) {
        distributionUserGroup.setShopId(Constant.PLATFORM_SHOP_ID);
        IPage<DistributionUserGroup> list = distributionUserGroupService.distributionUserGroupsAndSysUserPage(page, distributionUserGroup);
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/info/{id}")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserGroup:info')")
    @Operation(summary = "根据id获取分销员分组信息")
    @Parameter(name = "id", description = "分销员分组id" )
    public ServerResponseEntity<DistributionUserGroup> info(@PathVariable("id") Long id) {
        DistributionUserGroup distributionUserGroup = distributionUserGroupService.getById(id);
        return ServerResponseEntity.success(distributionUserGroup);
    }
    @PostMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserGroup:save')")
    @Operation(summary = "保存分销员分组信息")
    public ServerResponseEntity<Void> save(@RequestBody @Valid DistributionUserGroup distributionUserGroup) {
        distributionUserGroup.setShopId(Constant.PLATFORM_SHOP_ID);
        distributionUserGroup.setUpdateTime(new Date());
        distributionUserGroup.setModifier(SecurityUtils.getSysUser().getUserId());
        distributionUserGroupService.save(distributionUserGroup);
        return ServerResponseEntity.success();
    }
    @PutMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserGroup:update')")
    @Operation(summary = "修改分销员分组信息")
    public ServerResponseEntity<Void> update(@RequestBody @Valid DistributionUserGroup distributionUserGroup) {
        distributionUserGroup.setUpdateTime(new Date());
        distributionUserGroup.setModifier(SecurityUtils.getSysUser().getUserId());
        distributionUserGroupService.updateById(distributionUserGroup);
        return ServerResponseEntity.success();
    }
    @DeleteMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserGroup:delete')")
    @Operation(summary = "根据分销员分组id列表批量删除分销员分组信息")
    @Parameter(name = "ids", description = "分销员分组id" )
    public ServerResponseEntity<Void> delete(@RequestBody List<Long> ids) {
        distributionUserGroupService.removeByIds(ids);
        return ServerResponseEntity.success();
    }
}
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionUserIncomeController.java
New file
@@ -0,0 +1,99 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.platform.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.model.DistributionUserIncome;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import com.yami.shop.distribution.common.service.DistributionUserIncomeService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
 * @author lgh on 2019/04/01.
 */
@RestController
@RequestMapping("/distribution/distributionUserIncome")
@Tag(name = "平台端分销员收入接口")
public class DistributionUserIncomeController {
    @Autowired
    private DistributionUserIncomeService distributionUserIncomeService;
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserIncome:page')")
    @Operation(summary = "分页获取分销员收入记录列表")
    public ServerResponseEntity<IPage<DistributionUserIncome>> page(@ParameterObject DistributionUserIncome distributionUserIncome,
                                                              PageParam<DistributionUserIncome> page) {
        IPage<DistributionUserIncome> list = distributionUserIncomeService.page(page, new LambdaQueryWrapper<DistributionUserIncome>());
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/page/anduser")
    @Operation(summary = "分页获取分销员以及收入记录列表")
    @Parameters({
            @Parameter(name = "userMobile", description = "分销员手机号码" ),
            @Parameter(name = "orderNumber", description = "订单编号" ),
            @Parameter(name = "state", description = "收入状态" )
    })
    public ServerResponseEntity<IPage<DistributionUserIncome>> page(PageParam<DistributionUserIncome> page,
                                                                    @ParameterObject RangeTimeParam rangeTimeParam, String userMobile, String orderNumber,
                                                              Integer state, @ParameterObject DistributionUserIncome distributionUserIncome) {
        IPage<DistributionUserIncome> list = distributionUserIncomeService.incomeAndDistributionUserPage(page, Constant.PLATFORM_SHOP_ID,
                rangeTimeParam, userMobile, orderNumber, state, distributionUserIncome);
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/info/{id}")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserIncome:info')")
    @Operation(summary = "根据id获取分销员收入信息")
    @Parameter(name = "id", description = "分销员收入id" )
    public ServerResponseEntity<DistributionUserIncome> info(@PathVariable("id") Long id) {
        DistributionUserIncome distributionUserIncome = distributionUserIncomeService.getById(id);
        return ServerResponseEntity.success(distributionUserIncome);
    }
    @PostMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserIncome:save')")
    @Operation(summary = "保存分销员收入信息")
    public ServerResponseEntity<Void> save(@RequestBody @Valid DistributionUserIncome distributionUserIncome) {
        distributionUserIncomeService.save(distributionUserIncome);
        return ServerResponseEntity.success();
    }
    @PutMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserIncome:update')")
    @Operation(summary = "修改分销员收入信息")
    public ServerResponseEntity<Void> update(@RequestBody @Valid DistributionUserIncome distributionUserIncome) {
        distributionUserIncomeService.updateById(distributionUserIncome);
        return ServerResponseEntity.success();
    }
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserIncome:delete')")
    @Operation(summary = "根据id删除分销员收入信息")
    @Parameter(name = "id", description = "分销员收入id" )
    public ServerResponseEntity<Void> delete(@PathVariable Long id) {
        distributionUserIncomeService.removeById(id);
        return ServerResponseEntity.success();
    }
}
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionUserWalletBillController.java
New file
@@ -0,0 +1,82 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.platform.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.model.DistributionUserWalletBill;
import com.yami.shop.distribution.common.service.DistributionUserWalletBillService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
 * @author xwc
 * @date 2019-04-29 16:39:13
 */
@RestController
@RequestMapping("/distribution/distributionUserWalletBill")
@Tag(name = "平台端分销员钱包流水接口")
public class DistributionUserWalletBillController {
    @Autowired
    private DistributionUserWalletBillService distributionUserWalletBillService;
    @GetMapping("/page")
    @Operation(summary = "分页获取分销员钱包流水列表")
    public ServerResponseEntity<IPage<DistributionUserWalletBill>> getDistributionUserWalletBillPage(PageParam<DistributionUserWalletBill> page,
                                                                                                     @ParameterObject DistributionUserWalletBill distributionUserWalletBill) {
        return ServerResponseEntity.success(distributionUserWalletBillService.page(page, new LambdaQueryWrapper<DistributionUserWalletBill>()));
    }
    @GetMapping("/pageAndUser")
    @Operation(summary = "分页查询(携带UserVO)")
    @Parameter(name = "userMobile", description = "分销员手机号码" )
    public ServerResponseEntity<IPage<DistributionUserWalletBill>> getDistributionUserWalletBillAndUserPage(PageParam page, String userMobile) {
        return ServerResponseEntity.success(distributionUserWalletBillService.getDistributionUserWalletBillAndUserPage(page, userMobile));
    }
    @GetMapping("/info/{id}")
    @Operation(summary = "根据id获取分销员钱包流水信息")
    @Parameter(name = "id", description = "分销员钱包流水id" )
    public ServerResponseEntity<DistributionUserWalletBill> getById(@PathVariable("id") Long id) {
        return ServerResponseEntity.success(distributionUserWalletBillService.getById(id));
    }
    @PostMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserWalletBill:save')")
    @Operation(summary = "新增分销员钱包流水")
    public ServerResponseEntity<Boolean> save(@RequestBody @Valid DistributionUserWalletBill distributionUserWalletBill) {
        return ServerResponseEntity.success(distributionUserWalletBillService.save(distributionUserWalletBill));
    }
    @PutMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserWalletBill:update')")
    @Operation(summary = "修改分销员钱包流水")
    public ServerResponseEntity<Boolean> updateById(@RequestBody @Valid DistributionUserWalletBill distributionUserWalletBill) {
        return ServerResponseEntity.success(distributionUserWalletBillService.updateById(distributionUserWalletBill));
    }
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('distribution:distributionUserWalletBill:delete')")
    @Operation(summary = "根据id删除分销员钱包流水")
    @Parameter(name = "id", description = "分销员钱包流水id" )
    public ServerResponseEntity<Boolean> removeById(@PathVariable Long id) {
        return ServerResponseEntity.success(distributionUserWalletBillService.removeById(id));
    }
}
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionUserWalletController.java
New file
@@ -0,0 +1,90 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.platform.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.model.DistributionUserWallet;
import com.yami.shop.distribution.common.service.DistributionUserWalletService;
import com.yami.shop.security.platform.util.SecurityUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
 * @author lgh on 2019/04/01.
 */
@RestController
@RequestMapping("/distribution/distributionUserWallet")
@Tag(name = "平台端分销员钱包接口")
public class DistributionUserWalletController {
    @Autowired
    private DistributionUserWalletService distributionUserWalletService;
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('admin:distributionUserWallet:page')")
    @Operation(summary = "分页获取分销员钱包信息列表")
    public ServerResponseEntity<IPage<DistributionUserWallet>> page(@ParameterObject DistributionUserWallet distributionUserWallet, PageParam<DistributionUserWallet> page) {
        IPage<DistributionUserWallet> list = distributionUserWalletService.page(page, new LambdaQueryWrapper<DistributionUserWallet>());
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/pageAndUser")
    @PreAuthorize("@pms.hasPermission('admin:distributionUserWallet:page')")
    @Operation(summary = "分页获取获取分销员绑定信息(携带UserVO)")
    @Parameter(name = "userMobile", description = "分销员手机号码" )
    public ServerResponseEntity<IPage<DistributionUserWallet>> pageAndUser(String userMobile, PageParam<DistributionUserWallet> page) {
        IPage<DistributionUserWallet> list = distributionUserWalletService.getDistributionUserWalletAndDistributionUserVoPage(page, userMobile);
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/info/{id}")
    @PreAuthorize("@pms.hasPermission('admin:distributionUserWallet:info')")
    @Operation(summary = "根据id获取分销员钱包信息")
    @Parameter(name = "id", description = "分销员钱包id" )
    public ServerResponseEntity<DistributionUserWallet> info(@PathVariable("id") Long id) {
        DistributionUserWallet distributionUserWallet = distributionUserWalletService.getById(id);
        return ServerResponseEntity.success(distributionUserWallet);
    }
    @PostMapping
    @PreAuthorize("@pms.hasPermission('admin:distributionUserWallet:save')")
    @Operation(summary = "保存分销员钱包信息")
    public ServerResponseEntity<Void> save(@RequestBody @Valid DistributionUserWallet distributionUserWallet) {
        distributionUserWalletService.save(distributionUserWallet);
        return ServerResponseEntity.success();
    }
    @PutMapping
    @PreAuthorize("@pms.hasPermission('admin:distributionUserWallet:update')")
    @Operation(summary = "修改分销员钱包信息")
    public ServerResponseEntity<Void> update(@RequestBody @Valid DistributionUserWallet distributionUserWallet) {
        distributionUserWalletService.updateDistributionUserWallet(distributionUserWallet, SecurityUtils.getSysUser().getUserId());
        return ServerResponseEntity.success();
    }
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('admin:distributionUserWallet:delete')")
    @Operation(summary = "根据id删除分销员钱包信息")
    @Parameter(name = "id", description = "分销员钱包id" )
    public ServerResponseEntity<Void> delete(@PathVariable Long id) {
        distributionUserWalletService.removeById(id);
        return ServerResponseEntity.success();
    }
}
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/controller/DistributionWithdrawCashController.java
New file
@@ -0,0 +1,124 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.platform.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.enums.EnterprisePayStatus;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.common.constants.DistributionAudit;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.model.DistributionUserWallet;
import com.yami.shop.distribution.common.model.DistributionWithdrawCash;
import com.yami.shop.distribution.common.param.RangeTimeParam;
import com.yami.shop.distribution.common.service.DistributionUserService;
import com.yami.shop.distribution.common.service.DistributionUserWalletService;
import com.yami.shop.distribution.common.service.DistributionWithdrawCashService;
import com.yami.shop.distribution.common.vo.DistributionConfigVO;
import com.yami.shop.security.common.enums.SocialType;
import com.yami.shop.security.common.model.AppConnect;
import com.yami.shop.security.common.service.AppConnectService;
import com.yami.shop.service.SysConfigService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.Objects;
/**
 * @author lgh on 2019/04/01.
 */
@RestController
@RequestMapping("/platform/distributionWithdrawCash")
@Tag(name = "平台端分销员提现申请接口")
public class DistributionWithdrawCashController {
    @Autowired
    private DistributionWithdrawCashService distributionWithdrawCashService;
    @Autowired
    private DistributionUserWalletService distributionUserWalletService;
    @Autowired
    private DistributionUserService distributionUserService;
    @Autowired
    private AppConnectService appConnectService;
    @Autowired
    private SysConfigService sysConfigService;
    /**
     * 分页获取
     */
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('platform:distributionWithdrawCash:page')")
    @Operation(summary = "分页获取分销员提现申请列表")
    @Parameter(name = "userMobile", description = "分销员手机号码" )
    public ServerResponseEntity<IPage<DistributionWithdrawCash>> page(PageParam<DistributionWithdrawCash> page, @ParameterObject RangeTimeParam rangeTimeParam,
                                                                String userMobile, @ParameterObject DistributionWithdrawCash distributionWithdrawCash) {
        IPage<DistributionWithdrawCash> list = distributionWithdrawCashService.distributionWithdrawCashsPage(page, null, rangeTimeParam, userMobile, distributionWithdrawCash);
        return ServerResponseEntity.success(list);
    }
    /**
     * 修改
     */
    @PutMapping("/toSuccess/{withdrawCashId}")
    @PreAuthorize("@pms.hasPermission('platform:distributionWithdrawCash:update')")
    @Operation(summary = "修改分销员提现申请信息")
    @Parameter(name = "withdrawCashId", description = "提现记录id" )
    public ServerResponseEntity<Void> update(@PathVariable String withdrawCashId) {
        DistributionWithdrawCash distributionWithdrawCash = distributionWithdrawCashService.getById(withdrawCashId);
        if (distributionWithdrawCash == null) {
            throw new YamiShopBindException("yami.get.user.cash.info");
        }
        Long walletId = distributionWithdrawCash.getWalletId();
        DistributionUserWallet wallet = distributionUserWalletService.getById(walletId);
        if (wallet == null) {
            throw new YamiShopBindException("yami.get.user.withdraw.info");
        }
        DistributionUser distributionUser = distributionUserService.getById(wallet.getDistributionUserId());
        if (distributionUser == null) {
            throw new YamiShopBindException("yami.user.no.exist");
        }
        if (!Objects.equals(distributionUser.getShopId(), Constant.PLATFORM_SHOP_ID)) {
            throw new YamiShopBindException("yami.withdrawCash.update.no.auth");
        }
        distributionWithdrawCash.setState(1);
        distributionWithdrawCash.setUpdateTime(new Date());
        distributionWithdrawCashService.updateById(distributionWithdrawCash);
        // 判断打款状态 1审核通过企业打款 2审核通过人工打款
        //获取店铺提现设置
        DistributionConfigVO distributionConfigVO = sysConfigService.getSysConfigObject(Constant.DISTRIBUTION_CONFIG, DistributionConfigVO.class);
        if (!distributionConfigVO.getWithdrawal().equals(DistributionAudit.Withdrawals_ONE.getValue())){
            return ServerResponseEntity.success();
        }
        // 获取用户的openId
        DistributionUserWallet one = distributionUserWalletService.getOne(new LambdaQueryWrapper<DistributionUserWallet>().eq(DistributionUserWallet::getWalletId, distributionWithdrawCash.getWalletId()));
//        AppConnect appConnect = appConnectService.getOne(new LambdaQueryWrapper<AppConnect>()
//                .eq(AppConnect::getUserId, distributionUserService.getById(one.getDistributionUserId()).getUserId())
//                .eq(AppConnect::getAppId, SocialType.MA.value())
//        );
//        // 添加企业支付记录
//        distributionWithdrawCashService.enterprisePay(distributionWithdrawCash, appConnect.getUserId(), appConnect.getBizUserId(), EnterprisePayStatus.APPLY.getValue());
        String userId = distributionUserService.getById(one.getDistributionUserId()).getUserId();
        // 添加企业支付记录
        distributionWithdrawCashService.enterprisePay(distributionWithdrawCash, userId, distributionWithdrawCash.getBizUserId(), EnterprisePayStatus.APPLY.getValue());
        return ServerResponseEntity.success();
    }
}
yami-shop-distribution/yami-shop-distribution-platform/src/main/java/com/yami/shop/distribution/platform/listener/EnterprisePayListener.java
New file
@@ -0,0 +1,84 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.distribution.platform.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.enums.EnterpriseApplyType;
import com.yami.shop.bean.event.EnterprisePayFailEvent;
import com.yami.shop.bean.event.EnterprisePaySuccessEvent;
import com.yami.shop.bean.model.EnterprisePay;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.util.Arith;
import com.yami.shop.distribution.common.constants.DistributionWithdrawCashStateEnum;
import com.yami.shop.distribution.common.model.DistributionUser;
import com.yami.shop.distribution.common.model.DistributionUserWallet;
import com.yami.shop.distribution.common.model.DistributionUserWalletBill;
import com.yami.shop.distribution.common.model.DistributionWithdrawCash;
import com.yami.shop.distribution.common.service.DistributionUserService;
import com.yami.shop.distribution.common.service.DistributionUserWalletBillService;
import com.yami.shop.distribution.common.service.DistributionUserWalletService;
import com.yami.shop.distribution.common.service.DistributionWithdrawCashService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.Objects;
/**
 * 企业支付事件监听
 * @author yami
 */
@Component("distributionWithdrawEnterprisePayListener")
@AllArgsConstructor
public class EnterprisePayListener {
    private final DistributionWithdrawCashService distributionWithdrawCashService;
    private final DistributionUserWalletService distributionUserWalletService;
    private final DistributionUserService distributionUserService;
    private final DistributionUserWalletBillService distributionUserWalletBillService;
    @EventListener(EnterprisePaySuccessEvent.class)
    public void distributionWithdrawEventHandle(EnterprisePaySuccessEvent event) {
        EnterprisePay enterprisePay = event.getEnterprisePay();
        if (!Objects.equals(enterprisePay.getType(), EnterpriseApplyType.DISTRIBUTION_WITHDRAW.value())) {
            return;
        }
        // 更新提现状态
        DistributionWithdrawCash distributionWithdrawCash = distributionWithdrawCashService.getById(enterprisePay.getBizId());
        distributionWithdrawCash.setState(DistributionWithdrawCashStateEnum.CASH_SUCCESS.getValue());
        distributionWithdrawCash.setUpdateTime(new Date());
        distributionWithdrawCashService.updateById(distributionWithdrawCash);
    }
    @EventListener(EnterprisePayFailEvent.class)
    public void shopWithdrawFailEventHandle(EnterprisePayFailEvent event) {
        EnterprisePay enterprisePay = event.getEnterprisePay();
        //商户提现失败
        if (!Objects.equals(EnterpriseApplyType.DISTRIBUTION_WITHDRAW.value(), enterprisePay.getType())) {
            return;
        }
        DistributionWithdrawCash distributionWithdrawCash = distributionWithdrawCashService.getById(enterprisePay.getBizId());
        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(enterprisePay.getUserId(), Constant.PLATFORM_SHOP_ID);
        DistributionUserWallet distributionUserWallet = distributionUserWalletService.getOne(new LambdaQueryWrapper<DistributionUserWallet>()
                .eq(DistributionUserWallet::getDistributionUserId, distributionUser.getDistributionUserId()));
        // 更新状态并将金额回退到分销员钱包中
        distributionWithdrawCash.setState(DistributionWithdrawCashStateEnum.CASH_FAIL.getValue());
        // 增加用户可提现金额
        distributionUserWallet.setSettledAmount(Arith.add(distributionUserWallet.getSettledAmount(), distributionWithdrawCash.getAmount()));
        //增加钱包流水记录
        distributionUserWalletBillService.save(new DistributionUserWalletBill(distributionUserWallet, "提现失败","Failed to withdraw cash", 0.0, distributionWithdrawCash.getAmount(), 0.0, 0.0, 0));
        distributionUserWalletService.updateById(distributionUserWallet);
    }
}
yami-shop-groupbuy/pom.xml
New file
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>yami-shop</artifactId>
        <groupId>com.yami.shop</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>yami-shop-groupbuy</artifactId>
    <description>商城团购模块</description>
    <packaging>pom</packaging>
    <modules>
        <module>yami-shop-groupbuy-api</module>
        <module>yami-shop-groupbuy-common</module>
        <module>yami-shop-groupbuy-multishop</module>
        <module>yami-shop-groupbuy-platform</module>
    </modules>
</project>
yami-shop-groupbuy/yami-shop-groupbuy-api/pom.xml
New file
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.yami.shop</groupId>
        <artifactId>yami-shop-groupbuy</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>yami-shop-groupbuy-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <modelVersion>4.0.0</modelVersion>
    <description>商城团购模块后台管理部分</description>
    <dependencies>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-groupbuy-common</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-security-api</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-delivery-api</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
    </dependencies>
</project>
yami-shop-groupbuy/yami-shop-groupbuy-api/src/main/java/com/yami/shop/groupbuy/api/config/SwaggerConfiguration.java
New file
@@ -0,0 +1,34 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.api.config;
import lombok.AllArgsConstructor;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * @author Yami
 */
@Configuration("groupbuySwaggerConfiguration")
@AllArgsConstructor
public class SwaggerConfiguration {
    @Bean
    public GroupedOpenApi groupBuyRestApi() {
        return GroupedOpenApi.builder()
                .group("团购活动接口")
                .packagesToScan("com.yami.shop.groupbuy.api.controller")
                .pathsToMatch("/**")
                .build();
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-api/src/main/java/com/yami/shop/groupbuy/api/controller/GroupController.java
New file
@@ -0,0 +1,51 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.api.controller;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupTeamDto;
import com.yami.shop.groupbuy.common.service.GroupTeamService;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
 * @author 小懒虫
 * @date 2019/9/2 9:01
 */
@RestController
@RequestMapping("/group")
@Tag(name = "团购信息接口")
public class GroupController {
    @Autowired
    private GroupTeamService groupTeamService;
    @GetMapping("/joinGroupList")
    @Operation(summary = "可加入的团列表" , description = "只显示最近n个团列表(默认10)")
    @Parameters({
            @Parameter(name = "groupActivityId",description = "拼团活动ID", required = true),
            @Parameter(name = "showSize", description = "显示数量(默认10)")
    })
    public ServerResponseEntity<List<ApiGroupTeamDto>> joinGroupList(@RequestParam(value = "groupActivityId") Long groupActivityId,
            @RequestParam(value = "showSize", defaultValue = "10") Integer showSize) {
        List<ApiGroupTeamDto> list = groupTeamService.listJoinGroup(groupActivityId, showSize);
        return ServerResponseEntity.success(list);
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-api/src/main/java/com/yami/shop/groupbuy/api/controller/GroupOrderController.java
New file
@@ -0,0 +1,259 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.api.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.StrUtil;
import com.yami.shop.bean.app.dto.*;
import com.yami.shop.bean.enums.DeliveryType;
import com.yami.shop.bean.enums.OrderType;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.vo.UserDeliveryInfoVO;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ResponseEnum;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.delivery.api.manager.DeliveryOrderManager;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupActivityDto;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupSkuDto;
import com.yami.shop.groupbuy.common.api.param.ApiGroupOrderSubmitParam;
import com.yami.shop.groupbuy.common.api.param.GroupOrderParam;
import com.yami.shop.groupbuy.common.bo.GroupOrderBO;
import com.yami.shop.groupbuy.common.enums.ActivityStatusEnum;
import com.yami.shop.groupbuy.common.enums.TeamStatusEnum;
import com.yami.shop.groupbuy.common.model.GroupTeam;
import com.yami.shop.groupbuy.common.service.GroupActivityService;
import com.yami.shop.groupbuy.common.service.GroupOrderService;
import com.yami.shop.groupbuy.common.service.GroupTeamService;
import com.yami.shop.manager.SubmitOrderManager;
import com.yami.shop.manager.impl.ConfirmOrderManager;
import com.yami.shop.manager.impl.ShopCartAdapter;
import com.yami.shop.manager.impl.ShopCartItemAdapter;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.ProductService;
import com.yami.shop.service.ShopCustomerService;
import com.yami.shop.service.SkuService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.AllArgsConstructor;
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.validation.Valid;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/**
 * @author Yami
 */
@RestController
@RequestMapping("/p/group/order")
@Tag(name = "拼团订单接口")
@AllArgsConstructor
public class GroupOrderController {
    private final GroupTeamService groupTeamService;
    private final GroupOrderService groupOrderService;
    private final Snowflake snowflake;
    private final SubmitOrderManager submitOrderManager;
    private final GroupActivityService groupActivityService;
    private final SkuService skuService;
    private final ProductService productService;
    private final ConfirmOrderManager confirmOrderManager;
    private final ShopCartAdapter shopCartAdapter;
    private final ShopCartItemAdapter shopCartItemAdapter;
    private final DeliveryOrderManager deliveryOrderManager;
    private final ShopCustomerService shopCustomerService;
    @PostMapping("/confirm")
    @Operation(summary = "结算,生成团购订单信息" , description = "传入参团/开团所需要的参数进行下单,如果用户为开团时拼团团队Id(groupTeamId)为0,如用户为参团则需要将拼团团队Id(groupTeamId)需要带上")
    public ServerResponseEntity<ShopCartOrderMergerDto> confirm(@Valid @RequestBody GroupOrderParam groupOrderParam) {
        String userId = SecurityUtils.getUser().getUserId();
        ApiGroupSkuDto apiGroupSku = checkActivityAndGetGroupSku(groupOrderParam);
        List<ShopCartItemDto> shopCartItemsDb = shopCartItemAdapter.getShopCartItem(groupOrderParam.getOrderItem(), apiGroupSku.getActPrice(), userId, groupOrderParam.getAddrId());
        // 将要返回给前端的完整的订单信息
        ShopCartOrderMergerDto shopCartOrderMerger = new ShopCartOrderMergerDto();
        shopCartOrderMerger.setDvyType(groupOrderParam.getDvyType());
        shopCartOrderMerger.setOrderType(OrderType.GROUP);
        // 筛选过滤掉不同配送的商品
        List<ShopCartItemDto> shopCartItems = confirmOrderManager.filterShopItemsByType(shopCartOrderMerger, shopCartItemsDb);
        // 该商品不满足任何的配送方式
        if (CollectionUtil.isEmpty(shopCartItems)) {
            return ServerResponseEntity.fail(ResponseEnum.ORDER_DELIVERY_NOT_SUPPORTED, shopCartOrderMerger);
        }
        ShopCartItemDto firstShopCartItem = shopCartItems.get(0);
        // 商品类别 0.实物商品 1. 虚拟商品
        int mold = 0;
        if (shopCartItems.stream().filter(shopCartItemDto -> shopCartItemDto.getMold() == 1).count() == shopCartItems.size()) {
            // 订单项中的所有商品都为虚拟商品时,才是虚拟订单
            mold = 1;
        }
        shopCartOrderMerger.setMold(mold);
        // 是否为预售订单
        groupOrderParam.setPreSellStatus(firstShopCartItem.getPreSellStatus());
        shopCartOrderMerger.setPreSellStatus(firstShopCartItem.getPreSellStatus());
        // 购物车
        List<ShopCartDto> shopCarts = shopCartAdapter.getShopCarts(shopCartItems);
        // 计算运费,获取用户地址,自提信息
        UserDeliveryInfoVO userDeliveryInfo = new UserDeliveryInfoVO();
        if (Objects.equals(mold, 0)) {
            userDeliveryInfo = deliveryOrderManager.calculateAndGetDeliverInfo(userId, groupOrderParam.getAddrId(), groupOrderParam.getDvyType(), shopCartItems);
        }
        // 当算完一遍店铺的各种满减活动时,重算一遍订单金额
        confirmOrderManager.recalculateAmountWhenFinishingCalculateShop(shopCartOrderMerger, shopCarts, userDeliveryInfo);
        // 结束平台优惠的计算之后,还要重算一遍金额
        confirmOrderManager.recalculateAmountWhenFinishingCalculatePlatform(shopCartOrderMerger);
        // 计算平台佣金
        confirmOrderManager.calculatePlatformCommission(shopCartOrderMerger);
        // 缓存计算
        confirmOrderManager.cacheCalculatedInfo(userId, shopCartOrderMerger);
        return ServerResponseEntity.success(shopCartOrderMerger);
    }
    @PostMapping("/submit")
    @Operation(summary = "提交订单,返回订单编号" , description = "根据订单信息,返回订单编号")
    public ServerResponseEntity<OrderNumbersDto> submitOrders(@Valid @RequestBody ApiGroupOrderSubmitParam apiGroupOrderSubmitParam) {
        String userId = SecurityUtils.getUser().getUserId();
        ServerResponseEntity<ShopCartOrderMergerDto> orderCheckResult = submitOrderManager.checkSubmitInfo(apiGroupOrderSubmitParam, userId);
        if (!orderCheckResult.isSuccess()) {
            if(StrUtil.equals(ResponseEnum.REPEAT_ORDER.value(),orderCheckResult.getCode())){
                OrderNumbersDto orderNumbersDto = new OrderNumbersDto(null);
                orderNumbersDto.setDuplicateError(1);
                return ServerResponseEntity.success(orderNumbersDto);
            }
        }
        ShopCartOrderMergerDto mergerOrder = orderCheckResult.getData();
        String orderNumber = String.valueOf(snowflake.nextId());
        if (Objects.isNull(mergerOrder.getUserAddr()) && !Objects.equals(mergerOrder.getMold(),1) && Objects.equals(mergerOrder.getDvyType(), DeliveryType.EXPRESS.getValue())) {
            // 请填写收货地址
            throw new YamiShopBindException("yami.delivery.address");
        }
        List<ShopCartOrderDto> shopCartOrders = mergerOrder.getShopCartOrders();
        ShopCartOrderDto shopCartOrderVO = shopCartOrders.get(0);
        shopCartOrderVO.setOrderNumber(orderNumber);
        ShopCartItemDto shopCartItemVO = shopCartOrderVO.getShopCartItemDiscounts().get(0).getShopCartItems().get(0);
        Long prodId = shopCartItemVO.getProdId();
        // 校验活动
        ApiGroupActivityDto apiGroupActivityDto = groupActivityService.getByProdId(prodId);
        if (Objects.isNull(apiGroupActivityDto) || !Objects.equals(apiGroupActivityDto.getActivityStatus(), ActivityStatusEnum.UNDER_WAY.value())) {
            // 拼团活动不在进行中,不能参与拼团
            throw new YamiShopBindException("yami.group.no.progress");
        }
        // 购买数量限制
        if (Objects.equals(apiGroupActivityDto.getHasMaxNum(), 1)) {
            Integer dbSpuCount = groupOrderService.getUserHadOrderCountByGroupProdId(userId, apiGroupActivityDto.getGroupActivityId());
            if (dbSpuCount + shopCartItemVO.getProdCount() > apiGroupActivityDto.getMaxNum()) {
                String message = I18nMessage.getMessage("yami.group.prod.shop.limit");
                String num = I18nMessage.getMessage("yami.seckill.num");
                String userNum = I18nMessage.getMessage("yami.group.user.shop.num");
                String nowNum = I18nMessage.getMessage("yami.group.user.now.shop");
                String maxNum = I18nMessage.getMessage("yami.group.prod.overstep.shop.limit");
                // 活动商品限购数量为x件,您已购买x件,现购x件,超出最大得购买数量
                throw new YamiShopBindException(message + apiGroupActivityDto.getMaxNum() + num + userNum
                        + dbSpuCount + num + nowNum + shopCartItemVO.getProdCount() + num + maxNum);
            }
        }
        // 查看未完成的订单数量
        int unGroupOrderCount = groupOrderService.getUserUnGroupOrderCount(userId, apiGroupActivityDto.getGroupActivityId(),prodId);
        if (unGroupOrderCount > 0) {
            // 您已有待成团或拼团中的订单,请在拼团成功后重试
            throw new YamiShopBindException("yami.group.prod.has.group.order");
        }
        // 校验拼团团队是否可以参团
        if (Objects.nonNull(apiGroupOrderSubmitParam.getGroupTeamId()) && apiGroupOrderSubmitParam.getGroupTeamId() != 0) {
            GroupTeam groupTeam = groupTeamService.getById(apiGroupOrderSubmitParam.getGroupTeamId());
            if (!Objects.equals(TeamStatusEnum.IN_GROUP.value(), groupTeam.getStatus())) {
                // 拼团团队不在拼团中,不能参与拼团
                throw new YamiShopBindException("yami.group.team.no.join");
            }
            if (System.currentTimeMillis() > groupTeam.getEndTime().getTime()) {
                // 该拼团团队已关闭,不能继续参团
                throw new YamiShopBindException("yami.group.order.no.exist");
            }
        }
        GroupOrderBO groupOrderBO = new GroupOrderBO();
        groupOrderBO.setGroupTeamId(apiGroupOrderSubmitParam.getGroupTeamId());
        groupOrderBO.setGroupActivityId(apiGroupActivityDto.getGroupActivityId());
        groupOrderBO.setShopId(shopCartOrderVO.getShopId());
        groupOrderBO.setUserId(userId);
        groupOrderBO.setShareUserId(userId);
        groupOrderBO.setActivityProdPrice(mergerOrder.getTotal());
        groupOrderBO.setPayPrice(mergerOrder.getActualTotal());
        groupOrderBO.setOrderNumber(shopCartOrderVO.getOrderNumber());
        groupOrderBO.setCount(shopCartOrderVO.getTotalCount());
        groupOrderBO.setProdId(shopCartItemVO.getProdId());
        groupOrderService.submit(mergerOrder,groupOrderBO);
        // 店铺客户创建
        Order order = new Order();
        order.setUserId(groupOrderBO.getUserId());
        order.setShopId(groupOrderBO.getShopId());
        shopCustomerService.saveCustomerByOrders(Collections.singletonList(order));
//        // 开启事务消息,通知订单订单服务开始创建订单
//        TransactionSendResult transactionSendResult = groupOrderCreateTemplate.sendMessageInTransaction(RocketMqConstant.GROUP_ORDER_CREATE_TOPIC, new GenericMessage<>(groupOrderBO), mergerOrder);
//
//
//        if (!Objects.equals(transactionSendResult.getLocalTransactionState(), LocalTransactionState.COMMIT_MESSAGE)) {
//            throw new YamiShopBindException(ResponseEnum.EXCEPTION);
//        }
        // 移除缓存
        for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartOrder.getShopCartItemDiscounts()) {
                for (ShopCartItemDto shopCartItem : shopCartItemDiscount.getShopCartItems()) {
                    skuService.removeSkuCacheBySkuId(shopCartItem.getSkuId(), shopCartItem.getProdId());
                    productService.removeProdCacheByProdId(shopCartItem.getProdId());
                }
            }
        }
        return ServerResponseEntity.success(new OrderNumbersDto(orderNumber));
    }
    /**
     * 检查活动状态
     */
    private ApiGroupSkuDto checkActivityAndGetGroupSku(GroupOrderParam groupOrderParam) {
        Long prodId = groupOrderParam.getOrderItem().getProdId();
        ApiGroupActivityDto activityDto = groupActivityService.getByProdId(prodId);
        if (Objects.isNull(activityDto) || !Objects.equals(activityDto.getActivityStatus(), ActivityStatusEnum.UNDER_WAY.value()) || activityDto.getEndTime().getTime() < System.currentTimeMillis()) {
            // 拼团活动不在进行中,请稍后重试
            throw new YamiShopBindException("yami.group.no.progress");
        }
        ApiGroupSkuDto apiGroupSku = null;
        List<ApiGroupSkuDto> groupSkuList = activityDto.getGroupSkuList();
        for (ApiGroupSkuDto apiGroupSkuDto : groupSkuList) {
            if (Objects.equals(apiGroupSkuDto.getGroupSkuId(), groupOrderParam.getGroupSkuId())) {
                apiGroupSku = apiGroupSkuDto;
                break;
            }
        }
        if (Objects.isNull(apiGroupSku)) {
            // 活动商品不在正常状态
            throw new YamiShopBindException("yami.group.prod.status.error");
        }
        return apiGroupSku;
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-api/src/main/java/com/yami/shop/groupbuy/api/controller/GroupTeamController.java
New file
@@ -0,0 +1,139 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.api.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qiniu.util.StringUtils;
import com.yami.shop.bean.app.vo.ProductVO;
import com.yami.shop.bean.enums.ProdStatusEnums;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.model.Product;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.config.ShopConfig;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupSkuDto;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupTeamDto;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupUserDto;
import com.yami.shop.groupbuy.common.api.vo.ApiGroupTeamInfoVo;
import com.yami.shop.groupbuy.common.model.GroupOrder;
import com.yami.shop.groupbuy.common.service.GroupOrderService;
import com.yami.shop.groupbuy.common.service.GroupSkuService;
import com.yami.shop.groupbuy.common.service.GroupTeamService;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.OrderItemService;
import com.yami.shop.service.ProductService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Objects;
/**
 * @author 小懒虫
 * @date 2019/9/2 9:01
 */
@RestController
@RequestMapping("/p/groupTeam")
@Tag(name = "拼团信息接口")
public class GroupTeamController {
    @Autowired
    private GroupOrderService groupOrderService;
    @Autowired
    private GroupTeamService groupTeamService;
    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    private GroupSkuService groupSkuService;
    @Autowired
    private ProductService productService;
    @Autowired
    private MapperFacade mapperFacade;
    @Autowired
    private ShopConfig shopConfig;
    @GetMapping("/info")
    @Operation(summary = "拼团详情" , description = "拼团详情,至少携带一个参数,查看拼团单(团队)信息")
    @Parameters({
            @Parameter(name = "groupTeamId",description = "拼团团队ID"),
            @Parameter(name = "orderNumber", description = "订单编号")
    })
    public ServerResponseEntity<ApiGroupTeamInfoVo> teamInfo(
            @RequestParam(value = "groupTeamId", required = false) Long groupTeamId,
            @RequestParam("orderNumber") String orderNumber) {
        // 通过订单编号获取团ID
        if (!StringUtils.isNullOrEmpty(orderNumber)) {
            GroupOrder groupOrder = groupOrderService.getOne(new LambdaQueryWrapper<GroupOrder>()
                    .eq(GroupOrder::getOrderNumber, orderNumber));
            if (Objects.nonNull(groupOrder) && Objects.nonNull(groupOrder.getGroupTeamId())) {
                groupTeamId = groupOrder.getGroupTeamId();
            }
        }
        // 获取拼团团队信息
        ApiGroupTeamDto groupTeam = groupTeamService.getApiGroupTeamDto(groupTeamId);
        if (groupTeam == null) {
            // 该拼团单不存在
            throw new YamiShopBindException("yami.group.order.no.exist");
        }
        // 获取参团的用户列表
        List<ApiGroupUserDto> groupUserList = groupOrderService.listApiGroupUserDto(groupTeamId);
        // 如果昵称为空则为机器人参团
        for (ApiGroupUserDto apiGroupUserDto : groupUserList) {
            apiGroupUserDto.setNickName(StrUtil.isBlank(apiGroupUserDto.getNickName()) ? "系统参团" : apiGroupUserDto.getNickName());
            if (StrUtil.isBlank(orderNumber)) {
                orderNumber = apiGroupUserDto.getOrderNumber();
            }
        }
        // 获取商品信息
        Product product = productService.getProductByProdId(groupTeam.getGroupProdId(), I18nMessage.getDbLang());
        if (product == null || !Objects.equals(product.getStatus(), ProdStatusEnums.NORMAL.getValue())) {
            // 活动商品不在正常状态
            throw new YamiShopBindException("yami.group.prod.status.error");
        }
        List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(orderNumber, I18nMessage.getDbLang());
        product.setActivityPrice(orderItems.get(0).getPrice());
        // 获取SKU列表
        List<ApiGroupSkuDto> groupSkuList = groupSkuService.getApiByGroupActivityIdAndProdId(groupTeam.getGroupActivityId());
        // 获取团购订单信息
        String userId = SecurityUtils.getUser().getUserId();
        GroupOrder groupOrder = groupOrderService.getOne(new LambdaQueryWrapper<GroupOrder>()
                .eq(GroupOrder::getGroupTeamId, groupTeamId).eq(GroupOrder::getUserId, userId).eq(GroupOrder::getStatus, 1));
        // 拼装拼团详情信息
        ApiGroupTeamInfoVo infoVo = new ApiGroupTeamInfoVo();
        infoVo.setGroupTeam(groupTeam);
        infoVo.setApiGroupUserList(groupUserList);
        infoVo.setProductVO(mapperFacade.map(product, ProductVO.class));
        infoVo.setGroupSkuList(groupSkuList);
        if (groupOrder != null) {
            infoVo.setOrderNumber(groupOrder.getOrderNumber());
        }
        return ServerResponseEntity.success(infoVo);
    }
    @GetMapping("/joinUsers")
    @Operation(summary = "参团的用户列表" , description = "参团的用户列表")
    @Parameter(name = "groupTeamId", description = "拼团团队ID" , required = true)
    public ServerResponseEntity<List<ApiGroupUserDto>> joinGroupUsers(
            @RequestParam("groupTeamId") Long groupTeamId) {
        // 获取参团的用户列表
        List<ApiGroupUserDto> groupUserList = groupOrderService.listApiGroupUserDto(groupTeamId);
        return ServerResponseEntity.success(groupUserList);
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-api/src/main/java/com/yami/shop/groupbuy/api/listener/CheckGroupOrderListener.java
New file
@@ -0,0 +1,52 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.api.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.event.CheckGroupOrderEvent;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.groupbuy.common.model.GroupOrder;
import com.yami.shop.groupbuy.common.model.GroupTeam;
import com.yami.shop.groupbuy.common.service.GroupOrderService;
import com.yami.shop.groupbuy.common.service.GroupTeamService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
/**
 * 支付时校验订单过期事件
 *
 * @author lhd
 */
@Component("checkGroupOrderListener")
@AllArgsConstructor
public class CheckGroupOrderListener {
    private final GroupOrderService groupOrderService;
    private final GroupTeamService groupTeamService;
    @EventListener(CheckGroupOrderEvent.class)
    public void checkGroupOrderHandle(CheckGroupOrderEvent event) {
        String orderNumber = event.getOrder().getOrderNumber();
        GroupOrder groupOrder = groupOrderService.getOne(new LambdaQueryWrapper<GroupOrder>()
                .eq(GroupOrder::getOrderNumber, orderNumber));
        GroupTeam groupTeam = groupTeamService.getOne(new LambdaQueryWrapper<GroupTeam>()
                .eq(GroupTeam::getGroupTeamId, groupOrder.getGroupTeamId()));
        if (groupTeam.getEndTime() != null && System.currentTimeMillis() > groupTeam.getEndTime().getTime()) {
            //该拼团单不存在
            throw new YamiShopBindException("yami.group.order.no.exist");
        }
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-api/src/main/java/com/yami/shop/groupbuy/api/listener/LoadProdActivistListener.java
New file
@@ -0,0 +1,103 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.api.listener;
import com.yami.shop.bean.app.dto.SkuDto;
import com.yami.shop.bean.app.vo.GroupActivityVO;
import com.yami.shop.bean.app.vo.GroupSkuVO;
import com.yami.shop.bean.enums.ProdType;
import com.yami.shop.bean.event.LoadProdActivistEvent;
import com.yami.shop.bean.order.LoadProdActivistOrder;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupActivityDto;
import com.yami.shop.groupbuy.common.api.dto.ApiJoinGroupTeamDto;
import com.yami.shop.groupbuy.common.enums.GroupActivityStatusEnum;
import com.yami.shop.groupbuy.common.enums.TeamStatusEnum;
import com.yami.shop.groupbuy.common.model.GroupTeam;
import com.yami.shop.groupbuy.common.service.GroupActivityService;
import com.yami.shop.groupbuy.common.service.GroupTeamService;
import lombok.AllArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
 * 加载商品团购信息
 * @author yami
 */
@Component("groupProdActivistListener")
@AllArgsConstructor
public class LoadProdActivistListener {
    private GroupActivityService groupActivityService;
    private GroupTeamService groupTeamService;
    private MapperFacade mapperFacade;
    @EventListener(LoadProdActivistEvent.class)
    @Order(LoadProdActivistOrder.DEFAULT)
    public void loadProdGroupHandle(LoadProdActivistEvent event) {
        // 不是团购商品,不用处理
        if (!Objects.equals(event.getProdType(), ProdType.PROD_TYPE_GROUP.value())) {
            return;
        }
        // 查询拼团活动信息
        ApiGroupActivityDto apiGroupActivityDto = groupActivityService.getByProdId(event.getProdId());
        GroupActivityVO groupActivityVO = mapperFacade.map(apiGroupActivityDto, GroupActivityVO.class);
        long currentTimeMillis = System.currentTimeMillis();
        // 无法获取团购信息、团购没有启用、当前时间大于活动结束时间, 则不添加活动信息
        boolean unActivity = Objects.isNull(apiGroupActivityDto)  ||
                !Objects.equals(apiGroupActivityDto.getStatus(), GroupActivityStatusEnum.ENABLE.value()) ||
                currentTimeMillis > groupActivityVO.getEndTime().getTime();
        // 没有开启预热且开始时间未到
        if (unActivity || Objects.equals(apiGroupActivityDto.getIsPreheat(),0) && currentTimeMillis < groupActivityVO.getStartTime().getTime()) {
            return;
        }
        // 插入sku信息
        Map<Long, SkuDto> skuMap = event.getProductVO().getSkuList().stream().collect(Collectors.toMap(SkuDto::getSkuId, s -> s));
        Iterator<GroupSkuVO> iterator = groupActivityVO.getGroupSkuList().iterator();
        while (iterator.hasNext()) {
            GroupSkuVO groupSkuVO = iterator.next();
            // 启用的sku中没有包含该团购sku,则删除该sku
            if (!skuMap.containsKey(groupSkuVO.getSkuId())) {
                iterator.remove();
                continue;
            }
            SkuDto skuDto = skuMap.get(groupSkuVO.getSkuId());
            groupSkuVO.setStocks(skuDto.getStocks());
            groupSkuVO.setPic(skuDto.getPic());
            groupSkuVO.setPrice(skuDto.getPrice());
            groupSkuVO.setProperties(skuDto.getProperties());
            groupSkuVO.setSkuName(skuDto.getSkuName());
        }
        // 获取拼团队伍
        ApiJoinGroupTeamDto joinTeam = groupTeamService.getJoinGroupTeamHasMaxNum(groupActivityVO.getGroupActivityId());
        if (joinTeam != null) {
            GroupTeam groupTeam = groupTeamService.getById(joinTeam.getJoinGroupTeamId());
            if (Objects.equals(groupTeam.getStatus(), TeamStatusEnum.IN_GROUP.value())) {
                groupActivityVO.setJoinGroupTeamId(joinTeam.getJoinGroupTeamId());
            }
            groupActivityVO.setProdCount(joinTeam.getProdCount());
        }
        // 获取商品活动最低价
        event.getProductVO().setGroupActivityVO(groupActivityVO);
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/pom.xml
New file
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.yami.shop</groupId>
        <artifactId>yami-shop-groupbuy</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>yami-shop-groupbuy-common</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-security-common</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
    </dependencies>
</project>
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupActivityDto.java
New file
@@ -0,0 +1,99 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.api.dto;
import com.yami.shop.groupbuy.common.utils.GroupActivityUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
 * @author yami
 * @date 2019/8/30 9:59
 */
@Data
public class ApiGroupActivityDto {
    @Schema(description = "拼团活动id" )
    private Long groupActivityId;
    @Schema(description = "商品id" )
    private Long prodId;
    @Schema(description = "店铺id" )
    private Long shopId;
    @Schema(description = "活动名称" )
    private String activityName;
    @Schema(description = "拼团状态(1:启用、2:未启用、0:已失效、-1:删除、3:违规下架、4:平台审核 5:已结束)" )
    private Integer status;
    @Schema(description = "活动开始时间" )
    private Date startTime;
    @Schema(description = "活动结束时间" )
    private Date endTime;
    @Schema(description = "服务器当前时间" )
    private Date nowTime;
    @Schema(description = "成团人数" )
    private Integer groupNumber;
    @Schema(description = "是否模拟成团" )
    private Integer hasRobot;
    @Schema(description = "商品是否限购(1:限购、0:不限购)" )
    private Integer hasMaxNum;
    @Schema(description = "限购数量" )
    private Integer maxNum = 0;
    @Schema(description = "已购买数量" )
    private Integer prodCount;
    @Schema(description = "当前用户参团的团队ID(null表示还没有参加该活动)" )
    private Long joinGroupTeamId;
    @Schema(description = "成团有效时间" )
    private Integer groupValidTime;
    @Schema(description = "开启模拟成团后,拼团有效期内人数未满的团,系统将会模拟“匿名买家”凑满人数,使该团成团。 你只需要对已付款参团的真实买家发货。建议合理开启,以提高成团率。" )
    private Integer hasGroupTip;
    @Schema(description = "开启后,商品详情页展示未开始的拼团活动,但活动开始前用户无法拼团购买" )
    private Integer isPreheat;
    @Schema(description = "活动状态(活动状态:1:未开始、2:进行中、3:已结束、4:已失效、5:违规下架、6:等待审核)" )
    private Integer activityStatus;
    @Schema(description = "商品活动价格(最低价)" )
    private Double actPrice;
    @Schema(description = "sku列表" )
    private List<ApiGroupSkuDto> groupSkuList;
    /**
     * 获取活动状态(活动状态:1:未开始、2:进行中、3:已结束、4:已失效、5:违规下架、6:等待审核)
     */
    public Integer getActivityStatus() {
        return GroupActivityUtil.getActivityStatus(startTime, endTime, status);
    }
    /**
     * 获取服务器当前时间
     */
    public Date getNowTime() {
        return new Date();
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupOrderSubmitResultDto.java
New file
@@ -0,0 +1,24 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.api.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * @author Yami
 */
@Data
@Schema(description = "订单提交后返回结果")
public class ApiGroupOrderSubmitResultDto {
    @Schema(description = "订单编号" )
    private String orderNumber;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupProdDto.java
New file
@@ -0,0 +1,83 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.api.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.yami.shop.common.serializer.json.ImgJsonSerializer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
/**
 * 拼团活动商品信息
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@Data
public class ApiGroupProdDto {
    @Schema(description = "商品名称" )
    private String prodName;
    @Schema(description = "商品图片" )
    @JsonSerialize(using = ImgJsonSerializer.class)
    private String prodPic;
    @Schema(description = "成团人数" )
    private Integer groupNumber;
    @Schema(description = "原售价格" )
    private Double price;
    @Schema(description = "活动价格" )
    private Double actPrice;
    @Schema(description = "活动开始时间" )
    private Date startTime;
    @Schema(description = "活动结束时间" )
    private Date endTime;
    @Schema(description = "创建时间" )
    private Date createTime;
    @Schema(description = "拼团活动ID" )
    private Long groupActivityId;
    @Schema(description = "商品ID" )
    private Long prodId;
    @Schema(description = "虚拟商品的留言备注" )
    private String virtualRemark;
    @Schema(description = "核销次数 -1.多次核销 0.无需核销 1.单次核销" )
    private Integer writeOffNum;
    @Schema(description = "多次核销次数 -1.无限次" )
    private Integer writeOffMultipleCount;
    @Schema(description = "核销有效期 -1.长期有效 0.自定义  x.x天内有效" )
    private Integer writeOffTime;
    @Schema(description = "核销开始时间" )
    private Date writeOffStart;
    @Schema(description = "核销结束时间" )
    private Date writeOffEnd;
    @Schema(description = "是否可以退款 1.可以 0不可以" )
    private Integer isRefund;
    @Schema(description = "商品类别 0.实物商品 1. 虚拟商品" )
    private Integer mold;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupSkuDto.java
New file
@@ -0,0 +1,51 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.api.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.yami.shop.common.serializer.json.ImgJsonSerializer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * @author yami
 * @date 2019/8/30 10:25
 */
@Data
public class ApiGroupSkuDto {
    @Schema(description = "拼团活动商品规格id" )
    private Long groupSkuId;
    @Schema(description = "商品规格Id" )
    private Long skuId;
    @Schema(description = "原售价格" )
    private Double price;
    @Schema(description = "活动价格" )
    private Double actPrice;
    @Schema(description = "sku名称" )
    private String skuName;
    @Schema(description = "已售数量" )
    private String sellNum;
    @JsonSerialize(using = ImgJsonSerializer.class)
    @Schema(description = "sku图片" )
    private String pic;
    @Schema(description = "销售属性组合字符串 格式是p1:v1;p2:v2" )
    private String properties;
    @Schema(description = "sku状态: 1启用 0禁用" )
    private Integer status;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupSkuInfoDto.java
New file
@@ -0,0 +1,94 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.api.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
/**
 * 拼团商品规格详细信息
 *
 * @author Yami
 */
@Data
@Schema(description = "拼团商品规格详细信息")
public class ApiGroupSkuInfoDto {
    @Schema(description = "拼团活动商品规格id" )
    private Long groupSkuId;
    @Schema(description = "拼团活动商品id" )
    private Long groupProdId;
    @Schema(description = "商品规格id" )
    private Long skuId;
    @Schema(description = "商品规格id" )
    private Long categoryId;
    @Schema(description = "规格原价" )
    private Double price;
    @Schema(description = "活动价格" )
    private Double actPrice;
    @Schema(description = "规格名称" )
    private String skuName;
    @Schema(description = "sku库存" )
    private Integer stocks;
    @Schema(description = "商品名称" )
    private String prodName;
    @Schema(description = "商品图片" )
    private String prodPic;
    @Schema(description = "规格图片" )
    private String skuPic;
    @Schema(description = "店铺id" )
    private Long shopId;
    @Schema(description = "店铺名称" )
    private String shopName;
    @Schema(description = "商品状态(-1:删除、0:商家下架、1:上架、2:违规下架、3:平台审核)" )
    private int prodStatus;
    /**
     * 虚拟商品信息
     */
    @Schema(description = "商品类别 0.实物商品 1. 虚拟商品" )
    private Integer mold = 0;
    @Schema(description = "虚拟商品的留言备注" )
    private String virtualRemark;
    @Schema(description = "核销次数 -1.多次核销 0.无需核销 1.单次核销" )
    private Integer writeOffNum;
    @Schema(description = "多次核销次数 -1.无限次" )
    private Integer writeOffMultipleCount;
    @Schema(description = "核销有效期 -1.长期有效 0.自定义  x.x天内有效" )
    private Integer writeOffTime;
    @Schema(description = "核销开始时间" )
    private Date writeOffStart;
    @Schema(description = "核销结束时间" )
    private Date writeOffEnd;
    @Schema(description = "是否可以退款 1.可以 0不可以" , required = true)
    private Integer isRefund;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupTeamDto.java
New file
@@ -0,0 +1,70 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.api.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
/**
 * @author 小懒虫
 * @date 2019/8/30 10:32
 */
@Data
public class ApiGroupTeamDto {
    @Schema(description = "拼团团队id" )
    private Long groupTeamId;
    @Schema(description = "拼团活动id" )
    private Long groupActivityId;
    @Schema(description = "活动成团人数" )
    private Integer groupNumber;
    @Schema(description = "已参团人数" )
    private Integer joinNum;
    @Schema(description = "结束时间" )
    private Date endTime;
    @Schema(description = "服务器当前时间" )
    private Date nowTime;
    @Schema(description = "团长user_Id" )
    private String shareUserId;
    @Schema(description = "团长昵称" )
    private String shareNickName;
    @Schema(description = "团长头像" )
    private String sharePic;
    @Schema(description = "团订单状态(0:待成团,1:拼团中,2:拼团成功,3:拼团失败)" )
    private String status;
    /**
     * 店铺ID
     */
    private Long shopId;
    /**
     * 拼团商品ID
     */
    private Long groupProdId;
    /**
     * 获取服务器当前时间
     */
    public Date getNowTime() {
        return new Date();
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupUserDto.java
New file
@@ -0,0 +1,47 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.api.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
/**
 * 拼团活动用户信息
 *
 * @author 小懒虫
 * @date 2019/9/2 17:11
 */
@Data
public class ApiGroupUserDto {
    /**
     * 等于value ,用于对字段的说明
     */
    @Schema(description = "用户ID(当ID为0时标识为机器人)" )
    private String userId;
    @Schema(description = "用户昵称" )
    private String nickName;
    @Schema(description = "用户头像" )
    private String pic;
    @Schema(description = "订单号" )
    private String orderNumber;
    @Schema(description = "用户类型(0:成员  1:团长)" )
    private Integer identityType;
    @Schema(description = "创建时间" )
    private Date createTime;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiGroupUserOrderDto.java
New file
@@ -0,0 +1,100 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.api.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.yami.shop.bean.app.dto.UserAddrDto;
import com.yami.shop.bean.vo.VirtualRemarkVO;
import com.yami.shop.common.serializer.json.ImgJsonSerializer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
 * 拼团用户订单
 *
 * @author Yami
 */
@Data
@Schema(description = "拼团用户订单对象")
public class ApiGroupUserOrderDto {
    @Schema(description = "商品图片" , required = true)
    @JsonSerialize(using = ImgJsonSerializer.class)
    private String prodPic;
    @Schema(description = "规格图片" , required = true)
    @JsonSerialize(using = ImgJsonSerializer.class)
    private String skuPic;
    @Schema(description = "商品名称" , required = true)
    private String prodName;
    @Schema(description = "规格名称" , required = true)
    private String skuName;
    @Schema(description = "商品原价(单价)" , required = true)
    private Double price;
    @Schema(description = "商品拼团价" , required = true)
    private Double actPrice;
    @Schema(description = "商品总数" , required = true)
    private Integer prodTotalCount;
    @Schema(description = "商品总值" , required = true)
    private Double prodTotalPrice;
    @Schema(description = "拼团商品实付金额" , required = true)
    private Double groupProdActualTotal;
    @Schema(description = "运费" , required = true)
    private Double transfee;
    @Schema(description = "订单总额" , required = true)
    private Double orderTotalPrice;
    @Schema(description = "优惠金额" , required = true)
    private Double discountPrice;
    @Schema(description = "店铺id" )
    private Long shopId;
    @Schema(description = "店铺名称" )
    private String shopName;
    @Schema(description = "规格id" )
    private Long skuId;
    @Schema(description = "商品id" )
    private Long prodId;
    @Schema(description = "用户地址信息" , required = true)
    private UserAddrDto userAddrDto;
    @Schema(description = "拼团活动id" )
    private Long groupActivityId;
    @Schema(description = "拼团团队id" )
    private Long groupTempId;
    @Schema(description = "拼团商品id" )
    private Long groupProdId;
    @Schema(description = "拼团商品规格id" )
    private Long groupSkuId;
    @Schema(description = "商品类别 0.实物商品 1. 虚拟商品" )
    private Integer mold = 0;
    @Schema(description = "虚拟商品留言备注" )
    private List<VirtualRemarkVO> virtualRemarkList;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/dto/ApiJoinGroupTeamDto.java
New file
@@ -0,0 +1,31 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.api.dto;
import lombok.Data;
/**
 * 参加拼团信息
 * @author 小懒虫
 * @date 2019/9/3 10:03
 */
@Data
public class ApiJoinGroupTeamDto {
    /**
     * 当前用户参团的团队ID(null表示还没有参加该活动)
     */
    private Long joinGroupTeamId;
    /**
     * 已交易数量
     */
    private Integer prodCount = 0;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/param/ApiGroupOrderSubmitParam.java
New file
@@ -0,0 +1,28 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.api.param;
import com.yami.shop.bean.app.param.SubmitOrderParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * @author Yami
 */
@Data
@Schema(description = "订单提交参数")
public class ApiGroupOrderSubmitParam extends SubmitOrderParam {
    @Schema(description = "拼团团队id,(如果用户为参团则需要填写对应的拼团团队Id(groupTeamId),如果为用户为开团,拼团团队Id(groupTeamId)为0)" )
    @NotNull(message = "拼团团队id不能为空")
    private Long groupTeamId;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/param/GroupOrderParam.java
New file
@@ -0,0 +1,35 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.api.param;
import com.yami.shop.bean.app.param.OrderParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull;
/**
 * 开团/参团需要的参数
 * @author Yami
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(description = "拼团下单参数")
public class GroupOrderParam extends OrderParam {
    @Schema(description = "拼团团队id,(如果用户为参团则需要填写对应的拼团团队Id(groupTeamId),如果为用户为开团,拼团团队Id(groupTeamId)为0)" )
    @NotNull(message = "拼团团队id不能为空")
    private Long groupTeamId;
    @NotNull(message = "活动商品规格Id不能为空")
    @Schema(description = "拼团商品规格Id" , required = true)
    private Long groupSkuId;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/api/vo/ApiGroupTeamInfoVo.java
New file
@@ -0,0 +1,44 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.api.vo;
import com.yami.shop.bean.app.vo.ProductVO;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupSkuDto;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupTeamDto;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupUserDto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
 * 拼团详情vo
 *
 * @author 小懒虫
 * @date 2019/9/2 9:11
 */
@Data
public class ApiGroupTeamInfoVo {
    @Schema(description = "拼团单信息" )
    private ApiGroupTeamDto groupTeam;
    @Schema(description = "拼团活动商品信息" )
    private ProductVO productVO;
    @Schema(description = "sku列表" )
    private List<ApiGroupSkuDto> groupSkuList;
    @Schema(description = "参团用户列表" )
    private List<ApiGroupUserDto> apiGroupUserList;
    @Schema(description = "订单编号" )
    private String orderNumber;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/bo/GroupOrderBO.java
New file
@@ -0,0 +1,67 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.bo;
import lombok.Data;
/**
 * @author lhd
 * @date 2022/05/17
 */
@Data
public class GroupOrderBO {
    /**
     * 拼团活动id
     */
    private Long groupActivityId;
    /**
     * 店铺id
     */
    private Long shopId;
    /**
     * 拼团团队id
     */
    private Long groupTeamId;
    /**
     * user_id(当user_id为0时标识为机器人)
     */
    private String userId;
    /**
     * 团长id
     */
    private String shareUserId;
    /**
     * 活动商品金额
     */
    private Double activityProdPrice;
    /**
     * 支付金额
     */
    private Double payPrice;
    /**
     * 订单编号
     */
    private String orderNumber;
    /**
     * 商品数量
     */
    private Integer count;
    private Long prodId;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dao/GroupActivityMapper.java
New file
@@ -0,0 +1,115 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.model.Product;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupActivityDto;
import com.yami.shop.groupbuy.common.dto.GroupActivityDto;
import com.yami.shop.groupbuy.common.model.GroupActivity;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
 * 拼团活动表
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
public interface GroupActivityMapper extends BaseMapper<GroupActivity> {
    /**
     * 根据商品id获取团购活动信息
     *
     * @param prodId
     * @return
     */
    ApiGroupActivityDto getByProdId(@Param("prodId") Long prodId);
    /**
     * 获取团购活动分页数据
     *
     * @param page             分页对象
     * @param groupActivityDto 查询数据
     * @return 团购活动列表
     */
    IPage<GroupActivityDto> getGroupActivityPage(PageParam<GroupActivityDto> page, @Param("groupActivityDto") GroupActivityDto groupActivityDto);
    /**
     * 获取拼团活动信息
     *
     * @param groupActivityId 拼团活动ID
     * @param prodId          商品ID
     * @return Api活动对象
     */
    ApiGroupActivityDto getApiGroupActivityInfo(@Param("groupActivityId") Long groupActivityId, @Param("prodId") Long prodId);
    /**
     * 更新活动为已删除状态
     *
     * @param groupActivityId 团购活动id
     */
    void updateToDelete(@Param("groupActivityId") Long groupActivityId);
    /**
     * 获取拼团物品列表
     *
     * @param date 当前时间
     * @return 商品
     */
    List<Product> getActivityFinishProduct(@Param("newDate") Date date);
    /**
     * 更新活动状态
     *
     * @param activityId 活动id
     * @param status     状态
     * @return 更新的数量
     */
    int updateStatus(@Param("activityId") Long activityId, @Param("status") Integer status);
    /**
     * 批量改变团购商品状态类型
     *
     * @param groupActivityIds 团购活动id列表
     * @param status           改变的状态
     */
    void batchUpdateGroupActivityStatus(@Param("groupActivityIds") List<Long> groupActivityIds, @Param("status") Integer status);
    /**
     * 根据商品获取指定未失效的活动
     *
     * @param prodId
     * @return
     */
    GroupActivity getUnInvalidGroupActivityByProdId(@Param("prodId") Long prodId);
    /**
     * 更新团购活动的状态
     *
     * @param groupActivityId
     * @param status
     */
    void updateGroupActivityStatus(@Param("groupActivityId") Long groupActivityId, @Param("status") Integer status);
    /**
     * 获取团购价格
     * @param prodIds
     * @return
     */
    List<GroupActivity> listActivityPrice(@Param("prodIds") List<Long> prodIds);
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dao/GroupOrderMapper.java
New file
@@ -0,0 +1,77 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupUserDto;
import com.yami.shop.groupbuy.common.model.GroupOrder;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
public interface GroupOrderMapper extends BaseMapper<GroupOrder> {
    /**
     * 获取参团的用户列表
     *
     * @param groupTeamId 拼团单ID
     * @return ApiGroupUserDto列表
     */
    List<ApiGroupUserDto> listApiGroupUserDto(@Param("groupTeamId") Long groupTeamId);
//
//    /**
//     * 获取活动已经成团的用户数量
//     *
//     * @param groupActivityId 团购活动id
//     * @param groupProdId 团购商品id
//     * @return 成团的用户数量
//     */
//    Long getHadGroupNumberCount(@Param("groupActivityId") Long groupActivityId, @Param("groupProdId") Long groupProdId);
//
//    /**
//     * 根据团购商品id, 获取团购订单列表
//     *
//     * @param groupProdId 团购商品id
//     * @param userId 用户id
//     * @return 团购订单
//     */
//    List<GroupOrder> listByGroupProdId(@Param("groupProdId") Long groupProdId, @Param("userId") String userId);
    /**
     * 获取拼团队列中,已拼团的商品数量
     * @param userId 用户id
     * @param groupActivityId 团购活动id
     * @return 团购商品数量
     */
    Integer getUserHadOrderCountByGroupProdId(@Param("userId") String userId, @Param("groupActivityId") Long groupActivityId);
    /**
     * 获取拼团订单数量
     * @param userId 用户id
     * @param groupActivityId 团购商品id
     * @param prodId
     * @return 拼团团队订单数
     */
    int getUserUnGroupOrderCount(@Param("userId") String userId, @Param("groupActivityId") Long groupActivityId, @Param("prodId") Long prodId);
    /**
     * 取消团购订单
     * @param orderNumber 订单编号
     * @param status 状态
     * @return 更新的订单数量
     */
    int cancelGroupOrder(@Param("orderNumber") String orderNumber,@Param("status") int status);
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dao/GroupSkuMapper.java
New file
@@ -0,0 +1,61 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupSkuDto;
import com.yami.shop.groupbuy.common.model.GroupSku;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 拼团活动商品规格
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
public interface GroupSkuMapper extends BaseMapper<GroupSku> {
    /**
     * 获取SKU列表数据
     *
     * @param groupActivityId 拼团活动ID
     * @param lang            当前语言
     * @return SKU列表
     */
    List<ApiGroupSkuDto> getApiByGroupActivityIdAndProdId(@Param("groupActivityId") Long groupActivityId, @Param("lang") Integer lang);
    /**
     * 获取指定商品的活动sku列表
     *
     * @param prodIds
     * @return
     */
    List<GroupSku> listSkuByProdIds(@Param("prodIds") List<Long> prodIds);
//    /**
//     * 通过skuId获取活动规格详情
//     *
//     * @param groupSkuId 团购商品规格id
//     * @param lang
//     * @return 团购商品及规格信息
//     */
//    ApiGroupSkuInfoDto getSkuInfoByGroupSkuId(@Param("groupSkuId") Long groupSkuId, @Param("lang") Integer lang);
    /**
     * 根据活动id和活动价格获取skuId
     * @param groupActivityId
     * @param actPrice
     * @return
     */
    Long getSkuIdByProdIdAndActPrice(@Param("groupActivityId")Long groupActivityId,@Param("actPrice") Double actPrice);
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dao/GroupTeamMapper.java
New file
@@ -0,0 +1,120 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.bean.model.Order;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupTeamDto;
import com.yami.shop.groupbuy.common.api.dto.ApiJoinGroupTeamDto;
import com.yami.shop.groupbuy.common.dto.GroupOrderDTO;
import com.yami.shop.groupbuy.common.dto.GroupRefundOrder;
import com.yami.shop.groupbuy.common.dto.GroupTeamDto;
import com.yami.shop.groupbuy.common.model.GroupOrder;
import com.yami.shop.groupbuy.common.model.GroupTeam;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
 * 拼团团队表
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
public interface GroupTeamMapper extends BaseMapper<GroupTeam> {
    /**
     * 获取分页列表
     *
     * @param page 分页信息
     * @param groupTeamDto 团购团队信息
     * @return 团购团队列表
     */
    IPage<GroupTeamDto> getPage(Page page, @Param("groupTeam") GroupTeamDto groupTeamDto);
    /**
     * 根据团队id分页获取拼团订单信息
     * @param page
     * @param groupOrder
     * @return
     */
    IPage<GroupOrderDTO> getGroupOrderPage(PageParam<GroupOrder> page, @Param("groupOrder") GroupOrder groupOrder);
    /**
     * 可加入的团列表
     *
     * @param groupActivityId 拼团活动ID
     * @param nowTime         当前时间
     * @param showSize        显示数量(默认10)
     * @return 团列表
     */
    List<ApiGroupTeamDto> listByJoinGroupAndNowDate(@Param("groupActivityId") Long groupActivityId, @Param("nowTime") Date nowTime, @Param("showSize") Integer showSize);
    /**
     * 获取拼团单(拼团团队)信息
     *
     * @param groupTeamId 团单ID
     * @return ApiGroupTeamDto对象
     */
    ApiGroupTeamDto getApiGroupTeamDtoByTeamId(@Param("groupTeamId") Long groupTeamId);
    /**
     * 获取拼团团队信息
     *
     * @param groupActivityId 活动ID
     * @return 拼团团队信息
     */
    ApiJoinGroupTeamDto getJoinGroupTeamHasMaxNum(@Param("groupActivityId") Long groupActivityId);
    /**
     * 获取活动结束或团单结束未成团的拼团团队
     *
     * @param nowDate 当前时间
     * @return GroupTeam列表
     */
    List<GroupTeam> getNotGroupTeamByNowDate(@Param("nowDate") Date nowDate);
    /**
     * 获取未成团的订单ID列表
     *
     * @param groupTeamId 拼团团队ID
     * @return 团购退款订单列表
     */
    List<GroupRefundOrder> getJoinNotGroupTeamOrder(@Param("groupTeamId") Long groupTeamId);
    /**
     * 通过活动id获取未成团的订单
     *
     * @param groupActivityId 团购活动id
     * @return 团购团队列表
     */
    List<GroupTeam> getNotGroupTeamsByActivityId(@Param("groupActivityId") Long groupActivityId);
    /**
     * 获取参团的订单列表
     * @param groupTeamId 拼团团队ID
     * @param status 支付状态
     * @return 订单列表
     */
    List<Order> getOrders(@Param("groupTeamId") Long groupTeamId, @Param("status") Integer status);
    /**
     * 通过活动商品id获取未成团的订单
     *
     * @param prodId 商品id
     * @return 团购团队列表
     */
    List<GroupTeam> getNotGroupTeamByProdId(@Param("prodId") Long prodId);
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dto/GroupActivityDto.java
New file
@@ -0,0 +1,64 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
/**
 * 拼团活动状态类型
 *
 * @author 小懒虫
 * @date 2019/8/30 9:02
 */
@Data
public class GroupActivityDto {
    @Schema(description = "拼团活动id" )
    private Long groupActivityId;
    @Schema(description = "店铺id" )
    private Long shopId;
    @Schema(description = "活动名称" )
    private String activityName;
    @Schema(description = "拼团状态(1:启用、2:未启用、0:已失效、-1:删除、3:违规下架、4:平台审核 5:已结束)" )
    private Integer status;
    @Schema(description = "活动开始时间" )
    private Date startTime;
    @Schema(description = "活动结束时间" )
    private Date endTime;
    @Schema(description = "成团人数" )
    private Integer groupNumber;
    @Schema(description = "已成团订单数(统计)" )
    private Long groupOrderCount;
    @Schema(description = "活动状态(根据活动时间生成)" )
    private Integer activityStatus;
    @Schema(description = "店铺名称" )
    private String shopName;
    @Schema(description = "商品名称" )
    private String prodName;
    @Schema(description = "商品图片" )
    private String pic;
    @Schema(description = "语言" )
    private Integer lang;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dto/GroupOrderDTO.java
New file
@@ -0,0 +1,59 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
/**
 * @author lhd
 * @date 2022/05/17
 */
@Data
public class GroupOrderDTO {
    @Schema(description = "拼团订单id" )
    private Long groupOrderId;
    @Schema(description = "店铺id" )
    private Long shopId;
    @Schema(description = "拼团团队id" )
    private Long groupTeamId;
    @Schema(description = "拼团活动id" )
    private Long groupActivityId;
    @Schema(description = "user_id(当user_id为0时标识为机器人)" )
    private String userId;
    @Schema(description = "身份标识(0:成员  1:团长)" )
    private Integer identityType;
    @Schema(description = "销售价" )
    private Double activityProdPrice;
    @Schema(description = "拼团价" )
    private Double groupPrice;
    @Schema(description = "实付金额" )
    private Double payPrice;
    @Schema(description = "订单编号" )
    private String orderNumber;
    @Schema(description = "创建时间" )
    private Date createTime;
    @Schema(description = "状态 0:待支付、1:支付成功、-1:失效" )
    private Integer status;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dto/GroupProdAndSkuListDto.java
New file
@@ -0,0 +1,58 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.dto;
import com.yami.shop.groupbuy.common.model.GroupSku;
import com.yami.shop.groupbuy.common.utils.GroupActivityUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
 * 活动商品和商品下所有规格属性
 *
 * @author Yami
 */
@Data
public class GroupProdAndSkuListDto {
    @Schema(description = "活动商品id" )
    private Integer groupProdId;
    @Schema(description = "商品id" )
    private Integer prodId;
    @Schema(description = "商品名称" )
    private String prodName;
    @Schema(description = "活动开始时间" )
    private Date startTime;
    @Schema(description = "活动结束时间" )
    private Date endTime;
    @Schema(description = "活动状态" )
    private Integer status;
    @Schema(description = "活动状态" )
    private Integer activityStatus;
    @Schema(description = "规格列表" )
    private List<GroupSku> skuDtoList;
    /**
     * 获取活动状态(活动状态:1:未开始、2:进行中、3:已结束、4:已失效)
     */
    public Integer getActivityStatus() {
        return GroupActivityUtil.getActivityStatus(startTime, endTime, status);
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dto/GroupProdDto.java
New file
@@ -0,0 +1,102 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.yami.shop.common.serializer.json.ImgJsonSerializer;
import com.yami.shop.groupbuy.common.model.GroupSku;
import com.yami.shop.groupbuy.common.utils.GroupActivityUtil;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
 * @author Yami
 */
@Data
public class GroupProdDto {
    /**
     * 活动商品id
     */
    private Long groupProdId;
    /**
     * 店铺id
     */
    private Long shopId;
    /**
     * 活动id
     */
    private Long groupActivityId;
    /**
     * 商品id
     */
    private Long prodId;
    /**
     * 创建时间
     */
    private Date createTime;
    /**
     * 已成团订单数(统计)
     */
    private Long groupOrderCount;
    /**
     * 已成团人数(统计)
     */
    private Long groupNumberCount;
    /**
     * 状态(1:正常 2:失效 -1:已删除)
     */
    private Integer groupProdStatus;
    /**
     * 商品名称
     */
    private String prodName;
    /**
     * 商品图片
     */
    @JsonSerialize(using = ImgJsonSerializer.class)
    private String pic;
    /**
     * 活动商品规格属性
     */
    private List<GroupSku> groupSkuList;
    /**
     * 活动开始时间
     */
    private Date startTime;
    /**
     * 活动结束时间
     */
    private Date endTime;
    /**
     * 状态
     */
    private Integer groupActivityStatus;
    /**
     * 活动状态
     */
    private Integer activityStatus;
    /**
     * 获取活动状态(活动状态:1:未开始、2:进行中、3:已结束、4:已失效)
     */
    public Integer getActivityStatus() {
        return GroupActivityUtil.getActivityStatus(startTime, endTime, groupActivityStatus);
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dto/GroupRefundOrder.java
New file
@@ -0,0 +1,44 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.dto;
import com.yami.shop.bean.model.Order;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * 拼团退款数据模型
 * @author 小懒虫
 * @date 2019/9/4 16:21
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class GroupRefundOrder extends Order {
    /**
     * 支付单ID
     */
    private Long settlementId;
    /**
     * 支付单号
     */
    private String orderPayNo;
    /**
     * 支付状态
     */
    private Integer payStatus;
    /**
     * 团购订单id
     */
    private Long groupOrderId;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dto/GroupTeamDto.java
New file
@@ -0,0 +1,66 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
*//*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
/**
 * 拼团活动状态类型
 *
 * @author 小懒虫
 * @date 2019/8/28 17:43
*/
@Data
public class GroupTeamDto {
    @Schema(description = "拼团团队ID" )
    private Long groupTeamId;
    @Schema(description = "活动id" )
    private Long groupActivityId;
    @Schema(description = "活动名称" )
    private String activityName;
    @Schema(description = "开团时间" )
    private Date startTime;
    @Schema(description = "成团人数" )
    private Integer groupNumber;
    @Schema(description = "已参团人数" )
    private Integer joinNum;
    @Schema(description = "订单总金额" )
    private Double totalPrice;
    @Schema(description = "拼团状态(0:待成团,1:拼团中,2:拼团成功,3:拼团失败)" )
    private Integer status;
    @Schema(description = "店铺Id" )
    private Long shopId;
    @Schema(description = "商品名称" )
    private String prodName;
    @Schema(description = "商品图片" )
    private String pic;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/dto/GroupUserActivityDto.java
New file
@@ -0,0 +1,32 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * 用户参团信息
 *
 * @author 小懒虫
 * @date 2019/8/31 11:33
 */
@Data
public class GroupUserActivityDto {
    @Schema(description = "用户是可参加当前商品拼团活动(1:可参加,2:已参加)" )
    private Integer isJoinActivity;
    @Schema(description = "拼团团队ID(已参加活动状态下)" )
    private Integer groupTeamId;
    @Schema(description = "已参加购买数量" )
    private Integer joinNumber;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/enums/ActivityStatusEnum.java
New file
@@ -0,0 +1,66 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.enums;
import lombok.Getter;
/**
 * 拼团活动状态类型(用户查询之后对活动活动的封装)
 *
 * @author Yami
 */
@Getter
public enum ActivityStatusEnum {
    /**
     * 未开始
     */
    NOT_STARTED(1, "未开始"),
    /**
     * 进行中
     */
    UNDER_WAY(2, "进行中"),
    /**
     * 已结束
     */
    FINISHED(3, "已结束"),
    /**
     * 已失效
     */
    EXPIRED(4, "已失效"),
    /**
     * 违规下架
     */
    OFFLINE(5, "违规下架"),
    /**
     * 等待审核
     */
    WAIT_AUDIT(6, "等待审核");
    private Integer code;
    private String title;
    public Integer value() {
        return code;
    }
    ActivityStatusEnum(Integer code, String title) {
        this.code = code;
        this.title = title;
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/enums/GroupActivityStatusEnum.java
New file
@@ -0,0 +1,70 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.enums;
import lombok.Getter;
/**
 * 拼团活动状态类型(对应数据库中的活动状态)
 *
 * @author Yami
 */
@Getter
public enum GroupActivityStatusEnum {
    /**
     * 删除
     */
    DELETE(-1, "删除"),
    /**
     * 已失效
     */
    INVALID(0, "已失效"),
    /**
     * 启用
     */
    ENABLE(1, "启用"),
    /**
     * 未启用
     */
    DISABLE(2, "未启用"),
    /**
     * 违规下架
     */
    OFFLINE(3, "违规下架"),
    /**
     * 等待审核
     */
    WAIT_AUDIT(4, "等待审核"),
    /**
     * 已结束
     */
    END(5, "已结束");
    private Integer code;
    private String title;
    public Integer value() {
        return code;
    }
    GroupActivityStatusEnum(Integer code, String title) {
        this.code = code;
        this.title = title;
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/enums/GroupOrderStatusEnum.java
New file
@@ -0,0 +1,42 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
 * 拼团订单状态类型
 *
 * @author Yami
 */
@Getter
@AllArgsConstructor
public enum GroupOrderStatusEnum {
    /** 待支付 */
    WAITING_PAY(0, "待支付"),
    /** 支付成功 */
    SUCCESS(1, "支付成功"),
    /** 失效 */
    FAIL(-1, "失效");
    private Integer code;
    private String title;
    public Integer value() {
        return code;
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/enums/GroupProdStatusEnum.java
New file
@@ -0,0 +1,51 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.enums;
import lombok.Getter;
/**
 * 拼团活动商品状态类型
 *
 * @author Yami
 */
@Getter
public enum GroupProdStatusEnum {
    /**
     * 正常
     */
    NORMAL(1, "正常"),
    /**
     * 已失效
     */
    EXPIRED(2, "已失效"),
    /**
     * 已结束
     */
    DELETE(-1, "已删除"),
    ;
    private Integer code;
    private String title;
    public Integer value() {
        return code;
    }
    GroupProdStatusEnum(Integer code, String title) {
        this.code = code;
        this.title = title;
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/enums/TeamStatusEnum.java
New file
@@ -0,0 +1,47 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.enums;
import lombok.Getter;
/**
 * 拼团团队状态类型
 *
 * @author Yami
 */
@Getter
public enum TeamStatusEnum {
    /** 待成团(未支付) */
    WAITING_GROUP(0, "待成团"),
    /** 拼团中(已支付) */
    IN_GROUP(1, "拼团中"),
    /** 拼团成功 */
    SUCCESS(2, "拼团成功"),
    /** 拼团失败 */
    FAIL(3, "拼团失败");
    private Integer code;
    private String title;
    public Integer value() {
        return code;
    }
    TeamStatusEnum(Integer code, String title){
        this.code = code;
        this.title = title;
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/CancelOrderListener.java
New file
@@ -0,0 +1,52 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.listener;
import com.yami.shop.bean.enums.OrderType;
import com.yami.shop.bean.event.CancelOrderEvent;
import com.yami.shop.bean.order.CancelOrderOrder;
import com.yami.shop.groupbuy.common.service.GroupOrderService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Objects;
/**
 * 取消订单事件监听
 *
 * @author Yami
 */
@Slf4j
@Component("cancelOrderListener")
@AllArgsConstructor
public class CancelOrderListener {
    final private GroupOrderService groupOrderService;
    /**
     * 取消团购订单
     */
    @EventListener(CancelOrderEvent.class)
    @Order(CancelOrderOrder.GROUPBUY)
    public void grouponCancelOrderListener(CancelOrderEvent event) {
        if (!Objects.equals(event.getOrder().getOrderType(), OrderType.GROUP.value())) {
            return;
        }
        String orderNumber = event.getOrder().getOrderNumber();
        int i = groupOrderService.cancelGroupOrder(orderNumber, -1);
        if(i < 1){
            log.error("取消团购订单失败  => {}", orderNumber);
        }
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/CategoryGroupbuyListener.java
New file
@@ -0,0 +1,34 @@
package com.yami.shop.groupbuy.common.listener;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.event.CategoryWordEvent;
import com.yami.shop.groupbuy.common.enums.GroupActivityStatusEnum;
import com.yami.shop.groupbuy.common.model.GroupActivity;
import com.yami.shop.groupbuy.common.service.GroupActivityService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.List;
@Component("CategoryGroupbuyListener")
@Slf4j
@AllArgsConstructor
public class CategoryGroupbuyListener {
    private final GroupActivityService groupActivityService;
    @EventListener(CategoryWordEvent.class)
    public void categoryListener(CategoryWordEvent event) {
        List<Long> prodIds = event.getProdIdList();
        // 失效拼团活动
        if(CollUtil.isNotEmpty(prodIds)){
            groupActivityService.update(Wrappers.lambdaUpdate(GroupActivity.class)
                    .set(GroupActivity::getStatus, GroupActivityStatusEnum.INVALID.getCode())
                    .in(GroupActivity::getProdId, prodIds)
                    .in(GroupActivity::getStatus, GroupActivityStatusEnum.ENABLE.getCode(), GroupActivityStatusEnum.DISABLE.getCode())
            );
        }
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/EsProductActivityInfoListener.java
New file
@@ -0,0 +1,73 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.listener;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.enums.ProdType;
import com.yami.shop.bean.event.EsProductActivityInfoEvent;
import com.yami.shop.bean.order.EsProductOrder;
import com.yami.shop.bean.vo.search.GroupActivitySearchVO;
import com.yami.shop.bean.vo.search.ProductSearchVO;
import com.yami.shop.groupbuy.common.dao.GroupActivityMapper;
import com.yami.shop.groupbuy.common.model.GroupActivity;
import lombok.AllArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
 * 获取商品团购数据事件
 * @author yami
 */
@Component("groupBuyEsProductActivityInfoListener")
@AllArgsConstructor
public class EsProductActivityInfoListener {
    private final GroupActivityMapper groupActivityMapper;
    private final MapperFacade mapperFacade;
    @EventListener(EsProductActivityInfoEvent.class)
    @Order(EsProductOrder.GROUP_BUY)
    public void groupBuyEsProductListener(EsProductActivityInfoEvent event) {
        Long currentTime = System.currentTimeMillis();
        List<ProductSearchVO> productList = event.getProductList();
        List<Long> activityIds = productList.stream()
                .filter(productSearchVO -> Objects.equals(productSearchVO.getProdType(), ProdType.PROD_TYPE_GROUP.value()) &&
                        Objects.nonNull(productSearchVO.getActivityStartTime()) &&
                        productSearchVO.getActivityStartTime() < currentTime
                )
                .map(ProductSearchVO::getActivityId)
                .collect(Collectors.toList());
        // 没有开始中的团购商品需要处理
        if (CollUtil.isEmpty(activityIds)) {
            return;
        }
        List<GroupActivity> groupActivities = groupActivityMapper.selectList(new LambdaQueryWrapper<GroupActivity>().in(GroupActivity::getGroupActivityId, activityIds));
        Map<Long, GroupActivity> groupMap = groupActivities.stream().collect(Collectors.toMap(GroupActivity::getGroupActivityId, g -> g));
        for (ProductSearchVO productSearchVO : productList) {
            GroupActivity groupActivity = groupMap.get(productSearchVO.getActivityId());
            if (Objects.isNull(groupActivity)) {
                continue;
            }
            GroupActivitySearchVO groupActivitySearchVO = mapperFacade.map(groupActivity, GroupActivitySearchVO.class);
            productSearchVO.setActivityInProgress(Boolean.TRUE);
            productSearchVO.setGroupActivitySearchVO(groupActivitySearchVO);
        }
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/EsProductListener.java
New file
@@ -0,0 +1,123 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.listener;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.bo.ProductBO;
import com.yami.shop.bean.enums.ProdType;
import com.yami.shop.bean.event.EsProductEvent;
import com.yami.shop.bean.model.Sku;
import com.yami.shop.bean.order.EsProductOrder;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.dao.SkuMapper;
import com.yami.shop.groupbuy.common.dao.GroupActivityMapper;
import com.yami.shop.groupbuy.common.dao.GroupSkuMapper;
import com.yami.shop.groupbuy.common.model.GroupActivity;
import com.yami.shop.groupbuy.common.model.GroupSku;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
/**
 * 获取es商品团购数据事件
 * @author yami
 */
@Component("groupBuyEsProductListener")
@Slf4j
@AllArgsConstructor
public class EsProductListener {
    private final GroupActivityMapper groupActivityMapper;
    private final GroupSkuMapper groupSkuMapper;
    private final SkuMapper skuMapper;
    @EventListener(EsProductEvent.class)
    @Order(EsProductOrder.GROUP_BUY)
    public void groupBuyEsProductListener(EsProductEvent event) {
        List<ProductBO> productList = event.getProductList();
        if (CollUtil.isEmpty(productList) || Objects.nonNull(event.getOperationType())) {
            return;
        }
        List<ProductBO> groupBuyProductList = new ArrayList<>();
        List<Long> groupActivityIds = new ArrayList<>();
        List<Long> prodIds = new ArrayList<>();
        for (ProductBO productBO : productList) {
            if (!Objects.equals(productBO.getProdType(), ProdType.PROD_TYPE_GROUP.value())) {
                continue;
            }
            groupBuyProductList.add(productBO);
            groupActivityIds.add(productBO.getActivityId());
            prodIds.add(productBO.getProdId());
        }
        if (CollUtil.isEmpty(groupActivityIds)) {
            return;
        }
        // 获取已启用的团购商品信息
        List<GroupActivity> groupActivities = groupActivityMapper.selectList(new LambdaQueryWrapper<GroupActivity>()
                .in( GroupActivity::getGroupActivityId, groupActivityIds)
                .eq(GroupActivity::getStatus, 1)
        );
        List<GroupSku> skuList = groupSkuMapper.listSkuByProdIds(prodIds);
        Map<Long, List<GroupSku>> skuMap = skuList.stream().collect(Collectors.groupingBy(GroupSku::getProdId));
        Map<Long, GroupActivity> groupActivityMap = groupActivities.stream().collect(Collectors.toMap(GroupActivity::getGroupActivityId, g -> g));
        // 获取商品最低价
        Long currentTime = System.currentTimeMillis();
        for (ProductBO productBO : groupBuyProductList) {
            if (!groupActivityMap.containsKey(productBO.getActivityId())) {
                continue;
            }
            GroupActivity groupActivity = groupActivityMap.get(productBO.getActivityId());
            // 活动未启用,或当前时间大于等于活动结束时间, 则不添加活动信息
            if (groupActivity.getEndTime().getTime() <= currentTime) {
                continue;
            }
            // 团购商品最低价和对应sku原价
            productBO.setActivityPrice(groupActivity.getPrice());
            Long skuId = groupSkuMapper.getSkuIdByProdIdAndActPrice(productBO.getActivityId(), groupActivity.getPrice());
            Sku skuBySkuId = skuMapper.getSkuBySkuId(skuId, I18nMessage.getLang());
            productBO.setActivityOriginalPrice(skuBySkuId.getOriPrice());
            productBO.setPrice(skuBySkuId.getPrice());
            productBO.setOriPrice(skuBySkuId.getOriPrice());
            long startTime = groupActivity.getStartTime().getTime();
            // 活动没有预热且活动开始时间大于当前时间,插入活动开始时间
            if (Objects.equals(groupActivity.getIsPreheat(), 0) && startTime > currentTime) {
                productBO.setActivityStartTime(startTime);
                continue;
            }
            // 活动预热、活动开始时间等于小于当前时间,插入当前时间
            productBO.setActivityStartTime(currentTime);
        }
    }
    private Double getActivityOriginalPrice(Double price, List<GroupSku> skus, Long groupActivityId) {
        if (CollUtil.isEmpty(skus)) {
            // 防止空指针-正常情况下不会出现这种情况
            log.error("id为{}的团购活动,sku列表无法获取", groupActivityId);
            return price;
        }
        // 活动sku金额正序 -> sku原价正序
        skus.sort(Comparator.comparing(GroupSku::getActPrice).thenComparing(GroupSku::getPrice));
        // 排序后,第一个sku就是活动sku金额及sku金额最低的
        return skus.get(0).getPrice();
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/InvalidGroupProdListener.java
New file
@@ -0,0 +1,56 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.listener;
import com.yami.shop.bean.enums.ProdStatusEnums;
import com.yami.shop.bean.enums.ProdType;
import com.yami.shop.bean.event.ProdChangeStatusEvent;
import com.yami.shop.bean.model.Product;
import com.yami.shop.bean.order.GeneralActivitiesOrder;
import com.yami.shop.groupbuy.common.service.GroupActivityService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Objects;
/**
 * @author Yami
 */
@Component("InvalidGroupProStatus")
@AllArgsConstructor
public class InvalidGroupProdListener {
    private final GroupActivityService groupActivityService;
    /**
     * 使团购商品失效
     */
    @EventListener(ProdChangeStatusEvent.class)
    @Order(GeneralActivitiesOrder.GROUPON)
    public void invalidGroupProStatusListener(ProdChangeStatusEvent event) {
        if (Objects.equals(ProdStatusEnums.NORMAL.getValue(), event.getStatus())) {
            return;
        }
        if (Objects.equals(ProdStatusEnums.PLATFORM_AUDIT.getValue(), event.getStatus())) {
            return;
        }
        Product product = event.getProduct();
        // 不是团购商品,就不用管他
        if(!Objects.equals(product.getProdType(), ProdType.PROD_TYPE_GROUP.value())){
            return;
        }
        Long prodId = product.getProdId();
        // 下架时检查是否有拼团活动,有的话使之全部失效
        groupActivityService.handleOfflineGroupProd(product.getShopId(),prodId);
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/PaySuccessOrderListener.java
New file
@@ -0,0 +1,52 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.listener;
import com.yami.shop.bean.enums.OrderType;
import com.yami.shop.bean.event.PaySuccessOrderEvent;
import com.yami.shop.bean.order.PaySuccessOrderOrder;
import com.yami.shop.groupbuy.common.service.GroupPayService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Objects;
/**
 * 团购支付回调
 *
 * @author Yami
 */
@Component("groupPaySuccessListener")
@AllArgsConstructor
public class PaySuccessOrderListener {
    private GroupPayService groupPayService;
    /**
     * 团购支付成功回调
     */
    @EventListener(PaySuccessOrderEvent.class)
    @Order(PaySuccessOrderOrder.GROUPON)
    public void grouponPaySuccessListener(PaySuccessOrderEvent event) {
        List<com.yami.shop.bean.model.Order> orders = event.getOrders();
        for (com.yami.shop.bean.model.Order order : orders) {
            if (!Objects.equals(order.getOrderType(), OrderType.GROUP.value())) {
                continue;
            }
            // 支付成功回调通知处理
            groupPayService.paySuccessNoticeHandle(order);
        }
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/ProcessActivityProdPriceListener.java
New file
@@ -0,0 +1,67 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.listener;
import cn.hutool.core.collection.CollUtil;
import com.yami.shop.bean.event.ProcessActivityProdPriceEvent;
import com.yami.shop.bean.model.Product;
import com.yami.shop.groupbuy.common.dao.GroupActivityMapper;
import com.yami.shop.groupbuy.common.model.GroupActivity;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * 处理活动商品价格的事件
 * @author lhd
 */
@Component("processGroupProdPriceListener")
@AllArgsConstructor
public class ProcessActivityProdPriceListener {
    private final GroupActivityMapper groupActivityMapper;
    @EventListener(ProcessActivityProdPriceEvent.class)
    public void processGroupProdPrice(ProcessActivityProdPriceEvent event) {
        if (CollUtil.isEmpty(event.getProducts())) {
            return;
        }
        List<Long> prodIds = event.getProducts().stream().map(Product::getProdId).collect(Collectors.toList());
        List<GroupActivity> groupActivityList = groupActivityMapper.listActivityPrice(prodIds);
        if (CollUtil.isEmpty(groupActivityList)) {
            return;
        }
        Map<Long, Double> groupProdMap = groupActivityList.stream().collect(Collectors.toMap(GroupActivity::getProdId, GroupActivity::getPrice));
        for (Product product : event.getProducts()) {
            if (!groupProdMap.containsKey(product.getProdId())) {
                continue;
            }
            product.setActivityPrice(groupProdMap.get(product.getProdId()));
        }
//
//
//        List<Product> products = event.getProducts();
//        List<Long> prodIds = new ArrayList<>();
//        products.forEach(product -> prodIds.add(product.getProdId()));
//        List<Product> activityProds = prodMapper.listByProdIds(prodIds);
//        Map<Long, Double> priceMap = activityProds.stream().collect(Collectors.toMap(Product::getProdId, Product::getPrice));
//        for (Product product : products) {
//            Double price = priceMap.get(product.getProdId());
//            product.setActivityPrice(price);
//        }
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/ProdChangeListener.java
New file
@@ -0,0 +1,70 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.listener;
import com.yami.shop.bean.event.ProdChangeEvent;
import com.yami.shop.bean.model.Product;
import com.yami.shop.groupbuy.common.model.GroupTeam;
import com.yami.shop.groupbuy.common.service.GroupActivityService;
import com.yami.shop.groupbuy.common.service.GroupTeamService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Objects;
/**
 * @author Yami
 */
@Slf4j
@Component("groupbuyProdChangeListener")
@AllArgsConstructor
public class ProdChangeListener {
    private final GroupActivityService groupActivityService;
    private final GroupTeamService groupTeamService;
    @EventListener(ProdChangeEvent.class)
    public void prodChangeEvent(ProdChangeEvent event) {
        // 删除的商品的时候,处理已经开团但是未成团的
        // 已经成团的订单按正常流程处理
        // 实际上不需要处理,开启定时任务后,如果开团成功后,删除掉商品,
        // 则拼团不会成功,则会自动退款,
        // 这里如果处理退款,有一定得几率和定时任务处理退款同时运行,所以这里不处理退款
//        handleGroupBugAfterDeleteProd(event);
    }
    /**  删除商品时,处理团购相关 */
    private void handleGroupBugAfterDeleteProd(ProdChangeEvent event) {
        Product product = event.getProduct();
        Long prodId = product.getProdId();
        if (Objects.isNull(prodId)) {
            return;
        }
        // 查询出所有已开团,待成团的订单,
        List<GroupTeam> groupTeams = groupTeamService.getNotGroupTeamByProdId(prodId);
        if (CollectionUtils.isEmpty(groupTeams)) {
            return;
        }
        // 处理未成团的拼团团队,返回退款单列表
        for (GroupTeam groupTeam : groupTeams) {
            groupTeamService.updateNotGroupTeam(groupTeam);
        }
        String okStr = true ? "成功" : "失败";
        log.info("删除商品prodId = " + prodId + "时,同时也去除在分销设置中的商品prodId = "+ prodId + " ,更新" + okStr);
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/listener/ShopChangeStatusListener.java
New file
@@ -0,0 +1,42 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.listener;
import com.yami.shop.bean.enums.ShopStatus;
import com.yami.shop.bean.event.ShopChangeStatusEvent;
import com.yami.shop.groupbuy.common.service.GroupActivityService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.Objects;
/**
 * 店铺改变状态监听
 *
 * @Author lth
 * @Date 2021/11/23 10:45
 */
@Component("groupBuyShopChangeStatusListener")
@AllArgsConstructor
public class ShopChangeStatusListener {
    private final GroupActivityService groupActivityService;
    @EventListener(ShopChangeStatusEvent.class)
    public void groupBuyShopChangeStatusListener(ShopChangeStatusEvent event) {
        Long shopId = event.getShopId();
        ShopStatus shopStatus = event.getShopStatus();
        if (Objects.equals(shopStatus, ShopStatus.OFFLINE)) {
            // 店铺下线时,失效所有状态为正在进行中的团购活动
            groupActivityService.invalidGroupByShopId(shopId);
        }
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/model/GroupActivity.java
New file
@@ -0,0 +1,107 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupSkuDto;
import com.yami.shop.groupbuy.common.utils.GroupActivityUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@Data
@TableName("tz_group_activity")
@Schema(description = "拼团活动表")
public class GroupActivity implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId
    @Schema(description = "拼团活动id" )
    private Long groupActivityId;
    @Schema(description = "店铺id" )
    private Long shopId;
    @Schema(description = "活动名称" )
    private String activityName;
    @Schema(description = "商品id" )
    private Long prodId;
    @Schema(description = "拼团状态(1:启用、2:未启用、0:已失效、-1:删除、3:违规下架、4:平台审核 5:已结束)" )
    private Integer status;
    @Schema(description = "活动开始时间" )
    private Date startTime;
    @Schema(description = "活动结束时间" )
    private Date endTime;
    @Schema(description = "成团有效期时间" )
    private Integer groupValidTime;
    @Schema(description = "成团人数" )
    private Integer groupNumber;
    @Schema(description = "商品是否限购" )
    private Integer hasMaxNum;
    @Schema(description = "限购数量" )
    private Integer maxNum;
    @Schema(description = "是否模拟成团" )
    private Integer hasRobot;
    @Schema(description = "活动是否预热" )
    private Integer isPreheat;
    @Schema(description = "是否开启凑团模式" )
    private Long hasGroupTip;
    @Schema(description = "拼团价格" )
    private Double price;
    @Schema(description = "创建时间" )
    private Date createTime;
    @Schema(description = "更新时间" )
    private Date updateTime;
    @TableField(exist = false)
    @Schema(description = "活动状态(根据活动时间生成)" )
    private Integer activityStatus;
    @TableField(exist = false)
    @Schema(description = "商品图片" )
    private String prodPic;
    @TableField(exist = false)
    @Schema(description = "商品名称" )
    private String prodName;
    @TableField(exist = false)
    @Schema(description = "商品名称" )
    private List<ApiGroupSkuDto> groupSkuList;
    @Schema(description = "获取活动状态(活动状态:1:未开始、2:进行中、3:已结束、4:已失效、5:违规下架、6:待审核)" )
    public Integer getActivityStatus(){
        return GroupActivityUtil.getActivityStatus(startTime, endTime, status);
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/model/GroupOrder.java
New file
@@ -0,0 +1,62 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.model;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@Data
@TableName("tz_group_order")
public class GroupOrder implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId
    @Schema(description = "拼团订单id" )
    private Long groupOrderId;
    @Schema(description = "店铺id" )
    private Long shopId;
    @Schema(description = "拼团团队id" )
    private Long groupTeamId;
    @Schema(description = "拼团活动id" )
    private Long groupActivityId;
    @Schema(description = "user_id(当user_id为0时标识为机器人)" )
    private String userId;
    @Schema(description = "身份标识(0:成员  1:团长)" )
    private Integer identityType;
    @Schema(description = "活动商品金额" )
    private Double activityProdPrice;
    @Schema(description = "支付金额" )
    private Double payPrice;
    @Schema(description = "订单编号" )
    private String orderNumber;
    @Schema(description = "创建时间" )
    private Date createTime;
    @Schema(description = "状态 0:待支付、1:支付成功、-1:失效" )
    private Integer status;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/model/GroupSku.java
New file
@@ -0,0 +1,61 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
/**
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@Data
@TableName("tz_group_sku")
@Schema(description = "拼团活动商品规格")
public class GroupSku implements Serializable {
    private static final long serialVersionUID = 1L;
    @Schema(description = "拼团活动商品规格id" )
    @TableId
    private Long groupSkuId;
    @Schema(description = "拼团活动id" )
    private Long groupActivityId;
    @Schema(description = "商品规格id" )
    private Long skuId;
    @Schema(description = "活动价格" )
    private Double actPrice;
    @Schema(description = "已售数量" )
    private Long sellNum;
    @Schema(description = "规格名称" )
    @TableField(exist = false)
    private String skuName;
    @Schema(description = "规格单价" )
    @TableField(exist = false)
    private Double price;
    @Schema(description = "sku库存" )
    @TableField(exist = false)
    private Long stocks;
    @Schema(description = "商品id" )
    @TableField(exist = false)
    private Long prodId;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/model/GroupTeam.java
New file
@@ -0,0 +1,76 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
 * 拼团团队表
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@Data
@TableName("tz_group_team")
public class GroupTeam implements Serializable {
    private static final long serialVersionUID = 1L;
    @Schema(description = "拼团团队id" )
    @TableId
    private Long groupTeamId;
    @Schema(description = "店铺id" )
    private Long shopId;
    @Schema(description = "拼团活动id" )
    private Long groupActivityId;
    @Schema(description = "商品Id" )
    private Long prodId;
    @Schema(description = "已参团人数" )
    private Integer joinNum;
    @Schema(description = "拼团状态(0:待成团,1:拼团中,2:拼团成功,3:拼团失败)" )
    private Integer status;
    @Schema(description = "团队订单总额" )
    private Double totalPrice;
    @Schema(description = "开始时间(团长支付成功时间)" )
    private Date startTime;
    @Schema(description = "结束时间" )
    private Date endTime;
    @Schema(description = "创建时间" )
    private Date createTime;
    @Schema(description = "团长user_Id" )
    private String shareUserId;
    @Schema(description = "更新时间" )
    private Date updateTime;
    @Schema(description = "是否模拟参团(1:模拟参团、0:不模拟)" )
    @TableField(exist = false)
    private Integer hasRobot;
    @Schema(description = "是否模拟参团(1:模拟参团、0:不模拟)" )
    @TableField(exist = false)
    private Integer groupNumber;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/param/GroupProdParam.java
New file
@@ -0,0 +1,30 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.param;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
 * 活动商品参数
 *
 * @author Yami
 */
@Data
public class GroupProdParam {
    @Schema(description = "活动id" )
    private Long groupActivityId;
    @Schema(description = "商品id列表" )
    private List<Long> prodIds;
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/GroupActivityService.java
New file
@@ -0,0 +1,138 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.bean.param.OfflineHandleEventAuditParam;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupActivityDto;
import com.yami.shop.groupbuy.common.dto.GroupActivityDto;
import com.yami.shop.groupbuy.common.model.GroupActivity;
/**
 * 拼团活动表
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
public interface GroupActivityService extends IService<GroupActivity> {
    /**
     * 根据商品id获取拼团活动信息
     * @param prodId 商品id
     * @return 拼团活动信息
     */
    ApiGroupActivityDto getByProdId(Long prodId);
    /**
     * 跟新拼团活动为已删除状态
     *
     */
    void updateToDelete(GroupActivity groupActivity);
    /**
     * 获取分页列表
     *
     * @param page             分页对象
     * @param groupActivityDto 拼团活动
     * @return 分页对象
     */
    IPage<GroupActivityDto> getGroupActivityPage(PageParam<GroupActivityDto> page, GroupActivityDto groupActivityDto);
    /**
     * 获取拼团活动信息
     *
     * @param groupActivityId 活动ID
     * @param prodId          商品ID
     * @return Api活动对象
     */
    ApiGroupActivityDto getApiGroupActivityInfo(Long groupActivityId, Long prodId);
    /**
     * 根据商品id清除团购活动缓存
     * @param prodId
     */
    void removeGroupActivityInfoCache(Long prodId);
    /**
     * 失效活动
     *
     * @param groupActivityId 团购活动信息
     */
    void invalidGroupActivity(Long groupActivityId);
    /**
     * 平台  -- 下架活动
     *
     * @param groupActivity 团购活动信息
     * @param offlineReason 下线原因
     * @param sysUserId 处理人id
     */
    void offline(GroupActivity groupActivity, String offlineReason, Long sysUserId);
    /**
     * 平台 -- 审核活动
     *
     * @param offlineHandleEventAuditParam 审核信息
     * @param sysUserId 处理人id
     */
    void auditGroupActivity(OfflineHandleEventAuditParam offlineHandleEventAuditParam, Long sysUserId);
    /**
     * 审核申请
     *
     * @param eventId 下线事件id
     * @param activityId 团购活动id
     * @param reapplyReason 申请理由
     */
    void auditApply(Long eventId, Long activityId, String reapplyReason);
    /**
     * 根据团购活动id列表,批量改变商品类型
     */
    void changeProdTypeByGroupActivityIdList();
    /**
     * 处理下下架商品时关联的团购活动
     * @param shopId 店铺id
     * @param prodId 商品id
     */
    void handleOfflineGroupProd(Long shopId, Long prodId);
    /**
     * 根据店铺id失效团购活动
     * @param shopId
     */
    void invalidGroupByShopId(Long shopId);
    /**
     * 保存团购信息
     * @param groupActivity
     */
    void saveGroupActivity(GroupActivity groupActivity);
    /**
     * 更新团购活动
     *
     * @param groupActivity
     * @return
     */
    void updateGroupActivity(GroupActivity groupActivity);
    /**
     * 获取团购信息(团购和绑定的商品信息)
     * @param groupActivityId
     * @return
     */
    GroupActivity getGroupActivityInfo(Long groupActivityId);
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/GroupOrderService.java
New file
@@ -0,0 +1,98 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.bean.app.dto.ShopCartOrderMergerDto;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupUserDto;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupUserOrderDto;
import com.yami.shop.groupbuy.common.bo.GroupOrderBO;
import com.yami.shop.groupbuy.common.model.GroupOrder;
import java.util.List;
/**
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
public interface GroupOrderService extends IService<GroupOrder> {
    /**
     * 获取参团的用户列表
     *
     * @param groupTeamId 拼团单ID
     * @return 参团的用户列表
     */
    List<ApiGroupUserDto> listApiGroupUserDto(Long groupTeamId);
    /**
     * 将确认订单的信息放入缓存
     * @param userId 用户id
     * @param apiGroupUserOrderDto 用户团购订单信息
     * @return 用户团购订单
     */
    ApiGroupUserOrderDto putConfirmOrderCache(String userId, ApiGroupUserOrderDto apiGroupUserOrderDto);
    /**
     * 获取缓存中确认订单的信息
     * @param userId 用户id
     * @return 用户团购订单
     */
    ApiGroupUserOrderDto getConfirmOrderCache(String userId);
    /**
     * 移除缓存中确认订单的信息
     * @param userId 用户id
     */
    void removeConfirmOrderCache(String userId);
    /**
     * 提交订单
     *
     * @param mergerOrder
     * @param groupOrderBO
     * @return 订单编号
     */
    void submit(ShopCartOrderMergerDto mergerOrder, GroupOrderBO groupOrderBO);
//    /**
//     * 通过活动商品id获取拼团订单列表
//     * @param groupActivityId 团购活动id
//     * @param userId 用户id
//     * @return 团购订单列表
//     */
//    List<GroupOrder> listByGroupProdId(Long groupActivityId, String userId);
    /**
     * 通过活动商品id获取用户已下单的商品数量
     * @param userId 用户id
     * @param groupActivityId 团购商品id
     * @return 商品的数量
     */
    Integer getUserHadOrderCountByGroupProdId(String userId, Long groupActivityId);
    /**
     * 获取用户未成团的订单数量
     * @param userId 用户ud
     * @param groupActivityId 团购商品id
     * @param prodId
     * @return 订单数量
     */
    int getUserUnGroupOrderCount(String userId, Long groupActivityId, Long prodId);
    /**
     * 取消团购订单
     * @param orderNumber 订单编号
     * @param status 状态
     * @return 更新的数量
     */
    int cancelGroupOrder(String orderNumber, int status);
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/GroupPayService.java
New file
@@ -0,0 +1,27 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.service;
import com.yami.shop.bean.model.Order;
/**
 * 拼团支付
 *
 * @author Yami
 */
public interface GroupPayService {
    /**
     * 支付成功事件通知  --支付成功处理
     * @param order 订单信息
     */
    void paySuccessNoticeHandle(Order order);
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/GroupSkuService.java
New file
@@ -0,0 +1,34 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupSkuDto;
import com.yami.shop.groupbuy.common.model.GroupSku;
import java.util.List;
/**
 * 拼团活动商品规格
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
public interface GroupSkuService extends IService<GroupSku> {
    /**
     * 获取SKU列表数据
     * @param groupActivityId 拼团活动ID
     * @return SKU列表
     */
    List<ApiGroupSkuDto> getApiByGroupActivityIdAndProdId(Long groupActivityId);
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/GroupTeamService.java
New file
@@ -0,0 +1,105 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupTeamDto;
import com.yami.shop.groupbuy.common.api.dto.ApiJoinGroupTeamDto;
import com.yami.shop.groupbuy.common.dto.GroupOrderDTO;
import com.yami.shop.groupbuy.common.dto.GroupTeamDto;
import com.yami.shop.groupbuy.common.model.GroupOrder;
import com.yami.shop.groupbuy.common.model.GroupTeam;
import java.util.List;
/**
 * 拼团团队表
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
public interface GroupTeamService extends IService<GroupTeam> {
    /**
     * 获取拼团团队分页列表
     *
     * @param page 分页
     * @param groupTeamDto 拼团团队
     * @return 拼团团队列表
     */
    IPage<GroupTeamDto> getPage(Page page, GroupTeamDto groupTeamDto);
    /**
     * 根据团队id分页获取拼团订单信息
     * @param page
     * @param groupOrder
     * @return
     */
    IPage<GroupOrderDTO> getGroupOrderPage(PageParam<GroupOrder> page, GroupOrder groupOrder);
    /**
     * 获取拼团单(拼团团队)
     *
     * @param groupTeamId 团单ID
     * @return ApiGroupTeamDto对象
     */
    ApiGroupTeamDto getApiGroupTeamDto(Long groupTeamId);
    /**
     * 获取参加的拼团团队信息
     *
     * @param groupActivityId 活动ID
     * @return 拼团团队
     */
    ApiJoinGroupTeamDto getJoinGroupTeamHasMaxNum(Long groupActivityId);
    /**
     * 获取活动结束或团单结束未成团的拼团团队
     *
     * @return ApiGroupTeamDto对象
     */
    List<GroupTeam> getNotGroupTeam();
    /**
     * 处理活动结束或团单结束未成团的拼团团队
     *
     * @param groupTeam 未成团的拼团团队
     */
    void updateNotGroupTeam(GroupTeam groupTeam);
    /**
     * 通过拼团活动id获取未成团的团队列表
     *
     * @param groupActivityId 团购活动id
     * @return 拼团团队列表
     */
    List<GroupTeam> getNotGroupTeamsByActivityId(Long groupActivityId);
    /**
     * 通过商品id获取未成团的团队列表
     *
     * @param prodId 商品id
     * @return 拼团团队列表
     */
    List<GroupTeam> getNotGroupTeamByProdId(Long prodId);
    /**
     * 可加入的团列表
     * @param groupActivityId
     * @param showSize
     * @return
     */
    List<ApiGroupTeamDto> listJoinGroup(Long groupActivityId, Integer showSize);
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/impl/GroupActivityServiceImpl.java
New file
@@ -0,0 +1,350 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.yami.shop.bean.enums.*;
import com.yami.shop.bean.event.EsProductUpdateEvent;
import com.yami.shop.bean.event.SendMessageEvent;
import com.yami.shop.bean.model.OfflineHandleEvent;
import com.yami.shop.bean.model.Product;
import com.yami.shop.bean.param.NotifyTemplateParam;
import com.yami.shop.bean.param.OfflineHandleEventAuditParam;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupActivityDto;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupSkuDto;
import com.yami.shop.groupbuy.common.dao.GroupActivityMapper;
import com.yami.shop.groupbuy.common.dto.GroupActivityDto;
import com.yami.shop.groupbuy.common.enums.ActivityStatusEnum;
import com.yami.shop.groupbuy.common.enums.GroupActivityStatusEnum;
import com.yami.shop.groupbuy.common.model.GroupActivity;
import com.yami.shop.groupbuy.common.model.GroupSku;
import com.yami.shop.groupbuy.common.model.GroupTeam;
import com.yami.shop.groupbuy.common.service.GroupActivityService;
import com.yami.shop.groupbuy.common.service.GroupSkuService;
import com.yami.shop.groupbuy.common.service.GroupTeamService;
import com.yami.shop.service.OfflineHandleEventService;
import com.yami.shop.service.ProductService;
import lombok.RequiredArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.springframework.aop.framework.AopContext;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * 拼团活动表
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@Service
@RequiredArgsConstructor
public class GroupActivityServiceImpl extends ServiceImpl<GroupActivityMapper, GroupActivity> implements GroupActivityService {
    private final GroupActivityMapper groupActivityMapper;
    private final ProductService productService;
    private final GroupTeamService groupTeamService;
    private final GroupSkuService groupSkuService;
    private final MapperFacade mapperFacade;
    private final OfflineHandleEventService offlineHandleEventService;
    private final ApplicationEventPublisher eventPublisher;
    @Override
    @Cacheable(cacheNames = "groupActivityInfo", key = "#prodId")
    public ApiGroupActivityDto getByProdId(Long prodId) {
        return groupActivityMapper.getByProdId(prodId);
    }
    @Override
    public IPage<GroupActivityDto> getGroupActivityPage(PageParam<GroupActivityDto> page, GroupActivityDto groupActivityDto) {
        return groupActivityMapper.getGroupActivityPage(page, groupActivityDto);
    }
    @Override
    public ApiGroupActivityDto getApiGroupActivityInfo(Long groupActivityId, Long prodId) {
        return groupActivityMapper.getApiGroupActivityInfo(groupActivityId, prodId);
    }
    @Override
    @CacheEvict(cacheNames = "groupActivityInfo", key = "#prodId")
    public void removeGroupActivityInfoCache(Long prodId) {
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void invalidGroupActivity(Long groupActivityId) {
        GroupActivity groupActivity = getById(groupActivityId);
        // 获取未成团的团队
        List<GroupTeam> groupTeamList = groupTeamService.getNotGroupTeamsByActivityId(groupActivity.getGroupActivityId());
        // 处理未成团的拼团团队
        for (GroupTeam groupTeam : groupTeamList) {
            groupTeamService.updateNotGroupTeam(groupTeam);
        }
        // 更新活动状态
        groupActivityMapper.updateStatus(groupActivityId, GroupActivityStatusEnum.INVALID.value());
        // 商品类型恢复为普通商品
        productService.updateProductType(groupActivity.getProdId(), ProdType.PROD_TYPE_NORMAL.value());
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditGroupActivity(OfflineHandleEventAuditParam offlineHandleEventAuditParam, Long sysUserId) {
        // 审核通过
        if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.AGREE_BY_PLATFORM.getValue())) {
            // 更新拼团活动为未开启状态
            groupActivityMapper.updateStatus(offlineHandleEventAuditParam.getHandleId(), GroupActivityStatusEnum.DISABLE.value());
            GroupActivity groupActivity = getById(offlineHandleEventAuditParam.getHandleId());
            // 清除缓存
            GroupActivityServiceImpl groupActivityService = (GroupActivityServiceImpl) AopContext.currentProxy();
            groupActivityService.removeGroupActivityInfoCache(groupActivity.getProdId());
        }
        // 审核不通过
        else if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.DISAGREE_BY_PLATFORM.getValue())) {
            groupActivityMapper.updateStatus(offlineHandleEventAuditParam.getHandleId(), GroupActivityStatusEnum.OFFLINE.getCode());
        }
        GroupActivity groupActivity = groupActivityMapper.selectById(offlineHandleEventAuditParam.getHandleId());
        //发送活动审核提醒给商家
        NotifyTemplateParam shopParam = new NotifyTemplateParam();
        shopParam.setShopId(groupActivity.getShopId());
        shopParam.setActivityId(groupActivity.getGroupActivityId());
        shopParam.setActivityName(groupActivity.getActivityName());
        shopParam.setSendType(SendType.ACTIVITY_AUDIT.getValue());
        eventPublisher.publishEvent(new SendMessageEvent(shopParam));
        offlineHandleEventService.auditOfflineEvent(offlineHandleEventAuditParam, sysUserId);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void offline(GroupActivity groupActivity, String offlineReason, Long sysUserId) {
        // 添加下线处理记录
        Date now = new Date();
        OfflineHandleEvent offlineHandleEvent = new OfflineHandleEvent();
        offlineHandleEvent.setHandleId(groupActivity.getGroupActivityId());
        offlineHandleEvent.setHandleType(OfflineHandleEventType.GROUP_BUY.getValue());
        offlineHandleEvent.setCreateTime(now);
        offlineHandleEvent.setHandlerId(sysUserId);
        offlineHandleEvent.setOfflineReason(offlineReason);
        offlineHandleEvent.setStatus(OfflineHandleEventStatus.OFFLINE_BY_PLATFORM.getValue());
        offlineHandleEvent.setShopId(groupActivity.getShopId());
        offlineHandleEvent.setUpdateTime(now);
        offlineHandleEventService.save(offlineHandleEvent);
        // 如果活动为开始的状态
        if (Objects.equals(groupActivity.getActivityStatus(), ActivityStatusEnum.UNDER_WAY.value())) {
            // 获取未成团的团队
            List<GroupTeam> groupTeamList = groupTeamService.getNotGroupTeamsByActivityId(groupActivity.getGroupActivityId());
            if (CollectionUtil.isNotEmpty(groupTeamList)) {
                for (GroupTeam groupTeam : groupTeamList) {
                    groupTeamService.updateNotGroupTeam(groupTeam);
                }
            }
        }
        // 更新活动状态为违规下架
        groupActivityMapper.updateStatus(groupActivity.getGroupActivityId(), GroupActivityStatusEnum.OFFLINE.value());
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditApply(Long eventId, Long activityId, String reapplyReason) {
        // 更新活动为待审核状态
        groupActivityMapper.updateStatus(activityId, GroupActivityStatusEnum.WAIT_AUDIT.value());
        // 更新事件状态
        offlineHandleEventService.updateToApply(eventId, reapplyReason);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeProdTypeByGroupActivityIdList() {
        // 获取活动结束或团单结束未成团的拼团团队
        List<GroupActivity> groupActivitieList = list(new LambdaQueryWrapper<GroupActivity>()
                .lt(GroupActivity::getEndTime,new Date())
                .ne(GroupActivity::getStatus,GroupActivityStatusEnum.END.getCode())
                .ne(GroupActivity::getStatus, GroupActivityStatusEnum.DELETE.getCode())
        );
        invalidOrEndGroupActivity(groupActivitieList, GroupActivityStatusEnum.END.value());
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handleOfflineGroupProd(Long shopId, Long prodId) {
        // 失效团购活动
        GroupActivity groupActivity = groupActivityMapper.getUnInvalidGroupActivityByProdId(prodId);
        if (Objects.isNull(groupActivity)) {
            return;
        }
        groupActivityMapper.updateGroupActivityStatus(groupActivity.getGroupActivityId(), GroupActivityStatusEnum.INVALID.value());
        // 团购商品恢复为普通商品
        productService.updateProductType(prodId, ProdType.PROD_TYPE_NORMAL.value());
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void invalidGroupByShopId(Long shopId) {
        // 查询状态为进行中的团购活动
        List<GroupActivity> groupActivityList = groupActivityMapper.selectList(Wrappers.lambdaQuery(GroupActivity.class)
                .select(GroupActivity::getGroupActivityId, GroupActivity::getProdId, GroupActivity::getStatus)
                .eq(GroupActivity::getShopId, shopId)
                .eq(GroupActivity::getStatus, GroupActivityStatusEnum.ENABLE.getCode())
        );
        if (CollUtil.isEmpty(groupActivityList)) {
            return;
        }
        invalidOrEndGroupActivity(groupActivityList, GroupActivityStatusEnum.INVALID.value());
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveGroupActivity(GroupActivity groupActivity) {
        // 判断是否是普通商品
        Product product = productService.getProductByProdId(groupActivity.getProdId(), I18nMessage.getDbLang());
        if (!Objects.equals(product.getProdType(), ProdType.PROD_TYPE_NORMAL.value())) {
            // 商品类型改变,请刷新页面后重试
            throw new YamiShopBindException("yami.prod.type.check");
        }
        // 默认为未启用状态
        groupActivity.setStatus(GroupActivityStatusEnum.DISABLE.value());
        groupActivity.setPrice(getGroupSpuPrice(groupActivity.getGroupSkuList()));
        // 保存团购信息
        save(groupActivity);
        // 保存sku
        batchSaveOrUpdateSku(groupActivity);
        // 更新商品为团购商品
        if (productService.updateProductToGroup(groupActivity.getGroupActivityId(), groupActivity.getProdId()) < 1) {
            // 商品类型改变,请刷新页面后重试
            throw new YamiShopBindException("yami.prod.type.check");
        }
        // 发送事件,清除掉如果是限时特惠中的可用商品
        //applicationContext.publishEvent(new RemoveDiscountProdByIdsEvent(Collections.singletonList(groupActivity.getProdId())));
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGroupActivity(GroupActivity groupActivity) {
        groupActivity.setStatus(null);
        GroupActivity dbGroupActivity = getById(groupActivity.getGroupActivityId());
        if (!Objects.equals(dbGroupActivity.getShopId(), groupActivity.getShopId())) {
            throw new YamiShopBindException("yami.no.auth");
        }
        groupActivity.setPrice(getGroupSpuPrice(groupActivity.getGroupSkuList()));
        // 不更新的字段-预防非法修改
        groupActivity.setStatus(null);
        groupActivity.setProdId(null);
        groupActivityMapper.updateById(groupActivity);
        // 状态为未启用可以更新sku
        if (Objects.equals(GroupActivityStatusEnum.DISABLE.value(), dbGroupActivity.getStatus())) {
            batchSaveOrUpdateSku(groupActivity);
        }
    }
    @Override
    public GroupActivity getGroupActivityInfo(Long groupActivityId) {
        GroupActivity groupActivity = getById(groupActivityId);
        Product product = productService.getById(groupActivity.getProdId());
        groupActivity.setProdPic(product.getPic());
        groupActivity.setProdName(product.getProdName());
        // 获取SKU列表
        List<ApiGroupSkuDto> groupSkuList = groupSkuService.getApiByGroupActivityIdAndProdId(groupActivity.getGroupActivityId());
        groupActivity.setGroupSkuList(groupSkuList);
        return groupActivity;
    }
    private void batchSaveOrUpdateSku(GroupActivity groupActivity) {
        List<GroupSku> groupSkus = mapperFacade.mapAsList(groupActivity.getGroupSkuList(), GroupSku.class);
        for (GroupSku sku : groupSkus) {
            sku.setGroupActivityId(groupActivity.getGroupActivityId());
            sku.setSellNum(null);
        }
        groupSkuService.saveOrUpdateBatch(groupSkus);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateToDelete(GroupActivity groupActivity) {
        // 团购活动已经删除
        if (Objects.equals(groupActivity.getStatus(), GroupActivityStatusEnum.DELETE.value())) {
            return;
        }
        // 更新活动为已删除状态
        groupActivityMapper.updateToDelete(groupActivity.getGroupActivityId());
        // 活动还未失效或结束,需要更新商品类型为普通商品
        if (!Objects.equals(groupActivity.getStatus(), GroupActivityStatusEnum.END.value()) && !Objects.equals(groupActivity.getStatus(), GroupActivityStatusEnum.END.value())) {
            // 活动商品恢复为普通商品
            productService.updateProductType(groupActivity.getProdId(), ProdType.PROD_TYPE_NORMAL.value());
        }
    }
    /**
     * 获取sku中的最低价格
     * @param groupSkuList
     * @return
     */
    private Double getGroupSpuPrice(List<ApiGroupSkuDto> groupSkuList) {
        Double minPrice = null;
        for (ApiGroupSkuDto groupSku : groupSkuList) {
            if ((Objects.isNull(minPrice) || groupSku.getActPrice() < minPrice) && Objects.equals(groupSku.getStatus(), 1)) {
                minPrice = groupSku.getActPrice();
            }
        }
        return minPrice;
    }
    private void invalidOrEndGroupActivity(List<GroupActivity> groupActivityList, Integer status) {
        if (CollUtil.isEmpty(groupActivityList)) {
            return;
        }
        List<Long> groupActivityIds = Lists.newArrayList();
        List<Long> prodIds = Lists.newArrayList();
        for (GroupActivity groupActivity: groupActivityList){
            groupActivityIds.add(groupActivity.getGroupActivityId());
            if (!Objects.equals(groupActivity.getStatus(), GroupActivityStatusEnum.INVALID.getCode())) {
                prodIds.add(groupActivity.getProdId());
            }
        }
        // 拼团活动结束,商品恢复为普通商品
        productService.bathUpdateProductType(prodIds, ProdType.PROD_TYPE_NORMAL.value());
        eventPublisher.publishEvent(new EsProductUpdateEvent(null, prodIds, EsOperationType.SAVE_BATCH));
        // 改变团购活动状态
        groupActivityMapper.batchUpdateGroupActivityStatus(groupActivityIds, status);
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/impl/GroupOrderServiceImpl.java
New file
@@ -0,0 +1,159 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.app.dto.ShopCartOrderMergerDto;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupUserDto;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupUserOrderDto;
import com.yami.shop.groupbuy.common.bo.GroupOrderBO;
import com.yami.shop.groupbuy.common.dao.GroupOrderMapper;
import com.yami.shop.groupbuy.common.dao.GroupTeamMapper;
import com.yami.shop.groupbuy.common.enums.GroupOrderStatusEnum;
import com.yami.shop.groupbuy.common.enums.TeamStatusEnum;
import com.yami.shop.groupbuy.common.model.GroupOrder;
import com.yami.shop.groupbuy.common.model.GroupTeam;
import com.yami.shop.groupbuy.common.service.GroupOrderService;
import com.yami.shop.service.OrderService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@Service
@AllArgsConstructor
@Slf4j
public class GroupOrderServiceImpl extends ServiceImpl<GroupOrderMapper, GroupOrder> implements GroupOrderService {
    private final GroupOrderMapper groupOrderMapper;
    private final OrderService orderService;
    private final GroupTeamMapper groupTeamMapper;
    /**
     * 获取参团的用户列表
     *
     * @param groupTeamId 拼团单ID
     * @return ApiGroupUserDto列表
     */
    @Override
    public List<ApiGroupUserDto> listApiGroupUserDto(Long groupTeamId) {
        return groupOrderMapper.listApiGroupUserDto(groupTeamId);
    }
    /**
     * @CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用
     * @param userId 用户id
     * @param apiGroupUserOrderDto
     * @return
     */
    @Override
    @CachePut(cacheNames = "ApiGroupUserOrderDto", key = "#userId")
    public ApiGroupUserOrderDto putConfirmOrderCache(String userId, ApiGroupUserOrderDto apiGroupUserOrderDto) {
        return apiGroupUserOrderDto;
    }
    /**
     * @Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
     * @param userId
     * @return
     */
    @Override
    @Cacheable(cacheNames = "ApiGroupUserOrderDto", key = "#userId")
    public ApiGroupUserOrderDto getConfirmOrderCache(String userId) {
        return null;
    }
    @Override
    @CacheEvict(cacheNames = "ApiGroupUserOrderDto", key = "#userId")
    public void removeConfirmOrderCache(String userId) {
    }
    @Override
    public int getUserUnGroupOrderCount(String userId, Long groupActivityId, Long prodId) {
        return groupOrderMapper.getUserUnGroupOrderCount(userId, groupActivityId,prodId);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int cancelGroupOrder(String orderNumber, int status) {
        GroupOrder groupOrder = groupOrderMapper.selectOne(new LambdaQueryWrapper<GroupOrder>().eq(GroupOrder::getOrderNumber, orderNumber));
        // 取消的订单未支付并且是团长订单,则失效拼团队伍
        if (Objects.equals(groupOrder.getStatus(), 0) && Objects.equals(groupOrder.getIdentityType(), 1)) {
            GroupTeam groupTeam = new GroupTeam();
            groupTeam.setGroupTeamId(groupOrder.getGroupTeamId());
            groupTeam.setStatus(3);
            groupTeamMapper.updateById(groupTeam);
        }
        return groupOrderMapper.cancelGroupOrder(orderNumber, status);
    }
    @Override
    public Integer getUserHadOrderCountByGroupProdId(String userId, Long groupActivityId) {
        return groupOrderMapper.getUserHadOrderCountByGroupProdId(userId, groupActivityId);
    }
    /**
     * 添加团购订单数据
     * @param mergerOrder
     * @param groupOrderBO 订单信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submit(ShopCartOrderMergerDto mergerOrder, GroupOrderBO groupOrderBO) {
        // 团购活动订单,先创建订单,然后创建团购活动订单
        orderService.submit(mergerOrder);
        Date now = new Date();
        // 插入拼团订单
        GroupOrder groupOrder = new GroupOrder();
        groupOrder.setGroupTeamId(groupOrderBO.getGroupTeamId());
        // 如果为团长,则需新建拼团团队
        if (groupOrderBO.getGroupTeamId() == 0) {
            GroupTeam groupTeam = new GroupTeam();
            groupTeam.setShareUserId(groupOrderBO.getShareUserId());
//            groupTeam.setGroupProdId(groupOrderBO.getGroupProdId());
            groupTeam.setProdId(groupOrderBO.getProdId());
            groupTeam.setGroupActivityId(groupOrderBO.getGroupActivityId());
            groupTeam.setJoinNum(1);
            groupTeam.setCreateTime(now);
            groupTeam.setUpdateTime(now);
            groupTeam.setShopId(groupOrderBO.getShopId());
            groupTeam.setStatus(TeamStatusEnum.WAITING_GROUP.value());
            groupTeam.setTotalPrice(groupOrderBO.getPayPrice());
            groupTeamMapper.insert(groupTeam);
            groupOrder.setGroupTeamId(groupTeam.getGroupTeamId());
        }
        groupOrder.setGroupActivityId(groupOrderBO.getGroupActivityId());
        groupOrder.setUserId(groupOrderBO.getUserId());
        groupOrder.setOrderNumber(groupOrderBO.getOrderNumber());
        groupOrder.setActivityProdPrice(groupOrderBO.getActivityProdPrice());
        groupOrder.setPayPrice(groupOrderBO.getPayPrice());
        groupOrder.setShopId(groupOrderBO.getShopId());
        groupOrder.setIdentityType(Objects.equals(groupOrderBO.getGroupTeamId(), 0L) ? 1 : 0);
        groupOrder.setStatus(GroupOrderStatusEnum.WAITING_PAY.value());
        groupOrder.setCreateTime(now);
        groupOrderMapper.insert(groupOrder);
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/impl/GroupPayServiceImpl.java
New file
@@ -0,0 +1,152 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.service.impl;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.enums.SendType;
import com.yami.shop.bean.model.Order;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.Arith;
import com.yami.shop.dao.OrderMapper;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupActivityDto;
import com.yami.shop.groupbuy.common.dao.GroupOrderMapper;
import com.yami.shop.groupbuy.common.dao.GroupTeamMapper;
import com.yami.shop.groupbuy.common.enums.GroupOrderStatusEnum;
import com.yami.shop.groupbuy.common.enums.TeamStatusEnum;
import com.yami.shop.groupbuy.common.model.GroupOrder;
import com.yami.shop.groupbuy.common.model.GroupTeam;
import com.yami.shop.groupbuy.common.service.GroupActivityService;
import com.yami.shop.groupbuy.common.service.GroupPayService;
import com.yami.shop.service.NotifyTemplateService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * 拼团支付
 *
 * @author Yami
 */
@Service
@AllArgsConstructor
@Slf4j
public class GroupPayServiceImpl implements GroupPayService {
    private final OrderMapper orderMapper;
    private final GroupTeamMapper groupTeamMapper;
    private final GroupOrderMapper groupOrderMapper;
    private final GroupActivityService groupActivityService;
    private final NotifyTemplateService notifyTemplateService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void paySuccessNoticeHandle(Order order) {
        log.info("处理拼团订单 订单编号:{}", order.getOrderNumber());
        orderMapper.updateToWaitGroup(order.getOrderNumber());
        Long prodId = order.getOrderItems().get(0).getProdId();
        // 获取用户拼团订单信息
        GroupOrder groupOrder = groupOrderMapper.selectOne(new LambdaQueryWrapper<GroupOrder>()
                .eq(GroupOrder::getOrderNumber, order.getOrderNumber()));
        // 获取拼团团队订单
        GroupTeam groupTeam = groupTeamMapper.selectById(groupOrder.getGroupTeamId());
        ApiGroupActivityDto apiGroupActivityInfo = groupActivityService.getApiGroupActivityInfo(groupTeam.getGroupActivityId(), prodId);
        Date now = new Date();
        // 如果为团长则直接开团,否则判断是否拼团已满
        if (Objects.equals(groupOrder.getIdentityType(), 1)) {
            groupTeam.setJoinNum(1);
            groupTeam.setUpdateTime(now);
            groupTeam.setStatus(TeamStatusEnum.IN_GROUP.value());
            groupTeam.setTotalPrice(groupOrder.getPayPrice());
            groupTeam.setStartTime(now);
            groupTeam.setEndTime(DateUtil.offsetMinute(now, apiGroupActivityInfo.getGroupValidTime()));
            groupTeamMapper.updateById(groupTeam);
            groupOrder.setStatus(GroupOrderStatusEnum.SUCCESS.value());
            groupOrderMapper.updateById(groupOrder);
            // 消息推送-开团成功
            notifyTemplateService.sendNotifyOfGroupStart(order,SendType.GROUP_START);
        } else {
            // 参团
            // 判断团是否已满,如果已满则重新开团,如果不是则继续参团
            if (Objects.equals(groupTeam.getStatus(), TeamStatusEnum.SUCCESS.value())) {
                // 满员开团
                GroupTeam newGroupTeam = new GroupTeam();
                newGroupTeam.setJoinNum(1);
                newGroupTeam.setCreateTime(now);
                newGroupTeam.setUpdateTime(now);
                newGroupTeam.setStartTime(now);
                newGroupTeam.setShopId(groupTeam.getShopId());
                newGroupTeam.setTotalPrice(groupOrder.getPayPrice());
                newGroupTeam.setShareUserId(groupOrder.getUserId());
                newGroupTeam.setStatus(TeamStatusEnum.IN_GROUP.value());
                groupTeam.setProdId(groupTeam.getProdId());
                newGroupTeam.setGroupActivityId(groupTeam.getGroupActivityId());
                newGroupTeam.setProdId(groupTeam.getProdId());
                newGroupTeam.setEndTime(DateUtil.offsetMinute(now, apiGroupActivityInfo.getGroupValidTime()));
                groupTeamMapper.insert(newGroupTeam);
                groupOrder.setIdentityType(1);
                groupOrder.setGroupTeamId(newGroupTeam.getGroupTeamId());
                groupOrder.setStatus(GroupOrderStatusEnum.SUCCESS.value());
                groupOrderMapper.updateById(groupOrder);
                // 消息推送-开团成功、拼团成功、拼团失败
                notifyTemplateService.sendNotifyOfGroupStart(order, SendType.GROUP_START);
            } else if (Objects.equals(groupTeam.getStatus(), TeamStatusEnum.IN_GROUP.value())) {
                // 参团
                groupTeam.setUpdateTime(now);
                groupTeam.setJoinNum(groupTeam.getJoinNum() + 1);
                groupTeam.setTotalPrice(Arith.add(groupTeam.getTotalPrice(), groupOrder.getPayPrice()));
                // 是否已达人数,则修改团信息及订单信息
                if (groupTeam.getJoinNum() >= apiGroupActivityInfo.getGroupNumber()) {
                    // 更新拼团成功
                    groupTeam.setStatus(TeamStatusEnum.SUCCESS.value());
                    List<Order> orders = orderMapper.selectOrderByGroupTeamId(groupTeam.getGroupTeamId());
                    // 查询是否为虚拟商品订单
                    int mold = Objects.isNull(orders.get(0).getOrderMold()) ? 0 : orders.get(0).getOrderMold();
                    // 更新将所有的订单订单待发货
                    if (orderMapper.updateToWaitDelivery(groupTeam.getGroupTeamId(),mold) <= 0) {
                        // 更新拼团订单为待发货失败,请稍后重试
                        throw new YamiShopBindException("yami.group.order.update.fail");
                    }
                    for (Order gOrder : orders) {
                        // 消息推送-开团成功、拼团成功、拼团失败
                        notifyTemplateService.sendNotifyOfGroupStart(gOrder, SendType.GROUP_SUCCESS);
                    }
                }
                groupOrder.setStatus(GroupOrderStatusEnum.SUCCESS.value());
                groupTeamMapper.updateById(groupTeam);
                groupOrderMapper.updateById(groupOrder);
                // 如果满团更新统计信息
                if (groupTeam.getJoinNum() >= apiGroupActivityInfo.getGroupNumber()) {
                    // 更新已成团订单数
//                    groupProd.setGroupOrderCount(groupProd.getGroupOrderCount() + groupTeam.getJoinNum());
//                    // 更新已成团人数
//                    Long count = groupOrderMapper.getHadGroupNumberCount(groupProd.getGroupActivityId(), groupProd.getGroupProdId());
//                    groupProd.setGroupNumberCount(count);
//                        groupProdService.updateById(groupProd);
//                    groupProdService.removeGroupProdCache(groupProd.getGroupProdId());
                }
            }
        }
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/impl/GroupSkuServiceImpl.java
New file
@@ -0,0 +1,46 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupSkuDto;
import com.yami.shop.groupbuy.common.dao.GroupSkuMapper;
import com.yami.shop.groupbuy.common.model.GroupSku;
import com.yami.shop.groupbuy.common.service.GroupSkuService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * 拼团活动商品规格
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@Service
@AllArgsConstructor
public class GroupSkuServiceImpl extends ServiceImpl<GroupSkuMapper, GroupSku> implements GroupSkuService {
    private final GroupSkuMapper groupSkuMapper;
    /**
     * 获取SKU列表数据
     * @param groupActivityId 拼团活动ID
     * @return SKU列表
     */
    @Override
    public List<ApiGroupSkuDto> getApiByGroupActivityIdAndProdId(Long groupActivityId) {
        return groupSkuMapper.getApiByGroupActivityIdAndProdId(groupActivityId, I18nMessage.getDbLang());
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/service/impl/GroupTeamServiceImpl.java
New file
@@ -0,0 +1,344 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.dto.OrderRefundDto;
import com.yami.shop.bean.enums.*;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderRefund;
import com.yami.shop.bean.model.Product;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.groupbuy.common.api.dto.ApiGroupTeamDto;
import com.yami.shop.groupbuy.common.api.dto.ApiJoinGroupTeamDto;
import com.yami.shop.groupbuy.common.dao.GroupActivityMapper;
import com.yami.shop.groupbuy.common.dao.GroupTeamMapper;
import com.yami.shop.groupbuy.common.dto.GroupOrderDTO;
import com.yami.shop.groupbuy.common.dto.GroupRefundOrder;
import com.yami.shop.groupbuy.common.dto.GroupTeamDto;
import com.yami.shop.groupbuy.common.enums.GroupOrderStatusEnum;
import com.yami.shop.groupbuy.common.enums.TeamStatusEnum;
import com.yami.shop.groupbuy.common.model.GroupOrder;
import com.yami.shop.groupbuy.common.model.GroupTeam;
import com.yami.shop.groupbuy.common.service.GroupOrderService;
import com.yami.shop.groupbuy.common.service.GroupTeamService;
import com.yami.shop.service.NotifyTemplateService;
import com.yami.shop.service.OrderRefundService;
import com.yami.shop.service.OrderService;
import com.yami.shop.service.ProductService;
import lombok.AllArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * 拼团团队表
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@Service
@AllArgsConstructor
public class GroupTeamServiceImpl extends ServiceImpl<GroupTeamMapper, GroupTeam> implements GroupTeamService {
    private final GroupTeamMapper groupTeamMapper;
    private final GroupActivityMapper groupActivityMapper;
    private final GroupOrderService groupOrderService;
    private final ProductService productService;
    private final OrderRefundService orderRefundService;
    private final NotifyTemplateService notifyTemplateService;
    private final OrderService orderService;
    private final Snowflake snowflake;
    private final MapperFacade mapperFacade;
    @Override
    public IPage<GroupTeamDto> getPage(Page page, GroupTeamDto groupTeamDto) {
        return groupTeamMapper.getPage(page, groupTeamDto);
    }
    @Override
    public IPage<GroupOrderDTO> getGroupOrderPage(PageParam<GroupOrder> page, GroupOrder groupOrder) {
        return groupTeamMapper.getGroupOrderPage(page, groupOrder);
    }
    @Override
    public ApiGroupTeamDto getApiGroupTeamDto(Long groupTeamId) {
        return groupTeamMapper.getApiGroupTeamDtoByTeamId(groupTeamId);
    }
    @Override
    public ApiJoinGroupTeamDto getJoinGroupTeamHasMaxNum(Long groupActivityId) {
        return groupTeamMapper.getJoinGroupTeamHasMaxNum(groupActivityId);
    }
    @Override
    public List<GroupTeam> getNotGroupTeam() {
        return groupTeamMapper.getNotGroupTeamByNowDate(new Date());
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateNotGroupTeam(GroupTeam groupTeam) {
        Date nowDate = new Date();
        // 机器人列表
        List<GroupOrder> robot = new ArrayList<>();
//        // 拼团成功的活动商品列表(机器人)
//        List<GroupProd> groupProdList = new ArrayList<>();
        // 修改订单状态(拼团中的状态定时任务修改不了及防止待成团订单重新进行支付)
        List<Order> changeStatusOrderList = new ArrayList<>();
        // 需要还原库存的订单
        List<Order> returnStockOrders = new ArrayList<>();
        // 未支付的拼团,不需要进行退款的操作
        if (groupTeam.getStatus().equals(TeamStatusEnum.WAITING_GROUP.value())) {
            groupTeam.setStatus(TeamStatusEnum.FAIL.value());
            // 获取拼团失败要取消的订单
            List<Order> teamOrderList = groupTeamMapper.getOrders(groupTeam.getGroupTeamId(),null);
            if(CollectionUtils.isNotEmpty(teamOrderList)){
                // 需要还原库存的订单
                returnStockOrders.addAll(teamOrderList);
                for (Order order : teamOrderList) {
                    order.setStatus(OrderStatus.CLOSE.value());
                    order.setCancelTime(nowDate);
                    order.setUpdateTime(nowDate);
                    changeStatusOrderList.add(order);
                }
            }
        }
        // 如果未成团,有机器人可以成团,不需要进行退款的操作
        if (groupTeam.getStatus().equals(TeamStatusEnum.IN_GROUP.value()) && groupTeam.getHasRobot() == 1) {
            handleWaitingGroupOrder(nowDate, groupTeam, robot, changeStatusOrderList, returnStockOrders);
        }
        // 如果在拼团中订单且没有模拟成团则需要退款
        if (groupTeam.getStatus().equals(TeamStatusEnum.IN_GROUP.value()) && groupTeam.getHasRobot() == 0) {
            handleRefundGroupOrder(groupTeam, changeStatusOrderList);
        }
        // 更新拼团团队信息
        groupTeam.setUpdateTime(nowDate);
        updateById(groupTeam);
        // 取消订单,还原库存
        if (CollectionUtils.isNotEmpty(returnStockOrders)) {
            orderService.cancelOrders(returnStockOrders);
        }
        // 批量保存机器人
        if (robot.size() > 0) {
            groupOrderService.saveBatch(robot);
        }
//        // 批量更新拼团成功的活动商品列表
//        if (groupProdList.size() > 0) {
//            groupProdService.saveOrUpdateBatch(groupProdList);
//
//        }
        // 更新订单状态
        if (changeStatusOrderList.size() > 0) {
            orderService.saveOrUpdateBatch(changeStatusOrderList);
        }
        // 批量清除商品拼团活动ID
        List<Product> products = groupActivityMapper.getActivityFinishProduct(nowDate);
        for (Product product : products) {
            product.setActivityId(0L);
            product.setProdType(ProdType.PROD_TYPE_NORMAL.value());
        }
        if (products.size() > 0) {
            productService.saveOrUpdateBatch(products);
        }
    }
    /**
     * 如果未成团,有机器人可以成团,不需要进行退款的操作
     * @param nowDate 当前时间
     * @param groupTeam 团购团队
     * @param robot 参团机器人
     * @param changeStatusOrderList 需要改变状态的订单列表
     * @param returnStockOrders 需要还原库存的订单列表
     */
    private void handleWaitingGroupOrder(Date nowDate, GroupTeam groupTeam, List<GroupOrder> robot, List<Order> changeStatusOrderList, List<Order> returnStockOrders) {
        // 模拟参团操作(添加机器人)
        for (int i = 0; i < groupTeam.getGroupNumber() - groupTeam.getJoinNum(); i++) {
            GroupOrder groupOrder = new GroupOrder();
            groupOrder.setShopId(groupTeam.getShopId());
            groupOrder.setGroupTeamId(groupTeam.getGroupTeamId());
            groupOrder.setUserId("0");
            groupOrder.setIdentityType(0);
            groupOrder.setStatus(1);
            groupOrder.setCreateTime(nowDate);
            robot.add(groupOrder);
        }
        // 更新拼团团队订单
        groupTeam.setJoinNum(groupTeam.getGroupNumber());
        groupTeam.setStatus(TeamStatusEnum.SUCCESS.value());
        // 更新所有的已支付订单状态
        List<Order> teamOrderList = groupTeamMapper.getOrders(groupTeam.getGroupTeamId(),1);
        for (Order order : teamOrderList) {
            // 虚拟订单成团的订单状态为待发货
            if(Objects.equals(order.getOrderMold(),1)){
                order.setStatus(OrderStatus.CONSIGNMENT.value());
                order.setDvyTime(nowDate);
                order.setDvyType(DvyType.NOT_DELIVERY.value());
            }else {
                order.setStatus(OrderStatus.PADYED.value());
            }
            changeStatusOrderList.add(order);
            order.setUpdateTime(nowDate);
            //商家开启模拟成团后,机器人填充的成团队伍也要给用户发送拼团成功消息提醒
            notifyTemplateService.sendNotifyOfGroupStart(order, SendType.GROUP_SUCCESS);
        }
        // 获取未支付要取消的订单
        List<Order> unPayOrderList = groupTeamMapper.getOrders(groupTeam.getGroupTeamId(),0);
        if(CollectionUtils.isNotEmpty(unPayOrderList)){
            // 需要还原库存的订单
            returnStockOrders.addAll(unPayOrderList);
            for (Order order : unPayOrderList) {
                order.setStatus(OrderStatus.CLOSE.value());
                order.setUpdateTime(nowDate);
                order.setCancelTime(nowDate);
                changeStatusOrderList.add(order);
            }
        }
    }
    @Override
    public List<GroupTeam> getNotGroupTeamsByActivityId(Long groupActivityId) {
        return groupTeamMapper.getNotGroupTeamsByActivityId(groupActivityId);
    }
    @Override
    public List<GroupTeam> getNotGroupTeamByProdId(Long prodId) {
        return groupTeamMapper.getNotGroupTeamByProdId(prodId);
    }
    @Override
    public List<ApiGroupTeamDto> listJoinGroup(Long groupActivityId, Integer showSize) {
        return groupTeamMapper.listByJoinGroupAndNowDate(groupActivityId, new Date(), showSize);
    }
    /**
     * 并生成退款单并保存到数据库,且获组装退款dto
     * @param groupRefundOrder 团购退款订单数据
     * @return 团购退款订单列表
     */
    private List<OrderRefundDto> saveRefundOrderAndGetOrderRefundDtoByGroupTeamId(List<GroupRefundOrder> groupRefundOrder) {
        // 退款单列表
        List<OrderRefund> orderRefundList = new ArrayList<>();
        // 退款数据列表
        List<OrderRefundDto> orderRefundDtoList = new ArrayList<>();
        for (GroupRefundOrder refundOrder : groupRefundOrder) {
            // 生成退款单信息
            OrderRefund orderRefund = new OrderRefund();
            orderRefund.setRefundSn(String.valueOf(snowflake.nextId()));
            orderRefund.setShopId(refundOrder.getShopId());
            orderRefund.setUserId(refundOrder.getUserId());
            orderRefund.setOrderId(refundOrder.getOrderId());
            orderRefund.setRefundType(RefundType.ALL.value());
            orderRefund.setRefundAmount(refundOrder.getActualTotal());
            orderRefund.setApplyType(1);
            orderRefund.setIsReceiver(false);
            orderRefund.setBuyerReason(BuyerReasonType.GROUP_FAILED.value()+"");
            orderRefund.setBuyerDesc("拼团失败:系统自动退款");
            orderRefund.setReturnMoneySts(ReturnMoneyStsType.SUCCESS.value());
            orderRefund.setSellerMsg("拼团失败:系统自动退款");
            orderRefund.setApplyTime(new Date());
            orderRefund.setHandelTime(new Date());
            orderRefund.setUpdateTime(new Date());
            orderRefundList.add(orderRefund);
            // 生成退款数据
            OrderRefundDto orderRefundDto = mapperFacade.map(orderRefund, OrderRefundDto.class);
            orderRefundDto.setOrderNumber(refundOrder.getOrderNumber());
            orderRefundDto.setOrderAmount(refundOrder.getActualTotal());
            orderRefundDto.setSettlementId(refundOrder.getSettlementId());
            orderRefundDto.setOrderPayNo(refundOrder.getOrderPayNo());
            orderRefundDto.setDistributionTotalAmount(0.0);
            orderRefundDtoList.add(orderRefundDto);
        }
        if (orderRefundList.size() > 0) {
            orderRefundService.saveBatch(orderRefundList);
        }
        return orderRefundDtoList;
    }
    /**
     * 如果在拼团中订单且没有模拟成团则需要退款
     * @param groupTeam 团购团队
     * @param changeStatusOrderList 需要改变状态的订单列表
     */
    private void handleRefundGroupOrder(GroupTeam groupTeam, List<Order> changeStatusOrderList) {
        // 更新拼团团队订单
        groupTeam.setStatus(TeamStatusEnum.FAIL.value());
        // 查询未成团的订单列表
        List<GroupRefundOrder> groupRefundOrders = groupTeamMapper.getJoinNotGroupTeamOrder(groupTeam.getGroupTeamId());
        // 需要退款订单
        List<GroupRefundOrder> needRefundOrder = new ArrayList<>();
        // 无需退款订单
        List<GroupOrder> noNeedGroupOrder = new ArrayList<>();
        for (GroupRefundOrder groupRefundOrder : groupRefundOrders) {
            if (groupRefundOrder.getPayStatus() == 1) {
                needRefundOrder.add(groupRefundOrder);
            } else {
                GroupOrder groupOrder = new GroupOrder();
                groupOrder.setGroupOrderId(groupRefundOrder.getGroupOrderId());
                groupOrder.setStatus(GroupOrderStatusEnum.FAIL.value());
                noNeedGroupOrder.add(groupOrder);
            }
            // 修改订单退款状态
            Order order = new Order();
            order.setOrderId(groupRefundOrder.getOrderId());
            order.setStatus(OrderStatus.CLOSE.value());
            order.setCancelTime(new Date());
            order.setUpdateTime(new Date());
            order.setRefundStatus(RefundStatusEnum.SUCCEED.value());
            changeStatusOrderList.add(order);
        }
        // 将订单变为失效状态
        if (CollectionUtil.isNotEmpty(noNeedGroupOrder)) {
            groupOrderService.updateBatchById(noNeedGroupOrder);
        }
        List<OrderRefundDto> orderRefundDtos = saveRefundOrderAndGetOrderRefundDtoByGroupTeamId(needRefundOrder);
        // 真正的退款操作
        orderRefundService.systemAutoRefundBatch(orderRefundDtos);
        // 消息推送-拼团失败
        List<String> orderNumbers = new ArrayList<>();
        orderRefundDtos.forEach(orderRefundDto ->  orderNumbers.add(orderRefundDto.getOrderNumber()));
        List<Order> orderList = orderService.list(new LambdaQueryWrapper<Order>().in(Order::getOrderNumber, orderNumbers));
        for (Order order : orderList) {
            notifyTemplateService.sendNotifyOfGroupStart(order, SendType.GROUP_FAIL);
        }
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/java/com/yami/shop/groupbuy/common/utils/GroupActivityUtil.java
New file
@@ -0,0 +1,51 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.common.utils;
import com.yami.shop.groupbuy.common.enums.ActivityStatusEnum;
import com.yami.shop.groupbuy.common.enums.GroupActivityStatusEnum;
import java.util.Date;
import java.util.Objects;
/**
 * @author 小懒虫
 * @date 2019/9/6 11:17
 */
public class GroupActivityUtil {
    /**
     * 判断活动状态
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param status    状态
     * @return 活动状态
     */
    public static Integer getActivityStatus(Date startTime, Date endTime, Integer status) {
        long now = System.currentTimeMillis();
        if (Objects.equals(status, GroupActivityStatusEnum.OFFLINE.value())) {
            return ActivityStatusEnum.OFFLINE.value();
        }
        if (Objects.equals(status, GroupActivityStatusEnum.WAIT_AUDIT.value())) {
            return ActivityStatusEnum.WAIT_AUDIT.value();
        }
        if (Objects.equals(status, GroupActivityStatusEnum.INVALID.value()) || Objects.equals(status, GroupActivityStatusEnum.DELETE.value())) {
            return ActivityStatusEnum.EXPIRED.value();
        }
        if (Objects.equals(status, GroupActivityStatusEnum.DISABLE.value()) || now < startTime.getTime()) {
            return ActivityStatusEnum.NOT_STARTED.value();
        }
        if (now >= startTime.getTime() && now <= endTime.getTime()) {
            return ActivityStatusEnum.UNDER_WAY.value();
        }
        return ActivityStatusEnum.FINISHED.value();
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/resources/mapper/GroupActivityMapper.xml
New file
@@ -0,0 +1,130 @@
<?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.yami.shop.groupbuy.common.dao.GroupActivityMapper">
    <resultMap id="groupActivityMap" type="com.yami.shop.groupbuy.common.model.GroupActivity">
        <id column="group_activity_id" property="groupActivityId"/>
        <result column="shop_id" property="shopId"/>
        <result column="activity_name" property="activityName"/>
        <result column="status" property="status"/>
        <result column="start_time" property="startTime"/>
        <result column="end_time" property="endTime"/>
        <result column="group_valid_time" property="groupValidTime"/>
        <result column="group_number" property="groupNumber"/>
        <result column="has_max_num" property="hasMaxNum"/>
        <result column="max_num" property="maxNum"/>
        <result column="prod_id" property="prodId"/>
        <result column="price" property="price"/>
        <result column="has_robot" property="hasRobot"/>
        <result column="is_preheat" property="isPreheat"/>
        <result column="has_group_tip" property="hasGroupTip"/>
        <result column="create_time" property="createTime"/>
        <result column="update_time" property="updateTime"/>
    </resultMap>
    <resultMap id="apiGroupActivityMap" type="com.yami.shop.groupbuy.common.api.dto.ApiGroupActivityDto" >
        <id column="group_activity_id" property="groupActivityId"/>
        <result column="shop_id" property="shopId"/>
        <result column="activity_name" property="activityName"/>
        <result column="status" property="status"/>
        <result column="start_time" property="startTime"/>
        <result column="end_time" property="endTime"/>
        <result column="group_valid_time" property="groupValidTime"/>
        <result column="group_number" property="groupNumber"/>
        <result column="has_max_num" property="hasMaxNum"/>
        <result column="max_num" property="maxNum"/>
        <result column="has_robot" property="hasRobot"/>
        <result column="is_preheat" property="isPreheat"/>
        <result column="has_group_tip" property="hasGroupTip"/>
        <result column="price" property="actPrice"/>
        <collection property="groupSkuList" ofType="com.yami.shop.groupbuy.common.api.dto.ApiGroupSkuDto">
            <result column="group_sku_id" property="groupSkuId"/>
            <result column="sku_id" property="skuId"/>
            <result column="act_price" property="actPrice"/>
            <result column="sell_num" property="sellNum"/>
        </collection>
    </resultMap>
    <select id="getByProdId" resultMap="apiGroupActivityMap">
        SELECT ga.*,
               gs.group_sku_id,gs.sku_id,gs.act_price,gs.sell_num
        FROM tz_group_activity ga
          LEFT JOIN tz_group_sku gs ON ga.group_activity_id = gs.group_activity_id
        WHERE ga.status = 1 AND ga.prod_id = #{prodId}
        order by gs.group_sku_id
    </select>
    <update id="updateToDelete">
        UPDATE tz_group_activity SET status = -1 WHERE group_activity_id = #{groupActivityId}
    </update>
    <select id="getGroupActivityPage" resultType="com.yami.shop.groupbuy.common.dto.GroupActivityDto">
        SELECT
            ga.*,
            (
            SELECT COUNT(DISTINCT group_team_id) FROM tz_group_order tgo
            WHERE ga.group_activity_id = tgo.group_activity_id AND tgo.status = 1
            ) AS group_order_count,
            sd.shop_name,tp.prod_name,tp.pic
        FROM tz_group_activity ga
        LEFT JOIN tz_shop_detail sd ON ga.shop_id = sd.shop_id
        JOIN tz_prod tp ON tp.`prod_id` = ga.`prod_id`
        LEFT JOIN tz_prod_lang tpl ON tpl.prod_id = tp.prod_id AND tpl.lang = #{groupActivityDto.lang}
        <where>
            ga.`status` != -1
            <if test="groupActivityDto.activityName != null">
                and trim(replace(ga.activity_name,' ','')) like trim(replace(concat('%',#{groupActivityDto.activityName},'%'),' ',''))
            </if>
            <if test="groupActivityDto.shopName != null">
                and trim(replace(sd.shop_name,' ','')) like trim(replace(concat('%',#{groupActivityDto.shopName},'%'),' ',''))
            </if>
            <if test="groupActivityDto.shopId != null">
               AND ga.shop_id = #{groupActivityDto.shopId}
            </if>
            <if test="groupActivityDto.status != null">
                AND ga.`status` = #{groupActivityDto.status}
            </if>
            <if test="groupActivityDto.prodName != null and groupActivityDto.prodName != ''">
                and ifnull(tpl.prod_name,tp.prod_name) like concat('%',#{groupActivityDto.prodName},'%')
            </if>
        </where>
        ORDER BY ga.create_time DESC
    </select>
    <select id="getApiGroupActivityInfo" resultType="com.yami.shop.groupbuy.common.api.dto.ApiGroupActivityDto">
        SELECT
          ga.*
        FROM tz_group_activity ga
        WHERE ga.group_activity_id = #{groupActivityId} AND ga.prod_id = #{prodId}
    </select>
    <select id="getActivityFinishProduct" resultType="com.yami.shop.bean.model.Product">
        SELECT p.* FROM tz_group_activity ga
        INNER JOIN tz_prod p ON ga.group_activity_id = p.activity_id
        WHERE ga.`status` = 1 AND ga.end_time <![CDATA[ < ]]> #{newDate}
    </select>
    <update id="updateStatus">
        UPDATE tz_group_activity ga SET ga.`status` =#{status}  WHERE ga.`group_activity_id` = #{activityId}
    </update>
    <update id="batchUpdateGroupActivityStatus">
        UPDATE tz_group_activity SET `status` = #{status} WHERE group_activity_id IN
        <foreach collection="groupActivityIds" item="groupActivityId" separator="," open="(" close=")">
            #{groupActivityId}
        </foreach>
    </update>
    <select id="getUnInvalidGroupActivityByProdId" resultMap="groupActivityMap">
<!--    根据商品id获取团购信息,不需要失效、删除和已结束状态的活动-->
        select  * from tz_group_activity where prod_id = #{prodId} and `status` in (1, 2, 3, 4)
    </select>
    <update id="updateGroupActivityStatus">
        UPDATE tz_group_activity SET `status` = #{status} WHERE group_activity_id = #{groupActivityId}
    </update>
    <select id="listActivityPrice" resultMap="groupActivityMap">
        SELECT prod_id,price FROM tz_group_activity WHERE prod_id IN
        <foreach collection="prodIds" item="prodId" open="(" close=")" separator=",">
            #{prodId}
        </foreach>
         AND `status` IN (1,2,3,4)
    </select>
</mapper>
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/resources/mapper/GroupOrderMapper.xml
New file
@@ -0,0 +1,67 @@
<?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.yami.shop.groupbuy.common.dao.GroupOrderMapper">
    <resultMap id="groupOrderMap" type="com.yami.shop.groupbuy.common.model.GroupOrder">
        <id column="group_order_id" property="groupOrderId"/>
        <result column="shop_id" property="shopId"/>
        <result column="group_team_id" property="groupTeamId"/>
        <result column="group_activity_id" property="groupActivityId"/>
        <result column="user_id" property="userId"/>
        <result column="identity_type" property="identityType"/>
        <result column="activity_prod_price" property="activityProdPrice"/>
        <result column="pay_price" property="payPrice"/>
        <result column="order_number" property="orderNumber"/>
        <result column="create_time" property="createTime"/>
        <result column="status" property="status"/>
    </resultMap>
    <select id="listApiGroupUserDto" resultType="com.yami.shop.groupbuy.common.api.dto.ApiGroupUserDto">
        SELECT
        go.user_id AS user_id,
        go.identity_type AS identity_type,
        go.order_number AS order_number,
        go.create_time AS create_time,
        IFNULL(u.nick_name,'系统参团') AS nick_name,
        u.pic AS pic
        FROM tz_group_order go
        LEFT JOIN tz_user u ON go.user_id = u.user_id
        WHERE go.group_team_id = #{groupTeamId} AND go.`status` = 1
    </select>
<!--    <select id="getHadGroupNumberCount" resultType="java.lang.Long">-->
<!--        SELECT COUNT(1) FROM-->
<!--        (SELECT go.`user_id` FROM tz_group_order go-->
<!--        LEFT JOIN tz_group_team gt ON gt.`group_team_id` = go.`group_team_id`-->
<!--        WHERE gt.`status` = 2 AND gt.`group_activity_id` = #{groupActivityId} AND gt.`group_prod_id` = #{groupProdId}-->
<!--        GROUP BY go.user_id) AS temp-->
<!--    </select>-->
<!--    <select id="listByGroupProdId" resultType="com.yami.shop.groupbuy.common.model.GroupOrder">-->
<!--        SELECT * FROM tz_group_order go-->
<!--        JOIN tz_group_team  gt ON go.`group_team_id` = gt.`group_team_id`-->
<!--        WHERE gt.`group_prod_id` =#{groupProdId}  AND go.`user_id` = #{userId} and go.status <![CDATA[<>]]> -1-->
<!--    </select>-->
    <select id="getUserHadOrderCountByGroupProdId" resultType="int">
        SELECT IFNULL(SUM(o.`product_nums`),0) AS num FROM tz_group_order go
        LEFT JOIN tz_group_team gt ON go.`group_team_id` = gt.`group_team_id`
        LEFT JOIN tz_order o ON o.`order_number` = go.`order_number`
        WHERE go.`user_id` = #{userId} and o.status  <![CDATA[ <> ]]> 6
        AND gt.`group_activity_id` = #{groupActivityId}
    </select>
    <select id="getUserUnGroupOrderCount" resultType="int">
        SELECT COUNT(1) AS num FROM tz_group_order go
        JOIN tz_group_team gt ON go.`group_team_id` = gt.`group_team_id`
        WHERE go.`user_id` = #{userId}
          AND go.`status` != -1
          AND go.`group_activity_id` = #{groupActivityId}
          AND gt.`prod_id` = #{prodId}
          AND (gt.status = 0 OR gt.status = 1)
    </select>
    <update id="cancelGroupOrder">
      update tz_group_order set status = #{status} where order_number = #{orderNumber}
    </update>
</mapper>
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/resources/mapper/GroupSkuMapper.xml
New file
@@ -0,0 +1,74 @@
<?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.yami.shop.groupbuy.common.dao.GroupSkuMapper">
    <resultMap id="groupSkuMap" type="com.yami.shop.groupbuy.common.model.GroupSku">
        <id column="group_sku_id" property="groupSkuId"/>
        <result column="sku_id" property="skuId"/>
        <result column="act_price" property="actPrice"/>
        <result column="sell_num" property="sellNum"/>
    </resultMap>
    <select id="getApiByGroupActivityIdAndProdId" resultType="com.yami.shop.groupbuy.common.api.dto.ApiGroupSkuDto">
        SELECT
            gs.*,
            s.price AS price,
            sl.sku_name AS sku_name,
            s.pic AS pic,
            sl.properties AS properties
        FROM tz_group_sku gs
        LEFT JOIN tz_sku s ON gs.sku_id = s.sku_id
        left join tz_sku_lang sl on sl.sku_id = s.sku_id and lang = #{lang}
        LEFT JOIN tz_group_activity ga ON ga.group_activity_id = gs.group_activity_id
        WHERE gs.group_activity_id = #{groupActivityId}
    </select>
    <select id="listSkuByProdIds" resultType="com.yami.shop.groupbuy.common.model.GroupSku">
        SELECT s.prod_id,s.price,gs.act_price FROM tz_group_sku gs
        JOIN tz_sku s ON gs.sku_id = s.sku_id
        WHERE group_activity_id IN (
            SELECT group_activity_id FROM tz_group_activity WHERE `status` IN (1,2,3,4) AND prod_id IN
            <foreach collection="prodIds" item="prodId" open="(" close=")" separator=",">
                #{prodId}
            </foreach>
        )
    </select>
    <select id="getSkuIdByProdIdAndActPrice" resultType="java.lang.Long">
        SELECT sku_id FROM tz_group_sku WHERE group_activity_id = #{groupActivityId} AND act_price = #{actPrice} LIMIT 1
    </select>
    <!--    <select id="getSkuInfoByGroupSkuId" resultType="com.yami.shop.groupbuy.common.api.dto.ApiGroupSkuInfoDto">-->
<!--        SELECT-->
<!--            gs.`group_prod_id`,-->
<!--            gs.`sku_id`,-->
<!--            gs.`group_sku_id`,-->
<!--            gs.`sku_id`,-->
<!--            p.category_id,-->
<!--            gs.`act_price`,-->
<!--            s.`price`,-->
<!--            IFNULL(sl.`sku_name`,s.`sku_name`) as sku_name,-->
<!--            s.`stocks`,-->
<!--            s.`pic` AS sku_pic,-->
<!--            IFNULL(pl.`prod_name`,p.`prod_name`) as prod_name,-->
<!--            p.`mold`,-->
<!--            p.`virtual_remark`,-->
<!--            p.`write_off_num`,-->
<!--            p.`write_off_time`,-->
<!--            p.`write_off_start`,-->
<!--            p.`write_off_end`,-->
<!--            p.`is_refund`,-->
<!--            p.`status` as prod_status,-->
<!--            p.pic AS prod_pic,-->
<!--            sd.`shop_id`,-->
<!--            sd.`shop_name`-->
<!--        FROM tz_group_sku gs-->
<!--        LEFT JOIN tz_sku s ON s.`sku_id` = gs.`sku_id`-->
<!--        LEFT JOIN tz_sku_lang sl ON s.`sku_id` = sl.`sku_id` AND sl.`lang` = #{lang}-->
<!--        LEFT JOIN tz_prod p ON s.`prod_id` = p.`prod_id`-->
<!--        LEFT JOIN tz_prod_lang pl ON pl.`prod_id` = p.`prod_id` AND pl.`lang` = #{lang}-->
<!--        LEFT JOIN tz_shop_detail sd ON sd.`shop_id` = p.`shop_id`-->
<!--        WHERE gs.`group_sku_id` = #{groupSkuId}  AND s.`status` = 1 AND p.`status` = 1 AND s.`stocks`> 0-->
<!--    </select>-->
</mapper>
yami-shop-groupbuy/yami-shop-groupbuy-common/src/main/resources/mapper/GroupTeamMapper.xml
New file
@@ -0,0 +1,184 @@
<?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.yami.shop.groupbuy.common.dao.GroupTeamMapper">
    <resultMap id="groupTeamMap" type="com.yami.shop.groupbuy.common.model.GroupTeam">
        <id column="group_team_id" property="groupTeamId"/>
        <result column="shop_id" property="shopId"/>
        <result column="group_activity_id" property="groupActivityId"/>
        <result column="prod_id" property="prodId"/>
        <result column="join_num" property="joinNum"/>
        <result column="status" property="status"/>
        <result column="total_price" property="totalPrice"/>
        <result column="start_time" property="startTime"/>
        <result column="end_time" property="endTime"/>
        <result column="create_time" property="createTime"/>
        <result column="share_user_id" property="shareUserId"/>
        <result column="update_time" property="updateTime"/>
    </resultMap>
    <resultMap type="com.yami.shop.bean.model.Order" id="orderAndOrderItemMap">
        <id column="order_id" jdbcType="BIGINT" property="orderId"/>
        <result column="shop_id" jdbcType="BIGINT" property="shopId"/>
        <result column="prod_name" jdbcType="VARCHAR" property="prodName"/>
        <result column="user_id" jdbcType="VARCHAR" property="userId"/>
        <result column="order_number" jdbcType="VARCHAR" property="orderNumber"/>
        <result column="total" jdbcType="DECIMAL" property="total"/>
        <result column="actual_total" jdbcType="DECIMAL" property="actualTotal"/>
        <result column="pay_type" jdbcType="INTEGER" property="payType"/>
        <result column="remarks" jdbcType="VARCHAR" property="remarks"/>
        <result column="status" jdbcType="INTEGER" property="status"/>
        <result column="dvy_type" jdbcType="VARCHAR" property="dvyType"/>
        <result column="dvy_id" jdbcType="BIGINT" property="dvyId"/>
        <result column="dvy_flow_id" jdbcType="VARCHAR" property="dvyFlowId"/>
        <result column="freight_amount" jdbcType="DECIMAL" property="freightAmount"/>
        <result column="addr_order_id" jdbcType="BIGINT" property="addrOrderId"/>
        <result column="product_nums" jdbcType="INTEGER" property="productNums"/>
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
        <result column="pay_time" jdbcType="TIMESTAMP" property="payTime"/>
        <result column="dvy_time" jdbcType="TIMESTAMP" property="dvyTime"/>
        <result column="finally_time" jdbcType="TIMESTAMP" property="finallyTime"/>
        <result column="cancel_time" jdbcType="TIMESTAMP" property="cancelTime"/>
        <result column="is_payed" jdbcType="BIT" property="isPayed"/>
        <result column="delete_status" jdbcType="INTEGER" property="deleteStatus"/>
        <result column="refund_status" jdbcType="INTEGER" property="refundStatus"/>
        <result column="order_type" jdbcType="INTEGER" property="orderType"/>
        <result column="close_type" jdbcType="INTEGER" property="closeType"/>
        <result column="order_mold" jdbcType="INTEGER" property="orderMold"/>
        <collection property="orderItems" ofType="com.yami.shop.bean.model.OrderItem">
            <id column="order_item_id" jdbcType="BIGINT" property="orderItemId"/>
            <result column="shop_id" jdbcType="BIGINT" property="shopId"/>
            <result column="order_number" jdbcType="VARCHAR" property="orderNumber"/>
            <result column="prod_id" jdbcType="BIGINT" property="prodId"/>
            <result column="sku_id" jdbcType="BIGINT" property="skuId"/>
            <result column="prod_count" jdbcType="INTEGER" property="prodCount"/>
            <result column="prod_name" jdbcType="VARCHAR" property="prodName"/>
            <result column="pic" jdbcType="VARCHAR" property="pic"/>
            <result column="price" jdbcType="DECIMAL" property="price"/>
            <result column="user_id" jdbcType="VARCHAR" property="userId"/>
            <result column="product_total_amount" jdbcType="DECIMAL" property="productTotalAmount"/>
            <result column="rec_time" jdbcType="TIMESTAMP" property="recTime"/>
            <result column="comm_sts" jdbcType="INTEGER" property="commSts"/>
            <result column="distribution_card_no" property="distributionCardNo"/>
            <result column="basket_date" property="basketDate"/>
            <result column="share_reduce" property="shareReduce"/>
            <result column="distribution_amount" property="distributionAmount"/>
            <result column="distribution_parent_amount" property="distributionParentAmount"/>
            <result column="return_money_sts" property="returnMoneySts"/>
        </collection>
    </resultMap>
    <select id="getPage" resultType="com.yami.shop.groupbuy.common.dto.GroupTeamDto">
        SELECT *,tp.prod_name,tp.pic
        FROM tz_group_team gt
        LEFT JOIN tz_group_activity ga ON gt.group_activity_id = ga.group_activity_id
        left join tz_prod tp on tp.prod_id = gt.prod_id
        <where>
            <if test="groupTeam.activityName != null and groupTeam.activityName != ''">
                AND ga.activity_name like concat('%',#{groupTeam.activityName},'%')
            </if>
            <if test="groupTeam.shopId != null">
                AND gt.shop_id = #{groupTeam.shopId}
            </if>
        </where>
        ORDER BY gt.create_time DESC
    </select>
    <select id="getGroupOrderPage" resultType="com.yami.shop.groupbuy.common.dto.GroupOrderDTO">
        SELECT tgo.pay_price - o.freight_amount  AS groupPrice,o.actual_total AS pay_price,tgo.*
        FROM `tz_group_order` tgo
        LEFT JOIN `tz_order` o ON o.`order_number` = tgo.`order_number`
        WHERE tgo.`group_team_id` = #{groupOrder.groupTeamId}
    </select>
    <select id="listByJoinGroupAndNowDate" resultType="com.yami.shop.groupbuy.common.api.dto.ApiGroupTeamDto">
        SELECT
            gt.*,
            ga.group_number AS group_number,
            u.nick_name AS share_nick_name,
            u.pic AS share_pic
        FROM tz_group_team gt
        INNER JOIN tz_group_activity ga ON gt.group_activity_id = ga.group_activity_id
        INNER JOIN tz_user u ON gt.share_user_id = u.user_id
        WHERE gt.group_activity_id = #{groupActivityId} AND gt.`status` = 1
        AND gt.start_time &lt;= #{nowTime} AND gt.end_time &gt;= #{nowTime}
        ORDER BY (ga.group_number - gt.join_num) ASC, gt.end_time ASC, gt.start_time DESC LIMIT #{showSize};
    </select>
    <select id="getApiGroupTeamDtoByTeamId" resultType="com.yami.shop.groupbuy.common.api.dto.ApiGroupTeamDto">
        SELECT
            gt.prod_id as group_prod_id,
            gt.*,
            ga.group_number AS group_number
        FROM tz_group_team gt
        LEFT JOIN tz_group_activity ga ON gt.group_activity_id = ga.group_activity_id
        WHERE gt.group_team_id = #{groupTeamId}
    </select>
    <select id="getJoinGroupTeamHasMaxNum" resultType="com.yami.shop.groupbuy.common.api.dto.ApiJoinGroupTeamDto">
        SELECT
        gt.group_team_id AS join_group_team_id
        FROM tz_group_team gt
        LEFT JOIN tz_group_order go ON gt.group_team_id = go.group_team_id
        WHERE gt.`status` != 3 AND gt.group_activity_id = #{groupActivityId}
        ORDER BY gt.start_time DESC LIMIT 1
    </select>
    <select id="getNotGroupTeamByNowDate" resultType="com.yami.shop.groupbuy.common.model.GroupTeam">
        SELECT
        gt.*,
        ga.has_robot AS has_robot,
        ga.group_number AS group_number
        FROM tz_group_team gt
        LEFT JOIN tz_group_activity ga ON gt.group_activity_id = ga.group_activity_id
        -- 活动结束 待成团、拼团中
        WHERE (gt.`status` IN (0,1) AND ga.`status` <![CDATA[ <> ]]>1 AND ga.end_time &lt; #{nowDate})
        -- 活动正常 团队结束 拼团中、待成团
        OR    (gt.`status` IN (0,1) AND ga.`status` = 1 AND ga.end_time &gt;= #{nowDate} AND gt.end_time &lt; #{nowDate})
    </select>
    <select id="getJoinNotGroupTeamOrder" resultType="com.yami.shop.groupbuy.common.dto.GroupRefundOrder">
        SELECT
        o.*,
        os.pay_no AS order_pay_no,
        os.settlement_id AS settlement_id,
            os.pay_status as pay_status, go.group_order_id as group_order_id
        FROM tz_group_order go
        INNER JOIN tz_order o ON go.order_number = o.order_number
        INNER JOIN tz_order_settlement os ON o.order_number = os.order_number
        WHERE go.group_team_id = #{groupTeamId}
    </select>
    <select id="getOrders" resultMap="orderAndOrderItemMap">
        SELECT o.*,oi.* FROM tz_group_team gt
        JOIN tz_group_order go ON gt.group_team_id = go.group_team_id
        JOIN tz_order o ON go.order_number = o.order_number
        join tz_order_item oi on o.order_number = oi.order_number
        WHERE gt.group_team_id = #{groupTeamId}
        <if test="status != null">
            and go.status = #{status}
        </if>
    </select>
    <select id="getNotGroupTeamsByActivityId" resultType="com.yami.shop.groupbuy.common.model.GroupTeam">
        SELECT
        gt.*,
        ga.has_robot AS has_robot,
        ga.group_number AS group_number
        FROM tz_group_team gt
        LEFT JOIN tz_group_activity ga ON gt.group_activity_id = ga.group_activity_id
        WHERE gt.`status` = 0 OR gt.`status` = 1 AND ga.`status` = 1
        AND  ga.group_activity_id = #{groupActivityId}
    </select>
    <select id="getNotGroupTeamByProdId" resultType="com.yami.shop.groupbuy.common.model.GroupTeam"
            parameterType="java.lang.Long">
        SELECT
        gt.*,
        ga.has_robot AS has_robot,
        ga.group_number AS group_number
        FROM tz_group_team gt
        LEFT JOIN tz_group_activity ga ON gt.group_activity_id = ga.group_activity_id
        WHERE gt.`status` = 0 OR gt.`status` = 1 AND ga.`status` = 1
        AND  gt.prod_id = #{prodId}
    </select>
</mapper>
yami-shop-groupbuy/yami-shop-groupbuy-multishop/pom.xml
New file
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.yami.shop</groupId>
        <artifactId>yami-shop-groupbuy</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>yami-shop-groupbuy-multishop</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <modelVersion>4.0.0</modelVersion>
    <description>商城团购模块后台管理部分</description>
    <dependencies>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-groupbuy-common</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-security-multishop</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
    </dependencies>
</project>
yami-shop-groupbuy/yami-shop-groupbuy-multishop/src/main/java/com/yami/shop/groupbuy/multishop/config/SwaggerConfiguration.java
New file
@@ -0,0 +1,35 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.multishop.config;
import lombok.AllArgsConstructor;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * @author Yami
 */
@Configuration("groupbuySwaggerConfiguration")
@AllArgsConstructor
public class SwaggerConfiguration {
    @Bean
    public GroupedOpenApi groupBuyRestApi() {
        return GroupedOpenApi.builder()
                .group("团购活动接口")
                .packagesToScan("com.yami.shop.groupbuy.multishop.controller")
                .pathsToMatch("/**")
                .build();
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-multishop/src/main/java/com/yami/shop/groupbuy/multishop/controller/GroupActivityController.java
New file
@@ -0,0 +1,246 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.multishop.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.dto.ProdAndSkuListsDto;
import com.yami.shop.bean.enums.EsOperationType;
import com.yami.shop.bean.enums.OfflineHandleEventType;
import com.yami.shop.bean.enums.ShopStatus;
import com.yami.shop.bean.event.EsProductUpdateEvent;
import com.yami.shop.bean.model.OfflineHandleEvent;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.bean.param.OfflineHandleEventAuditParam;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.groupbuy.common.dto.GroupActivityDto;
import com.yami.shop.groupbuy.common.dto.GroupProdAndSkuListDto;
import com.yami.shop.groupbuy.common.enums.ActivityStatusEnum;
import com.yami.shop.groupbuy.common.model.GroupActivity;
import com.yami.shop.groupbuy.common.service.GroupActivityService;
import com.yami.shop.security.multishop.util.SecurityUtils;
import com.yami.shop.service.OfflineHandleEventService;
import com.yami.shop.service.ProductService;
import com.yami.shop.service.ShopDetailService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * 拼团活动表
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/group/activity")
@Tag(name = "商家端拼团活动接口")
public class GroupActivityController {
    private final MapperFacade mapperFacade;
    private final ProductService productService;
    private final ApplicationEventPublisher eventPublisher;
    private final GroupActivityService groupActivityService;
    private final OfflineHandleEventService offlineHandleEventService;
    private final ShopDetailService shopDetailService;
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('group:activity:page')")
    @Operation(summary = "分页获取拼团活动列表")
    public ServerResponseEntity<IPage<GroupActivityDto>> getGroupActivityPage(PageParam<GroupActivityDto> page, @ParameterObject GroupActivityDto groupActivityDto) {
        groupActivityDto.setLang(I18nMessage.getDbLang());
        groupActivityDto.setShopId(SecurityUtils.getShopUser().getShopId());
        return ServerResponseEntity.success(groupActivityService.getGroupActivityPage(page, groupActivityDto));
    }
    @GetMapping("/info/{groupActivityId}")
    @Operation(summary = "通过id查询拼团活动表")
    @Parameter(name = "groupActivityId", description = "拼团活动id" , required = true)
    public ServerResponseEntity<GroupActivity> getById(@PathVariable("groupActivityId") Long groupActivityId) {
        GroupActivity groupActivity = groupActivityService.getGroupActivityInfo(groupActivityId);
        if (!Objects.equals(SecurityUtils.getShopUser().getShopId(), groupActivity.getShopId())) {
            throw new YamiShopBindException("yami.no.auth");
        }
        return ServerResponseEntity.success(groupActivity);
    }
    @PostMapping
    @PreAuthorize("@pms.hasPermission('group:activity:save')")
    @Operation(summary = "新增拼团活动表")
    public ServerResponseEntity<Long> save(@RequestBody @Valid GroupActivity groupActivity) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId);
        if (!Objects.equals(shopDetail.getShopStatus(), ShopStatus.STOP.value()) && !Objects.equals(shopDetail.getShopStatus(), ShopStatus.OPEN.value())) {
            // 店铺处于违规下线中,不能进行此操作,请联系管理员后重试
            throw new YamiShopBindException("yami.product.shop.offline");
        }
        if (Objects.isNull(groupActivity.getProdId())) {
            // 请选择商品
            throw new YamiShopBindException("yami.score.select.num");
        }
        if (CollUtil.isEmpty(groupActivity.getGroupSkuList())) {
            // sku列表不能为空
            throw new YamiShopBindException("yami.sku.cannot.empty");
        }
        Date now = new Date();
        // 未启用状态
        groupActivity.setStatus(2);
        groupActivity.setShopId(shopId);
        groupActivityService.saveGroupActivity(groupActivity);
        productService.removeProdCacheByProdId(groupActivity.getProdId());
        groupActivityService.removeGroupActivityInfoCache(groupActivity.getProdId());
        // 更新商品信息
        eventPublisher.publishEvent(new EsProductUpdateEvent(groupActivity.getProdId(), null, EsOperationType.UPDATE));
        return ServerResponseEntity.success(groupActivity.getGroupActivityId());
    }
    @PutMapping
    @PreAuthorize("@pms.hasPermission('group:activity:update')")
    @Operation(summary = "修改拼团活动表")
    public ServerResponseEntity<Boolean> updateById(@RequestBody @Valid GroupActivity groupActivity) {
        if (CollUtil.isEmpty(groupActivity.getGroupSkuList())) {
            // sku列表不能为空
            throw new YamiShopBindException("yami.sku.cannot.empty");
        }
        Long prodId = groupActivity.getProdId();
        groupActivity.setShopId(SecurityUtils.getShopUser().getShopId());
        groupActivityService.updateGroupActivity(groupActivity);
        groupActivityService.removeGroupActivityInfoCache(prodId);
        // 更新商品信息
        eventPublisher.publishEvent(new EsProductUpdateEvent(prodId, null, EsOperationType.UPDATE));
        return ServerResponseEntity.success(Boolean.TRUE);
    }
    @PutMapping("/active/{groupActivityId}")
    @Operation(summary = "通过id启用拼团活动")
    @Parameter(name = "groupActivityId", description = "拼团活动id" , required = true)
    public ServerResponseEntity<Boolean> activeGroupActivity(@PathVariable Long groupActivityId) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        GroupActivity groupActivity = groupActivityService.getById(groupActivityId);
        if (groupActivity == null) {
            // 未找到此活动,请稍后重试
            throw new YamiShopBindException("yami.activity.cannot.find");
        }
        if (!Objects.equals(shopId, groupActivity.getShopId())) {
            throw new YamiShopBindException("当前拼团活动不属于您的店铺");
        }
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId);
        if (!Objects.equals(shopDetail.getShopStatus(), ShopStatus.STOP.value()) && !Objects.equals(shopDetail.getShopStatus(), ShopStatus.OPEN.value())) {
            throw new YamiShopBindException("店铺处于违规下架状态,不能启用拼团活动");
        }
        int compare = DateUtil.compare(groupActivity.getEndTime(), DateUtil.date());
        if (compare <= 0) {
            // 当前时间已超过活动结束时间,不能启用活动
            throw new YamiShopBindException("yami.activity.now.over.end.time");
        }
        // 启用状态
        GroupActivity newGroupActivity = new GroupActivity();
        newGroupActivity.setGroupActivityId(groupActivityId);
        newGroupActivity.setStatus(1);
        groupActivityService.updateById(newGroupActivity);
        groupActivityService.removeGroupActivityInfoCache(groupActivity.getProdId());
        eventPublisher.publishEvent(new EsProductUpdateEvent(groupActivity.getProdId(), null, EsOperationType.UPDATE));
        return ServerResponseEntity.success(true);
    }
    @DeleteMapping("/{groupActivityId}")
    @PreAuthorize("@pms.hasPermission('group:activity:delete')")
    @Operation(summary = "删除拼团活动表")
    @Parameter(name = "groupActivityId", description = "拼团活动id" , required = true)
    public ServerResponseEntity<Boolean> removeById(@PathVariable Long groupActivityId) {
        // 查看活动是否为失效状态或者活动结束
        GroupActivity groupActivity = groupActivityService.getById(groupActivityId);
        if (Objects.isNull(groupActivity)) {
            // 未找到此活动,请稍后重试
            throw new YamiShopBindException("yami.activity.cannot.find");
        }
        boolean canDelete = !(Objects.equals(groupActivity.getActivityStatus(), ActivityStatusEnum.EXPIRED.value()) ||
                (groupActivity.getActivityStatus() >= 3 && groupActivity.getActivityStatus() <= 6));
        if (canDelete && groupActivity.getActivityStatus() != 1) {
            // 该活动状态下不能进行删除
            throw new YamiShopBindException("yami.activity.cannot.delete");
        }
        groupActivityService.updateToDelete(groupActivity);
        // 获取该活动下的所有商品
        productService.removeProdCacheByProdId(groupActivity.getProdId());
        eventPublisher.publishEvent(new EsProductUpdateEvent(groupActivity.getProdId(), null, EsOperationType.UPDATE));
        groupActivityService.removeGroupActivityInfoCache(groupActivity.getProdId());
        return ServerResponseEntity.success(true);
    }
    /**
     * 获取活动商品的信息及商品下规格信息
     */
    @GetMapping("/getProdAndSkuLists")
    @Operation(summary = "通过商品id列表获取活动商品的信息及商品下规格信息")
    @Parameter(name = "prodIds", description = "商品id" , required = true)
    public ServerResponseEntity<List<GroupProdAndSkuListDto>> getProdAndSkuLists(@RequestParam List<Long> prodIds) {
        List<ProdAndSkuListsDto> prodAndSkuListsDtoList = productService.getProdAndSkuLists(prodIds);
        List<GroupProdAndSkuListDto> groupProdAndSkuLists = mapperFacade.mapAsList(prodAndSkuListsDtoList, GroupProdAndSkuListDto.class);
        return ServerResponseEntity.success(groupProdAndSkuLists);
    }
    @PutMapping("/invalid/{groupActivityId}")
    @PreAuthorize("@pms.hasPermission('group:activity:invalid')")
    @Operation(summary = "失效进行中的拼团活动")
    @Parameter(name = "groupActivityId", description = "拼团活动id" , required = true)
    public ServerResponseEntity<Boolean> invalidActivity(@PathVariable Long groupActivityId) {
        // 查看活动
        GroupActivity groupActivity = groupActivityService.getById(groupActivityId);
        //不是进行中的也不是预热启动的活动
        boolean canInvalid = Objects.isNull(groupActivity) || (!Objects.equals(groupActivity.getActivityStatus(), ActivityStatusEnum.UNDER_WAY.value())
                && !(Objects.equals(groupActivity.getActivityStatus(), ActivityStatusEnum.NOT_STARTED.value()) && Objects.equals(groupActivity.getStatus(), 1)));
        if (canInvalid) {
            // 失效失败,活动不在进行中无法进行失效操作
            throw new YamiShopBindException("yami.activity.disable");
        }
        Long shopId = SecurityUtils.getShopUser().getShopId();
        if (!Objects.equals(groupActivity.getShopId(), shopId)) {
            // 您无权操作此活动
            throw new YamiShopBindException("yami.activity.no.auth");
        }
        groupActivityService.invalidGroupActivity(groupActivityId);
        eventPublisher.publishEvent(new EsProductUpdateEvent(groupActivity.getProdId(), null, EsOperationType.UPDATE));
        groupActivityService.removeGroupActivityInfoCache(groupActivity.getProdId());
        return ServerResponseEntity.success(true);
    }
    @GetMapping("/getOfflineHandleEventByActivityId/{activityId}")
    @Operation(summary = "通过活动id获取下线信息")
    @Parameter(name = "activityId", description = "活动id" , required = true)
    public ServerResponseEntity<OfflineHandleEvent> getOfflineHandleEventByActivityId(@PathVariable("activityId") Long activityId) {
        OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.GROUP_BUY.getValue(), activityId);
        return ServerResponseEntity.success(offlineHandleEvent);
    }
    @PostMapping("/auditApply")
    @PreAuthorize("@pms.hasPermission('group:activity:auditApply')")
    @Operation(summary = "申请审核拼团活动")
    public ServerResponseEntity<Void> auditApply(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) {
        groupActivityService.auditApply(offlineHandleEventAuditParam.getEventId(), offlineHandleEventAuditParam.getHandleId(), offlineHandleEventAuditParam.getReapplyReason());
        return ServerResponseEntity.success();
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-multishop/src/main/java/com/yami/shop/groupbuy/multishop/controller/GroupOrderController.java
New file
@@ -0,0 +1,78 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.multishop.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.groupbuy.common.model.GroupOrder;
import com.yami.shop.groupbuy.common.service.GroupOrderService;
import com.yami.shop.security.multishop.util.SecurityUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Objects;
/**
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@RestController
@RequestMapping("/group/order")
@Tag(name = "商家端团购订单接口")
public class GroupOrderController {
    @Autowired
    private GroupOrderService groupOrderService;
    @GetMapping("/page")
    @Operation(summary = "分页查找团购订单列表")
    public ServerResponseEntity<IPage<GroupOrder>> getGroupOrderPage(PageParam<GroupOrder> page, @ParameterObject GroupOrder groupOrder) {
        return ServerResponseEntity.success(groupOrderService.page(page, new LambdaQueryWrapper<GroupOrder>()));
    }
    @GetMapping("/info/{groupOrderId}")
    @Operation(summary = "通过id查询团购订单活动")
    @Parameter(name = "groupOrderId", description = "团购订单id" , required = true)
    public ServerResponseEntity<GroupOrder> getById(@PathVariable("groupOrderId") Long groupOrderId) {
        GroupOrder groupOrder = groupOrderService.getById(groupOrderId);
        if (!Objects.equals(SecurityUtils.getShopUser().getShopId(), groupOrder.getShopId())) {
            throw new YamiShopBindException("yami.no.auth");
        }
        return ServerResponseEntity.success(groupOrder);
    }
    @PostMapping
    @Operation(summary = "新增团购订单")
    public ServerResponseEntity<Boolean> save(@RequestBody @Valid GroupOrder groupOrder) {
        return ServerResponseEntity.success(groupOrderService.save(groupOrder));
    }
    @PutMapping
    @Operation(summary = "修改团购订单")
    public ServerResponseEntity<Boolean> updateById(@RequestBody @Valid GroupOrder groupOrder) {
        return ServerResponseEntity.success(groupOrderService.updateById(groupOrder));
    }
    @DeleteMapping("/{groupOrderId}")
    @Operation(summary = "通过id删除团购订单活动")
    @Parameter(name = "groupOrderId", description = "团购订单id" , required = true)
    public ServerResponseEntity<Boolean> removeById(@PathVariable Long groupOrderId) {
        return ServerResponseEntity.success(groupOrderService.removeById(groupOrderId));
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-multishop/src/main/java/com/yami/shop/groupbuy/multishop/controller/GroupSkuController.java
New file
@@ -0,0 +1,71 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.multishop.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.groupbuy.common.model.GroupSku;
import com.yami.shop.groupbuy.common.service.GroupSkuService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import lombok.AllArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@RestController
@AllArgsConstructor
@RequestMapping("/group/sku")
@Tag(name = "商家端团购商品规格接口")
public class GroupSkuController {
    private final GroupSkuService groupSkuService;
    @GetMapping("/page")
    @Operation(summary = "分页查找团购商品规格列表")
    public ServerResponseEntity<IPage<GroupSku>> getGroupSkuPage(PageParam<GroupSku> page, @ParameterObject GroupSku groupSku) {
        return ServerResponseEntity.success(groupSkuService.page(page, new LambdaQueryWrapper<GroupSku>()));
    }
    @GetMapping("/info/{groupSkuId}")
    @Operation(summary = "通过id查询团购商品规格活动")
    @Parameter(name = "groupSkuId", description = "团购商品规格id" , required = true)
    public ServerResponseEntity<GroupSku> getById(@PathVariable("groupSkuId") Long groupSkuId) {
        return ServerResponseEntity.success(groupSkuService.getById(groupSkuId));
    }
    @PostMapping
    @Operation(summary = "新增拼团活动商品规格")
    public ServerResponseEntity<Boolean> save(@RequestBody @Valid GroupSku groupSku) {
        return ServerResponseEntity.success(groupSkuService.save(groupSku));
    }
    @PutMapping
    @Operation(summary = "修改拼团活动商品规格")
    public ServerResponseEntity<Boolean> updateById(@RequestBody @Valid GroupSku groupSku) {
        return ServerResponseEntity.success(groupSkuService.updateById(groupSku));
    }
    @DeleteMapping("/{groupSkuId}")
    @Operation(summary = "通过id删除拼团活动商品规格")
    @Parameter(name = "groupSkuId", description = "团购商品规格id" , required = true)
    public ServerResponseEntity<Boolean> removeById(@PathVariable Long groupSkuId) {
        return ServerResponseEntity.success(groupSkuService.removeById(groupSkuId));
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-multishop/src/main/java/com/yami/shop/groupbuy/multishop/controller/GroupTeamController.java
New file
@@ -0,0 +1,58 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.multishop.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.groupbuy.common.dto.GroupOrderDTO;
import com.yami.shop.groupbuy.common.dto.GroupTeamDto;
import com.yami.shop.groupbuy.common.model.GroupOrder;
import com.yami.shop.groupbuy.common.model.GroupTeam;
import com.yami.shop.groupbuy.common.service.GroupTeamService;
import com.yami.shop.security.multishop.util.SecurityUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.AllArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * 拼团团队表
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@RestController
@AllArgsConstructor
@RequestMapping("/group/team")
@Tag(name = "商家端拼团团队接口")
public class GroupTeamController {
    private final GroupTeamService groupTeamService;
    @GetMapping("/page")
    @Operation(summary = "分页查找拼团团队列表")
    public ServerResponseEntity<IPage<GroupTeamDto>> getGroupTeamPage(PageParam<GroupTeam> page, @ParameterObject GroupTeamDto groupTeamDto) {
        groupTeamDto.setShopId(SecurityUtils.getShopUser().getShopId());
        IPage<GroupTeamDto> pageList = groupTeamService.getPage(page, groupTeamDto);
        return ServerResponseEntity.success(pageList);
    }
    @GetMapping("/info")
    @Operation(summary = "查看同团订单列表")
    public ServerResponseEntity<IPage<GroupOrderDTO>> getById(PageParam<GroupOrder> page, @ParameterObject GroupOrder groupOrder) {
        IPage<GroupOrderDTO> orderPage = groupTeamService.getGroupOrderPage(page, groupOrder);
        return ServerResponseEntity.success(orderPage);
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-platform/pom.xml
New file
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.yami.shop</groupId>
        <artifactId>yami-shop-groupbuy</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>yami-shop-groupbuy-platform</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <modelVersion>4.0.0</modelVersion>
    <description>商城团购模块后台管理部分</description>
    <dependencies>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-groupbuy-common</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-security-platform</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
    </dependencies>
</project>
yami-shop-groupbuy/yami-shop-groupbuy-platform/src/main/java/com/yami/shop/groupbuy/platform/config/SwaggerConfiguration.java
New file
@@ -0,0 +1,34 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.platform.config;
import lombok.AllArgsConstructor;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * @author Yami
 */
@Configuration("groupbuySwaggerConfiguration")
@AllArgsConstructor
public class SwaggerConfiguration {
    @Bean
    public GroupedOpenApi groupBuyRestApi() {
        return GroupedOpenApi.builder()
                .group("团购活动接口")
                .packagesToScan("com.yami.shop.groupbuy.platform.controller")
                .pathsToMatch("/**")
                .build();
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-platform/src/main/java/com/yami/shop/groupbuy/platform/controller/GroupActivityController.java
New file
@@ -0,0 +1,143 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.platform.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.enums.EsOperationType;
import com.yami.shop.bean.enums.OfflineHandleEventType;
import com.yami.shop.bean.enums.SendType;
import com.yami.shop.bean.event.EsProductUpdateEvent;
import com.yami.shop.bean.event.SendMessageEvent;
import com.yami.shop.bean.model.OfflineHandleEvent;
import com.yami.shop.bean.param.NotifyTemplateParam;
import com.yami.shop.bean.param.OfflineHandleEventAuditParam;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.groupbuy.common.dto.GroupActivityDto;
import com.yami.shop.groupbuy.common.enums.ActivityStatusEnum;
import com.yami.shop.groupbuy.common.model.GroupActivity;
import com.yami.shop.groupbuy.common.service.GroupActivityService;
import com.yami.shop.security.platform.util.SecurityUtils;
import com.yami.shop.service.OfflineHandleEventService;
import com.yami.shop.service.ProductService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.Objects;
/**
 * @author Yami
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/platform/group/activity")
@Tag(name = "平台端团购活动接口")
public class GroupActivityController {
    private final OfflineHandleEventService offlineHandleEventService;
    private final GroupActivityService groupActivityService;
    private final ProductService productService;
    private final ApplicationEventPublisher eventPublisher;
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('group:activity:page')")
    @Operation(summary = "分页查找团购活动列表")
    public ServerResponseEntity<IPage<GroupActivityDto>> getGroupActivityPage(PageParam<GroupActivityDto> page, @ParameterObject GroupActivityDto groupActivityDto) {
        groupActivityDto.setLang(I18nMessage.getDbLang());
        return ServerResponseEntity.success(groupActivityService.getGroupActivityPage(page, groupActivityDto));
    }
    @GetMapping("/info/{groupActivityId}")
    @PreAuthorize("@pms.hasPermission('group:activity:info')")
    @Operation(summary = "通过id查询团购活动")
    @Parameter(name = "groupActivityId", description = "团购活动id" , required = true)
    public ServerResponseEntity<GroupActivity> getById(@PathVariable("groupActivityId") Long groupActivityId) {
        return ServerResponseEntity.success(groupActivityService.getGroupActivityInfo(groupActivityId));
    }
    @DeleteMapping("/{groupActivityId}")
    @PreAuthorize("@pms.hasPermission('group:activity:delete')")
    @Operation(summary = "通过id删除拼团活动表")
    @Parameter(name = "groupActivityId", description = "团购活动id" , required = true)
    public ServerResponseEntity<Boolean> removeById(@PathVariable Long groupActivityId) {
        // 查看活动是否为失效状态或者活动结束
        GroupActivity groupActivity = groupActivityService.getById(groupActivityId);
        if (Objects.isNull(groupActivity)) {
            // 未找到此活动,请稍后重试
            throw new YamiShopBindException("yami.activity.cannot.find");
        }
        // 如果活动状态不在 【未开始】、【已结束】、【已失效】、【违规下架】、【等待审核】的状态下无法进行删除操作
        boolean canDelete = !(Objects.equals(groupActivity.getActivityStatus(), ActivityStatusEnum.EXPIRED.value()) ||
                (groupActivity.getActivityStatus() >= 3 && groupActivity.getActivityStatus() <= 6));
        if (canDelete) {
            // 该活动状态下不能进行删除
            throw new YamiShopBindException("yami.activity.cannot.delete");
        }
        groupActivityService.updateToDelete(groupActivity);
        // 获取该活动下的所有商品
        productService.removeProdCacheByProdId(groupActivity.getProdId());
        eventPublisher.publishEvent(new EsProductUpdateEvent(groupActivity.getProdId(), null, EsOperationType.UPDATE));
        groupActivityService.removeGroupActivityInfoCache(groupActivity.getProdId());
        return ServerResponseEntity.success(true);
    }
    @GetMapping("/getOfflineHandleEventByActivityId/{activityId}")
    @PreAuthorize("@pms.hasPermission('group:activity:info')")
    @Operation(summary = "通过活动id获取下线信息")
    @Parameter(name = "activityId", description = "活动id" , required = true)
    public ServerResponseEntity<OfflineHandleEvent> getOfflineHandleEventByActivityId(@PathVariable("activityId") Long activityId) {
        OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.GROUP_BUY.getValue(), activityId);
        return ServerResponseEntity.success(offlineHandleEvent);
    }
    @PostMapping("/offline")
    @PreAuthorize("@pms.hasPermission('group:activity:update')")
    @Operation(summary = "下线活动")
    public ServerResponseEntity<Void> offline(@RequestBody OfflineHandleEvent offlineHandleEvent) {
        GroupActivity groupActivity = groupActivityService.getById(offlineHandleEvent.getHandleId());
        if (groupActivity == null) {
            // 未找到此活动,请稍后重试
            throw new YamiShopBindException("yami.activity.cannot.find");
        }
        if (Objects.equals(groupActivity.getStatus(),-1)) {
            //活动已被删除,请刷新页面重试
            throw new YamiShopBindException("yami.active.is.delete");
        }
        Long sysUserId = SecurityUtils.getSysUser().getUserId();
        groupActivityService.offline(groupActivity, offlineHandleEvent.getOfflineReason(), sysUserId);
        eventPublisher.publishEvent(new EsProductUpdateEvent(groupActivity.getProdId(), null, EsOperationType.UPDATE));
        //发送活动下架提醒给商家
        NotifyTemplateParam shopParam = new NotifyTemplateParam();
        shopParam.setShopId(groupActivity.getShopId());
        shopParam.setActivityId(groupActivity.getGroupActivityId());
        shopParam.setActivityName(groupActivity.getActivityName());
        shopParam.setSendType(SendType.ACTIVITY_OFFLINE.getValue());
        eventPublisher.publishEvent(new SendMessageEvent(shopParam));
        groupActivityService.removeGroupActivityInfoCache(groupActivity.getProdId());
        return ServerResponseEntity.success();
    }
    @PostMapping("/auditGroupActivity")
    @PreAuthorize("@pms.hasPermission('group:activity:update')")
    @Operation(summary = "审核活动")
    public ServerResponseEntity<Void> auditGroupActivity(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) {
        Long sysUserId = SecurityUtils.getSysUser().getUserId();
        groupActivityService.auditGroupActivity(offlineHandleEventAuditParam, sysUserId);
        return ServerResponseEntity.success();
    }
}
yami-shop-groupbuy/yami-shop-groupbuy-platform/src/main/java/com/yami/shop/groupbuy/platform/task/GroupBuyTask.java
New file
@@ -0,0 +1,69 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.groupbuy.platform.task;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.yami.shop.groupbuy.common.model.GroupTeam;
import com.yami.shop.groupbuy.common.service.GroupActivityService;
import com.yami.shop.groupbuy.common.service.GroupTeamService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
 * 拼团任务定时任务
 *
 * @author 小懒虫
 * @date 2019/9/3 11:41
 */
@Component
public class GroupBuyTask {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private GroupTeamService groupTeamService;
    @Autowired
    private  GroupActivityService groupActivityService;
    /**
     * 拼团活动/团订单结束任务
     */
    @XxlJob("activityFinish")
    public void activityFinish() {
        logger.info("取消拼团活动/团订单结束的任务。。。");
        // 获取活动结束或团单结束未成团的拼团团队
        List<GroupTeam> groupTeams = groupTeamService.getNotGroupTeam();
        if (groupTeams.size() > 0) {
            // 处理未成团的拼团团队,返回退款单列表
            for (GroupTeam groupTeam : groupTeams) {
                groupTeamService.updateNotGroupTeam(groupTeam);
            }
        }
    }
    /**
     * 拼团活动/团订单结束任务
     */
    @XxlJob("activityFinishAndProdChange")
    public void activityFinishAndProdChange() {
        logger.info("拼团活动结束,团购商品恢复为普通商品。。。");
        groupActivityService.changeProdTypeByGroupActivityIdList();
    }
}